@cloudgrid-io/ui 0.19.0 → 0.20.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.
|
@@ -14,6 +14,71 @@
|
|
|
14
14
|
* does not route. All of that stays where it belongs. A design system that
|
|
15
15
|
* learns the product's rules stops being a design system.
|
|
16
16
|
*
|
|
17
|
+
* ## Three sizes, one card underneath them
|
|
18
|
+
*
|
|
19
|
+
* `size` is `default`, `compact` or `row`. Founder direction 2026-09-08 (#182):
|
|
20
|
+
* every entity card in the console behaves the same way, and the only things
|
|
21
|
+
* that vary are its SIZE and, later, its MODE. The console census of the same
|
|
22
|
+
* day found eight renderers, three hand-built tiles and three track widths
|
|
23
|
+
* across Home, Discover, Spaces, Saved and the inspired-by rails. This axis is
|
|
24
|
+
* what lets all of them route through one block.
|
|
25
|
+
*
|
|
26
|
+
* Every size carries the same kind badge, the same state node and the same two
|
|
27
|
+
* actions. What changes is the type scale, the padding, how much of the
|
|
28
|
+
* description survives the clamp, and — on `row` — the direction the card runs
|
|
29
|
+
* in.
|
|
30
|
+
*
|
|
31
|
+
* **One recommended grid track per size**, because a card sized for a track it
|
|
32
|
+
* is not in is the failure this axis exists to prevent:
|
|
33
|
+
*
|
|
34
|
+
* default the 1200/630 media card this file already was. Track:
|
|
35
|
+
* `repeat(auto-fill, minmax(320px, 1fr))`, which is the 360px the
|
|
36
|
+
* console's Discover grid renders today.
|
|
37
|
+
* compact the same card at the console's 260 and 280 tracks. Track:
|
|
38
|
+
* `repeat(auto-fill, minmax(240px, 1fr))`.
|
|
39
|
+
* row not a track at all. One column, at least 640px of it. That floor
|
|
40
|
+
* is measured rather than picked: the two actions RESERVE their
|
|
41
|
+
* width at rest so that nothing reflows when they appear, and with
|
|
42
|
+
* the state chip beside them the end of a row costs about 245px
|
|
43
|
+
* whether or not anything is hovering it. Add the 128px thumbnail
|
|
44
|
+
* and the padding and a row cannot go under about 420px at all;
|
|
45
|
+
* between 420 and 640 the description is truncated to a few words.
|
|
46
|
+
* Under 640, `compact` is the right form — not a narrower row.
|
|
47
|
+
*
|
|
48
|
+
* **Rest and hover are identical on `default` and `compact`.** The reveal panel,
|
|
49
|
+
* its scrim, the ink surface it declares and the tap-target rule below all carry
|
|
50
|
+
* across unchanged. Compact reduces the type and the padding and nothing else.
|
|
51
|
+
*
|
|
52
|
+
* Two things compact does drop, and both are about height rather than taste. The
|
|
53
|
+
* description is clamped to one line whatever `descriptionLines` says, and the
|
|
54
|
+
* stats collapse to the first: at 260px a second stat wraps, which takes that
|
|
55
|
+
* card a line taller than the ones beside it and breaks the row it sits in.
|
|
56
|
+
*
|
|
57
|
+
* **`row` is the one that differs, and not for space.** A reveal exists to show
|
|
58
|
+
* what a thumbnail is covering — the title, the line, the creator, the state. A
|
|
59
|
+
* row shows all of that already, so there is nothing left to reveal, and a panel
|
|
60
|
+
* sliding over a 128px thumbnail would hide the smallest part of the card to
|
|
61
|
+
* repeat what the widest part already says. What appears on hover and on
|
|
62
|
+
* focus-within is the two actions, and only those.
|
|
63
|
+
*
|
|
64
|
+
* `stats` and `footer` are not rendered on a row. They are the stacked sizes'
|
|
65
|
+
* furniture: a stat rule under a one-line description makes the row two and a
|
|
66
|
+
* half lines tall, and a list of those stops being scannable. `meta` is
|
|
67
|
+
* rendered, on the creator's line, because the console's residence line is one
|
|
68
|
+
* line and belongs next to who made the thing.
|
|
69
|
+
*
|
|
70
|
+
* ## The open mode is NOT here
|
|
71
|
+
*
|
|
72
|
+
* #182 names a second axis as well: `open`, the card expanded in place with the
|
|
73
|
+
* full information — description unclamped, the residence grid, the owner, the
|
|
74
|
+
* tags — without navigating anywhere. It is deliberately not built. Its content
|
|
75
|
+
* comes from Figma frames that have not been shared yet, and a mode invented
|
|
76
|
+
* ahead of them is a second thing to unpick rather than a head start.
|
|
77
|
+
*
|
|
78
|
+
* The seam is `size`'s own: a `mode` prop beside it, resolved in the same place,
|
|
79
|
+
* with `SIZE_STYLE` below gaining a column rather than this component gaining a
|
|
80
|
+
* branch. Nothing here forecloses it, and nothing here pretends it exists.
|
|
81
|
+
*
|
|
17
82
|
* ## Two tiers of preview, and neither can fail dark
|
|
18
83
|
*
|
|
19
84
|
* `seed` turns the preview region on. With `seed` alone the card shows the
|
|
@@ -223,6 +288,18 @@ export declare const ENTITY_KIND_ICON: Record<EntityKind, React.ComponentType<{
|
|
|
223
288
|
* Plain nouns, no adjective: this names a thing, it does not sell it.
|
|
224
289
|
*/
|
|
225
290
|
export declare const ENTITY_KIND_LABEL: Record<EntityKind, string>;
|
|
291
|
+
/**
|
|
292
|
+
* The sizes, in the order they get smaller. Read from the console census
|
|
293
|
+
* (2026-09-08) rather than invented: `default` is the 360px track, `compact`
|
|
294
|
+
* covers the 260 and 280 ones, `row` is the list surfaces, the rails and the
|
|
295
|
+
* sidebar.
|
|
296
|
+
*
|
|
297
|
+
* The array is the source and the type is derived from it, the same arrangement
|
|
298
|
+
* `ENTITY_KIND_ORDER` uses: a size added here is immediately missing from
|
|
299
|
+
* `SIZE_STYLE` and typecheck says so.
|
|
300
|
+
*/
|
|
301
|
+
export declare const ENTITY_CARD_SIZE_ORDER: readonly ["default", "compact", "row"];
|
|
302
|
+
export type EntityCardSize = (typeof ENTITY_CARD_SIZE_ORDER)[number];
|
|
226
303
|
/**
|
|
227
304
|
* The kind badge on its own, exported because a listing header, a detail page or
|
|
228
305
|
* a row may want the same mark without a card around it.
|
|
@@ -235,12 +312,24 @@ declare function EntityKindBadge({ kind, size, className, ...props }: Omit<React
|
|
|
235
312
|
kind: EntityKind;
|
|
236
313
|
size?: "sm" | "md";
|
|
237
314
|
}): import("react").JSX.Element;
|
|
238
|
-
declare function EntityCard({ title, slug, description, titleLines, descriptionLines, status, headerActions, stats, seed, previewUrl, kind, reveal, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
|
|
315
|
+
declare function EntityCard({ title, slug, description, size, titleLines, descriptionLines, status, headerActions, stats, seed, previewUrl, kind, reveal, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }: Omit<React.ComponentProps<"div">, "ref" | "title"> & {
|
|
239
316
|
title: string;
|
|
240
317
|
/** The entity's address, in the mono utility face. */
|
|
241
318
|
slug?: string;
|
|
242
319
|
description?: string;
|
|
320
|
+
/**
|
|
321
|
+
* How big, and which way up. `default` is the 1200/630 media card, `compact`
|
|
322
|
+
* the same card at the console's 260 and 280 tracks, `row` the horizontal
|
|
323
|
+
* list form. See the note at the top of this file for the grid track each one
|
|
324
|
+
* is meant for, and for what `row` deliberately does differently.
|
|
325
|
+
*/
|
|
326
|
+
size?: EntityCardSize;
|
|
243
327
|
titleLines?: 1 | 2;
|
|
328
|
+
/**
|
|
329
|
+
* Ignored on `compact` and on `row`, both of which always clamp to one line.
|
|
330
|
+
* At 260px a second line of description takes the card taller than the ones
|
|
331
|
+
* beside it, and a row has one line by definition.
|
|
332
|
+
*/
|
|
244
333
|
descriptionLines?: 1 | 2;
|
|
245
334
|
/**
|
|
246
335
|
* Top right of the header row, and ALSO inside the reveal panel. One node,
|
|
@@ -312,9 +401,13 @@ declare function EntityCard({ title, slug, description, titleLines, descriptionL
|
|
|
312
401
|
href?: string;
|
|
313
402
|
/** Accessible name for the whole-card link. Defaults to `title`. */
|
|
314
403
|
ariaLabel?: string;
|
|
315
|
-
/**
|
|
404
|
+
/**
|
|
405
|
+
* Between the description and the stats. The console puts its residence line
|
|
406
|
+
* here. On a `row` it sits on the creator's line instead, which is the only
|
|
407
|
+
* line a row has left.
|
|
408
|
+
*/
|
|
316
409
|
meta?: React.ReactNode;
|
|
317
|
-
/** Below everything, under no rule of its own. */
|
|
410
|
+
/** Below everything, under no rule of its own. Not rendered on a `row`. */
|
|
318
411
|
footer?: React.ReactNode;
|
|
319
412
|
/** Replaces the whole body. The preview and the card chrome still render. */
|
|
320
413
|
children?: React.ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"AAWA
|
|
1
|
+
{"version":3,"file":"entity-card.d.ts","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}
|
|
@@ -34,6 +34,75 @@ export const ENTITY_KIND_LABEL = {
|
|
|
34
34
|
inspiration: "Inspiration",
|
|
35
35
|
app: "App",
|
|
36
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* The sizes, in the order they get smaller. Read from the console census
|
|
39
|
+
* (2026-09-08) rather than invented: `default` is the 360px track, `compact`
|
|
40
|
+
* covers the 260 and 280 ones, `row` is the list surfaces, the rails and the
|
|
41
|
+
* sidebar.
|
|
42
|
+
*
|
|
43
|
+
* The array is the source and the type is derived from it, the same arrangement
|
|
44
|
+
* `ENTITY_KIND_ORDER` uses: a size added here is immediately missing from
|
|
45
|
+
* `SIZE_STYLE` and typecheck says so.
|
|
46
|
+
*/
|
|
47
|
+
export const ENTITY_CARD_SIZE_ORDER = ["default", "compact", "row"];
|
|
48
|
+
/**
|
|
49
|
+
* WHAT EACH SIZE CHANGES, in one table.
|
|
50
|
+
*
|
|
51
|
+
* Every entry is a type or spacing utility, never a colour: a size is a
|
|
52
|
+
* measurement, and a card that changed hue when it got smaller would be a
|
|
53
|
+
* second design rather than the same one at another scale. That is also what
|
|
54
|
+
* keeps the literals gate honest here — there is nothing in this table a token
|
|
55
|
+
* does not already own.
|
|
56
|
+
*
|
|
57
|
+
* It is a table rather than a run of ternaries at the call sites because the
|
|
58
|
+
* whole point of the axis is that the sizes stay comparable. Three ternaries in
|
|
59
|
+
* three places is how one of them silently stops matching the other two.
|
|
60
|
+
*
|
|
61
|
+
* `row` builds its own composition below, so its `stats`, `reveal` and
|
|
62
|
+
* `revealTitle` entries are empty: a row has no stat rule and no reveal panel.
|
|
63
|
+
* They are present rather than omitted so the record stays total and a fourth
|
|
64
|
+
* size cannot be half-added.
|
|
65
|
+
*/
|
|
66
|
+
const SIZE_STYLE = {
|
|
67
|
+
default: {
|
|
68
|
+
cardSpacing: "",
|
|
69
|
+
body: "gap-3",
|
|
70
|
+
title: "text-body-sm",
|
|
71
|
+
description: "text-body-sm",
|
|
72
|
+
stats: "gap-4 pt-3",
|
|
73
|
+
reveal: "gap-1.5 p-3",
|
|
74
|
+
revealTitle: "text-body-sm",
|
|
75
|
+
},
|
|
76
|
+
compact: {
|
|
77
|
+
cardSpacing: "[--card-spacing:--spacing(3)]",
|
|
78
|
+
body: "gap-2",
|
|
79
|
+
title: "text-caption",
|
|
80
|
+
description: "text-caption",
|
|
81
|
+
stats: "gap-3 pt-2",
|
|
82
|
+
reveal: "gap-1 p-2",
|
|
83
|
+
revealTitle: "text-caption",
|
|
84
|
+
},
|
|
85
|
+
row: {
|
|
86
|
+
cardSpacing: "[--card-spacing:--spacing(3)]",
|
|
87
|
+
body: "gap-0.5",
|
|
88
|
+
title: "text-body-sm",
|
|
89
|
+
description: "text-caption",
|
|
90
|
+
stats: "",
|
|
91
|
+
reveal: "",
|
|
92
|
+
revealTitle: "",
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* The row thumbnail's width. Fixed rather than a fraction, so every row in a
|
|
97
|
+
* list starts its text at the same x — which is what makes a list of these
|
|
98
|
+
* scannable, and what a percentage width would lose the moment the column
|
|
99
|
+
* resized.
|
|
100
|
+
*
|
|
101
|
+
* 128px against the 1200/630 ratio is a 67px picture, so a row is a little over
|
|
102
|
+
* 90px tall with its padding. A 28px kind badge would cover a fifth of that
|
|
103
|
+
* thumbnail, which is why the row uses the small one.
|
|
104
|
+
*/
|
|
105
|
+
const ROW_THUMBNAIL = "w-32";
|
|
37
106
|
/**
|
|
38
107
|
* Make a caller's URL safe to sit inside a CSS `url("…")` string — and nothing
|
|
39
108
|
* more than that.
|
|
@@ -95,13 +164,19 @@ function EntityKindBadge({ kind, size = "md", className, ...props }) {
|
|
|
95
164
|
border: "1px solid color-mix(in srgb, var(--cg-ink) 12%, transparent)",
|
|
96
165
|
}, ...props, children: [_jsx(Icon, { className: size === "md" ? "size-4" : "size-3.5" }), _jsx("span", { className: "sr-only", children: ENTITY_KIND_LABEL[kind] })] }));
|
|
97
166
|
}
|
|
98
|
-
function EntityCard({ title, slug, description, titleLines = 2, descriptionLines = 1, status, headerActions, stats, seed, previewUrl, kind, reveal = false, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }) {
|
|
167
|
+
function EntityCard({ title, slug, description, size = "default", titleLines = 2, descriptionLines = 1, status, headerActions, stats, seed, previewUrl, kind, reveal = false, dashboardHref, settingsHref, creator, href, ariaLabel, meta, footer, className, children, ...props }) {
|
|
168
|
+
const sized = SIZE_STYLE[size];
|
|
99
169
|
// The reveal owns the preview and spends the `href`, so it only exists when
|
|
100
170
|
// both are there. Asked for without a `seed` it would be a panel over nothing;
|
|
101
171
|
// asked for without an `href` its Open action would be an anchor with no
|
|
102
172
|
// target, which renders as a link, is not focusable, and does nothing when
|
|
103
173
|
// clicked. Silently off in both cases rather than half-built.
|
|
104
|
-
|
|
174
|
+
//
|
|
175
|
+
// A `row` never reveals, whatever the caller passed. Not a limitation: the row
|
|
176
|
+
// already shows everything the panel carries, so there is nothing to reveal —
|
|
177
|
+
// see the size note at the top. Its two actions are rendered at the end of the
|
|
178
|
+
// row and appear on hover, which is the half of the behaviour that survives.
|
|
179
|
+
const revealed = reveal && Boolean(seed) && Boolean(href) && size !== "row";
|
|
105
180
|
// One target, two prop names, for one minor. `settingsHref` is the old name
|
|
106
181
|
// (#182 renamed the action to Dashboard, because the console page it opens is
|
|
107
182
|
// a dashboard and not a settings screen), and it is resolved here rather than
|
|
@@ -110,13 +185,138 @@ function EntityCard({ title, slug, description, titleLines = 2, descriptionLines
|
|
|
110
185
|
// saying "no target", and coalescing it to the deprecated name would resurrect
|
|
111
186
|
// a link the caller had switched off.
|
|
112
187
|
const dashboardTarget = dashboardHref ?? settingsHref;
|
|
188
|
+
// Compact keeps the stat ROW and shows one stat in it, rather than dropping
|
|
189
|
+
// the row. The row is a hairline plus a number, and a listing where some cards
|
|
190
|
+
// carry it and some do not has two card heights in one grid. Which stat
|
|
191
|
+
// survives is the caller's order, not a rule here: a card that reordered its
|
|
192
|
+
// caller's stats would be deciding which one matters.
|
|
193
|
+
const shownStats = stats && size === "compact" ? stats.slice(0, 1) : stats;
|
|
194
|
+
// One line on compact and on row, whatever the caller asked for. See the note
|
|
195
|
+
// on the prop: this is a height rule, not a preference.
|
|
196
|
+
const clampDescription = size === "default" && descriptionLines === 2 ? "line-clamp-2" : "truncate";
|
|
197
|
+
/**
|
|
198
|
+
* THE TWO ACTIONS. One pair, written once, used by the reveal panel and by the
|
|
199
|
+
* row alike — because #182's premise is that every entity card offers the same
|
|
200
|
+
* two doors, and two copies of a pair is how one of them quietly grows a third.
|
|
201
|
+
*
|
|
202
|
+
* Both halves of the hit model travel with them, and both are load-bearing:
|
|
203
|
+
*
|
|
204
|
+
* Open carries `after:absolute after:inset-0`, which stretches it over its
|
|
205
|
+
* nearest POSITIONED ancestor. That is the reveal panel on a media card (the
|
|
206
|
+
* panel is `absolute`) and the card itself on a row (which declares `relative`
|
|
207
|
+
* for exactly this). Either way a click anywhere on the card opens the entity,
|
|
208
|
+
* including on a phone where nothing ever hovers. The anchor itself must not
|
|
209
|
+
* be positioned or the stretched layer would size to the pill.
|
|
210
|
+
*
|
|
211
|
+
* Dashboard is `relative`, which lifts it above that stretched layer — and
|
|
212
|
+
* because it is lifted it must not be live while it is invisible.
|
|
213
|
+
* `opacity-0` is a paint state, not a pointer state, so at rest the pill was
|
|
214
|
+
* a region of the card that went somewhere different from every pixel around
|
|
215
|
+
* it, with nothing to see (#171). `pointer-events-none` until hover or
|
|
216
|
+
* focus-within, and Open's overlay untouched, is the whole fix.
|
|
217
|
+
*/
|
|
218
|
+
const actionPair = (_jsxs(_Fragment, { children: [_jsxs("a", { href: href, "data-slot": "entity-card-open", className: "inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline after:absolute after:inset-0 after:content-[''] focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(OpenLiveIcon, { className: "size-3.5" }), "Open"] }), dashboardTarget ? (_jsxs("a", { href: dashboardTarget, "data-slot": "entity-card-dashboard", className: "pointer-events-none relative inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline group-hover/card:pointer-events-auto group-focus-within/card:pointer-events-auto focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(EntityDashboardIcon, { className: "size-3.5" }), "Dashboard"] })) : null] }));
|
|
113
219
|
const body = children ??
|
|
114
|
-
(_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("span", { dir: "auto", "data-slot": "entity-card-title", title: title, className: cn("block
|
|
220
|
+
(_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("span", { dir: "auto", "data-slot": "entity-card-title", title: title, className: cn("block font-medium break-words text-ink", sized.title, titleLines === 1 ? "truncate" : "line-clamp-2"), children: [kind && !seed ? (_jsx(EntityKindBadge, { kind: kind, size: "sm", className: "mr-1.5 align-[-0.2em]" })) : null, title] }), slug ? (_jsx("span", { dir: "auto", "data-slot": "entity-card-slug", title: slug, className: "mt-0.5 block truncate font-mono text-caption text-faint", children: slug })) : null] }), status ? _jsx("div", { className: "shrink-0", children: status }) : null, headerActions ? (_jsx("div", { "data-slot": "entity-card-actions",
|
|
115
221
|
// items-center against the title's first line, and -mt-1 to pull an
|
|
116
222
|
// icon button's own padding back so the glyph optically lines up
|
|
117
223
|
// with the title rather than sitting a couple of pixels low.
|
|
118
|
-
className: "-mt-1 flex shrink-0 items-center gap-1", children: headerActions })) : null] }), description ? (_jsx("p", { dir: "auto", "data-slot": "entity-card-description", title: description, className: cn("m-0 text-body
|
|
119
|
-
|
|
224
|
+
className: "-mt-1 flex shrink-0 items-center gap-1", children: headerActions })) : null] }), description ? (_jsx("p", { dir: "auto", "data-slot": "entity-card-description", title: description, className: cn("m-0 text-body", sized.description, clampDescription), children: description })) : null, meta, _jsx("div", { "aria-hidden": "true", className: "grow" }), shownStats && shownStats.length > 0 ? (_jsx("div", { "data-slot": "entity-card-stats", className: cn("flex flex-wrap items-center border-t border-hairline text-caption text-body", sized.stats), children: shownStats.map((stat) => (_jsxs("span", { className: "inline-flex items-center gap-1.5", children: [stat.icon ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex [&>svg]:size-4", children: stat.icon })) : null, stat.value, _jsx("span", { className: "sr-only", children: stat.label })] }, stat.label))) })) : null, footer] }));
|
|
225
|
+
/**
|
|
226
|
+
* The preview region, shared by all three sizes.
|
|
227
|
+
*
|
|
228
|
+
* A function rather than a second copy, because the two things that differ
|
|
229
|
+
* between the stacked sizes and the row are its shape and whether a panel goes
|
|
230
|
+
* over it. Everything that is easy to get wrong — the capture painting over
|
|
231
|
+
* the identity rather than instead of it, the badge sitting after the panel so
|
|
232
|
+
* the scrim does not smudge it, the badge not eating a click meant for the
|
|
233
|
+
* link — is written once and is the same picture in every size.
|
|
234
|
+
*/
|
|
235
|
+
const previewRegion = (shape, badgeSize, panel) => seed ? (_jsxs("div", { "data-slot": "entity-card-preview", className: cn("relative shrink-0", shape), children: [_jsx(EntityIdentity, { seed: seed, name: title }), previewUrl ? (_jsx("div", { "data-slot": "entity-card-capture", "aria-hidden": "true", className: "absolute inset-0 bg-cover bg-center",
|
|
236
|
+
// A background image, not an <img>: a URL that 404s paints nothing
|
|
237
|
+
// and the identity tile below shows through, with no state and no
|
|
238
|
+
// client boundary. The URL goes out exactly as the caller wrote it —
|
|
239
|
+
// `cssUrlString` escapes only the quote and backslash that would
|
|
240
|
+
// break out of url("..."), and never re-encodes an already-encoded
|
|
241
|
+
// URL (ui#178).
|
|
242
|
+
style: { backgroundImage: `url("${cssUrlString(previewUrl)}")` } })) : null, panel, kind ? (_jsx(EntityKindBadge, { kind: kind, size: badgeSize, className: cn("pointer-events-none absolute", badgeSize === "md" ? "top-2 right-2" : "top-1 right-1") })) : null] })) : null;
|
|
243
|
+
/**
|
|
244
|
+
* The reveal panel, which belongs to the stacked sizes only.
|
|
245
|
+
*
|
|
246
|
+
* Extracted to a variable rather than left inline because `previewRegion`
|
|
247
|
+
* above is now shared with the row, and the row deliberately has no panel to
|
|
248
|
+
* pass it. The alternative — a boolean the region branches on — would put the
|
|
249
|
+
* decision in two places instead of one.
|
|
250
|
+
*/
|
|
251
|
+
const revealPanel = revealed ? (_jsxs("div", { "data-slot": "entity-card-reveal", "data-cg-surface": "ink", className: cn("absolute inset-0 flex flex-col justify-end bg-scrim-strong text-ink",
|
|
252
|
+
// The only thing compact changes about this panel is its
|
|
253
|
+
// measurements. Same scrim, same ink surface, same two
|
|
254
|
+
// foregrounds — a panel that got smaller AND paler would be
|
|
255
|
+
// trading contrast for space, which is the one thing the
|
|
256
|
+
// guardrail exists to stop.
|
|
257
|
+
sized.reveal,
|
|
258
|
+
// opacity-0, not hidden: the panel is in the tab order at all
|
|
259
|
+
// times, so tabbing into Open is what reveals it, and a touch
|
|
260
|
+
// user with no hover still has a live tap target.
|
|
261
|
+
"opacity-0 transition-opacity duration-[var(--cg-duration)] ease-out", "group-hover/card:opacity-100 group-focus-within/card:opacity-100",
|
|
262
|
+
// Reduced motion removes the FADE, not the panel. Someone who
|
|
263
|
+
// has asked for less movement still needs the actions.
|
|
264
|
+
"motion-reduce:transition-none"), children: [_jsx("span", { "data-slot": "entity-card-reveal-title", dir: "auto", className: cn("truncate font-medium", sized.revealTitle), children: title }), description ? (_jsx("p", { "data-slot": "entity-card-reveal-description", dir: "auto",
|
|
265
|
+
// text-body, never text-faint. The secondary measures 6.18:1
|
|
266
|
+
// on this scrim and the guardrail holds it there; the muted
|
|
267
|
+
// rung measures 4.06:1, under AA, and is deliberately outside
|
|
268
|
+
// that assertion because it is documented as non-essential
|
|
269
|
+
// text. So there is no muted tier available on this panel.
|
|
270
|
+
className: "m-0 truncate text-caption text-body", children: description })) : null, creator || status ? (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2", children: [creator ? (_jsxs("span", { "data-slot": "entity-card-reveal-creator", className: "flex min-w-0 items-center gap-1.5 text-caption text-body", children: [creator.avatar ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex size-4 shrink-0 overflow-hidden rounded-pill [&>*]:size-full", children: creator.avatar })) : null, _jsx("span", { className: "truncate", children: creator.name })] })) : (_jsx("span", {})), status ? _jsx("span", { className: "shrink-0", children: status }) : null] })) : null, _jsx("div", { className: "flex items-center gap-2 pt-0.5", children: actionPair })] })) : null;
|
|
271
|
+
/**
|
|
272
|
+
* THE ROW. The same card, running across instead of down.
|
|
273
|
+
*
|
|
274
|
+
* Its own return rather than a set of conditionals threaded through the
|
|
275
|
+
* stacked one, because almost nothing about the arrangement survives the
|
|
276
|
+
* rotation: the preview is beside the text rather than above it, the title,
|
|
277
|
+
* the description and the creator are one column of single lines, and the
|
|
278
|
+
* state, the header's controls and the two actions form a cluster at the end.
|
|
279
|
+
* Threading that through would leave a body that reads as neither shape.
|
|
280
|
+
*
|
|
281
|
+
* What IS shared is shared for real: `previewRegion` paints the same picture,
|
|
282
|
+
* `actionPair` is the same two anchors, and `SIZE_STYLE.row` is a column of
|
|
283
|
+
* the same table. Nothing about a row is a second implementation of something
|
|
284
|
+
* the media card already does.
|
|
285
|
+
*
|
|
286
|
+
* ## The hit model, which is the media card's with one thing moved
|
|
287
|
+
*
|
|
288
|
+
* `relative` on the card is load-bearing: it is what Open's stretched
|
|
289
|
+
* `::after` sizes to, so a click anywhere on the row opens the entity, exactly
|
|
290
|
+
* as a click anywhere on a thumbnail does. That also means a row is never
|
|
291
|
+
* wrapped in a whole-card anchor — the actions are anchors, and an anchor
|
|
292
|
+
* inside an anchor is invalid HTML that browsers repair by closing the outer
|
|
293
|
+
* one.
|
|
294
|
+
*
|
|
295
|
+
* `headerActions` is the thing that moves. On a media card it sits in the body
|
|
296
|
+
* and nothing is stretched over it. Here it sits inside Open's hit area, so it
|
|
297
|
+
* carries `relative z-10` to stay above it. That is safe in a way the same
|
|
298
|
+
* treatment on the panel's Dashboard was not (#171): these controls are
|
|
299
|
+
* VISIBLE at rest, so a tap landing on the save toggle rather than on the row
|
|
300
|
+
* is what a reader can see is going to happen. The invisible-at-rest rule
|
|
301
|
+
* still binds the two actions, which is why Dashboard keeps its
|
|
302
|
+
* `pointer-events-none`.
|
|
303
|
+
*
|
|
304
|
+
* `stats` and `footer` are not rendered here — see the size note at the top.
|
|
305
|
+
*/
|
|
306
|
+
if (size === "row") {
|
|
307
|
+
return (_jsxs(Card, { "data-slot": "entity-card", "data-entity-size": "row", className: cn("relative flex-row items-center gap-3 p-(--card-spacing)", sized.cardSpacing, className), ...props, children: [previewRegion(
|
|
308
|
+
// A left thumbnail, so it rounds on all four corners rather than
|
|
309
|
+
// sharing the card's top edge, and it carries a full hairline rather
|
|
310
|
+
// than the media card's single bottom rule.
|
|
311
|
+
cn("overflow-hidden rounded-lg border border-hairline", ROW_THUMBNAIL), "sm", null), _jsx("div", { className: cn("flex w-0 min-w-0 flex-1 flex-col", sized.body), children: children ?? (_jsxs(_Fragment, { children: [_jsxs("span", { dir: "auto", "data-slot": "entity-card-title", title: title, className: cn("block truncate font-medium text-ink", sized.title), children: [kind && !seed ? (_jsx(EntityKindBadge, { kind: kind, size: "sm", className: "mr-1.5 align-[-0.2em]" })) : null, title] }), slug ? (_jsx("span", { dir: "auto", "data-slot": "entity-card-slug", title: slug, className: "block truncate font-mono text-caption text-faint", children: slug })) : null, description ? (_jsx("p", { dir: "auto", "data-slot": "entity-card-description", title: description, className: cn("m-0 truncate text-body", sized.description), children: description })) : null, creator || meta ? (_jsxs("div", { className: "flex min-w-0 items-center gap-2 text-caption text-body", children: [creator ? (_jsxs("span", { "data-slot": "entity-card-creator", className: "flex min-w-0 items-center gap-1.5", children: [creator.avatar ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex size-4 shrink-0 overflow-hidden rounded-pill [&>*]:size-full", children: creator.avatar })) : null, _jsx("span", { className: "truncate", children: creator.name })] })) : null, meta] })) : null] })) }), _jsxs("div", { className: "flex shrink-0 items-center gap-2", children: [status ? _jsx("span", { className: "shrink-0", children: status }) : null, headerActions ? (_jsx("div", { "data-slot": "entity-card-actions", className: "relative z-10 flex shrink-0 items-center gap-1", children: headerActions })) : null, href ? (_jsx("div", { "data-slot": "entity-card-row-actions", className: cn("flex shrink-0 items-center gap-2",
|
|
312
|
+
// The row's whole hover behaviour, and all of it: the
|
|
313
|
+
// information is already on screen, so what arrives is the two
|
|
314
|
+
// actions and nothing else.
|
|
315
|
+
"opacity-0 transition-opacity duration-[var(--cg-duration)] ease-out", "group-hover/card:opacity-100 group-focus-within/card:opacity-100",
|
|
316
|
+
// Reduced motion removes the FADE, not the actions.
|
|
317
|
+
"motion-reduce:transition-none"), children: actionPair })) : null] })] }));
|
|
318
|
+
}
|
|
319
|
+
const card = (_jsxs(Card, { "data-slot": "entity-card", "data-entity-size": size,
|
|
120
320
|
// gap-0 py-0: `Card` pads itself for a header/content/footer stack, and
|
|
121
321
|
// this card's preview is full bleed to the top edge. The padding moves
|
|
122
322
|
// inside, onto the body, so the preview can touch the corners.
|
|
@@ -130,53 +330,12 @@ function EntityCard({ title, slug, description, titleLines = 2, descriptionLines
|
|
|
130
330
|
// anchor. As a direct grid item it must NOT be h-full: a grid area has a
|
|
131
331
|
// definite height, so height:100% pins the card to the tallest card in the
|
|
132
332
|
// row even when the grid was told `items-start`.
|
|
133
|
-
className: cn("gap-0 py-0", href && !revealed && "h-full", className), ...props, children: [
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// A background image, not an <img>: a URL that 404s paints
|
|
140
|
-
// nothing and the identity tile below shows through, with no
|
|
141
|
-
// state and no client boundary. The URL goes out exactly as the
|
|
142
|
-
// caller wrote it — `cssUrlString` escapes only the quote and
|
|
143
|
-
// backslash that would break out of url("..."), and never
|
|
144
|
-
// re-encodes an already-encoded URL (ui#178).
|
|
145
|
-
style: { backgroundImage: `url("${cssUrlString(previewUrl)}")` } })) : null, revealed ? (_jsxs("div", { "data-slot": "entity-card-reveal", "data-cg-surface": "ink", className: cn("absolute inset-0 flex flex-col justify-end gap-1.5 bg-scrim-strong p-3 text-ink",
|
|
146
|
-
// opacity-0, not hidden: the panel is in the tab order at all
|
|
147
|
-
// times, so tabbing into Open is what reveals it, and a touch
|
|
148
|
-
// user with no hover still has a live tap target.
|
|
149
|
-
"opacity-0 transition-opacity duration-[var(--cg-duration)] ease-out", "group-hover/card:opacity-100 group-focus-within/card:opacity-100",
|
|
150
|
-
// Reduced motion removes the FADE, not the panel. Someone who
|
|
151
|
-
// has asked for less movement still needs the actions.
|
|
152
|
-
"motion-reduce:transition-none"), children: [_jsx("span", { "data-slot": "entity-card-reveal-title", dir: "auto", className: "truncate text-body-sm font-medium", children: title }), description ? (_jsx("p", { "data-slot": "entity-card-reveal-description", dir: "auto",
|
|
153
|
-
// text-body, never text-faint. The secondary measures 6.18:1
|
|
154
|
-
// on this scrim and the guardrail holds it there; the muted
|
|
155
|
-
// rung measures 4.06:1, under AA, and is deliberately outside
|
|
156
|
-
// that assertion because it is documented as non-essential
|
|
157
|
-
// text. So there is no muted tier available on this panel.
|
|
158
|
-
className: "m-0 truncate text-caption text-body", children: description })) : null, creator || status ? (_jsxs("div", { className: "flex min-w-0 items-center justify-between gap-2", children: [creator ? (_jsxs("span", { "data-slot": "entity-card-reveal-creator", className: "flex min-w-0 items-center gap-1.5 text-caption text-body", children: [creator.avatar ? (_jsx("span", { "aria-hidden": "true", className: "inline-flex size-4 shrink-0 overflow-hidden rounded-pill [&>*]:size-full", children: creator.avatar })) : null, _jsx("span", { className: "truncate", children: creator.name })] })) : (_jsx("span", {})), status ? _jsx("span", { className: "shrink-0", children: status }) : null] })) : null, _jsxs("div", { className: "flex items-center gap-2 pt-0.5", children: [_jsxs("a", { href: href, "data-slot": "entity-card-open",
|
|
159
|
-
// after:inset-0 makes this link the whole panel, so a click
|
|
160
|
-
// anywhere on the thumbnail opens the entity. The anchor
|
|
161
|
-
// itself must NOT be positioned or the stretched layer sizes
|
|
162
|
-
// to the anchor instead of to the panel — the panel is already
|
|
163
|
-
// absolute, so it is the containing block. Dashboard comes
|
|
164
|
-
// later in the DOM and IS positioned, so it stacks above the
|
|
165
|
-
// stretched layer rather than under it.
|
|
166
|
-
className: "inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline after:absolute after:inset-0 after:content-[''] focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(OpenLiveIcon, { className: "size-3.5" }), "Open"] }), dashboardTarget ? (_jsxs("a", { href: dashboardTarget, "data-slot": "entity-card-dashboard",
|
|
167
|
-
// relative, and that is load-bearing: it lifts this link
|
|
168
|
-
// above Open's stretched ::after, which otherwise covers the
|
|
169
|
-
// whole panel and would swallow every click meant for here.
|
|
170
|
-
//
|
|
171
|
-
// And because it is lifted, it must not be live while the
|
|
172
|
-
// panel is invisible: opacity-0 is a paint state, so at rest
|
|
173
|
-
// this pill was a region of the thumbnail that went here on
|
|
174
|
-
// a tap instead of opening the entity (#171).
|
|
175
|
-
// pointer-events-none until the panel is actually revealed —
|
|
176
|
-
// the same reasoning the kind mark carries. Open keeps its
|
|
177
|
-
// stretched hit area at all times, so the touch fallback is
|
|
178
|
-
// untouched.
|
|
179
|
-
className: "pointer-events-none relative inline-flex items-center gap-1 rounded-pill border border-hairline px-2 py-1 text-caption no-underline group-hover/card:pointer-events-auto group-focus-within/card:pointer-events-auto focus-visible:ring-3 focus-visible:ring-ring focus-visible:outline-none", children: [_jsx(EntityDashboardIcon, { className: "size-3.5" }), "Dashboard"] })) : null] })] })) : null, kind ? (_jsx(EntityKindBadge, { kind: kind, className: "pointer-events-none absolute top-2 right-2" })) : null] })) : null, _jsx("div", { className: "flex min-h-0 flex-1 flex-col gap-3 p-(--card-spacing)", children: body })] }));
|
|
333
|
+
className: cn("gap-0 py-0", sized.cardSpacing, href && !revealed && "h-full", className), ...props, children: [previewRegion(
|
|
334
|
+
// rounded-t-xl is the same --cg-radius-xl the card rounds to, and
|
|
335
|
+
// overflow-hidden is what keeps the reveal panel inside it. The card
|
|
336
|
+
// already clips; stating it here means the panel can never paint a
|
|
337
|
+
// corner the card does not have.
|
|
338
|
+
"overflow-hidden rounded-t-xl border-b border-hairline", "md", revealPanel), _jsx("div", { className: cn("flex min-h-0 flex-1 flex-col p-(--card-spacing)", sized.body), children: body })] }));
|
|
180
339
|
// A revealed card is never wrapped: the panel's Open action is already an
|
|
181
340
|
// anchor, and an anchor inside an anchor is invalid HTML that browsers repair
|
|
182
341
|
// by closing the outer one.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity-card.js","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAC9D,OAAO,EACL,mBAAmB,EACnB,aAAa,EACb,WAAW,EACX,mBAAmB,EACnB,YAAY,GACb,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"entity-card.js","sourceRoot":"","sources":["../../src/blocks/entity-card.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED