@crisp-ui-kit/crisp 0.51.0 → 0.52.0
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/cjs/core/caret-rect.js +73 -0
- package/dist/cjs/core/index.js +7 -1
- package/dist/cjs/core/mention.js +32 -0
- package/dist/cjs/core/use-mention-trigger.js +124 -0
- package/dist/cjs/product/recordpanel/recordpanel.js +13 -81
- package/dist/cjs/product/recordpanel/recordpanel.recipe.js +53 -44
- package/dist/cjs/product/recordstable/editable-field.js +11 -8
- package/dist/cjs/product/recordstable/recordstable.tag.js +8 -3
- package/dist/cjs/product/richtext/index.js +2 -1
- package/dist/cjs/product/richtext/richtext.js +440 -23
- package/dist/cjs/product/richtext/richtext.recipe.js +59 -9
- package/dist/esm/core/caret-rect.js +70 -0
- package/dist/esm/core/index.js +3 -0
- package/dist/esm/core/mention.js +29 -0
- package/dist/esm/core/use-mention-trigger.js +88 -0
- package/dist/esm/product/recordpanel/index.js +1 -1
- package/dist/esm/product/recordpanel/recordpanel.js +15 -83
- package/dist/esm/product/recordpanel/recordpanel.recipe.js +54 -45
- package/dist/esm/product/recordstable/editable-field.js +11 -8
- package/dist/esm/product/recordstable/recordstable.tag.js +8 -3
- package/dist/esm/product/richtext/index.js +1 -1
- package/dist/esm/product/richtext/richtext.js +439 -22
- package/dist/esm/product/richtext/richtext.recipe.js +60 -10
- package/dist/recordpanel.css +47 -41
- package/dist/recordpanel.layered.css +47 -41
- package/dist/richtext.css +31 -5
- package/dist/richtext.layered.css +31 -5
- package/dist/styles.css +79 -47
- package/dist/styles.layered.css +79 -47
- package/dist/types/core/caret-rect.d.ts +16 -0
- package/dist/types/core/index.d.ts +3 -0
- package/dist/types/core/mention.d.ts +27 -0
- package/dist/types/core/use-mention-trigger.d.ts +41 -0
- package/dist/types/product/recordpanel/index.d.ts +1 -1
- package/dist/types/product/recordpanel/recordpanel.d.ts +81 -27
- package/dist/types/product/recordstable/editable-field.d.ts +11 -8
- package/dist/types/product/recordstable/recordstable.tag.d.ts +8 -3
- package/dist/types/product/richtext/index.d.ts +1 -1
- package/dist/types/product/richtext/richtext.d.ts +168 -7
- package/package.json +1 -1
package/dist/recordpanel.css
CHANGED
|
@@ -2,52 +2,58 @@
|
|
|
2
2
|
position: absolute; top: var(--crisp-space-2); inset-inline-end: var(--crisp-space-2); bottom: var(--crisp-space-2); z-index: 20; display: flex; flex-direction: column; overflow: hidden; width: 420px; max-width: calc(92% - var(--crisp-space-2)); background: var(--crisp-bg-surface); border-radius: var(--crisp-radius-xl); 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); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: translateX(0); transition: transform .2s ease;
|
|
3
3
|
@starting-style { transform: translateX(calc(100% + var(--crisp-space-2))); }
|
|
4
4
|
& * { box-sizing: border-box; }
|
|
5
|
-
|
|
5
|
+
/* #448: measured live on app.attio.com's peek -- a toolbar row above
|
|
6
|
+
the identity header: Close, then Previous/Next, on the left; "Open
|
|
7
|
+
record" on the right. 49px tall, 8px/10px padding, a hairline border
|
|
8
|
+
beneath (the same borderSubtle every other panel/row edge here
|
|
9
|
+
already uses). Close keeps the existing transparent ghost button;
|
|
10
|
+
Previous/Next/Open record are a distinct field-elevation style
|
|
11
|
+
(white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
|
|
12
|
+
& .crisp-recordpanel-toolbar { display: flex; align-items: center; height: 49px; flex-shrink: 0; padding: var(--crisp-space-2) var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); }
|
|
13
|
+
& .crisp-recordpanel-toolbar-spacer { flex: 1; }
|
|
14
|
+
& .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
|
|
15
|
+
& .crisp-recordpanel-iconbtn { 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: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
16
|
+
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
17
|
+
& .crisp-recordpanel-navbtn { 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: var(--crisp-bg-surface); 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); color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
|
|
18
|
+
& .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
|
|
19
|
+
& .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
20
|
+
& .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
|
|
6
21
|
& .crisp-recordpanel-fav { width: 22px; height: var(--crisp-size-chip); border-radius: var(--crisp-radius-sm); flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
|
|
7
22
|
& .crisp-recordpanel-title { flex: 1; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
8
|
-
& .crisp-recordpanel-iconbtn { 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: transparent; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
9
|
-
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
10
23
|
& .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
& .crisp-recordpanel-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
size/weight). A field row's own hover tint above already carries the "this is interactive" affordance; the pending/error treatment isn't
|
|
26
|
-
Attio-measured -- it reuses the same tokens DataTable's identical states already use (opacity 0.5, `bgDanger`), per #385/#430. */
|
|
27
|
-
& .crisp-recordpanel-edit { display: block; width: 100%; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; box-shadow: none; outline: none; font: inherit; color: inherit; }
|
|
28
|
-
/* not Attio-measured (its own field shows no focus ring either, caret only) -- kept for real keyboard users, the same brand ring every other crisp field already shows on focus (DataTable's identical
|
|
29
|
-
.crisp-datatable-edit:focus, e.g.). */
|
|
30
|
-
& .crisp-recordpanel-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
31
|
-
& .crisp-recordpanel-edit:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
32
|
-
& .crisp-recordpanel-edit-pending { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
33
|
-
& .crisp-recordpanel-edit-error { flex-basis: 100%; margin-top: var(--crisp-space-0-5); font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
|
|
34
|
-
& .crisp-recordpanel-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; }
|
|
35
|
-
& .crisp-recordpanel-edit-picker .crisp-select-trigger { flex: 1; min-width: 0; }
|
|
36
|
-
|
|
37
|
-
& .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
|
|
38
|
-
& .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
|
|
39
|
-
& .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent); }
|
|
40
|
-
& .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 30%, transparent); }
|
|
41
|
-
& .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent); }
|
|
42
|
-
& .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-purple) 30%, transparent); }
|
|
43
|
-
& .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-cyan) 30%, transparent); }
|
|
44
|
-
& .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent); }
|
|
45
|
-
& .crisp-recordpanel-link { color: var(--crisp-bg-brand-solid); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
|
|
46
|
-
& .crisp-recordpanel-link:hover { text-decoration: underline; }
|
|
24
|
+
/* #448: measured live on app.attio.com's peek (hover a Companies row,
|
|
25
|
+
click "Open preview"). Section label reads identically for both
|
|
26
|
+
Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
|
|
27
|
+
RecordPage's own field-label already uses (product/recordpage's
|
|
28
|
+
.crisp-recordpage-field-label) -- one more surface landing on the
|
|
29
|
+
same measured "muted section heading" colour. */
|
|
30
|
+
& .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
|
|
31
|
+
& .crisp-recordpanel-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 20px; margin-bottom: var(--crisp-space-2); }
|
|
32
|
+
& .crisp-recordpanel-section-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
33
|
+
/* "View all" -- measured 10px/400, a lighter mix than the section label
|
|
34
|
+
(55%, not 63%) -- its own distinct, honestly-measured value, not a
|
|
35
|
+
reuse of a nearby one that happened to be close. */
|
|
36
|
+
& .crisp-recordpanel-section-action { border: none; background: none; padding: 0; font-family: inherit; font-size: 10px; font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
|
|
37
|
+
& .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
|
|
47
38
|
|
|
48
|
-
/*
|
|
49
|
-
|
|
39
|
+
/* Highlights: a 2-column grid of label+icon+value cards, no card
|
|
40
|
+
chrome at all (no border/background/radius/shadow -- confirmed on
|
|
41
|
+
the live DOM: every highlight's computed style is fully transparent). 8px row/column gap; two rows measured "233x86" inside 473px content width is exactly (473 - 8) / 2. */
|
|
42
|
+
& .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
|
|
43
|
+
& .crisp-recordpanel-highlight { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
44
|
+
& .crisp-recordpanel-highlight-label { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
45
|
+
& .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
46
|
+
& .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
47
|
+
& .crisp-recordpanel-highlight-value { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; }
|
|
48
|
+
/* Activity is a consumer-supplied slot (crisp has no activity-feed model of its own to render) -- this only wraps it with the measured section heading above. */
|
|
49
|
+
& .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
|
|
50
|
+
/* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
|
|
51
|
+
same horizontal inset (space.3), the same hairline border token
|
|
52
|
+
(borderSubtle, flipped to border-top since this sits at the opposite
|
|
53
|
+
edge), and the header/body gap (space.2) for its own vertical padding
|
|
54
|
+
and for spacing between whatever it's given. */
|
|
50
55
|
& .crisp-recordpanel-footer { flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); border-top: 1px solid var(--crisp-border-subtle); }
|
|
56
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
51
57
|
}
|
|
52
58
|
|
|
53
59
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -3,52 +3,58 @@
|
|
|
3
3
|
position: absolute; top: var(--crisp-space-2); inset-inline-end: var(--crisp-space-2); bottom: var(--crisp-space-2); z-index: 20; display: flex; flex-direction: column; overflow: hidden; width: 420px; max-width: calc(92% - var(--crisp-space-2)); background: var(--crisp-bg-surface); border-radius: var(--crisp-radius-xl); 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); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: translateX(0); transition: transform .2s ease;
|
|
4
4
|
@starting-style { transform: translateX(calc(100% + var(--crisp-space-2))); }
|
|
5
5
|
& * { box-sizing: border-box; }
|
|
6
|
-
|
|
6
|
+
/* #448: measured live on app.attio.com's peek -- a toolbar row above
|
|
7
|
+
the identity header: Close, then Previous/Next, on the left; "Open
|
|
8
|
+
record" on the right. 49px tall, 8px/10px padding, a hairline border
|
|
9
|
+
beneath (the same borderSubtle every other panel/row edge here
|
|
10
|
+
already uses). Close keeps the existing transparent ghost button;
|
|
11
|
+
Previous/Next/Open record are a distinct field-elevation style
|
|
12
|
+
(white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
|
|
13
|
+
& .crisp-recordpanel-toolbar { display: flex; align-items: center; height: 49px; flex-shrink: 0; padding: var(--crisp-space-2) var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); }
|
|
14
|
+
& .crisp-recordpanel-toolbar-spacer { flex: 1; }
|
|
15
|
+
& .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
|
|
16
|
+
& .crisp-recordpanel-iconbtn { 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: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
17
|
+
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
18
|
+
& .crisp-recordpanel-navbtn { 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: var(--crisp-bg-surface); 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); color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
|
|
19
|
+
& .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
|
|
20
|
+
& .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
21
|
+
& .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
|
|
7
22
|
& .crisp-recordpanel-fav { width: 22px; height: var(--crisp-size-chip); border-radius: var(--crisp-radius-sm); flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
|
|
8
23
|
& .crisp-recordpanel-title { flex: 1; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
9
|
-
& .crisp-recordpanel-iconbtn { 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: transparent; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
10
|
-
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
11
24
|
& .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
& .crisp-recordpanel-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
size/weight). A field row's own hover tint above already carries the "this is interactive" affordance; the pending/error treatment isn't
|
|
27
|
-
Attio-measured -- it reuses the same tokens DataTable's identical states already use (opacity 0.5, `bgDanger`), per #385/#430. */
|
|
28
|
-
& .crisp-recordpanel-edit { display: block; width: 100%; margin: 0; padding: 0; border: none; border-radius: var(--crisp-radius-sm); background: none; box-shadow: none; outline: none; font: inherit; color: inherit; }
|
|
29
|
-
/* not Attio-measured (its own field shows no focus ring either, caret only) -- kept for real keyboard users, the same brand ring every other crisp field already shows on focus (DataTable's identical
|
|
30
|
-
.crisp-datatable-edit:focus, e.g.). */
|
|
31
|
-
& .crisp-recordpanel-edit:focus { box-shadow: inset 0 0 0 1px var(--crisp-bg-brand-solid); }
|
|
32
|
-
& .crisp-recordpanel-edit:disabled { opacity: 0.5; cursor: not-allowed; }
|
|
33
|
-
& .crisp-recordpanel-edit-pending { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
34
|
-
& .crisp-recordpanel-edit-error { flex-basis: 100%; margin-top: var(--crisp-space-0-5); font-size: var(--crisp-text-sm); color: var(--crisp-bg-danger); }
|
|
35
|
-
& .crisp-recordpanel-edit-picker { display: flex; align-items: center; gap: var(--crisp-space-1); width: 100%; }
|
|
36
|
-
& .crisp-recordpanel-edit-picker .crisp-select-trigger { flex: 1; min-width: 0; }
|
|
37
|
-
|
|
38
|
-
& .crisp-recordstable-tag { display: inline-flex; align-items: center; height: var(--crisp-size-chip); padding: 0 var(--crisp-space-1); border-radius: var(--crisp-radius-chip); font-size: var(--crisp-text-lg); line-height: 20px; font-weight: var(--crisp-weight-medium); white-space: nowrap; background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: color-mix(in srgb, var(--crisp-fg-primary) 82%, transparent); box-shadow: inset 0 0 0 1px var(--crisp-border-subtle); }
|
|
39
|
-
& .crisp-recordstable-tag[data-tone="brand"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-brand-solid) 30%, transparent); }
|
|
40
|
-
& .crisp-recordstable-tag[data-tone="success"] { background: color-mix(in srgb, var(--crisp-bg-success) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-success) 78%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-success) 30%, transparent); }
|
|
41
|
-
& .crisp-recordstable-tag[data-tone="warning"] { background: color-mix(in srgb, var(--crisp-bg-warning) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-warning) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-warning) 30%, transparent); }
|
|
42
|
-
& .crisp-recordstable-tag[data-tone="danger"] { background: color-mix(in srgb, var(--crisp-bg-danger) 15%, transparent); color: color-mix(in srgb, var(--crisp-bg-danger) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-danger) 30%, transparent); }
|
|
43
|
-
& .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-purple) 30%, transparent); }
|
|
44
|
-
& .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-cyan) 30%, transparent); }
|
|
45
|
-
& .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent); }
|
|
46
|
-
& .crisp-recordpanel-link { color: var(--crisp-bg-brand-solid); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
|
|
47
|
-
& .crisp-recordpanel-link:hover { text-decoration: underline; }
|
|
25
|
+
/* #448: measured live on app.attio.com's peek (hover a Companies row,
|
|
26
|
+
click "Open preview"). Section label reads identically for both
|
|
27
|
+
Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
|
|
28
|
+
RecordPage's own field-label already uses (product/recordpage's
|
|
29
|
+
.crisp-recordpage-field-label) -- one more surface landing on the
|
|
30
|
+
same measured "muted section heading" colour. */
|
|
31
|
+
& .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
|
|
32
|
+
& .crisp-recordpanel-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 20px; margin-bottom: var(--crisp-space-2); }
|
|
33
|
+
& .crisp-recordpanel-section-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
34
|
+
/* "View all" -- measured 10px/400, a lighter mix than the section label
|
|
35
|
+
(55%, not 63%) -- its own distinct, honestly-measured value, not a
|
|
36
|
+
reuse of a nearby one that happened to be close. */
|
|
37
|
+
& .crisp-recordpanel-section-action { border: none; background: none; padding: 0; font-family: inherit; font-size: 10px; font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
|
|
38
|
+
& .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
|
|
48
39
|
|
|
49
|
-
/*
|
|
50
|
-
|
|
40
|
+
/* Highlights: a 2-column grid of label+icon+value cards, no card
|
|
41
|
+
chrome at all (no border/background/radius/shadow -- confirmed on
|
|
42
|
+
the live DOM: every highlight's computed style is fully transparent). 8px row/column gap; two rows measured "233x86" inside 473px content width is exactly (473 - 8) / 2. */
|
|
43
|
+
& .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
|
|
44
|
+
& .crisp-recordpanel-highlight { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
45
|
+
& .crisp-recordpanel-highlight-label { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
46
|
+
& .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
47
|
+
& .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
48
|
+
& .crisp-recordpanel-highlight-value { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; }
|
|
49
|
+
/* Activity is a consumer-supplied slot (crisp has no activity-feed model of its own to render) -- this only wraps it with the measured section heading above. */
|
|
50
|
+
& .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
|
|
51
|
+
/* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
|
|
52
|
+
same horizontal inset (space.3), the same hairline border token
|
|
53
|
+
(borderSubtle, flipped to border-top since this sits at the opposite
|
|
54
|
+
edge), and the header/body gap (space.2) for its own vertical padding
|
|
55
|
+
and for spacing between whatever it's given. */
|
|
51
56
|
& .crisp-recordpanel-footer { flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); border-top: 1px solid var(--crisp-border-subtle); }
|
|
57
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/richtext.css
CHANGED
|
@@ -15,12 +15,38 @@
|
|
|
15
15
|
& .crisp-rte-body code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: var(--crisp-text-md); padding: 1px var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
16
16
|
& .crisp-rte-body a { color: var(--crisp-bg-brand-solid); text-decoration: underline; text-underline-offset: 2px; }
|
|
17
17
|
& .crisp-rte-body strong { font-weight: var(--crisp-weight-semibold); }
|
|
18
|
-
& .crisp-rte-
|
|
18
|
+
& .crisp-rte-body img { display: block; max-width: 100%; border-radius: var(--crisp-radius-md); }
|
|
19
|
+
/* Not measured against Attio (#428) — nothing in a read-only pass over app.attio.com had a live @mention rendered to read computed styles from, and typing one to create one is off-limits there. Reused verbatim from the one measured "brand" tag/chip this repo already has (RecordsTable/MultiSelect's [data-tone="brand"]) rather than
|
|
20
|
+
inventing a new color or shape. */
|
|
21
|
+
& .crisp-rte-mention { display: inline; border-radius: var(--crisp-radius-chip); padding: 0 var(--crisp-space-1); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); font-weight: var(--crisp-weight-medium); cursor: default; }
|
|
22
|
+
|
|
23
|
+
& .crisp-rte-toolbar { position: fixed; z-index: 70; display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 10px; 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); transform: translate(-50%, -100%); opacity: 1; transition: opacity 0.1s ease; }
|
|
19
24
|
& .crisp-rte-toolbar { @starting-style { opacity: 0; } }
|
|
20
|
-
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; width:
|
|
21
|
-
& .crisp-rte-tool
|
|
22
|
-
& .crisp-rte-tool
|
|
23
|
-
& .crisp-rte-tool-
|
|
25
|
+
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); min-width: 30px; height: 28px; padding: 0 7px; margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .1s; }
|
|
26
|
+
& .crisp-rte-tool--labelled { width: auto; }
|
|
27
|
+
& .crisp-rte-tool:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
|
|
28
|
+
& .crisp-rte-tool[data-active], & .crisp-rte-tool[aria-expanded="true"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
|
|
29
|
+
& .crisp-rte-tool-sep { width: 1px; height: 16px; margin: 0 2px; background: var(--crisp-border-subtle); }
|
|
30
|
+
|
|
31
|
+
& .crisp-rte-swatchpanel { position: fixed; z-index: 71; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--crisp-space-1); width: 168px; padding: var(--crisp-space-1-5); border-radius: var(--crisp-radius-lg); 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); transform: translate(-50%, var(--crisp-space-1-5)); opacity: 1; transition: opacity 0.1s ease; }
|
|
32
|
+
& .crisp-rte-swatchpanel { @starting-style { opacity: 0; } }
|
|
33
|
+
& .crisp-rte-swatch { width: 28px; height: 28px; padding: 0; margin: 0; border: none; border-radius: 50%; background: none; font-family: inherit; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); cursor: pointer; }
|
|
34
|
+
& .crisp-rte-swatch--none { background: var(--crisp-bg-surface); position: relative; }
|
|
35
|
+
& .crisp-rte-swatch--none::after { content: ""; position: absolute; inset: 6px; border-top: 1.5px solid color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); transform: rotate(-45deg); }
|
|
36
|
+
|
|
37
|
+
& .crisp-rte-blockmenu { position: fixed; z-index: 71; box-sizing: border-box; width: 356px; padding: 0; 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); opacity: 1; transition: opacity 0.1s ease; }
|
|
38
|
+
& .crisp-rte-blockmenu { @starting-style { opacity: 0; } }
|
|
39
|
+
& .crisp-rte-blockmenu-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-2-5) var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
40
|
+
& .crisp-rte-blockmenu-input { flex: 1; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); height: 20px; color: var(--crisp-fg-primary); }
|
|
41
|
+
& .crisp-rte-blockmenu-input::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
42
|
+
& .crisp-rte-blockmenu-list { display: flex; flex-direction: column; padding: var(--crisp-space-1-5); gap: var(--crisp-space-px); }
|
|
43
|
+
& .crisp-rte-blockmenu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 52px; padding: var(--crisp-space-1-5) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; text-align: start; cursor: pointer; }
|
|
44
|
+
& .crisp-rte-blockmenu-item svg { flex-shrink: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
45
|
+
& .crisp-rte-blockmenu-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
46
|
+
& .crisp-rte-blockmenu-item-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
47
|
+
& .crisp-rte-blockmenu-item-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
|
|
48
|
+
& .crisp-rte-blockmenu-item-desc { font-size: var(--crisp-text-sm); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
49
|
+
& .crisp-rte-blockmenu-empty { padding: var(--crisp-space-4) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
24
50
|
}
|
|
25
51
|
|
|
26
52
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -16,12 +16,38 @@
|
|
|
16
16
|
& .crisp-rte-body code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: var(--crisp-text-md); padding: 1px var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
17
17
|
& .crisp-rte-body a { color: var(--crisp-bg-brand-solid); text-decoration: underline; text-underline-offset: 2px; }
|
|
18
18
|
& .crisp-rte-body strong { font-weight: var(--crisp-weight-semibold); }
|
|
19
|
-
& .crisp-rte-
|
|
19
|
+
& .crisp-rte-body img { display: block; max-width: 100%; border-radius: var(--crisp-radius-md); }
|
|
20
|
+
/* Not measured against Attio (#428) — nothing in a read-only pass over app.attio.com had a live @mention rendered to read computed styles from, and typing one to create one is off-limits there. Reused verbatim from the one measured "brand" tag/chip this repo already has (RecordsTable/MultiSelect's [data-tone="brand"]) rather than
|
|
21
|
+
inventing a new color or shape. */
|
|
22
|
+
& .crisp-rte-mention { display: inline; border-radius: var(--crisp-radius-chip); padding: 0 var(--crisp-space-1); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); font-weight: var(--crisp-weight-medium); cursor: default; }
|
|
23
|
+
|
|
24
|
+
& .crisp-rte-toolbar { position: fixed; z-index: 70; display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 10px; 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); transform: translate(-50%, -100%); opacity: 1; transition: opacity 0.1s ease; }
|
|
20
25
|
& .crisp-rte-toolbar { @starting-style { opacity: 0; } }
|
|
21
|
-
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; width:
|
|
22
|
-
& .crisp-rte-tool
|
|
23
|
-
& .crisp-rte-tool
|
|
24
|
-
& .crisp-rte-tool-
|
|
26
|
+
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); min-width: 30px; height: 28px; padding: 0 7px; margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .1s; }
|
|
27
|
+
& .crisp-rte-tool--labelled { width: auto; }
|
|
28
|
+
& .crisp-rte-tool:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
|
|
29
|
+
& .crisp-rte-tool[data-active], & .crisp-rte-tool[aria-expanded="true"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
|
|
30
|
+
& .crisp-rte-tool-sep { width: 1px; height: 16px; margin: 0 2px; background: var(--crisp-border-subtle); }
|
|
31
|
+
|
|
32
|
+
& .crisp-rte-swatchpanel { position: fixed; z-index: 71; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--crisp-space-1); width: 168px; padding: var(--crisp-space-1-5); border-radius: var(--crisp-radius-lg); 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); transform: translate(-50%, var(--crisp-space-1-5)); opacity: 1; transition: opacity 0.1s ease; }
|
|
33
|
+
& .crisp-rte-swatchpanel { @starting-style { opacity: 0; } }
|
|
34
|
+
& .crisp-rte-swatch { width: 28px; height: 28px; padding: 0; margin: 0; border: none; border-radius: 50%; background: none; font-family: inherit; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); cursor: pointer; }
|
|
35
|
+
& .crisp-rte-swatch--none { background: var(--crisp-bg-surface); position: relative; }
|
|
36
|
+
& .crisp-rte-swatch--none::after { content: ""; position: absolute; inset: 6px; border-top: 1.5px solid color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); transform: rotate(-45deg); }
|
|
37
|
+
|
|
38
|
+
& .crisp-rte-blockmenu { position: fixed; z-index: 71; box-sizing: border-box; width: 356px; padding: 0; 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); opacity: 1; transition: opacity 0.1s ease; }
|
|
39
|
+
& .crisp-rte-blockmenu { @starting-style { opacity: 0; } }
|
|
40
|
+
& .crisp-rte-blockmenu-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-2-5) var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
41
|
+
& .crisp-rte-blockmenu-input { flex: 1; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); height: 20px; color: var(--crisp-fg-primary); }
|
|
42
|
+
& .crisp-rte-blockmenu-input::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
43
|
+
& .crisp-rte-blockmenu-list { display: flex; flex-direction: column; padding: var(--crisp-space-1-5); gap: var(--crisp-space-px); }
|
|
44
|
+
& .crisp-rte-blockmenu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 52px; padding: var(--crisp-space-1-5) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; text-align: start; cursor: pointer; }
|
|
45
|
+
& .crisp-rte-blockmenu-item svg { flex-shrink: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
46
|
+
& .crisp-rte-blockmenu-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
47
|
+
& .crisp-rte-blockmenu-item-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
48
|
+
& .crisp-rte-blockmenu-item-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
|
|
49
|
+
& .crisp-rte-blockmenu-item-desc { font-size: var(--crisp-text-sm); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
50
|
+
& .crisp-rte-blockmenu-empty { padding: var(--crisp-space-4) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
25
51
|
}
|
|
26
52
|
|
|
27
53
|
@media (prefers-reduced-motion: reduce) {
|
package/dist/styles.css
CHANGED
|
@@ -2238,52 +2238,58 @@
|
|
|
2238
2238
|
position: absolute; top: var(--crisp-space-2); inset-inline-end: var(--crisp-space-2); bottom: var(--crisp-space-2); z-index: 20; display: flex; flex-direction: column; overflow: hidden; width: 420px; max-width: calc(92% - var(--crisp-space-2)); background: var(--crisp-bg-surface); border-radius: var(--crisp-radius-xl); 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); font-family: var(--crisp-font-sans); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; transform: translateX(0); transition: transform .2s ease;
|
|
2239
2239
|
@starting-style { transform: translateX(calc(100% + var(--crisp-space-2))); }
|
|
2240
2240
|
& * { box-sizing: border-box; }
|
|
2241
|
-
|
|
2241
|
+
/* #448: measured live on app.attio.com's peek -- a toolbar row above
|
|
2242
|
+
the identity header: Close, then Previous/Next, on the left; "Open
|
|
2243
|
+
record" on the right. 49px tall, 8px/10px padding, a hairline border
|
|
2244
|
+
beneath (the same borderSubtle every other panel/row edge here
|
|
2245
|
+
already uses). Close keeps the existing transparent ghost button;
|
|
2246
|
+
Previous/Next/Open record are a distinct field-elevation style
|
|
2247
|
+
(white fill, e.field's own ring+shadow, solid icon) -- measured as genuinely different chrome from Close, not a reuse. */
|
|
2248
|
+
& .crisp-recordpanel-toolbar { display: flex; align-items: center; height: 49px; flex-shrink: 0; padding: var(--crisp-space-2) var(--crisp-space-2-5); border-bottom: 1px solid var(--crisp-border-subtle); }
|
|
2249
|
+
& .crisp-recordpanel-toolbar-spacer { flex: 1; }
|
|
2250
|
+
& .crisp-recordpanel-pager { display: flex; align-items: center; gap: var(--crisp-space-1-5); margin-inline-start: var(--crisp-space-3); }
|
|
2251
|
+
& .crisp-recordpanel-iconbtn { 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: transparent; color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
2252
|
+
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2253
|
+
& .crisp-recordpanel-navbtn { 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: var(--crisp-bg-surface); 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); color: var(--crisp-fg-primary); font-family: inherit; cursor: pointer; }
|
|
2254
|
+
& .crisp-recordpanel-navbtn:hover:not(:disabled) { background: var(--crisp-bg-raised); }
|
|
2255
|
+
& .crisp-recordpanel-navbtn:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
2256
|
+
& .crisp-recordpanel-header { display: flex; align-items: center; gap: var(--crisp-space-2); height: 52px; flex-shrink: 0; padding: 0 var(--crisp-space-3); }
|
|
2242
2257
|
& .crisp-recordpanel-fav { width: 22px; height: var(--crisp-size-chip); border-radius: var(--crisp-radius-sm); flex-shrink: 0; object-fit: cover; background: var(--crisp-bg-raised); }
|
|
2243
2258
|
& .crisp-recordpanel-title { flex: 1; min-width: 0; font-size: var(--crisp-text-xl); font-weight: var(--crisp-weight-semibold); letter-spacing: -0.2px; color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2244
|
-
& .crisp-recordpanel-iconbtn { 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: transparent; color: var(--crisp-fg-muted); font-family: inherit; cursor: pointer; transition: background-color .12s; }
|
|
2245
|
-
& .crisp-recordpanel-iconbtn:hover { background: var(--crisp-bg-raised); color: var(--crisp-fg-primary); }
|
|
2246
2259
|
& .crisp-recordpanel-body { flex: 1; min-height: 0; overflow-y: auto; padding: var(--crisp-space-2) var(--crisp-space-3); }
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
& .crisp-recordpanel-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
& .crisp-recordpanel-
|
|
2267
|
-
& .crisp-recordpanel-
|
|
2268
|
-
& .crisp-recordpanel-
|
|
2269
|
-
& .crisp-recordpanel-
|
|
2270
|
-
& .crisp-recordpanel-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
& .crisp-recordstable-tag[data-tone="purple"] { background: color-mix(in srgb, var(--crisp-bg-purple) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-purple) 80%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-purple) 30%, transparent); }
|
|
2279
|
-
& .crisp-recordstable-tag[data-tone="cyan"] { background: color-mix(in srgb, var(--crisp-bg-cyan) 18%, transparent); color: color-mix(in srgb, var(--crisp-bg-cyan) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-cyan) 30%, transparent); }
|
|
2280
|
-
& .crisp-recordstable-tag[data-tone="orange"] { background: color-mix(in srgb, var(--crisp-bg-orange) 16%, transparent); color: color-mix(in srgb, var(--crisp-bg-orange) 82%, var(--crisp-fg-primary)); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-bg-orange) 30%, transparent); }
|
|
2281
|
-
& .crisp-recordpanel-link { color: var(--crisp-bg-brand-solid); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
|
|
2282
|
-
& .crisp-recordpanel-link:hover { text-decoration: underline; }
|
|
2283
|
-
|
|
2284
|
-
/* #329: an optional slot for record actions (e.g. Edit). Reuses the
|
|
2285
|
-
header's own measured values rather than inventing new ones -- the same horizontal inset (space.3), the same hairline border token (borderSubtle, flipped to border-top since this sits at the opposite edge), and the header/body gap (space.2) for its own vertical padding and for spacing between whatever it's given. */
|
|
2260
|
+
/* #448: measured live on app.attio.com's peek (hover a Companies row,
|
|
2261
|
+
click "Open preview"). Section label reads identically for both
|
|
2262
|
+
Highlights and Activity: 14px/500, the same 63%-of-fgPrimary mix
|
|
2263
|
+
RecordPage's own field-label already uses (product/recordpage's
|
|
2264
|
+
.crisp-recordpage-field-label) -- one more surface landing on the
|
|
2265
|
+
same measured "muted section heading" colour. */
|
|
2266
|
+
& .crisp-recordpanel-section { padding: var(--crisp-space-2) var(--crisp-space-1) 0; }
|
|
2267
|
+
& .crisp-recordpanel-section-head { display: flex; align-items: center; justify-content: space-between; gap: var(--crisp-space-2); height: 20px; margin-bottom: var(--crisp-space-2); }
|
|
2268
|
+
& .crisp-recordpanel-section-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2269
|
+
/* "View all" -- measured 10px/400, a lighter mix than the section label
|
|
2270
|
+
(55%, not 63%) -- its own distinct, honestly-measured value, not a
|
|
2271
|
+
reuse of a nearby one that happened to be close. */
|
|
2272
|
+
& .crisp-recordpanel-section-action { border: none; background: none; padding: 0; font-family: inherit; font-size: 10px; font-weight: var(--crisp-weight-regular); color: color-mix(in srgb, var(--crisp-fg-primary) 55%, transparent); cursor: pointer; }
|
|
2273
|
+
& .crisp-recordpanel-section-action:hover { color: var(--crisp-fg-primary); }
|
|
2274
|
+
|
|
2275
|
+
/* Highlights: a 2-column grid of label+icon+value cards, no card
|
|
2276
|
+
chrome at all (no border/background/radius/shadow -- confirmed on
|
|
2277
|
+
the live DOM: every highlight's computed style is fully transparent). 8px row/column gap; two rows measured "233x86" inside 473px content width is exactly (473 - 8) / 2. */
|
|
2278
|
+
& .crisp-recordpanel-highlights { display: grid; grid-template-columns: 1fr 1fr; gap: var(--crisp-space-2); }
|
|
2279
|
+
& .crisp-recordpanel-highlight { display: flex; flex-direction: column; gap: var(--crisp-space-1-5); min-width: 0; }
|
|
2280
|
+
& .crisp-recordpanel-highlight-label { display: flex; align-items: center; gap: var(--crisp-space-1); font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2281
|
+
& .crisp-recordpanel-highlight-label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2282
|
+
& .crisp-recordpanel-highlight-label svg { flex-shrink: 0; color: var(--crisp-fg-muted); }
|
|
2283
|
+
& .crisp-recordpanel-highlight-value { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); overflow: hidden; text-overflow: ellipsis; }
|
|
2284
|
+
/* Activity is a consumer-supplied slot (crisp has no activity-feed model of its own to render) -- this only wraps it with the measured section heading above. */
|
|
2285
|
+
& .crisp-recordpanel-activity { font-size: var(--crisp-text-lg); }
|
|
2286
|
+
/* #329: an optional slot for record actions (e.g. Edit). Reuses the header's own measured values rather than inventing new ones -- the
|
|
2287
|
+
same horizontal inset (space.3), the same hairline border token
|
|
2288
|
+
(borderSubtle, flipped to border-top since this sits at the opposite
|
|
2289
|
+
edge), and the header/body gap (space.2) for its own vertical padding
|
|
2290
|
+
and for spacing between whatever it's given. */
|
|
2286
2291
|
& .crisp-recordpanel-footer { flex-shrink: 0; display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3); border-top: 1px solid var(--crisp-border-subtle); }
|
|
2292
|
+
[dir="rtl"] & [data-rtl-flip] { transform: scaleX(-1); }
|
|
2287
2293
|
}
|
|
2288
2294
|
|
|
2289
2295
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -2531,12 +2537,38 @@
|
|
|
2531
2537
|
& .crisp-rte-body code { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; font-size: var(--crisp-text-md); padding: 1px var(--crisp-space-1); border-radius: var(--crisp-radius-sm); background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
2532
2538
|
& .crisp-rte-body a { color: var(--crisp-bg-brand-solid); text-decoration: underline; text-underline-offset: 2px; }
|
|
2533
2539
|
& .crisp-rte-body strong { font-weight: var(--crisp-weight-semibold); }
|
|
2534
|
-
& .crisp-rte-
|
|
2540
|
+
& .crisp-rte-body img { display: block; max-width: 100%; border-radius: var(--crisp-radius-md); }
|
|
2541
|
+
/* Not measured against Attio (#428) — nothing in a read-only pass over app.attio.com had a live @mention rendered to read computed styles from, and typing one to create one is off-limits there. Reused verbatim from the one measured "brand" tag/chip this repo already has (RecordsTable/MultiSelect's [data-tone="brand"]) rather than
|
|
2542
|
+
inventing a new color or shape. */
|
|
2543
|
+
& .crisp-rte-mention { display: inline; border-radius: var(--crisp-radius-chip); padding: 0 var(--crisp-space-1); background: color-mix(in srgb, var(--crisp-bg-brand-solid) 14%, transparent); color: color-mix(in srgb, var(--crisp-bg-brand-solid) 82%, var(--crisp-fg-primary)); font-weight: var(--crisp-weight-medium); cursor: default; }
|
|
2544
|
+
|
|
2545
|
+
& .crisp-rte-toolbar { position: fixed; z-index: 70; display: inline-flex; align-items: center; gap: 2px; padding: 2px; border-radius: 10px; 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); transform: translate(-50%, -100%); opacity: 1; transition: opacity 0.1s ease; }
|
|
2535
2546
|
& .crisp-rte-toolbar { @starting-style { opacity: 0; } }
|
|
2536
|
-
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; width:
|
|
2537
|
-
& .crisp-rte-tool
|
|
2538
|
-
& .crisp-rte-tool
|
|
2539
|
-
& .crisp-rte-tool-
|
|
2547
|
+
& .crisp-rte-tool { display: inline-flex; align-items: center; justify-content: center; gap: var(--crisp-space-1); min-width: 30px; height: 28px; padding: 0 7px; margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); font-family: inherit; font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); cursor: pointer; transition: background-color .1s; }
|
|
2548
|
+
& .crisp-rte-tool--labelled { width: auto; }
|
|
2549
|
+
& .crisp-rte-tool:hover { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); color: var(--crisp-fg-primary); }
|
|
2550
|
+
& .crisp-rte-tool[data-active], & .crisp-rte-tool[aria-expanded="true"] { background: color-mix(in srgb, var(--crisp-bg-brand-solid) 12%, transparent); color: var(--crisp-bg-brand-solid); }
|
|
2551
|
+
& .crisp-rte-tool-sep { width: 1px; height: 16px; margin: 0 2px; background: var(--crisp-border-subtle); }
|
|
2552
|
+
|
|
2553
|
+
& .crisp-rte-swatchpanel { position: fixed; z-index: 71; display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--crisp-space-1); width: 168px; padding: var(--crisp-space-1-5); border-radius: var(--crisp-radius-lg); 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); transform: translate(-50%, var(--crisp-space-1-5)); opacity: 1; transition: opacity 0.1s ease; }
|
|
2554
|
+
& .crisp-rte-swatchpanel { @starting-style { opacity: 0; } }
|
|
2555
|
+
& .crisp-rte-swatch { width: 28px; height: 28px; padding: 0; margin: 0; border: none; border-radius: 50%; background: none; font-family: inherit; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--crisp-fg-primary) 10%, transparent); cursor: pointer; }
|
|
2556
|
+
& .crisp-rte-swatch--none { background: var(--crisp-bg-surface); position: relative; }
|
|
2557
|
+
& .crisp-rte-swatch--none::after { content: ""; position: absolute; inset: 6px; border-top: 1.5px solid color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); transform: rotate(-45deg); }
|
|
2558
|
+
|
|
2559
|
+
& .crisp-rte-blockmenu { position: fixed; z-index: 71; box-sizing: border-box; width: 356px; padding: 0; 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); opacity: 1; transition: opacity 0.1s ease; }
|
|
2560
|
+
& .crisp-rte-blockmenu { @starting-style { opacity: 0; } }
|
|
2561
|
+
& .crisp-rte-blockmenu-search { display: flex; align-items: center; gap: var(--crisp-space-1-5); padding: var(--crisp-space-2-5) var(--crisp-space-3); border-bottom: 1px solid var(--crisp-border-subtle); color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2562
|
+
& .crisp-rte-blockmenu-input { flex: 1; border: none; outline: none; background: none; font-family: inherit; font-size: var(--crisp-text-lg); height: 20px; color: var(--crisp-fg-primary); }
|
|
2563
|
+
& .crisp-rte-blockmenu-input::placeholder { color: color-mix(in srgb, var(--crisp-fg-primary) 40%, transparent); }
|
|
2564
|
+
& .crisp-rte-blockmenu-list { display: flex; flex-direction: column; padding: var(--crisp-space-1-5); gap: var(--crisp-space-px); }
|
|
2565
|
+
& .crisp-rte-blockmenu-item { display: flex; align-items: center; gap: var(--crisp-space-1-5); height: 52px; padding: var(--crisp-space-1-5) var(--crisp-space-2); margin: 0; border: none; border-radius: var(--crisp-radius-md); background: none; font-family: inherit; text-align: start; cursor: pointer; }
|
|
2566
|
+
& .crisp-rte-blockmenu-item svg { flex-shrink: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 63%, transparent); }
|
|
2567
|
+
& .crisp-rte-blockmenu-item[data-highlighted] { background: color-mix(in srgb, var(--crisp-fg-primary) 6%, transparent); }
|
|
2568
|
+
& .crisp-rte-blockmenu-item-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
|
|
2569
|
+
& .crisp-rte-blockmenu-item-label { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
|
|
2570
|
+
& .crisp-rte-blockmenu-item-desc { font-size: var(--crisp-text-sm); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
2571
|
+
& .crisp-rte-blockmenu-empty { padding: var(--crisp-space-4) var(--crisp-space-3); text-align: center; font-size: var(--crisp-text-md); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
|
|
2540
2572
|
}
|
|
2541
2573
|
|
|
2542
2574
|
@media (prefers-reduced-motion: reduce) {
|