@crisp-ui-kit/crisp 0.54.3 → 0.54.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/board.css +13 -1
- package/dist/board.layered.css +13 -1
- package/dist/cjs/components/tabletoolbar/tabletoolbar.js +41 -4
- package/dist/cjs/index.js +2 -0
- package/dist/cjs/product/board/board.js +60 -2
- package/dist/cjs/product/board/board.recipe.js +10 -0
- package/dist/cjs/product/comments/comments.js +426 -0
- package/dist/cjs/product/comments/comments.recipe.js +126 -0
- package/dist/cjs/product/comments/index.js +8 -0
- package/dist/cjs/product/listpage/listpage.recipe.js +10 -1
- package/dist/cjs/product/objectsettings/index.js +16 -0
- package/dist/cjs/product/objectsettings/objectsettings.js +365 -0
- package/dist/cjs/product/objectsettings/objectsettings.recipe.js +65 -0
- package/dist/cjs/product/taskstable/taskstable.recipe.js +10 -1
- package/dist/comments.css +80 -0
- package/dist/comments.d.ts +7 -0
- package/dist/comments.layered.css +82 -0
- package/dist/esm/components/tabletoolbar/tabletoolbar.js +43 -6
- package/dist/esm/index.js +2 -0
- package/dist/esm/product/board/board.js +61 -3
- package/dist/esm/product/board/board.recipe.js +10 -0
- package/dist/esm/product/comments/comments.js +388 -0
- package/dist/esm/product/comments/comments.recipe.js +123 -0
- package/dist/esm/product/comments/index.js +2 -0
- package/dist/esm/product/listpage/listpage.recipe.js +10 -1
- package/dist/esm/product/objectsettings/index.js +2 -0
- package/dist/esm/product/objectsettings/objectsettings.js +322 -0
- package/dist/esm/product/objectsettings/objectsettings.recipe.js +62 -0
- package/dist/esm/product/taskstable/taskstable.recipe.js +10 -1
- package/dist/listpage.css +8 -1
- package/dist/listpage.layered.css +8 -1
- package/dist/objectsettings.css +49 -0
- package/dist/objectsettings.d.ts +7 -0
- package/dist/objectsettings.layered.css +51 -0
- package/dist/styles.css +160 -3
- package/dist/styles.layered.css +160 -3
- package/dist/taskstable.css +8 -1
- package/dist/taskstable.layered.css +8 -1
- package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +8 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/product/board/board.d.ts +20 -1
- package/dist/types/product/comments/comments.d.ts +192 -0
- package/dist/types/product/comments/comments.recipe.d.ts +3 -0
- package/dist/types/product/comments/index.d.ts +2 -0
- package/dist/types/product/objectsettings/index.d.ts +2 -0
- package/dist/types/product/objectsettings/objectsettings.d.ts +261 -0
- package/dist/types/product/objectsettings/objectsettings.recipe.d.ts +3 -0
- package/package.json +11 -1
package/dist/styles.css
CHANGED
|
@@ -2025,8 +2025,20 @@
|
|
|
2025
2025
|
& .crisp-board-card[data-dragging] { opacity: 0.4; }
|
|
2026
2026
|
& .crisp-board-card:focus { outline: none; }
|
|
2027
2027
|
& .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
|
|
2028
|
+
/* #604: a per-column calc footer, mirroring the table's own (measured
|
|
2029
|
+
live, Deals pipeline). Sits below the scrollable card body, not
|
|
2030
|
+
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. */
|
|
2031
|
+
& .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
|
|
2032
|
+
& .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; }
|
|
2033
|
+
& .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
|
|
2034
|
+
& .crisp-board-col-calc[data-empty] { opacity: 0.7; }
|
|
2035
|
+
& .crisp-board-col-calc-label { text-transform: capitalize; }
|
|
2036
|
+
& .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
|
|
2028
2037
|
/* announced, never drawn */
|
|
2029
|
-
& .crisp-board-live {
|
|
2038
|
+
& .crisp-board-live {
|
|
2039
|
+
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
2040
|
+
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
|
|
2041
|
+
}
|
|
2030
2042
|
}
|
|
2031
2043
|
|
|
2032
2044
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -2078,6 +2090,87 @@
|
|
|
2078
2090
|
}
|
|
2079
2091
|
}
|
|
2080
2092
|
|
|
2093
|
+
.crisp-comments {
|
|
2094
|
+
display: flex; flex-direction: column; box-sizing: border-box; width: 320px; height: 100%; background: var(--crisp-bg-surface); border-inline-start: 1px solid var(--crisp-border-subtle); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
2095
|
+
& * { box-sizing: border-box; }
|
|
2096
|
+
& .crisp-comments-head { display: flex; align-items: center; gap: var(--crisp-space-1); flex-shrink: 0; height: 49px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); }
|
|
2097
|
+
& .crisp-comments-headbtn { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
2098
|
+
& .crisp-comments-headbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2099
|
+
& .crisp-comments-title-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
2100
|
+
& .crisp-comments-title { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2101
|
+
& .crisp-comments-breadcrumb { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2102
|
+
& .crisp-comments-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
|
|
2103
|
+
& .crisp-comments-body--pad-top { padding-top: var(--crisp-space-3); }
|
|
2104
|
+
/* One comment row -- avatar 16px (Avatar size="sm"), 6px gap to the name/time line, 14px/600 name + 12px/500 63%-muted time, 14px/400 body two lines below. Hover actions fade in flush with the name line. */
|
|
2105
|
+
& .crisp-comments-row { position: relative; display: flex; gap: var(--crisp-space-1-5); }
|
|
2106
|
+
& .crisp-comments-row-main { flex: 1; min-width: 0; }
|
|
2107
|
+
& .crisp-comments-row-head { display: flex; align-items: baseline; gap: var(--crisp-space-1-5); height: 20px; }
|
|
2108
|
+
& .crisp-comments-author { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
|
|
2109
|
+
& .crisp-comments-time { font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; }
|
|
2110
|
+
& .crisp-comments-resolved-label { display: flex; align-items: center; gap: var(--crisp-space-1); margin-bottom: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2111
|
+
& .crisp-comments-body-text { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
|
|
2112
|
+
/* Hover actions -- measured: 4 buttons, 28x28, radius 8, flush side-by-side (0 gap), transparent by default, 16px icon at 55% ink. */
|
|
2113
|
+
& .crisp-comments-row-actions { position: absolute; top: 0; inset-inline-end: 0; display: flex; opacity: 0; pointer-events: none; background: var(--crisp-bg-surface); }
|
|
2114
|
+
& .crisp-comments-row:hover .crisp-comments-row-actions, & .crisp-comments-row-actions:focus-within { opacity: 1; pointer-events: auto; }
|
|
2115
|
+
& .crisp-comments-action { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
2116
|
+
& .crisp-comments-action:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2117
|
+
& .crisp-comments-action[data-active] { color: var(--crisp-bg-brand-solid); }
|
|
2118
|
+
/* Reactions -- measured: 28px pill, radius 8, subtle 4% ink fill, padding 4px 8px 4px 6px, gap 4px between the emoji glyph and count. */
|
|
2119
|
+
& .crisp-comments-reactions { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-1-5); }
|
|
2120
|
+
& .crisp-comments-reaction { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 28px; padding: 4px 8px 4px 6px; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); font-family: inherit; font-size: 12px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); cursor: pointer; }
|
|
2121
|
+
& .crisp-comments-reaction[data-reacted] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
|
|
2122
|
+
& .crisp-comments-reaction-add { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: var(--crisp-radius-md); background: transparent; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; opacity: 0; transition: opacity .12s, background-color .12s; }
|
|
2123
|
+
& .crisp-comments-row:hover .crisp-comments-reaction-add { opacity: 1; }
|
|
2124
|
+
& .crisp-comments-reaction-add:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2125
|
+
/* Reply-in-thread view -- an indented block of replies below the root. */
|
|
2126
|
+
& .crisp-comments-replies { display: flex; flex-direction: column; gap: var(--crisp-space-4); margin-top: var(--crisp-space-3); padding-inline-start: var(--crisp-space-4); border-inline-start: 1px solid var(--crisp-border-subtle); }
|
|
2127
|
+
& .crisp-comments-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--crisp-space-1); padding: var(--crisp-space-6) var(--crisp-space-4); text-align: center; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-size: var(--crisp-text-lg); }
|
|
2128
|
+
/* Composer -- measured: 14px/20px body text, 16px gap above the reply/mention icon row, Comment button 84x32 padding 6px 10px radius 9 (= radius.lg) brand-solid fill, 14px/500 white label, opacity .4 disabled / 1 enabled (no color/background change between the two). */
|
|
2129
|
+
& .crisp-comments-composer { flex-shrink: 0; padding: var(--crisp-space-3) var(--crisp-space-4) var(--crisp-space-4); border-top: 1px solid var(--crisp-border-subtle); }
|
|
2130
|
+
& .crisp-comments-field { min-height: 20px; max-height: 120px; overflow-y: auto; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); outline: none; white-space: pre-wrap; word-break: break-word; }
|
|
2131
|
+
& .crisp-comments-field:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; }
|
|
2132
|
+
& .crisp-comments-field:empty::before { content: attr(data-placeholder); color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
2133
|
+
& .crisp-comments-composer-foot { display: flex; align-items: center; justify-content: space-between; margin-top: var(--crisp-space-4); }
|
|
2134
|
+
& .crisp-comments-composer-tools { display: flex; align-items: center; gap: var(--crisp-space-1); }
|
|
2135
|
+
& .crisp-comments-tool { 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; color: color-mix(in srgb, var(--crisp-fg-primary) 45%, transparent); font-family: inherit; cursor: pointer; }
|
|
2136
|
+
& .crisp-comments-tool:hover { color: var(--crisp-fg-primary); }
|
|
2137
|
+
/* Same fill/shadow as Button's own intent="primary" (crisp/button.recipe.ts) --
|
|
2138
|
+
confirmed byte-identical against the live "Comment" button's computed box-shadow, so this reuses that literal rather than re-deriving it. 32px/radius.lg/6px-10px padding has no matching Button `size` yet (24/28/40 are the three that exist), so this stays hand-rolled instead of stretching one of those. */
|
|
2139
|
+
& .crisp-comments-post { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 6px var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-brand-solid); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-on-brand); cursor: pointer; opacity: 1; transition: opacity .12s, background-color .12s; }
|
|
2140
|
+
& .crisp-comments-post:hover:not(:disabled) { background: var(--crisp-bg-brand-solid-pressed); }
|
|
2141
|
+
& .crisp-comments-post:disabled { opacity: .4; cursor: default; }
|
|
2142
|
+
/* Filter menu -- measured: 220px, radius 12 (radius.xl), 4px padding, elevation.floating -- a plain reuse of crisp's own Menu, so no rules
|
|
2143
|
+
live here; kept as a comment for the record. */
|
|
2144
|
+
|
|
2145
|
+
/* An inserted "@mention" chip in the composer -- same shape as
|
|
2146
|
+
RichTextEditor's own `.crisp-rte-mention` (crisp#428), reused here rather than re-derived since it's the same atomic-chip affordance. */
|
|
2147
|
+
& .crisp-comments-mention { display: inline; padding: 0 2px; border-radius: 4px; background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); font-weight: var(--crisp-weight-medium); user-select: none; }
|
|
2148
|
+
|
|
2149
|
+
/* Reaction picker -- see `ReactionPicker`'s own doc comment: the exact chrome wasn't independently pixel-measured this pass (screenshot
|
|
2150
|
+
capture broke mid-session), so this reuses Menu's already-measured floating-popover shell rather than a new value. */
|
|
2151
|
+
& .crisp-comments-reactionpicker { width: 240px; padding: var(--crisp-space-2); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); }
|
|
2152
|
+
& .crisp-comments-reactionpicker-search { box-sizing: border-box; width: 100%; height: 28px; margin-bottom: var(--crisp-space-2); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-raised); font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); }
|
|
2153
|
+
& .crisp-comments-reactionpicker-search::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
2154
|
+
& .crisp-comments-reactionpicker-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: var(--crisp-space-0-5); max-height: 160px; overflow-y: auto; }
|
|
2155
|
+
& .crisp-comments-reactionpicker-item { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; font-size: 16px; line-height: 1; cursor: pointer; }
|
|
2156
|
+
& .crisp-comments-reactionpicker-item:hover { background: var(--crisp-bg-raised); }
|
|
2157
|
+
/* Row badge (CommentCountBadge) -- lives in its own class family so the grid lanes can drop it into a cell without pulling in the panel's
|
|
2158
|
+
CSS. Persistent state: a 6px grey dot. Hover state: a 12px comment
|
|
2159
|
+
icon + 12px count text, both at 55% ink, replacing the dot. */
|
|
2160
|
+
& .crisp-comments-badge { display: inline-flex; align-items: center; gap: var(--crisp-space-1); border: none; background: none; padding: 0; margin: 0; font-family: inherit; cursor: pointer; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); }
|
|
2161
|
+
& .crisp-comments-badge-dot { width: 6px; height: 6px; border-radius: var(--crisp-radius-full); background: color-mix(in srgb, var(--crisp-fg-primary) 38%, transparent); }
|
|
2162
|
+
& .crisp-comments-badge-count { font-size: 12px; line-height: 16px; }
|
|
2163
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
2164
|
+
}
|
|
2165
|
+
|
|
2166
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2167
|
+
.crisp-comments, .crisp-comments * {
|
|
2168
|
+
animation-duration: 0.01ms !important;
|
|
2169
|
+
animation-iteration-count: 1 !important;
|
|
2170
|
+
transition-duration: 0.01ms !important;
|
|
2171
|
+
}
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2081
2174
|
.crisp-entitycard {
|
|
2082
2175
|
display: flex; flex-direction: column; box-sizing: border-box; width: 100%; min-width: 0; text-align: start; padding: var(--crisp-space-3) var(--crisp-space-4); margin: 0; border: none; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-primary); font-family: var(--crisp-font-sans); cursor: pointer; transition: box-shadow .12s ease, background-color .12s ease; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
2083
2176
|
&:hover { box-shadow: inset 0 0 0 1px var(--crisp-border-default), 0 1px 2px rgba(0,0,0,0.04), 0 6px 16px -6px rgba(28,40,64,0.12); }
|
|
@@ -2208,7 +2301,14 @@
|
|
|
2208
2301
|
& .crisp-listpage-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-header); flex-shrink: 0; padding: 0 var(--crisp-space-3); }
|
|
2209
2302
|
& .crisp-listpage-toolbar-lead { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
2210
2303
|
& .crisp-listpage-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); white-space: nowrap; }
|
|
2211
|
-
|
|
2304
|
+
/* #641: trailing (View settings / New) has to reach the toolbar's own
|
|
2305
|
+
inline-end edge on its own -- the only thing pushing it there used
|
|
2306
|
+
to be .crisp-listpage-count's margin-inline-start: auto, which a consumer with no count badge (TasksTable, measured live: trailing sat right after leading, nowhere near the row's own right edge)
|
|
2307
|
+
never renders. A bare margin-inline-start: auto here is safely
|
|
2308
|
+
overridden by the more specific rule right below whenever count IS
|
|
2309
|
+
present, so the two cases don't fight -- count's own auto margin
|
|
2310
|
+
still does the pushing there, this one only fires when it's absent. */
|
|
2311
|
+
& .crisp-listpage-toolbar-trail { display: flex; align-items: center; gap: var(--crisp-space-2); margin-inline-start: auto; }
|
|
2212
2312
|
& .crisp-listpage-count + .crisp-listpage-toolbar-trail { margin-inline-start: var(--crisp-space-3); }
|
|
2213
2313
|
& .crisp-listpage-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--crisp-space-3) var(--crisp-space-3); }
|
|
2214
2314
|
& .crisp-listpage-section-label { padding: 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); }
|
|
@@ -2249,6 +2349,56 @@
|
|
|
2249
2349
|
}
|
|
2250
2350
|
}
|
|
2251
2351
|
|
|
2352
|
+
.crisp-objectsettings {
|
|
2353
|
+
& .crisp-objectsettings-page { display: flex; flex-direction: column; gap: var(--crisp-space-6); }
|
|
2354
|
+
& .crisp-objectsettings-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--crisp-space-4); }
|
|
2355
|
+
& .crisp-objectsettings-heading { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); min-width: 0; }
|
|
2356
|
+
& .crisp-objectsettings-title { display: flex; align-items: center; gap: var(--crisp-space-2); font-size: 24px; line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.48px; color: var(--crisp-fg-primary); margin: 0; }
|
|
2357
|
+
& .crisp-objectsettings-subtitle { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); margin: 0; }
|
|
2358
|
+
& .crisp-objectsettings-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
2359
|
+
& .crisp-objectsettings-search { display: flex; align-items: center; flex: 1; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5); border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-muted); transition: box-shadow .15s; }
|
|
2360
|
+
& .crisp-objectsettings-search:focus-within { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
2361
|
+
& .crisp-objectsettings-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
|
|
2362
|
+
& .crisp-objectsettings-search input::placeholder { color: var(--crisp-fg-muted); }
|
|
2363
|
+
& .crisp-objectsettings-filterbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5) 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
|
|
2364
|
+
& .crisp-objectsettings-filterbtn:hover { background: var(--crisp-bg-raised); }
|
|
2365
|
+
/* Object / attribute icon tile — Attio's own squircle (measured
|
|
2366
|
+
border-radius: 30%, not a scale token: it's a proportional radius tied to the tile's own size, unlike every other radius crisp uses,
|
|
2367
|
+
which is a fixed px). */
|
|
2368
|
+
& .crisp-objectsettings-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 16px; height: 16px; border-radius: 30%; color: var(--crisp-fg-on-brand); }
|
|
2369
|
+
& .crisp-objectsettings-icon--lg { width: 48px; height: 48px; border-radius: 16px; }
|
|
2370
|
+
|
|
2371
|
+
/* "Standard"/"Custom" type badge and the muted "No records" cell —
|
|
2372
|
+
plain text, not a Badge pill (measured: transparent background). */
|
|
2373
|
+
& .crisp-objectsettings-typebadge { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
|
|
2374
|
+
& .crisp-objectsettings-muted { color: var(--crisp-fg-muted); }
|
|
2375
|
+
|
|
2376
|
+
/* Attribute-type option row (icon + label + optional trailing badge),
|
|
2377
|
+
composed as a Select option's `label` ReactNode. */
|
|
2378
|
+
& .crisp-objectsettings-typeoption { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; min-width: 0; }
|
|
2379
|
+
& .crisp-objectsettings-typeoption-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
2380
|
+
& .crisp-objectsettings-typeoption-badge { flex-shrink: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-brand-soft); }
|
|
2381
|
+
/* Create-attribute dialog's AI-autofill row and the submit button's ⌘↵ hint (measured off the same dialog, same shape as Dialog's own
|
|
2382
|
+
.crisp-dialog-submit-key, kept local rather than reaching into
|
|
2383
|
+
another component's scoped classes). */
|
|
2384
|
+
& .crisp-objectsettings-aiautofill { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
|
|
2385
|
+
& .crisp-objectsettings-aiautofill-label { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
|
|
2386
|
+
& .crisp-objectsettings-aiautofill-row { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5); border-radius: var(--crisp-radius-md); box-shadow: inset 0 0 0 1px var(--crisp-border-default); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
|
|
2387
|
+
& .crisp-objectsettings-aiautofill-row > svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
2388
|
+
& .crisp-objectsettings-aiautofill-row > span { flex: 1; }
|
|
2389
|
+
& .crisp-objectsettings-kbd { display: inline-flex; align-items: center; gap: var(--crisp-space-1); margin-inline-start: var(--crisp-space-1); }
|
|
2390
|
+
& .crisp-objectsettings-kbd kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: inherit; font-family: inherit; font-style: normal; font-size: 10px; }
|
|
2391
|
+
& .crisp-objectsettings-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-4); }
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2395
|
+
.crisp-objectsettings, .crisp-objectsettings * {
|
|
2396
|
+
animation-duration: 0.01ms !important;
|
|
2397
|
+
animation-iteration-count: 1 !important;
|
|
2398
|
+
transition-duration: 0.01ms !important;
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2252
2402
|
.crisp-onboarding {
|
|
2253
2403
|
display: flex; flex-direction: column; box-sizing: border-box; width: 272px; padding: var(--crisp-space-3); gap: var(--crisp-space-2); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent), 0 8px 28px -6px rgba(28,40,64,0.16), 0 2px 6px -2px rgba(28,40,64,0.10);
|
|
2254
2404
|
& .crisp-onboarding-head { display: flex; align-items: center; gap: var(--crisp-space-1); }
|
|
@@ -3033,7 +3183,14 @@
|
|
|
3033
3183
|
& .crisp-taskstable-colhead { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-height: 49px; max-height: 49px; padding: var(--crisp-space-2-5) var(--crisp-space-3); box-shadow: inset 0 -1px 0 var(--crisp-border-subtle); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
|
|
3034
3184
|
& .crisp-taskstable-colhead-cell { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
3035
3185
|
& .crisp-taskstable-row { display: flex; align-items: center; gap: var(--crisp-space-1-5); }
|
|
3036
|
-
|
|
3186
|
+
/* #642: measured live -- title, due date and assignee name are ALL 14px/500 on Attio's own Tasks page. Only -title/-due set their own
|
|
3187
|
+
font-size (and only -title its own weight), so an unstyled consumer
|
|
3188
|
+
slot (a plain PersonChip/RecordChip name span with no font-size of
|
|
3189
|
+
its own) fell through to the browser/body default, 16px/400. Set
|
|
3190
|
+
the ambient font here so it cascades to any slot content that
|
|
3191
|
+
doesn't override it -- -title/-due's own declarations still apply,
|
|
3192
|
+
unchanged, they're just now redundant with this baseline rather than the only source of it. */
|
|
3193
|
+
& .crisp-taskstable-cell { display: flex; align-items: center; min-width: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); }
|
|
3037
3194
|
& .crisp-taskstable-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s; }
|
|
3038
3195
|
& .crisp-taskstable-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
|
|
3039
3196
|
& .crisp-taskstable-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
|
package/dist/styles.layered.css
CHANGED
|
@@ -2026,8 +2026,20 @@
|
|
|
2026
2026
|
& .crisp-board-card[data-dragging] { opacity: 0.4; }
|
|
2027
2027
|
& .crisp-board-card:focus { outline: none; }
|
|
2028
2028
|
& .crisp-board-card:focus-visible { outline: 2px solid var(--crisp-bg-brand-solid); outline-offset: 1px; }
|
|
2029
|
+
/* #604: a per-column calc footer, mirroring the table's own (measured
|
|
2030
|
+
live, Deals pipeline). Sits below the scrollable card body, not
|
|
2031
|
+
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. */
|
|
2032
|
+
& .crisp-board-col-footer { flex-shrink: 0; padding: var(--crisp-space-1) 0; }
|
|
2033
|
+
& .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; }
|
|
2034
|
+
& .crisp-board-col-calc:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); }
|
|
2035
|
+
& .crisp-board-col-calc[data-empty] { opacity: 0.7; }
|
|
2036
|
+
& .crisp-board-col-calc-label { text-transform: capitalize; }
|
|
2037
|
+
& .crisp-board-col-calc-value { color: var(--crisp-fg-primary); font-variant-numeric: tabular-nums; }
|
|
2029
2038
|
/* announced, never drawn */
|
|
2030
|
-
& .crisp-board-live {
|
|
2039
|
+
& .crisp-board-live {
|
|
2040
|
+
position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
|
|
2041
|
+
overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
|
|
2042
|
+
}
|
|
2031
2043
|
}
|
|
2032
2044
|
|
|
2033
2045
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -2079,6 +2091,87 @@
|
|
|
2079
2091
|
}
|
|
2080
2092
|
}
|
|
2081
2093
|
|
|
2094
|
+
.crisp-comments {
|
|
2095
|
+
display: flex; flex-direction: column; box-sizing: border-box; width: 320px; height: 100%; background: var(--crisp-bg-surface); border-inline-start: 1px solid var(--crisp-border-subtle); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
2096
|
+
& * { box-sizing: border-box; }
|
|
2097
|
+
& .crisp-comments-head { display: flex; align-items: center; gap: var(--crisp-space-1); flex-shrink: 0; height: 49px; padding: 0 var(--crisp-space-2) 0 var(--crisp-space-4); }
|
|
2098
|
+
& .crisp-comments-headbtn { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
2099
|
+
& .crisp-comments-headbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2100
|
+
& .crisp-comments-title-wrap { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
|
2101
|
+
& .crisp-comments-title { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2102
|
+
& .crisp-comments-breadcrumb { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2103
|
+
& .crisp-comments-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--crisp-space-4); display: flex; flex-direction: column; gap: var(--crisp-space-4); }
|
|
2104
|
+
& .crisp-comments-body--pad-top { padding-top: var(--crisp-space-3); }
|
|
2105
|
+
/* One comment row -- avatar 16px (Avatar size="sm"), 6px gap to the name/time line, 14px/600 name + 12px/500 63%-muted time, 14px/400 body two lines below. Hover actions fade in flush with the name line. */
|
|
2106
|
+
& .crisp-comments-row { position: relative; display: flex; gap: var(--crisp-space-1-5); }
|
|
2107
|
+
& .crisp-comments-row-main { flex: 1; min-width: 0; }
|
|
2108
|
+
& .crisp-comments-row-head { display: flex; align-items: baseline; gap: var(--crisp-space-1-5); height: 20px; }
|
|
2109
|
+
& .crisp-comments-author { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
|
|
2110
|
+
& .crisp-comments-time { font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); white-space: nowrap; }
|
|
2111
|
+
& .crisp-comments-resolved-label { display: flex; align-items: center; gap: var(--crisp-space-1); margin-bottom: var(--crisp-space-1); font-size: 12px; font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2112
|
+
& .crisp-comments-body-text { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); white-space: pre-wrap; word-break: break-word; }
|
|
2113
|
+
/* Hover actions -- measured: 4 buttons, 28x28, radius 8, flush side-by-side (0 gap), transparent by default, 16px icon at 55% ink. */
|
|
2114
|
+
& .crisp-comments-row-actions { position: absolute; top: 0; inset-inline-end: 0; display: flex; opacity: 0; pointer-events: none; background: var(--crisp-bg-surface); }
|
|
2115
|
+
& .crisp-comments-row:hover .crisp-comments-row-actions, & .crisp-comments-row-actions:focus-within { opacity: 1; pointer-events: auto; }
|
|
2116
|
+
& .crisp-comments-action { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-md); background: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s, color .12s; }
|
|
2117
|
+
& .crisp-comments-action:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2118
|
+
& .crisp-comments-action[data-active] { color: var(--crisp-bg-brand-solid); }
|
|
2119
|
+
/* Reactions -- measured: 28px pill, radius 8, subtle 4% ink fill, padding 4px 8px 4px 6px, gap 4px between the emoji glyph and count. */
|
|
2120
|
+
& .crisp-comments-reactions { display: flex; flex-wrap: wrap; gap: var(--crisp-space-1); margin-top: var(--crisp-space-1-5); }
|
|
2121
|
+
& .crisp-comments-reaction { display: inline-flex; align-items: center; gap: var(--crisp-space-1); height: 28px; padding: 4px 8px 4px 6px; border: none; border-radius: var(--crisp-radius-md); background: color-mix(in srgb, var(--crisp-fg-primary) 4%, transparent); font-family: inherit; font-size: 12px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); cursor: pointer; }
|
|
2122
|
+
& .crisp-comments-reaction[data-reacted] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
|
|
2123
|
+
& .crisp-comments-reaction-add { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: var(--crisp-radius-md); background: transparent; font-family: inherit; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; opacity: 0; transition: opacity .12s, background-color .12s; }
|
|
2124
|
+
& .crisp-comments-row:hover .crisp-comments-reaction-add { opacity: 1; }
|
|
2125
|
+
& .crisp-comments-reaction-add:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2126
|
+
/* Reply-in-thread view -- an indented block of replies below the root. */
|
|
2127
|
+
& .crisp-comments-replies { display: flex; flex-direction: column; gap: var(--crisp-space-4); margin-top: var(--crisp-space-3); padding-inline-start: var(--crisp-space-4); border-inline-start: 1px solid var(--crisp-border-subtle); }
|
|
2128
|
+
& .crisp-comments-empty { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--crisp-space-1); padding: var(--crisp-space-6) var(--crisp-space-4); text-align: center; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-size: var(--crisp-text-lg); }
|
|
2129
|
+
/* Composer -- measured: 14px/20px body text, 16px gap above the reply/mention icon row, Comment button 84x32 padding 6px 10px radius 9 (= radius.lg) brand-solid fill, 14px/500 white label, opacity .4 disabled / 1 enabled (no color/background change between the two). */
|
|
2130
|
+
& .crisp-comments-composer { flex-shrink: 0; padding: var(--crisp-space-3) var(--crisp-space-4) var(--crisp-space-4); border-top: 1px solid var(--crisp-border-subtle); }
|
|
2131
|
+
& .crisp-comments-field { min-height: 20px; max-height: 120px; overflow-y: auto; font-family: inherit; font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-regular); color: var(--crisp-fg-primary); outline: none; white-space: pre-wrap; word-break: break-word; }
|
|
2132
|
+
& .crisp-comments-field:focus-visible { outline: 2px solid var(--crisp-stroke-focus-ring); outline-offset: 2px; }
|
|
2133
|
+
& .crisp-comments-field:empty::before { content: attr(data-placeholder); color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
2134
|
+
& .crisp-comments-composer-foot { display: flex; align-items: center; justify-content: space-between; margin-top: var(--crisp-space-4); }
|
|
2135
|
+
& .crisp-comments-composer-tools { display: flex; align-items: center; gap: var(--crisp-space-1); }
|
|
2136
|
+
& .crisp-comments-tool { 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; color: color-mix(in srgb, var(--crisp-fg-primary) 45%, transparent); font-family: inherit; cursor: pointer; }
|
|
2137
|
+
& .crisp-comments-tool:hover { color: var(--crisp-fg-primary); }
|
|
2138
|
+
/* Same fill/shadow as Button's own intent="primary" (crisp/button.recipe.ts) --
|
|
2139
|
+
confirmed byte-identical against the live "Comment" button's computed box-shadow, so this reuses that literal rather than re-deriving it. 32px/radius.lg/6px-10px padding has no matching Button `size` yet (24/28/40 are the three that exist), so this stays hand-rolled instead of stretching one of those. */
|
|
2140
|
+
& .crisp-comments-post { display: inline-flex; align-items: center; justify-content: center; height: 32px; padding: 6px var(--crisp-space-2-5); border: none; border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-brand-solid); box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px -2px rgba(38,109,240,0.12), 0 3px 6px -2px rgba(38,109,240,0.08); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-on-brand); cursor: pointer; opacity: 1; transition: opacity .12s, background-color .12s; }
|
|
2141
|
+
& .crisp-comments-post:hover:not(:disabled) { background: var(--crisp-bg-brand-solid-pressed); }
|
|
2142
|
+
& .crisp-comments-post:disabled { opacity: .4; cursor: default; }
|
|
2143
|
+
/* Filter menu -- measured: 220px, radius 12 (radius.xl), 4px padding, elevation.floating -- a plain reuse of crisp's own Menu, so no rules
|
|
2144
|
+
live here; kept as a comment for the record. */
|
|
2145
|
+
|
|
2146
|
+
/* An inserted "@mention" chip in the composer -- same shape as
|
|
2147
|
+
RichTextEditor's own `.crisp-rte-mention` (crisp#428), reused here rather than re-derived since it's the same atomic-chip affordance. */
|
|
2148
|
+
& .crisp-comments-mention { display: inline; padding: 0 2px; border-radius: 4px; background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); font-weight: var(--crisp-weight-medium); user-select: none; }
|
|
2149
|
+
|
|
2150
|
+
/* Reaction picker -- see `ReactionPicker`'s own doc comment: the exact chrome wasn't independently pixel-measured this pass (screenshot
|
|
2151
|
+
capture broke mid-session), so this reuses Menu's already-measured floating-popover shell rather than a new value. */
|
|
2152
|
+
& .crisp-comments-reactionpicker { width: 240px; padding: var(--crisp-space-2); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-ring-popover), 0 0 0 1px var(--crisp-shadow-popover1), 0 4px 8px -4px var(--crisp-shadow-popover2), 0 4px 12px -2px var(--crisp-shadow-popover3); }
|
|
2153
|
+
& .crisp-comments-reactionpicker-search { box-sizing: border-box; width: 100%; height: 28px; margin-bottom: var(--crisp-space-2); padding: 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-md); background: var(--crisp-bg-raised); font-family: inherit; font-size: var(--crisp-text-md); color: var(--crisp-fg-primary); }
|
|
2154
|
+
& .crisp-comments-reactionpicker-search::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
2155
|
+
& .crisp-comments-reactionpicker-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: var(--crisp-space-0-5); max-height: 160px; overflow-y: auto; }
|
|
2156
|
+
& .crisp-comments-reactionpicker-item { display: inline-flex; align-items: center; justify-content: center; width: 26px; height: 26px; border: none; border-radius: var(--crisp-radius-sm); background: none; font-family: inherit; font-size: 16px; line-height: 1; cursor: pointer; }
|
|
2157
|
+
& .crisp-comments-reactionpicker-item:hover { background: var(--crisp-bg-raised); }
|
|
2158
|
+
/* Row badge (CommentCountBadge) -- lives in its own class family so the grid lanes can drop it into a cell without pulling in the panel's
|
|
2159
|
+
CSS. Persistent state: a 6px grey dot. Hover state: a 12px comment
|
|
2160
|
+
icon + 12px count text, both at 55% ink, replacing the dot. */
|
|
2161
|
+
& .crisp-comments-badge { display: inline-flex; align-items: center; gap: var(--crisp-space-1); border: none; background: none; padding: 0; margin: 0; font-family: inherit; cursor: pointer; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); }
|
|
2162
|
+
& .crisp-comments-badge-dot { width: 6px; height: 6px; border-radius: var(--crisp-radius-full); background: color-mix(in srgb, var(--crisp-fg-primary) 38%, transparent); }
|
|
2163
|
+
& .crisp-comments-badge-count { font-size: 12px; line-height: 16px; }
|
|
2164
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2168
|
+
.crisp-comments, .crisp-comments * {
|
|
2169
|
+
animation-duration: 0.01ms !important;
|
|
2170
|
+
animation-iteration-count: 1 !important;
|
|
2171
|
+
transition-duration: 0.01ms !important;
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
|
|
2082
2175
|
.crisp-entitycard {
|
|
2083
2176
|
display: flex; flex-direction: column; box-sizing: border-box; width: 100%; min-width: 0; text-align: start; padding: var(--crisp-space-3) var(--crisp-space-4); margin: 0; border: none; border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); color: var(--crisp-fg-primary); font-family: var(--crisp-font-sans); cursor: pointer; transition: box-shadow .12s ease, background-color .12s ease; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale;
|
|
2084
2177
|
&:hover { box-shadow: inset 0 0 0 1px var(--crisp-border-default), 0 1px 2px rgba(0,0,0,0.04), 0 6px 16px -6px rgba(28,40,64,0.12); }
|
|
@@ -2209,7 +2302,14 @@
|
|
|
2209
2302
|
& .crisp-listpage-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-header); flex-shrink: 0; padding: 0 var(--crisp-space-3); }
|
|
2210
2303
|
& .crisp-listpage-toolbar-lead { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
2211
2304
|
& .crisp-listpage-count { margin-inline-start: auto; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); white-space: nowrap; }
|
|
2212
|
-
|
|
2305
|
+
/* #641: trailing (View settings / New) has to reach the toolbar's own
|
|
2306
|
+
inline-end edge on its own -- the only thing pushing it there used
|
|
2307
|
+
to be .crisp-listpage-count's margin-inline-start: auto, which a consumer with no count badge (TasksTable, measured live: trailing sat right after leading, nowhere near the row's own right edge)
|
|
2308
|
+
never renders. A bare margin-inline-start: auto here is safely
|
|
2309
|
+
overridden by the more specific rule right below whenever count IS
|
|
2310
|
+
present, so the two cases don't fight -- count's own auto margin
|
|
2311
|
+
still does the pushing there, this one only fires when it's absent. */
|
|
2312
|
+
& .crisp-listpage-toolbar-trail { display: flex; align-items: center; gap: var(--crisp-space-2); margin-inline-start: auto; }
|
|
2213
2313
|
& .crisp-listpage-count + .crisp-listpage-toolbar-trail { margin-inline-start: var(--crisp-space-3); }
|
|
2214
2314
|
& .crisp-listpage-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0 var(--crisp-space-3) var(--crisp-space-3); }
|
|
2215
2315
|
& .crisp-listpage-section-label { padding: 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); }
|
|
@@ -2250,6 +2350,56 @@
|
|
|
2250
2350
|
}
|
|
2251
2351
|
}
|
|
2252
2352
|
|
|
2353
|
+
.crisp-objectsettings {
|
|
2354
|
+
& .crisp-objectsettings-page { display: flex; flex-direction: column; gap: var(--crisp-space-6); }
|
|
2355
|
+
& .crisp-objectsettings-head { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--crisp-space-4); }
|
|
2356
|
+
& .crisp-objectsettings-heading { display: flex; flex-direction: column; gap: var(--crisp-space-0-5); min-width: 0; }
|
|
2357
|
+
& .crisp-objectsettings-title { display: flex; align-items: center; gap: var(--crisp-space-2); font-size: 24px; line-height: 28px; font-weight: var(--crisp-weight-semibold); letter-spacing: -0.48px; color: var(--crisp-fg-primary); margin: 0; }
|
|
2358
|
+
& .crisp-objectsettings-subtitle { font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); margin: 0; }
|
|
2359
|
+
& .crisp-objectsettings-toolbar { display: flex; align-items: center; gap: var(--crisp-space-2); }
|
|
2360
|
+
& .crisp-objectsettings-search { display: flex; align-items: center; flex: 1; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5); border-radius: var(--crisp-radius-md); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-muted); transition: box-shadow .15s; }
|
|
2361
|
+
& .crisp-objectsettings-search:focus-within { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
2362
|
+
& .crisp-objectsettings-search input { flex: 1; min-width: 0; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); }
|
|
2363
|
+
& .crisp-objectsettings-search input::placeholder { color: var(--crisp-fg-muted); }
|
|
2364
|
+
& .crisp-objectsettings-filterbtn { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5) 0 var(--crisp-space-2); border: none; border-radius: var(--crisp-radius-lg); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px var(--crisp-border-default); color: var(--crisp-fg-primary); font-family: inherit; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); cursor: pointer; white-space: nowrap; }
|
|
2365
|
+
& .crisp-objectsettings-filterbtn:hover { background: var(--crisp-bg-raised); }
|
|
2366
|
+
/* Object / attribute icon tile — Attio's own squircle (measured
|
|
2367
|
+
border-radius: 30%, not a scale token: it's a proportional radius tied to the tile's own size, unlike every other radius crisp uses,
|
|
2368
|
+
which is a fixed px). */
|
|
2369
|
+
& .crisp-objectsettings-icon { display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: 16px; height: 16px; border-radius: 30%; color: var(--crisp-fg-on-brand); }
|
|
2370
|
+
& .crisp-objectsettings-icon--lg { width: 48px; height: 48px; border-radius: 16px; }
|
|
2371
|
+
|
|
2372
|
+
/* "Standard"/"Custom" type badge and the muted "No records" cell —
|
|
2373
|
+
plain text, not a Badge pill (measured: transparent background). */
|
|
2374
|
+
& .crisp-objectsettings-typebadge { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-neutral-soft); }
|
|
2375
|
+
& .crisp-objectsettings-muted { color: var(--crisp-fg-muted); }
|
|
2376
|
+
|
|
2377
|
+
/* Attribute-type option row (icon + label + optional trailing badge),
|
|
2378
|
+
composed as a Select option's `label` ReactNode. */
|
|
2379
|
+
& .crisp-objectsettings-typeoption { display: flex; align-items: center; gap: var(--crisp-space-2); width: 100%; min-width: 0; }
|
|
2380
|
+
& .crisp-objectsettings-typeoption-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
2381
|
+
& .crisp-objectsettings-typeoption-badge { flex-shrink: 0; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-brand-soft); }
|
|
2382
|
+
/* Create-attribute dialog's AI-autofill row and the submit button's ⌘↵ hint (measured off the same dialog, same shape as Dialog's own
|
|
2383
|
+
.crisp-dialog-submit-key, kept local rather than reaching into
|
|
2384
|
+
another component's scoped classes). */
|
|
2385
|
+
& .crisp-objectsettings-aiautofill { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); }
|
|
2386
|
+
& .crisp-objectsettings-aiautofill-label { font-size: var(--crisp-text-md); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-muted); }
|
|
2387
|
+
& .crisp-objectsettings-aiautofill-row { display: flex; align-items: center; gap: var(--crisp-space-2); height: var(--crisp-size-menuRow); padding: 0 var(--crisp-space-2-5); border-radius: var(--crisp-radius-md); box-shadow: inset 0 0 0 1px var(--crisp-border-default); font-size: var(--crisp-text-lg); color: var(--crisp-fg-primary); cursor: pointer; }
|
|
2388
|
+
& .crisp-objectsettings-aiautofill-row > svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
2389
|
+
& .crisp-objectsettings-aiautofill-row > span { flex: 1; }
|
|
2390
|
+
& .crisp-objectsettings-kbd { display: inline-flex; align-items: center; gap: var(--crisp-space-1); margin-inline-start: var(--crisp-space-1); }
|
|
2391
|
+
& .crisp-objectsettings-kbd kbd { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; padding: 0 3px; border-radius: 4px; background: transparent; color: inherit; font-family: inherit; font-style: normal; font-size: 10px; }
|
|
2392
|
+
& .crisp-objectsettings-fieldrow { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-4); }
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
@media (prefers-reduced-motion: reduce) {
|
|
2396
|
+
.crisp-objectsettings, .crisp-objectsettings * {
|
|
2397
|
+
animation-duration: 0.01ms !important;
|
|
2398
|
+
animation-iteration-count: 1 !important;
|
|
2399
|
+
transition-duration: 0.01ms !important;
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2253
2403
|
.crisp-onboarding {
|
|
2254
2404
|
display: flex; flex-direction: column; box-sizing: border-box; width: 272px; padding: var(--crisp-space-3); gap: var(--crisp-space-2); border-radius: var(--crisp-radius-xl); background: var(--crisp-bg-surface); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent), 0 8px 28px -6px rgba(28,40,64,0.16), 0 2px 6px -2px rgba(28,40,64,0.10);
|
|
2255
2405
|
& .crisp-onboarding-head { display: flex; align-items: center; gap: var(--crisp-space-1); }
|
|
@@ -3034,7 +3184,14 @@
|
|
|
3034
3184
|
& .crisp-taskstable-colhead { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-height: 49px; max-height: 49px; padding: var(--crisp-space-2-5) var(--crisp-space-3); box-shadow: inset 0 -1px 0 var(--crisp-border-subtle); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
|
|
3035
3185
|
& .crisp-taskstable-colhead-cell { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
3036
3186
|
& .crisp-taskstable-row { display: flex; align-items: center; gap: var(--crisp-space-1-5); }
|
|
3037
|
-
|
|
3187
|
+
/* #642: measured live -- title, due date and assignee name are ALL 14px/500 on Attio's own Tasks page. Only -title/-due set their own
|
|
3188
|
+
font-size (and only -title its own weight), so an unstyled consumer
|
|
3189
|
+
slot (a plain PersonChip/RecordChip name span with no font-size of
|
|
3190
|
+
its own) fell through to the browser/body default, 16px/400. Set
|
|
3191
|
+
the ambient font here so it cascades to any slot content that
|
|
3192
|
+
doesn't override it -- -title/-due's own declarations still apply,
|
|
3193
|
+
unchanged, they're just now redundant with this baseline rather than the only source of it. */
|
|
3194
|
+
& .crisp-taskstable-cell { display: flex; align-items: center; min-width: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); }
|
|
3038
3195
|
& .crisp-taskstable-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s; }
|
|
3039
3196
|
& .crisp-taskstable-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
|
|
3040
3197
|
& .crisp-taskstable-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
|
package/dist/taskstable.css
CHANGED
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
& .crisp-taskstable-colhead { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-height: 49px; max-height: 49px; padding: var(--crisp-space-2-5) var(--crisp-space-3); box-shadow: inset 0 -1px 0 var(--crisp-border-subtle); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
|
|
4
4
|
& .crisp-taskstable-colhead-cell { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
5
5
|
& .crisp-taskstable-row { display: flex; align-items: center; gap: var(--crisp-space-1-5); }
|
|
6
|
-
|
|
6
|
+
/* #642: measured live -- title, due date and assignee name are ALL 14px/500 on Attio's own Tasks page. Only -title/-due set their own
|
|
7
|
+
font-size (and only -title its own weight), so an unstyled consumer
|
|
8
|
+
slot (a plain PersonChip/RecordChip name span with no font-size of
|
|
9
|
+
its own) fell through to the browser/body default, 16px/400. Set
|
|
10
|
+
the ambient font here so it cascades to any slot content that
|
|
11
|
+
doesn't override it -- -title/-due's own declarations still apply,
|
|
12
|
+
unchanged, they're just now redundant with this baseline rather than the only source of it. */
|
|
13
|
+
& .crisp-taskstable-cell { display: flex; align-items: center; min-width: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); }
|
|
7
14
|
& .crisp-taskstable-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s; }
|
|
8
15
|
& .crisp-taskstable-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
|
|
9
16
|
& .crisp-taskstable-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
|
|
@@ -4,7 +4,14 @@
|
|
|
4
4
|
& .crisp-taskstable-colhead { display: flex; align-items: center; gap: var(--crisp-space-1-5); min-height: 49px; max-height: 49px; padding: var(--crisp-space-2-5) var(--crisp-space-3); box-shadow: inset 0 -1px 0 var(--crisp-border-subtle); font-size: var(--crisp-text-sm); color: var(--crisp-fg-muted); }
|
|
5
5
|
& .crisp-taskstable-colhead-cell { display: inline-flex; align-items: center; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
6
6
|
& .crisp-taskstable-row { display: flex; align-items: center; gap: var(--crisp-space-1-5); }
|
|
7
|
-
|
|
7
|
+
/* #642: measured live -- title, due date and assignee name are ALL 14px/500 on Attio's own Tasks page. Only -title/-due set their own
|
|
8
|
+
font-size (and only -title its own weight), so an unstyled consumer
|
|
9
|
+
slot (a plain PersonChip/RecordChip name span with no font-size of
|
|
10
|
+
its own) fell through to the browser/body default, 16px/400. Set
|
|
11
|
+
the ambient font here so it cascades to any slot content that
|
|
12
|
+
doesn't override it -- -title/-due's own declarations still apply,
|
|
13
|
+
unchanged, they're just now redundant with this baseline rather than the only source of it. */
|
|
14
|
+
& .crisp-taskstable-cell { display: flex; align-items: center; min-width: 0; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); }
|
|
8
15
|
& .crisp-taskstable-check { appearance: none; -webkit-appearance: none; box-sizing: border-box; flex-shrink: 0; margin: 0; width: 16px; height: 16px; border: none; border-radius: var(--crisp-radius-full); background: var(--crisp-bg-surface); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 9%, transparent); cursor: pointer; transition: background-color .12s, box-shadow .12s; }
|
|
9
16
|
& .crisp-taskstable-check:hover { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 30%, transparent); }
|
|
10
17
|
& .crisp-taskstable-check:checked { background: var(--crisp-bg-brand-solid) center / 10px no-repeat; box-shadow: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 6.5 5 9l4.5-5'/%3E%3C/svg%3E"); }
|
|
@@ -8,7 +8,7 @@ export type ToolbarSort = {
|
|
|
8
8
|
key: string;
|
|
9
9
|
dir: SortDir;
|
|
10
10
|
};
|
|
11
|
-
export type ToolbarFilterOp = "contains" | "is" | "isnot" | "isanyof" | "empty" | "notempty";
|
|
11
|
+
export type ToolbarFilterOp = "contains" | "doesnotcontain" | "startswith" | "endswith" | "is" | "isnot" | "isanyof" | "empty" | "notempty";
|
|
12
12
|
export type ToolbarFilter = {
|
|
13
13
|
id: string;
|
|
14
14
|
key: string;
|
|
@@ -92,6 +92,12 @@ export type TableToolbarProps = Omit<React.ComponentPropsWithoutRef<"div">, "chi
|
|
|
92
92
|
filterFieldPlaceholder?: string;
|
|
93
93
|
/** Placeholder in a filter row's value input (default "Value…"). */
|
|
94
94
|
filterValuePlaceholder?: string;
|
|
95
|
+
/** aria-label on a filter chip's "⋮" kebab (default "Filter options"). */
|
|
96
|
+
filterOptionsLabel?: string;
|
|
97
|
+
/** Label on the filter chip kebab's "Delete filter" action (default
|
|
98
|
+
* "Delete filter") — Attio's own chip kebab (#594) has exactly this one
|
|
99
|
+
* item. */
|
|
100
|
+
deleteFilterLabel?: string;
|
|
95
101
|
/** Label on the "ascending" sort-direction option (default "Ascending"). */
|
|
96
102
|
ascendingLabel?: string;
|
|
97
103
|
/** Label on the "descending" sort-direction option (default "Descending"). */
|
|
@@ -139,7 +145,7 @@ export declare function applySorts<T>(rows: T[], sorts: ToolbarSort[], get?: (ro
|
|
|
139
145
|
* this (Sort: Due date/Assignee/Creation date; Filter: Assignee/Record/
|
|
140
146
|
* Created by), which one shared list can't reproduce.
|
|
141
147
|
*/
|
|
142
|
-
export declare function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: filterColumnsProp, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel: sortLabelProp, filterLabel: filterLabelProp, reorderSortLabel: reorderSortLabelProp, noSortsLabel: noSortsLabelProp, addSortLabel: addSortLabelProp, learnSortingLabel: learnSortingLabelProp, selectConditionLabel: selectConditionLabelProp, sortFieldLabel: sortFieldLabelProp, sortDirectionLabel: sortDirectionLabelProp, removeSortLabel: removeSortLabelProp, filterFieldLabel: filterFieldLabelProp, filterFieldPlaceholder: filterFieldPlaceholderProp, filterValuePlaceholder: filterValuePlaceholderProp, ascendingLabel: ascendingLabelProp, descendingLabel: descendingLabelProp, sortTriggerLabel, filterTriggerLabel, inline, ...rest }: TableToolbarProps): React.JSX.Element;
|
|
148
|
+
export declare function TableToolbar({ columns, sortColumns: sortColumnsProp, filterColumns: filterColumnsProp, sorts: sortsProp, defaultSorts, onSortsChange, filters: filtersProp, defaultFilters, onFiltersChange, count, children, helpHref, className, sortLabel: sortLabelProp, filterLabel: filterLabelProp, reorderSortLabel: reorderSortLabelProp, noSortsLabel: noSortsLabelProp, addSortLabel: addSortLabelProp, learnSortingLabel: learnSortingLabelProp, selectConditionLabel: selectConditionLabelProp, sortFieldLabel: sortFieldLabelProp, sortDirectionLabel: sortDirectionLabelProp, removeSortLabel: removeSortLabelProp, filterFieldLabel: filterFieldLabelProp, filterFieldPlaceholder: filterFieldPlaceholderProp, filterValuePlaceholder: filterValuePlaceholderProp, filterOptionsLabel: filterOptionsLabelProp, deleteFilterLabel: deleteFilterLabelProp, ascendingLabel: ascendingLabelProp, descendingLabel: descendingLabelProp, sortTriggerLabel, filterTriggerLabel, inline, ...rest }: TableToolbarProps): React.JSX.Element;
|
|
143
149
|
export type ToolbarToolProps = React.ComponentPropsWithoutRef<"button"> & {
|
|
144
150
|
/** Drawn the way Sort/Filter are once a condition is set (#399). */
|
|
145
151
|
active?: boolean;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ export * from "./product/appshell";
|
|
|
65
65
|
export * from "./product/authshell";
|
|
66
66
|
export * from "./product/board";
|
|
67
67
|
export * from "./product/command";
|
|
68
|
+
export * from "./product/comments";
|
|
68
69
|
export * from "./product/entitycard";
|
|
69
70
|
export * from "./product/flowcanvas";
|
|
70
71
|
export * from "./product/formdialog";
|
|
@@ -73,6 +74,7 @@ export * from "./product/importdialog";
|
|
|
73
74
|
export * from "./product/inbox";
|
|
74
75
|
export * from "./product/listpage";
|
|
75
76
|
export * from "./product/navitem";
|
|
77
|
+
export * from "./product/objectsettings";
|
|
76
78
|
export * from "./product/onboarding";
|
|
77
79
|
export * from "./product/recordpage";
|
|
78
80
|
export * from "./product/recordpanel";
|
|
@@ -9,6 +9,16 @@ export type BoardCard = {
|
|
|
9
9
|
id: string;
|
|
10
10
|
columnId: string;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* #604: the eight aggregations Attio's own per-column board calc footer
|
|
14
|
+
* offers (measured live, Deals pipeline) -- a different set from the
|
|
15
|
+
* table's own calc footer (`count`/`filled`/`sum`/`avg`/`min`/`max`,
|
|
16
|
+
* `product/recordstable`): Board additionally splits "not empty" into a
|
|
17
|
+
* count AND a percent, and does the same for "empty". Not reconciled with
|
|
18
|
+
* the table's vocabulary -- these are two different Attio surfaces with
|
|
19
|
+
* two different measured menus, not one concept with two names.
|
|
20
|
+
*/
|
|
21
|
+
export type BoardAgg = "countEmpty" | "countFilled" | "percentEmpty" | "percentFilled" | "sum" | "average" | "max" | "min";
|
|
12
22
|
export type BoardProps<T extends BoardCard> = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
|
|
13
23
|
columns: BoardColumn[];
|
|
14
24
|
cards: T[];
|
|
@@ -26,6 +36,15 @@ export type BoardProps<T extends BoardCard> = Omit<React.ComponentPropsWithoutRe
|
|
|
26
36
|
getCardLabel?: (card: T) => string;
|
|
27
37
|
/** What a screen reader hears after a keyboard move. */
|
|
28
38
|
announceMove?: (columnTitle: string, cardLabel?: string) => string;
|
|
39
|
+
/**
|
|
40
|
+
* A per-column calc footer (#604), mirroring the table's. Omit to skip
|
|
41
|
+
* it entirely -- Board has no footer by default. `getValue` reads the
|
|
42
|
+
* number to aggregate off a card (e.g. a deal's value); return
|
|
43
|
+
* null/undefined for a card with nothing set there ("empty").
|
|
44
|
+
*/
|
|
45
|
+
calc?: {
|
|
46
|
+
getValue: (card: T) => number | null | undefined;
|
|
47
|
+
};
|
|
29
48
|
className?: string;
|
|
30
49
|
};
|
|
31
50
|
/**
|
|
@@ -34,7 +53,7 @@ export type BoardProps<T extends BoardCard> = Omit<React.ComponentPropsWithoutRe
|
|
|
34
53
|
* (the parent owns the cards, so the move is a controlled state update).
|
|
35
54
|
* Measured from a deals pipeline.
|
|
36
55
|
*/
|
|
37
|
-
export declare function Board<T extends BoardCard>({ columns, cards, onCardsChange, renderCard, onNewCard, newCardLabel: newCardLabelProp, getCardLabel, announceMove: announceMoveProp, className, ...rest }: BoardProps<T>): React.JSX.Element;
|
|
56
|
+
export declare function Board<T extends BoardCard>({ columns, cards, onCardsChange, renderCard, onNewCard, newCardLabel: newCardLabelProp, getCardLabel, announceMove: announceMoveProp, calc, className, ...rest }: BoardProps<T>): React.JSX.Element;
|
|
38
57
|
export declare namespace Board {
|
|
39
58
|
var displayName: string;
|
|
40
59
|
}
|