@activecollab/components 2.0.363 → 2.0.364
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/presentation/stackedCard/content/ImageCard.js +60 -0
- package/dist/cjs/presentation/stackedCard/content/ImageCard.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/LinkCard.js +348 -0
- package/dist/cjs/presentation/stackedCard/content/LinkCard.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/NoteCard.js +92 -0
- package/dist/cjs/presentation/stackedCard/content/NoteCard.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/SwatchCard.js +74 -0
- package/dist/cjs/presentation/stackedCard/content/SwatchCard.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/TaskCard.js +231 -0
- package/dist/cjs/presentation/stackedCard/content/TaskCard.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/index.js +83 -0
- package/dist/cjs/presentation/stackedCard/content/index.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/shared.js +144 -0
- package/dist/cjs/presentation/stackedCard/content/shared.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/content/unfurl.js +172 -0
- package/dist/cjs/presentation/stackedCard/content/unfurl.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/primitives.js +254 -0
- package/dist/cjs/presentation/stackedCard/primitives.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/resizePolicy.js +183 -0
- package/dist/cjs/presentation/stackedCard/resizePolicy.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/shell.js +165 -0
- package/dist/cjs/presentation/stackedCard/shell.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/storyScaffold.js +72 -0
- package/dist/cjs/presentation/stackedCard/storyScaffold.js.map +1 -0
- package/dist/cjs/presentation/stackedCard/useInlineEdit.js +208 -0
- package/dist/cjs/presentation/stackedCard/useInlineEdit.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/ImageCard.d.ts +15 -0
- package/dist/esm/presentation/stackedCard/content/ImageCard.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/ImageCard.js +50 -0
- package/dist/esm/presentation/stackedCard/content/ImageCard.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/LinkCard.d.ts +28 -0
- package/dist/esm/presentation/stackedCard/content/LinkCard.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/LinkCard.js +336 -0
- package/dist/esm/presentation/stackedCard/content/LinkCard.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/NoteCard.d.ts +10 -0
- package/dist/esm/presentation/stackedCard/content/NoteCard.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/NoteCard.js +82 -0
- package/dist/esm/presentation/stackedCard/content/NoteCard.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/SwatchCard.d.ts +14 -0
- package/dist/esm/presentation/stackedCard/content/SwatchCard.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/SwatchCard.js +64 -0
- package/dist/esm/presentation/stackedCard/content/SwatchCard.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/TaskCard.d.ts +29 -0
- package/dist/esm/presentation/stackedCard/content/TaskCard.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/TaskCard.js +218 -0
- package/dist/esm/presentation/stackedCard/content/TaskCard.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/index.d.ts +8 -0
- package/dist/esm/presentation/stackedCard/content/index.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/index.js +8 -0
- package/dist/esm/presentation/stackedCard/content/index.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/shared.d.ts +46 -0
- package/dist/esm/presentation/stackedCard/content/shared.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/shared.js +134 -0
- package/dist/esm/presentation/stackedCard/content/shared.js.map +1 -0
- package/dist/esm/presentation/stackedCard/content/unfurl.d.ts +89 -0
- package/dist/esm/presentation/stackedCard/content/unfurl.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/content/unfurl.js +147 -0
- package/dist/esm/presentation/stackedCard/content/unfurl.js.map +1 -0
- package/dist/esm/presentation/stackedCard/primitives.d.ts +84 -0
- package/dist/esm/presentation/stackedCard/primitives.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/primitives.js +241 -0
- package/dist/esm/presentation/stackedCard/primitives.js.map +1 -0
- package/dist/esm/presentation/stackedCard/resizePolicy.d.ts +97 -0
- package/dist/esm/presentation/stackedCard/resizePolicy.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/resizePolicy.js +173 -0
- package/dist/esm/presentation/stackedCard/resizePolicy.js.map +1 -0
- package/dist/esm/presentation/stackedCard/shell.d.ts +46 -0
- package/dist/esm/presentation/stackedCard/shell.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/shell.js +156 -0
- package/dist/esm/presentation/stackedCard/shell.js.map +1 -0
- package/dist/esm/presentation/stackedCard/storyScaffold.d.ts +28 -0
- package/dist/esm/presentation/stackedCard/storyScaffold.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/storyScaffold.js +66 -0
- package/dist/esm/presentation/stackedCard/storyScaffold.js.map +1 -0
- package/dist/esm/presentation/stackedCard/useInlineEdit.d.ts +68 -0
- package/dist/esm/presentation/stackedCard/useInlineEdit.d.ts.map +1 -0
- package/dist/esm/presentation/stackedCard/useInlineEdit.js +192 -0
- package/dist/esm/presentation/stackedCard/useInlineEdit.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useUnfurl = exports.formatFetchedAt = exports.MOCK_LINKS = void 0;
|
|
7
|
+
var _react = require("react");
|
|
8
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
9
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
10
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
11
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
12
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
13
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
14
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
15
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
16
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
17
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
18
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
19
|
+
/**
|
|
20
|
+
* Mock unfurl service for the LinkCard concept.
|
|
21
|
+
*
|
|
22
|
+
* A link preview is a LIFECYCLE, not two static layouts. The real service is
|
|
23
|
+
* server-side (SSRF-guarded, oEmbed → OpenGraph → Twitter Cards → <title>,
|
|
24
|
+
* cached ~24h with a stored `fetchedAt` and a manual re-unfurl affordance — see
|
|
25
|
+
* note 52104 §B3). This is a promise-based fake with a configurable delay and a
|
|
26
|
+
* failure toggle so the story can drive the whole lifecycle without a network.
|
|
27
|
+
*
|
|
28
|
+
* The data arrives on a PROGRESSIVE LADDER of three tiers, each carrying more
|
|
29
|
+
* than the last:
|
|
30
|
+
* url → just the raw URL (nothing fetched yet)
|
|
31
|
+
* basic → favicon + title + domain
|
|
32
|
+
* full → + description, hero image, media kind / duration
|
|
33
|
+
* The card reserves the next tier's space at every tier, so climbing the ladder
|
|
34
|
+
* never reflows the card.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/** The cumulative data shape. Fields fill in as the ladder climbs. */
|
|
38
|
+
|
|
39
|
+
/** A seed link — what the fake "server" would resolve the URL to at tier full. */
|
|
40
|
+
|
|
41
|
+
var MOCK_LINKS = exports.MOCK_LINKS = {
|
|
42
|
+
vimeo: {
|
|
43
|
+
url: "https://vimeo.com/876631121",
|
|
44
|
+
faviconColor: "#0F6E56",
|
|
45
|
+
title: "Brand refresh — motion explorations for the spring launch",
|
|
46
|
+
domain: "vimeo.com",
|
|
47
|
+
description: "A reel of motion studies exploring the refreshed brand system: type in motion, the new mark, and transitions for the marketing site.",
|
|
48
|
+
heroColor: "#1D9E75",
|
|
49
|
+
kind: "Video",
|
|
50
|
+
duration: "4:32",
|
|
51
|
+
playable: true
|
|
52
|
+
},
|
|
53
|
+
history: {
|
|
54
|
+
url: "https://ww2history.org/timeline",
|
|
55
|
+
faviconColor: "#8C5A2B",
|
|
56
|
+
title: "The Second World War • Timeline, key battles, and firsthand accounts",
|
|
57
|
+
domain: "ww2history.org",
|
|
58
|
+
description: "An illustrated timeline of the Second World War with primary sources, maps, and firsthand accounts from each theatre of the war.",
|
|
59
|
+
heroColor: "#B5793B",
|
|
60
|
+
kind: "Article",
|
|
61
|
+
playable: false
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/** Progressive tier data derived from a seed link. */
|
|
66
|
+
var tierData = function tierData(link, tier) {
|
|
67
|
+
if (tier === "url") return {
|
|
68
|
+
url: link.url
|
|
69
|
+
};
|
|
70
|
+
if (tier === "basic") {
|
|
71
|
+
return {
|
|
72
|
+
url: link.url,
|
|
73
|
+
faviconColor: link.faviconColor,
|
|
74
|
+
title: link.title,
|
|
75
|
+
domain: link.domain
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return _objectSpread({}, link);
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Drives one link through the unfurl lifecycle. Climbs url → basic → full on a
|
|
82
|
+
* timer, or lands in `error` if `shouldFail`. `retry` / `reunfurl` re-run it;
|
|
83
|
+
* `markStale` moves a resolved card to the stale state so the re-unfurl
|
|
84
|
+
* affordance can be shown.
|
|
85
|
+
*/
|
|
86
|
+
var useUnfurl = exports.useUnfurl = function useUnfurl(_ref) {
|
|
87
|
+
var link = _ref.link,
|
|
88
|
+
_ref$delayMs = _ref.delayMs,
|
|
89
|
+
delayMs = _ref$delayMs === void 0 ? 900 : _ref$delayMs,
|
|
90
|
+
_ref$shouldFail = _ref.shouldFail,
|
|
91
|
+
shouldFail = _ref$shouldFail === void 0 ? false : _ref$shouldFail;
|
|
92
|
+
var _useState = (0, _react.useState)("resolving"),
|
|
93
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
94
|
+
status = _useState2[0],
|
|
95
|
+
setStatus = _useState2[1];
|
|
96
|
+
var _useState3 = (0, _react.useState)("url"),
|
|
97
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
98
|
+
tier = _useState4[0],
|
|
99
|
+
setTier = _useState4[1];
|
|
100
|
+
var _useState5 = (0, _react.useState)(function () {
|
|
101
|
+
return tierData(link, "url");
|
|
102
|
+
}),
|
|
103
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
104
|
+
data = _useState6[0],
|
|
105
|
+
setData = _useState6[1];
|
|
106
|
+
var _useState7 = (0, _react.useState)(null),
|
|
107
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
108
|
+
fetchedAt = _useState8[0],
|
|
109
|
+
setFetchedAt = _useState8[1];
|
|
110
|
+
var timers = (0, _react.useRef)([]);
|
|
111
|
+
var clearTimers = (0, _react.useCallback)(function () {
|
|
112
|
+
timers.current.forEach(clearTimeout);
|
|
113
|
+
timers.current = [];
|
|
114
|
+
}, []);
|
|
115
|
+
var start = (0, _react.useCallback)(function () {
|
|
116
|
+
clearTimers();
|
|
117
|
+
setStatus("resolving");
|
|
118
|
+
setTier("url");
|
|
119
|
+
setData(tierData(link, "url"));
|
|
120
|
+
if (shouldFail) {
|
|
121
|
+
// Fail partway: the favicon + title never arrive; we keep the raw URL.
|
|
122
|
+
timers.current.push(setTimeout(function () {
|
|
123
|
+
return setStatus("error");
|
|
124
|
+
}, delayMs));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
timers.current.push(setTimeout(function () {
|
|
128
|
+
setTier("basic");
|
|
129
|
+
setData(tierData(link, "basic"));
|
|
130
|
+
}, delayMs));
|
|
131
|
+
timers.current.push(setTimeout(function () {
|
|
132
|
+
setTier("full");
|
|
133
|
+
setData(tierData(link, "full"));
|
|
134
|
+
setStatus("resolved");
|
|
135
|
+
setFetchedAt(Date.now());
|
|
136
|
+
}, delayMs * 2));
|
|
137
|
+
}, [clearTimers, link, delayMs, shouldFail]);
|
|
138
|
+
var markStale = (0, _react.useCallback)(function () {
|
|
139
|
+
setStatus(function (prev) {
|
|
140
|
+
return prev === "resolved" ? "stale" : prev;
|
|
141
|
+
});
|
|
142
|
+
}, []);
|
|
143
|
+
|
|
144
|
+
// Kick off on mount and whenever the config that defines the run changes.
|
|
145
|
+
(0, _react.useEffect)(function () {
|
|
146
|
+
start();
|
|
147
|
+
return clearTimers;
|
|
148
|
+
}, [start, clearTimers]);
|
|
149
|
+
return {
|
|
150
|
+
status,
|
|
151
|
+
tier,
|
|
152
|
+
data,
|
|
153
|
+
fetchedAt,
|
|
154
|
+
start,
|
|
155
|
+
retry: start,
|
|
156
|
+
reunfurl: start,
|
|
157
|
+
markStale
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
/** Human-readable "fetched N ago" for the stale affordance. */
|
|
162
|
+
var formatFetchedAt = exports.formatFetchedAt = function formatFetchedAt(fetchedAt) {
|
|
163
|
+
if (!fetchedAt) return "";
|
|
164
|
+
var seconds = Math.max(1, Math.round((Date.now() - fetchedAt) / 1000));
|
|
165
|
+
if (seconds < 60) return "".concat(seconds, "s ago");
|
|
166
|
+
var minutes = Math.round(seconds / 60);
|
|
167
|
+
if (minutes < 60) return "".concat(minutes, "m ago");
|
|
168
|
+
var hours = Math.round(minutes / 60);
|
|
169
|
+
if (hours < 24) return "".concat(hours, "h ago");
|
|
170
|
+
return "".concat(Math.round(hours / 24), "d ago");
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=unfurl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unfurl.js","names":["_react","require","_slicedToArray","r","e","_arrayWithHoles","_iterableToArrayLimit","_unsupportedIterableToArray","_nonIterableRest","TypeError","a","_arrayLikeToArray","t","toString","call","slice","constructor","name","Array","from","test","length","n","l","Symbol","iterator","i","u","f","o","next","Object","done","push","value","return","isArray","ownKeys","keys","getOwnPropertySymbols","filter","getOwnPropertyDescriptor","enumerable","apply","_objectSpread","arguments","forEach","_defineProperty","getOwnPropertyDescriptors","defineProperties","defineProperty","_toPropertyKey","configurable","writable","_toPrimitive","toPrimitive","String","Number","MOCK_LINKS","exports","vimeo","url","faviconColor","title","domain","description","heroColor","kind","duration","playable","history","tierData","link","tier","useUnfurl","_ref","_ref$delayMs","delayMs","_ref$shouldFail","shouldFail","_useState","useState","_useState2","status","setStatus","_useState3","_useState4","setTier","_useState5","_useState6","data","setData","_useState7","_useState8","fetchedAt","setFetchedAt","timers","useRef","clearTimers","useCallback","current","clearTimeout","start","setTimeout","Date","now","markStale","prev","useEffect","retry","reunfurl","formatFetchedAt","seconds","Math","max","round","concat","minutes","hours"],"sources":["../../../../../src/presentation/stackedCard/content/unfurl.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\n\n/**\n * Mock unfurl service for the LinkCard concept.\n *\n * A link preview is a LIFECYCLE, not two static layouts. The real service is\n * server-side (SSRF-guarded, oEmbed → OpenGraph → Twitter Cards → <title>,\n * cached ~24h with a stored `fetchedAt` and a manual re-unfurl affordance — see\n * note 52104 §B3). This is a promise-based fake with a configurable delay and a\n * failure toggle so the story can drive the whole lifecycle without a network.\n *\n * The data arrives on a PROGRESSIVE LADDER of three tiers, each carrying more\n * than the last:\n * url → just the raw URL (nothing fetched yet)\n * basic → favicon + title + domain\n * full → + description, hero image, media kind / duration\n * The card reserves the next tier's space at every tier, so climbing the ladder\n * never reflows the card.\n */\n\nexport type UnfurlTier = \"url\" | \"basic\" | \"full\";\n\nexport type UnfurlStatus = \"resolving\" | \"resolved\" | \"stale\" | \"error\";\n\n/** The cumulative data shape. Fields fill in as the ladder climbs. */\nexport interface UnfurlData {\n /** Always present — the raw pasted URL. */\n url: string;\n /** Tier `basic` and up: a stand-in favicon colour. */\n faviconColor?: string;\n /** Tier `basic` and up: page title. */\n title?: string;\n /** Tier `basic` and up: the display domain. */\n domain?: string;\n /** Tier `full`: short description / summary. */\n description?: string;\n /** Tier `full`: hero image src (a real <img> in production). */\n heroSrc?: string;\n /** Tier `full`: hero fill colour, used when there is no hero image. */\n heroColor?: string;\n /** Tier `full`: media kind chip (Video, Article, …). */\n kind?: string;\n /** Tier `full`: duration chip for playable media. */\n duration?: string;\n /** Tier `full`: whether the media is playable (shows the cover play badge). */\n playable?: boolean;\n}\n\n/** A seed link — what the fake \"server\" would resolve the URL to at tier full. */\nexport interface MockLink {\n url: string;\n faviconColor: string;\n title: string;\n domain: string;\n description: string;\n heroColor: string;\n heroSrc?: string;\n kind: string;\n duration?: string;\n playable?: boolean;\n}\n\nexport const MOCK_LINKS: Record<string, MockLink> = {\n vimeo: {\n url: \"https://vimeo.com/876631121\",\n faviconColor: \"#0F6E56\",\n title: \"Brand refresh — motion explorations for the spring launch\",\n domain: \"vimeo.com\",\n description:\n \"A reel of motion studies exploring the refreshed brand system: type in motion, the new mark, and transitions for the marketing site.\",\n heroColor: \"#1D9E75\",\n kind: \"Video\",\n duration: \"4:32\",\n playable: true,\n },\n history: {\n url: \"https://ww2history.org/timeline\",\n faviconColor: \"#8C5A2B\",\n title:\n \"The Second World War • Timeline, key battles, and firsthand accounts\",\n domain: \"ww2history.org\",\n description:\n \"An illustrated timeline of the Second World War with primary sources, maps, and firsthand accounts from each theatre of the war.\",\n heroColor: \"#B5793B\",\n kind: \"Article\",\n playable: false,\n },\n};\n\n/** Progressive tier data derived from a seed link. */\nconst tierData = (link: MockLink, tier: UnfurlTier): UnfurlData => {\n if (tier === \"url\") return { url: link.url };\n if (tier === \"basic\") {\n return {\n url: link.url,\n faviconColor: link.faviconColor,\n title: link.title,\n domain: link.domain,\n };\n }\n return { ...link };\n};\n\nexport interface UnfurlConfig {\n /** Which seed link to resolve. */\n link: MockLink;\n /** Per-tier delay in ms (url→basic and basic→full each wait this long). */\n delayMs?: number;\n /** When true, the unfurl fails partway and lands in the error state. */\n shouldFail?: boolean;\n}\n\nexport interface UnfurlController {\n status: UnfurlStatus;\n tier: UnfurlTier;\n data: UnfurlData;\n /** Epoch ms of the last successful resolve (drives the stale affordance). */\n fetchedAt: number | null;\n /** Start (or restart) the unfurl ladder from scratch. */\n start: () => void;\n /** Retry after an error — re-runs the simulation. */\n retry: () => void;\n /** Re-unfurl a resolved/stale card — re-runs the simulation. */\n reunfurl: () => void;\n /** Force the resolved card into the stale state (demo affordance). */\n markStale: () => void;\n}\n\n/**\n * Drives one link through the unfurl lifecycle. Climbs url → basic → full on a\n * timer, or lands in `error` if `shouldFail`. `retry` / `reunfurl` re-run it;\n * `markStale` moves a resolved card to the stale state so the re-unfurl\n * affordance can be shown.\n */\nexport const useUnfurl = ({\n link,\n delayMs = 900,\n shouldFail = false,\n}: UnfurlConfig): UnfurlController => {\n const [status, setStatus] = useState<UnfurlStatus>(\"resolving\");\n const [tier, setTier] = useState<UnfurlTier>(\"url\");\n const [data, setData] = useState<UnfurlData>(() => tierData(link, \"url\"));\n const [fetchedAt, setFetchedAt] = useState<number | null>(null);\n\n const timers = useRef<ReturnType<typeof setTimeout>[]>([]);\n\n const clearTimers = useCallback(() => {\n timers.current.forEach(clearTimeout);\n timers.current = [];\n }, []);\n\n const start = useCallback(() => {\n clearTimers();\n setStatus(\"resolving\");\n setTier(\"url\");\n setData(tierData(link, \"url\"));\n\n if (shouldFail) {\n // Fail partway: the favicon + title never arrive; we keep the raw URL.\n timers.current.push(setTimeout(() => setStatus(\"error\"), delayMs));\n return;\n }\n\n timers.current.push(\n setTimeout(() => {\n setTier(\"basic\");\n setData(tierData(link, \"basic\"));\n }, delayMs)\n );\n timers.current.push(\n setTimeout(() => {\n setTier(\"full\");\n setData(tierData(link, \"full\"));\n setStatus(\"resolved\");\n setFetchedAt(Date.now());\n }, delayMs * 2)\n );\n }, [clearTimers, link, delayMs, shouldFail]);\n\n const markStale = useCallback(() => {\n setStatus((prev) => (prev === \"resolved\" ? \"stale\" : prev));\n }, []);\n\n // Kick off on mount and whenever the config that defines the run changes.\n useEffect(() => {\n start();\n return clearTimers;\n }, [start, clearTimers]);\n\n return {\n status,\n tier,\n data,\n fetchedAt,\n start,\n retry: start,\n reunfurl: start,\n markStale,\n };\n};\n\n/** Human-readable \"fetched N ago\" for the stale affordance. */\nexport const formatFetchedAt = (fetchedAt: number | null): string => {\n if (!fetchedAt) return \"\";\n const seconds = Math.max(1, Math.round((Date.now() - fetchedAt) / 1000));\n if (seconds < 60) return `${seconds}s ago`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m ago`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `${hours}h ago`;\n return `${Math.round(hours / 24)}d ago`;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.StackRow = exports.Stack = exports.RemoveCoverGlyph = exports.ROLE_PADDING = exports.PlayBadge = exports.ExpandGlyph = exports.CoverButton = exports.Cover = exports.CollapseGlyph = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _styledComponents = _interopRequireWildcard(require("styled-components"));
|
|
9
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
/**
|
|
12
|
+
* StackedCard layout primitives (story-local, presentation-only).
|
|
13
|
+
*
|
|
14
|
+
* These are the documented foundation of the StackedCard subsystem — the
|
|
15
|
+
* building blocks that every StackedCard concept story in this task set
|
|
16
|
+
* imports from. They are NOT exported from the design-system barrel; they
|
|
17
|
+
* live here so the concept stories share one source of truth instead of
|
|
18
|
+
* re-declaring one-off styled blocks.
|
|
19
|
+
*
|
|
20
|
+
* Three primitives:
|
|
21
|
+
* - Stack — the vertical column. A card is a Stack of StackRows.
|
|
22
|
+
* - StackRow — the one layout primitive. Everything (cover, title, meta,
|
|
23
|
+
* footer) is a row; a `role` sets the default padding and the
|
|
24
|
+
* allowed direction so the anatomy stays predictable.
|
|
25
|
+
* - Cover — sugar for a bleed row that holds media, reserves its height
|
|
26
|
+
* with `aspect-ratio` (so a late image never reflows), and
|
|
27
|
+
* carries two control slots (center + top-right).
|
|
28
|
+
*
|
|
29
|
+
* Colours here come exclusively from CSS variables — the dark scrim behind
|
|
30
|
+
* cover controls is `--sc-scrim` / `--sc-scrim-strong` / `--sc-scrim-fg`, all
|
|
31
|
+
* declared story-side as DS token candidates. No rgba/hex is hardcoded in a
|
|
32
|
+
* primitive; only data colours (a swatch value, a label dot) are ever literal,
|
|
33
|
+
* and those are passed in by the content, never baked in here.
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/* ------------------------------------------------------------------ */
|
|
37
|
+
/* Stack — vertical flex column. No own padding. */
|
|
38
|
+
/* ------------------------------------------------------------------ */
|
|
39
|
+
|
|
40
|
+
var Stack = exports.Stack = _styledComponents.default.div.withConfig({
|
|
41
|
+
displayName: "primitives__Stack",
|
|
42
|
+
componentId: "sc-1ax68l9-0"
|
|
43
|
+
})(["position:relative;display:flex;flex-direction:column;"]);
|
|
44
|
+
|
|
45
|
+
/* ------------------------------------------------------------------ */
|
|
46
|
+
/* StackRow — the only layout primitive, differentiated by `role`. */
|
|
47
|
+
/* ------------------------------------------------------------------ */
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Role → default padding. The row is the increment: title/footer carry the
|
|
51
|
+
* system padding, meta is a tighter properties line, cover bleeds to the edge.
|
|
52
|
+
* `custom` starts from the system padding and expects the caller to adjust.
|
|
53
|
+
*/
|
|
54
|
+
var ROLE_PADDING = exports.ROLE_PADDING = {
|
|
55
|
+
cover: "0",
|
|
56
|
+
title: "8px 12px",
|
|
57
|
+
meta: "2px 12px 4px",
|
|
58
|
+
footer: "8px 12px",
|
|
59
|
+
custom: "8px 12px"
|
|
60
|
+
};
|
|
61
|
+
var StyledRow = _styledComponents.default.div.withConfig({
|
|
62
|
+
displayName: "primitives__StyledRow",
|
|
63
|
+
componentId: "sc-1ax68l9-1"
|
|
64
|
+
})(["position:relative;display:flex;flex-direction:", ";align-items:", ";gap:", ";padding:", ";", " ", ""], function (_ref) {
|
|
65
|
+
var $direction = _ref.$direction;
|
|
66
|
+
return $direction;
|
|
67
|
+
}, function (_ref2) {
|
|
68
|
+
var $direction = _ref2.$direction;
|
|
69
|
+
return $direction === "column" ? "stretch" : "center";
|
|
70
|
+
}, function (_ref3) {
|
|
71
|
+
var $direction = _ref3.$direction;
|
|
72
|
+
return $direction === "column" ? "4px" : "8px";
|
|
73
|
+
}, function (_ref4) {
|
|
74
|
+
var $role = _ref4.$role,
|
|
75
|
+
$bleed = _ref4.$bleed;
|
|
76
|
+
return $bleed ? "0" : ROLE_PADDING[$role];
|
|
77
|
+
}, function (_ref5) {
|
|
78
|
+
var $background = _ref5.$background;
|
|
79
|
+
return $background && (0, _styledComponents.css)(["background:", ";"], $background);
|
|
80
|
+
}, function (_ref6) {
|
|
81
|
+
var $direction = _ref6.$direction;
|
|
82
|
+
return $direction === "row" && (0, _styledComponents.css)(["> *{flex:1 1 0;min-width:0;}> [data-fixed]{flex:0 0 auto;}"]);
|
|
83
|
+
});
|
|
84
|
+
var StackRow = exports.StackRow = function StackRow(_ref7) {
|
|
85
|
+
var _ref7$role = _ref7.role,
|
|
86
|
+
role = _ref7$role === void 0 ? "custom" : _ref7$role,
|
|
87
|
+
bleed = _ref7.bleed,
|
|
88
|
+
_ref7$direction = _ref7.direction,
|
|
89
|
+
direction = _ref7$direction === void 0 ? "row" : _ref7$direction,
|
|
90
|
+
background = _ref7.background,
|
|
91
|
+
className = _ref7.className,
|
|
92
|
+
children = _ref7.children;
|
|
93
|
+
return /*#__PURE__*/_react.default.createElement(StyledRow, {
|
|
94
|
+
$role: role,
|
|
95
|
+
$bleed: bleed,
|
|
96
|
+
$direction: direction,
|
|
97
|
+
$background: background,
|
|
98
|
+
className: className
|
|
99
|
+
}, children);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
/* ------------------------------------------------------------------ */
|
|
103
|
+
/* Cover — sugar for a bleed row that holds media. */
|
|
104
|
+
/* ------------------------------------------------------------------ */
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The media box reserves its height with `aspect-ratio` so the image (or the
|
|
108
|
+
* skeleton that stands in for it) never reflows the card when it arrives.
|
|
109
|
+
* Controls carry the `sc-control` class and are hidden until the cover is
|
|
110
|
+
* hovered OR holds focus (`:focus-within`) — the focus path keeps the cover
|
|
111
|
+
* controls reachable by keyboard, not mouse-only.
|
|
112
|
+
*/
|
|
113
|
+
var StyledCoverMedia = _styledComponents.default.div.withConfig({
|
|
114
|
+
displayName: "primitives__StyledCoverMedia",
|
|
115
|
+
componentId: "sc-1ax68l9-2"
|
|
116
|
+
})(["position:relative;width:100%;aspect-ratio:", ";overflow:hidden;.sc-control{opacity:0;transition:opacity 120ms ease;}&:hover .sc-control,&:focus-within .sc-control{opacity:1;}"], function (_ref8) {
|
|
117
|
+
var $aspectRatio = _ref8.$aspectRatio;
|
|
118
|
+
return $aspectRatio;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
/* The fill (an <img>, an inline <svg> wrapper, or a solid-colour box) is laid
|
|
122
|
+
over the reserved box and made to cover it. */
|
|
123
|
+
var StyledCoverFill = _styledComponents.default.div.withConfig({
|
|
124
|
+
displayName: "primitives__StyledCoverFill",
|
|
125
|
+
componentId: "sc-1ax68l9-3"
|
|
126
|
+
})(["position:absolute;inset:0;> *{width:100%;height:100%;}> img{display:block;object-fit:cover;}"]);
|
|
127
|
+
var StyledCoverCenter = _styledComponents.default.div.withConfig({
|
|
128
|
+
displayName: "primitives__StyledCoverCenter",
|
|
129
|
+
componentId: "sc-1ax68l9-4"
|
|
130
|
+
})(["position:absolute;inset:0;display:flex;align-items:center;justify-content:center;"]);
|
|
131
|
+
var StyledCoverTopRight = _styledComponents.default.div.withConfig({
|
|
132
|
+
displayName: "primitives__StyledCoverTopRight",
|
|
133
|
+
componentId: "sc-1ax68l9-5"
|
|
134
|
+
})(["position:absolute;top:8px;right:8px;display:flex;gap:6px;"]);
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Collapsed cover — the media box gives way to a thin strip. The strip is the
|
|
138
|
+
* expand affordance itself: the whole bar is a button, and a chevron hint is
|
|
139
|
+
* revealed on hover OR focus (`.sc-control`, same reveal rule as every other
|
|
140
|
+
* cover control) so it is reachable by keyboard, not mouse-only. The strip
|
|
141
|
+
* holds no reserved height of its own — the caller's `collapsedStrip` (an ~8px
|
|
142
|
+
* colour bar, or a favicon + domain row for links) sets how tall it reads.
|
|
143
|
+
*/
|
|
144
|
+
var StyledCollapsedStrip = _styledComponents.default.button.withConfig({
|
|
145
|
+
displayName: "primitives__StyledCollapsedStrip",
|
|
146
|
+
componentId: "sc-1ax68l9-6"
|
|
147
|
+
})(["position:relative;display:flex;align-items:center;width:100%;min-height:16px;padding:0;border:0;background:transparent;cursor:pointer;text-align:left;.sc-control{opacity:0;transition:opacity 120ms ease;}&:hover .sc-control,&:focus-visible .sc-control{opacity:1;}&:focus-visible{outline:2px solid var(--sc-selection-ring);outline-offset:-2px;}"]);
|
|
148
|
+
|
|
149
|
+
/* The expand chevron sits at the right, vertically centred over the strip, so
|
|
150
|
+
it reads the same whether the strip is a hairline colour bar or a taller
|
|
151
|
+
favicon row. Small + theme-coloured so it fits a thin strip without a scrim
|
|
152
|
+
button (the whole strip is the button). */
|
|
153
|
+
var StyledStripExpand = _styledComponents.default.span.withConfig({
|
|
154
|
+
displayName: "primitives__StyledStripExpand",
|
|
155
|
+
componentId: "sc-1ax68l9-7"
|
|
156
|
+
})(["position:absolute;top:50%;right:8px;transform:translateY(-50%);display:inline-flex;width:16px;height:16px;color:var(--color-theme-600);svg{width:14px;height:14px;}"]);
|
|
157
|
+
var Cover = exports.Cover = function Cover(_ref9) {
|
|
158
|
+
var _ref9$aspectRatio = _ref9.aspectRatio,
|
|
159
|
+
aspectRatio = _ref9$aspectRatio === void 0 ? "260 / 132" : _ref9$aspectRatio,
|
|
160
|
+
centerSlot = _ref9.centerSlot,
|
|
161
|
+
topRightSlot = _ref9.topRightSlot,
|
|
162
|
+
collapsed = _ref9.collapsed,
|
|
163
|
+
collapsedStrip = _ref9.collapsedStrip,
|
|
164
|
+
onExpand = _ref9.onExpand,
|
|
165
|
+
_ref9$expandLabel = _ref9.expandLabel,
|
|
166
|
+
expandLabel = _ref9$expandLabel === void 0 ? "Expand cover" : _ref9$expandLabel,
|
|
167
|
+
className = _ref9.className,
|
|
168
|
+
children = _ref9.children;
|
|
169
|
+
return /*#__PURE__*/_react.default.createElement(StackRow, {
|
|
170
|
+
role: "cover",
|
|
171
|
+
bleed: true,
|
|
172
|
+
className: className
|
|
173
|
+
}, collapsed ? /*#__PURE__*/_react.default.createElement(StyledCollapsedStrip, {
|
|
174
|
+
type: "button",
|
|
175
|
+
"aria-label": expandLabel,
|
|
176
|
+
onClick: onExpand
|
|
177
|
+
}, collapsedStrip, /*#__PURE__*/_react.default.createElement(StyledStripExpand, {
|
|
178
|
+
className: "sc-control",
|
|
179
|
+
"aria-hidden": "true"
|
|
180
|
+
}, /*#__PURE__*/_react.default.createElement(ExpandGlyph, null))) : /*#__PURE__*/_react.default.createElement(StyledCoverMedia, {
|
|
181
|
+
$aspectRatio: aspectRatio
|
|
182
|
+
}, /*#__PURE__*/_react.default.createElement(StyledCoverFill, null, children), centerSlot ? /*#__PURE__*/_react.default.createElement(StyledCoverCenter, {
|
|
183
|
+
className: "sc-control"
|
|
184
|
+
}, centerSlot) : null, topRightSlot ? /*#__PURE__*/_react.default.createElement(StyledCoverTopRight, {
|
|
185
|
+
className: "sc-control"
|
|
186
|
+
}, topRightSlot) : null));
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
/* ------------------------------------------------------------------ */
|
|
190
|
+
/* Cover controls — dark, scrim-backed chrome shared by every story. */
|
|
191
|
+
/* ------------------------------------------------------------------ */
|
|
192
|
+
|
|
193
|
+
/* Centered media control (a play button). The caller drops the glyph inside. */
|
|
194
|
+
var PlayBadge = exports.PlayBadge = _styledComponents.default.span.withConfig({
|
|
195
|
+
displayName: "primitives__PlayBadge",
|
|
196
|
+
componentId: "sc-1ax68l9-8"
|
|
197
|
+
})(["display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;border-radius:12px;background:var(--sc-scrim);color:var(--sc-scrim-fg);svg{fill:currentColor;width:20px;height:20px;margin-left:2px;}"]);
|
|
198
|
+
|
|
199
|
+
/* Top-right cover-management button (collapse, remove …). */
|
|
200
|
+
var CoverButton = exports.CoverButton = _styledComponents.default.button.withConfig({
|
|
201
|
+
displayName: "primitives__CoverButton",
|
|
202
|
+
componentId: "sc-1ax68l9-9"
|
|
203
|
+
})(["display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;padding:0;border:0;border-radius:8px;cursor:pointer;color:var(--sc-scrim-fg);background:var(--sc-scrim);svg{width:16px;height:16px;display:block;}&:hover{background:var(--sc-scrim-strong);}"]);
|
|
204
|
+
|
|
205
|
+
/* Cover-management glyphs (act on the cover itself, not the entity). */
|
|
206
|
+
var CollapseGlyph = exports.CollapseGlyph = function CollapseGlyph() {
|
|
207
|
+
return /*#__PURE__*/_react.default.createElement("svg", {
|
|
208
|
+
viewBox: "0 0 16 16",
|
|
209
|
+
fill: "none",
|
|
210
|
+
"aria-hidden": "true"
|
|
211
|
+
}, /*#__PURE__*/_react.default.createElement("path", {
|
|
212
|
+
d: "M6.5 2.5v4h-4M9.5 13.5v-4h4",
|
|
213
|
+
stroke: "currentColor",
|
|
214
|
+
strokeWidth: "1.5",
|
|
215
|
+
strokeLinecap: "round",
|
|
216
|
+
strokeLinejoin: "round"
|
|
217
|
+
}));
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
/* Expand glyph — the inverse of collapse; shown on the collapsed strip. */
|
|
221
|
+
var ExpandGlyph = exports.ExpandGlyph = function ExpandGlyph() {
|
|
222
|
+
return /*#__PURE__*/_react.default.createElement("svg", {
|
|
223
|
+
viewBox: "0 0 16 16",
|
|
224
|
+
fill: "none",
|
|
225
|
+
"aria-hidden": "true"
|
|
226
|
+
}, /*#__PURE__*/_react.default.createElement("path", {
|
|
227
|
+
d: "M2.5 6.5v-4h4M13.5 9.5v4h-4",
|
|
228
|
+
stroke: "currentColor",
|
|
229
|
+
strokeWidth: "1.5",
|
|
230
|
+
strokeLinecap: "round",
|
|
231
|
+
strokeLinejoin: "round"
|
|
232
|
+
}));
|
|
233
|
+
};
|
|
234
|
+
var RemoveCoverGlyph = exports.RemoveCoverGlyph = function RemoveCoverGlyph() {
|
|
235
|
+
return /*#__PURE__*/_react.default.createElement("svg", {
|
|
236
|
+
viewBox: "0 0 16 16",
|
|
237
|
+
fill: "none",
|
|
238
|
+
"aria-hidden": "true"
|
|
239
|
+
}, /*#__PURE__*/_react.default.createElement("rect", {
|
|
240
|
+
x: "2.25",
|
|
241
|
+
y: "3.75",
|
|
242
|
+
width: "11.5",
|
|
243
|
+
height: "8.5",
|
|
244
|
+
rx: "1.5",
|
|
245
|
+
stroke: "currentColor",
|
|
246
|
+
strokeWidth: "1.5"
|
|
247
|
+
}), /*#__PURE__*/_react.default.createElement("path", {
|
|
248
|
+
d: "M6 9.5L10 6M10 9.5L6 6",
|
|
249
|
+
stroke: "currentColor",
|
|
250
|
+
strokeWidth: "1.5",
|
|
251
|
+
strokeLinecap: "round"
|
|
252
|
+
}));
|
|
253
|
+
};
|
|
254
|
+
//# sourceMappingURL=primitives.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"primitives.js","names":["_react","_interopRequireDefault","require","_styledComponents","_interopRequireWildcard","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","_t","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","Stack","exports","styled","div","withConfig","displayName","componentId","ROLE_PADDING","cover","title","meta","footer","custom","StyledRow","_ref","$direction","_ref2","_ref3","_ref4","$role","$bleed","_ref5","$background","css","_ref6","StackRow","_ref7","_ref7$role","role","bleed","_ref7$direction","direction","background","className","children","createElement","StyledCoverMedia","_ref8","$aspectRatio","StyledCoverFill","StyledCoverCenter","StyledCoverTopRight","StyledCollapsedStrip","button","StyledStripExpand","span","Cover","_ref9","_ref9$aspectRatio","aspectRatio","centerSlot","topRightSlot","collapsed","collapsedStrip","onExpand","_ref9$expandLabel","expandLabel","type","onClick","ExpandGlyph","PlayBadge","CoverButton","CollapseGlyph","viewBox","fill","d","stroke","strokeWidth","strokeLinecap","strokeLinejoin","RemoveCoverGlyph","x","y","width","height","rx"],"sources":["../../../../src/presentation/stackedCard/primitives.tsx"],"sourcesContent":["import React, { ReactElement, ReactNode } from \"react\";\n\nimport styled, { css } from \"styled-components\";\n\n/**\n * StackedCard layout primitives (story-local, presentation-only).\n *\n * These are the documented foundation of the StackedCard subsystem — the\n * building blocks that every StackedCard concept story in this task set\n * imports from. They are NOT exported from the design-system barrel; they\n * live here so the concept stories share one source of truth instead of\n * re-declaring one-off styled blocks.\n *\n * Three primitives:\n * - Stack — the vertical column. A card is a Stack of StackRows.\n * - StackRow — the one layout primitive. Everything (cover, title, meta,\n * footer) is a row; a `role` sets the default padding and the\n * allowed direction so the anatomy stays predictable.\n * - Cover — sugar for a bleed row that holds media, reserves its height\n * with `aspect-ratio` (so a late image never reflows), and\n * carries two control slots (center + top-right).\n *\n * Colours here come exclusively from CSS variables — the dark scrim behind\n * cover controls is `--sc-scrim` / `--sc-scrim-strong` / `--sc-scrim-fg`, all\n * declared story-side as DS token candidates. No rgba/hex is hardcoded in a\n * primitive; only data colours (a swatch value, a label dot) are ever literal,\n * and those are passed in by the content, never baked in here.\n */\n\n/* ------------------------------------------------------------------ */\n/* Stack — vertical flex column. No own padding. */\n/* ------------------------------------------------------------------ */\n\nexport const Stack = styled.div`\n position: relative;\n display: flex;\n flex-direction: column;\n`;\n\n/* ------------------------------------------------------------------ */\n/* StackRow — the only layout primitive, differentiated by `role`. */\n/* ------------------------------------------------------------------ */\n\nexport type StackRowRole = \"cover\" | \"title\" | \"meta\" | \"footer\" | \"custom\";\n\nexport type StackRowDirection = \"row\" | \"column\";\n\n/**\n * Role → default padding. The row is the increment: title/footer carry the\n * system padding, meta is a tighter properties line, cover bleeds to the edge.\n * `custom` starts from the system padding and expects the caller to adjust.\n */\nexport const ROLE_PADDING: Record<StackRowRole, string> = {\n cover: \"0\",\n title: \"8px 12px\",\n meta: \"2px 12px 4px\",\n footer: \"8px 12px\",\n custom: \"8px 12px\",\n};\n\ninterface StyledRowProps {\n $role: StackRowRole;\n $bleed?: boolean;\n $direction: StackRowDirection;\n $background?: string;\n}\n\nconst StyledRow = styled.div<StyledRowProps>`\n position: relative;\n display: flex;\n flex-direction: ${({ $direction }) => $direction};\n align-items: ${({ $direction }) =>\n $direction === \"column\" ? \"stretch\" : \"center\"};\n gap: ${({ $direction }) => ($direction === \"column\" ? \"4px\" : \"8px\")};\n\n /* bleed overrides any role and runs the row edge to edge. */\n padding: ${({ $role, $bleed }) => ($bleed ? \"0\" : ROLE_PADDING[$role])};\n\n ${({ $background }) =>\n $background &&\n css`\n background: ${$background};\n `}\n\n /* Distribution (row direction only): fixed-width children keep their width,\n the rest share what remains evenly; drop an empty spacer to push items. */\n ${({ $direction }) =>\n $direction === \"row\" &&\n css`\n > * {\n flex: 1 1 0;\n min-width: 0;\n }\n\n > [data-fixed] {\n flex: 0 0 auto;\n }\n `}\n`;\n\nexport interface StackRowProps {\n /** Named role → default padding + allowed direction. Defaults to `custom`. */\n role?: StackRowRole;\n /** Zero the padding, overriding the role (media rows, edge-to-edge bands). */\n bleed?: boolean;\n /** Footer bands lay their children out vertically. Defaults to `row`. */\n direction?: StackRowDirection;\n /** A row can carry its own background (the tinted link-footer band). */\n background?: string;\n className?: string;\n children: ReactNode;\n}\n\nexport const StackRow = ({\n role = \"custom\",\n bleed,\n direction = \"row\",\n background,\n className,\n children,\n}: StackRowProps): ReactElement => (\n <StyledRow\n $role={role}\n $bleed={bleed}\n $direction={direction}\n $background={background}\n className={className}\n >\n {children}\n </StyledRow>\n);\n\n/* ------------------------------------------------------------------ */\n/* Cover — sugar for a bleed row that holds media. */\n/* ------------------------------------------------------------------ */\n\n/**\n * The media box reserves its height with `aspect-ratio` so the image (or the\n * skeleton that stands in for it) never reflows the card when it arrives.\n * Controls carry the `sc-control` class and are hidden until the cover is\n * hovered OR holds focus (`:focus-within`) — the focus path keeps the cover\n * controls reachable by keyboard, not mouse-only.\n */\nconst StyledCoverMedia = styled.div<{ $aspectRatio: string }>`\n position: relative;\n width: 100%;\n aspect-ratio: ${({ $aspectRatio }) => $aspectRatio};\n overflow: hidden;\n\n .sc-control {\n opacity: 0;\n transition: opacity 120ms ease;\n }\n\n &:hover .sc-control,\n &:focus-within .sc-control {\n opacity: 1;\n }\n`;\n\n/* The fill (an <img>, an inline <svg> wrapper, or a solid-colour box) is laid\n over the reserved box and made to cover it. */\nconst StyledCoverFill = styled.div`\n position: absolute;\n inset: 0;\n\n > * {\n width: 100%;\n height: 100%;\n }\n\n > img {\n display: block;\n object-fit: cover;\n }\n`;\n\nconst StyledCoverCenter = styled.div`\n position: absolute;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n`;\n\nconst StyledCoverTopRight = styled.div`\n position: absolute;\n top: 8px;\n right: 8px;\n display: flex;\n gap: 6px;\n`;\n\n/**\n * Collapsed cover — the media box gives way to a thin strip. The strip is the\n * expand affordance itself: the whole bar is a button, and a chevron hint is\n * revealed on hover OR focus (`.sc-control`, same reveal rule as every other\n * cover control) so it is reachable by keyboard, not mouse-only. The strip\n * holds no reserved height of its own — the caller's `collapsedStrip` (an ~8px\n * colour bar, or a favicon + domain row for links) sets how tall it reads.\n */\nconst StyledCollapsedStrip = styled.button`\n position: relative;\n display: flex;\n align-items: center;\n width: 100%;\n min-height: 16px;\n padding: 0;\n border: 0;\n background: transparent;\n cursor: pointer;\n text-align: left;\n\n .sc-control {\n opacity: 0;\n transition: opacity 120ms ease;\n }\n\n &:hover .sc-control,\n &:focus-visible .sc-control {\n opacity: 1;\n }\n\n &:focus-visible {\n outline: 2px solid var(--sc-selection-ring);\n outline-offset: -2px;\n }\n`;\n\n/* The expand chevron sits at the right, vertically centred over the strip, so\n it reads the same whether the strip is a hairline colour bar or a taller\n favicon row. Small + theme-coloured so it fits a thin strip without a scrim\n button (the whole strip is the button). */\nconst StyledStripExpand = styled.span`\n position: absolute;\n top: 50%;\n right: 8px;\n transform: translateY(-50%);\n display: inline-flex;\n width: 16px;\n height: 16px;\n color: var(--color-theme-600);\n\n svg {\n width: 14px;\n height: 14px;\n }\n`;\n\nexport interface CoverProps {\n /**\n * CSS `aspect-ratio` value that reserves the cover's height, e.g.\n * `\"260 / 132\"`. Kept as a ratio (not a pixel height) so the cover scales\n * with the card and holds its space before media loads.\n */\n aspectRatio?: string;\n /** Center slot — the media control (a play button over audio/video). */\n centerSlot?: ReactNode;\n /** Top-right slot — cover management (collapse, remove). */\n topRightSlot?: ReactNode;\n /**\n * Collapsed cover: render the thin strip instead of the media box. The\n * collapse *control* lives in the caller's `topRightSlot`; this flag is the\n * resulting visual state. See the \"Collapsed cover\" story section.\n */\n collapsed?: boolean;\n /**\n * What the collapsed strip shows — an ~8px colour bar, or a favicon + domain\n * row for links. Content-specific, so the caller supplies it.\n */\n collapsedStrip?: ReactNode;\n /** Fired when the collapsed strip's expand affordance is activated. */\n onExpand?: () => void;\n /** Accessible label for the expand affordance. */\n expandLabel?: string;\n className?: string;\n /** The fill: an `<img>`, an inline `<svg>`, or a solid-colour box. */\n children: ReactNode;\n}\n\nexport const Cover = ({\n aspectRatio = \"260 / 132\",\n centerSlot,\n topRightSlot,\n collapsed,\n collapsedStrip,\n onExpand,\n expandLabel = \"Expand cover\",\n className,\n children,\n}: CoverProps): ReactElement => (\n <StackRow role=\"cover\" bleed className={className}>\n {collapsed ? (\n <StyledCollapsedStrip\n type=\"button\"\n aria-label={expandLabel}\n onClick={onExpand}\n >\n {collapsedStrip}\n <StyledStripExpand className=\"sc-control\" aria-hidden=\"true\">\n <ExpandGlyph />\n </StyledStripExpand>\n </StyledCollapsedStrip>\n ) : (\n <StyledCoverMedia $aspectRatio={aspectRatio}>\n <StyledCoverFill>{children}</StyledCoverFill>\n {centerSlot ? (\n <StyledCoverCenter className=\"sc-control\">\n {centerSlot}\n </StyledCoverCenter>\n ) : null}\n {topRightSlot ? (\n <StyledCoverTopRight className=\"sc-control\">\n {topRightSlot}\n </StyledCoverTopRight>\n ) : null}\n </StyledCoverMedia>\n )}\n </StackRow>\n);\n\n/* ------------------------------------------------------------------ */\n/* Cover controls — dark, scrim-backed chrome shared by every story. */\n/* ------------------------------------------------------------------ */\n\n/* Centered media control (a play button). The caller drops the glyph inside. */\nexport const PlayBadge = styled.span`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n border-radius: 12px;\n background: var(--sc-scrim);\n color: var(--sc-scrim-fg);\n\n svg {\n fill: currentColor;\n width: 20px;\n height: 20px;\n margin-left: 2px;\n }\n`;\n\n/* Top-right cover-management button (collapse, remove …). */\nexport const CoverButton = styled.button`\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n padding: 0;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n color: var(--sc-scrim-fg);\n background: var(--sc-scrim);\n\n svg {\n width: 16px;\n height: 16px;\n display: block;\n }\n\n &:hover {\n background: var(--sc-scrim-strong);\n }\n`;\n\n/* Cover-management glyphs (act on the cover itself, not the entity). */\nexport const CollapseGlyph = (): ReactElement => (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M6.5 2.5v4h-4M9.5 13.5v-4h4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n/* Expand glyph — the inverse of collapse; shown on the collapsed strip. */\nexport const ExpandGlyph = (): ReactElement => (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2.5 6.5v-4h4M13.5 9.5v4h-4\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\nexport const RemoveCoverGlyph = (): ReactElement => (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect\n x=\"2.25\"\n y=\"3.75\"\n width=\"11.5\"\n height=\"8.5\"\n rx=\"1.5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <path\n d=\"M6 9.5L10 6M10 9.5L6 6\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n"],"mappings":"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","ignoreList":[]}
|