@activecollab/components 2.0.362 → 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.
Files changed (79) hide show
  1. package/dist/cjs/presentation/stackedCard/content/ImageCard.js +60 -0
  2. package/dist/cjs/presentation/stackedCard/content/ImageCard.js.map +1 -0
  3. package/dist/cjs/presentation/stackedCard/content/LinkCard.js +348 -0
  4. package/dist/cjs/presentation/stackedCard/content/LinkCard.js.map +1 -0
  5. package/dist/cjs/presentation/stackedCard/content/NoteCard.js +92 -0
  6. package/dist/cjs/presentation/stackedCard/content/NoteCard.js.map +1 -0
  7. package/dist/cjs/presentation/stackedCard/content/SwatchCard.js +74 -0
  8. package/dist/cjs/presentation/stackedCard/content/SwatchCard.js.map +1 -0
  9. package/dist/cjs/presentation/stackedCard/content/TaskCard.js +231 -0
  10. package/dist/cjs/presentation/stackedCard/content/TaskCard.js.map +1 -0
  11. package/dist/cjs/presentation/stackedCard/content/index.js +83 -0
  12. package/dist/cjs/presentation/stackedCard/content/index.js.map +1 -0
  13. package/dist/cjs/presentation/stackedCard/content/shared.js +144 -0
  14. package/dist/cjs/presentation/stackedCard/content/shared.js.map +1 -0
  15. package/dist/cjs/presentation/stackedCard/content/unfurl.js +172 -0
  16. package/dist/cjs/presentation/stackedCard/content/unfurl.js.map +1 -0
  17. package/dist/cjs/presentation/stackedCard/primitives.js +254 -0
  18. package/dist/cjs/presentation/stackedCard/primitives.js.map +1 -0
  19. package/dist/cjs/presentation/stackedCard/resizePolicy.js +183 -0
  20. package/dist/cjs/presentation/stackedCard/resizePolicy.js.map +1 -0
  21. package/dist/cjs/presentation/stackedCard/shell.js +165 -0
  22. package/dist/cjs/presentation/stackedCard/shell.js.map +1 -0
  23. package/dist/cjs/presentation/stackedCard/storyScaffold.js +72 -0
  24. package/dist/cjs/presentation/stackedCard/storyScaffold.js.map +1 -0
  25. package/dist/cjs/presentation/stackedCard/useInlineEdit.js +208 -0
  26. package/dist/cjs/presentation/stackedCard/useInlineEdit.js.map +1 -0
  27. package/dist/esm/presentation/stackedCard/content/ImageCard.d.ts +15 -0
  28. package/dist/esm/presentation/stackedCard/content/ImageCard.d.ts.map +1 -0
  29. package/dist/esm/presentation/stackedCard/content/ImageCard.js +50 -0
  30. package/dist/esm/presentation/stackedCard/content/ImageCard.js.map +1 -0
  31. package/dist/esm/presentation/stackedCard/content/LinkCard.d.ts +28 -0
  32. package/dist/esm/presentation/stackedCard/content/LinkCard.d.ts.map +1 -0
  33. package/dist/esm/presentation/stackedCard/content/LinkCard.js +336 -0
  34. package/dist/esm/presentation/stackedCard/content/LinkCard.js.map +1 -0
  35. package/dist/esm/presentation/stackedCard/content/NoteCard.d.ts +10 -0
  36. package/dist/esm/presentation/stackedCard/content/NoteCard.d.ts.map +1 -0
  37. package/dist/esm/presentation/stackedCard/content/NoteCard.js +82 -0
  38. package/dist/esm/presentation/stackedCard/content/NoteCard.js.map +1 -0
  39. package/dist/esm/presentation/stackedCard/content/SwatchCard.d.ts +14 -0
  40. package/dist/esm/presentation/stackedCard/content/SwatchCard.d.ts.map +1 -0
  41. package/dist/esm/presentation/stackedCard/content/SwatchCard.js +64 -0
  42. package/dist/esm/presentation/stackedCard/content/SwatchCard.js.map +1 -0
  43. package/dist/esm/presentation/stackedCard/content/TaskCard.d.ts +29 -0
  44. package/dist/esm/presentation/stackedCard/content/TaskCard.d.ts.map +1 -0
  45. package/dist/esm/presentation/stackedCard/content/TaskCard.js +218 -0
  46. package/dist/esm/presentation/stackedCard/content/TaskCard.js.map +1 -0
  47. package/dist/esm/presentation/stackedCard/content/index.d.ts +8 -0
  48. package/dist/esm/presentation/stackedCard/content/index.d.ts.map +1 -0
  49. package/dist/esm/presentation/stackedCard/content/index.js +8 -0
  50. package/dist/esm/presentation/stackedCard/content/index.js.map +1 -0
  51. package/dist/esm/presentation/stackedCard/content/shared.d.ts +46 -0
  52. package/dist/esm/presentation/stackedCard/content/shared.d.ts.map +1 -0
  53. package/dist/esm/presentation/stackedCard/content/shared.js +134 -0
  54. package/dist/esm/presentation/stackedCard/content/shared.js.map +1 -0
  55. package/dist/esm/presentation/stackedCard/content/unfurl.d.ts +89 -0
  56. package/dist/esm/presentation/stackedCard/content/unfurl.d.ts.map +1 -0
  57. package/dist/esm/presentation/stackedCard/content/unfurl.js +147 -0
  58. package/dist/esm/presentation/stackedCard/content/unfurl.js.map +1 -0
  59. package/dist/esm/presentation/stackedCard/primitives.d.ts +84 -0
  60. package/dist/esm/presentation/stackedCard/primitives.d.ts.map +1 -0
  61. package/dist/esm/presentation/stackedCard/primitives.js +241 -0
  62. package/dist/esm/presentation/stackedCard/primitives.js.map +1 -0
  63. package/dist/esm/presentation/stackedCard/resizePolicy.d.ts +97 -0
  64. package/dist/esm/presentation/stackedCard/resizePolicy.d.ts.map +1 -0
  65. package/dist/esm/presentation/stackedCard/resizePolicy.js +173 -0
  66. package/dist/esm/presentation/stackedCard/resizePolicy.js.map +1 -0
  67. package/dist/esm/presentation/stackedCard/shell.d.ts +46 -0
  68. package/dist/esm/presentation/stackedCard/shell.d.ts.map +1 -0
  69. package/dist/esm/presentation/stackedCard/shell.js +156 -0
  70. package/dist/esm/presentation/stackedCard/shell.js.map +1 -0
  71. package/dist/esm/presentation/stackedCard/storyScaffold.d.ts +28 -0
  72. package/dist/esm/presentation/stackedCard/storyScaffold.d.ts.map +1 -0
  73. package/dist/esm/presentation/stackedCard/storyScaffold.js +66 -0
  74. package/dist/esm/presentation/stackedCard/storyScaffold.js.map +1 -0
  75. package/dist/esm/presentation/stackedCard/useInlineEdit.d.ts +68 -0
  76. package/dist/esm/presentation/stackedCard/useInlineEdit.d.ts.map +1 -0
  77. package/dist/esm/presentation/stackedCard/useInlineEdit.js +192 -0
  78. package/dist/esm/presentation/stackedCard/useInlineEdit.js.map +1 -0
  79. package/package.json +1 -1
@@ -0,0 +1,336 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import { StyledChip, StyledClamp, StyledColorCover, StyledFavicon, coverManagement, playControl, Placeholder } from "./shared";
5
+ import { formatFetchedAt } from "./unfurl";
6
+ import { ArrowRefreshIcon, InsertLinkIcon, WarningTriangleIcon } from "../../../components/Icons";
7
+ import { SkeletonLoader } from "../../../components/Loaders";
8
+ import { Body2, Caption1 } from "../../../components/Typography";
9
+ import { Typography } from "../../../components/Typography/Typography";
10
+ import { Cover, StackRow } from "../primitives";
11
+ import { COVER_RATIO, COVER_RATIO_HERO } from "../shell";
12
+
13
+ /**
14
+ * LinkCard — a link preview as a LIFECYCLE, not two static layouts.
15
+ *
16
+ * Data climbs a progressive ladder (url → basic → full); the anatomy is
17
+ * CONSTANT at every tier, so each slot swaps a skeleton for real content in
18
+ * place and the card never reflows on upgrade. Four statuses layer on top:
19
+ * resolving — climbing the ladder, aspect + rows reserved by skeletons
20
+ * resolved — the full card
21
+ * stale — resolved, but past its cache window: shows `fetchedAt` and a
22
+ * re-unfurl affordance
23
+ * error — the unfurl failed: favicon + raw URL + retry, NO media
24
+ *
25
+ * Compact ↔ expanded is a user-switchable DISPLAY LEVEL on the same link
26
+ * entity (the data lives in the controller, so switching never refetches or
27
+ * loses it) — not two separate card types.
28
+ */
29
+
30
+ /* ------------------------------------------------------------------ */
31
+ /* Small building blocks */
32
+ /* ------------------------------------------------------------------ */
33
+
34
+ const StyledDomainRow = styled.div.withConfig({
35
+ displayName: "LinkCard__StyledDomainRow",
36
+ componentId: "sc-qyea73-0"
37
+ })(["display:flex;align-items:center;gap:8px;min-height:16px;"]);
38
+ const StyledChips = styled.div.withConfig({
39
+ displayName: "LinkCard__StyledChips",
40
+ componentId: "sc-qyea73-1"
41
+ })(["display:flex;align-items:center;gap:6px;min-height:18px;"]);
42
+
43
+ /* The stale strip — a re-unfurl affordance with the fetch time. */
44
+ const StyledStaleStrip = styled.div.withConfig({
45
+ displayName: "LinkCard__StyledStaleStrip",
46
+ componentId: "sc-qyea73-2"
47
+ })(["display:flex;align-items:center;gap:8px;color:var(--color-theme-600);> span{flex:1 1 auto;min-width:0;}"]);
48
+ const StyledReunfurl = styled.button.withConfig({
49
+ displayName: "LinkCard__StyledReunfurl",
50
+ componentId: "sc-qyea73-3"
51
+ })(["display:inline-flex;align-items:center;gap:4px;flex:0 0 auto;padding:3px 8px;border:1px solid var(--border-primary);border-radius:6px;background:var(--page-paper-main);color:var(--color-theme-800);font-size:11px;cursor:pointer;svg{width:12px;height:12px;}&:hover{background:var(--color-theme-200);border-color:var(--sc-selection-ring);}"]);
52
+
53
+ /* The error body — favicon + raw URL + retry, no media (per spec §5). */
54
+ const StyledErrorBody = styled.div.withConfig({
55
+ displayName: "LinkCard__StyledErrorBody",
56
+ componentId: "sc-qyea73-4"
57
+ })(["display:flex;flex-direction:column;gap:10px;padding:12px;.err-head{display:flex;align-items:center;gap:8px;color:var(--red-alert);}.err-head svg{width:16px;height:16px;flex:0 0 auto;}.err-url{display:flex;align-items:center;gap:8px;word-break:break-all;}"]);
58
+ const StyledRetry = styled.button.withConfig({
59
+ displayName: "LinkCard__StyledRetry",
60
+ componentId: "sc-qyea73-5"
61
+ })(["align-self:flex-start;display:inline-flex;align-items:center;gap:6px;padding:5px 10px;border:1px solid var(--border-primary);border-radius:6px;background:var(--page-paper-main);color:var(--color-theme-800);cursor:pointer;svg{width:14px;height:14px;}&:hover{background:var(--color-theme-200);border-color:var(--sc-selection-ring);}"]);
62
+
63
+ /* The expanded footer band — tinted, holds the title + domain under the hero. */
64
+ const StyledFooterTitle = styled(Body2).withConfig({
65
+ displayName: "LinkCard__StyledFooterTitle",
66
+ componentId: "sc-qyea73-6"
67
+ })(["display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;"]);
68
+
69
+ /* ------------------------------------------------------------------ */
70
+ /* The display-level switch — lives in the entity "…" slot */
71
+ /* ------------------------------------------------------------------ */
72
+
73
+ const StyledDisplayToggle = styled.button.withConfig({
74
+ displayName: "LinkCard__StyledDisplayToggle",
75
+ componentId: "sc-qyea73-7"
76
+ })(["display:inline-flex;align-items:center;padding:2px 8px;border:1px solid var(--border-primary);border-radius:10px;background:var(--color-theme-200);color:var(--color-theme-700);font-size:11px;cursor:pointer;white-space:nowrap;&:hover{background:var(--color-theme-300);}"]);
77
+ const DisplayToggle = _ref => {
78
+ let display = _ref.display,
79
+ onToggle = _ref.onToggle;
80
+ return /*#__PURE__*/React.createElement(StyledDisplayToggle, {
81
+ type: "button",
82
+ "data-fixed": true,
83
+ className: "sc-control",
84
+ "aria-label": "Switch display level",
85
+ onClick: onToggle
86
+ }, display === "compact" ? "Expand ▾" : "Compact ▴");
87
+ };
88
+
89
+ /* ------------------------------------------------------------------ */
90
+ /* LinkCard */
91
+ /* ------------------------------------------------------------------ */
92
+
93
+ export const LinkCard = _ref2 => {
94
+ var _data$heroColor2, _data$faviconColor2;
95
+ let unfurl = _ref2.unfurl,
96
+ _ref2$display = _ref2.display,
97
+ display = _ref2$display === void 0 ? "compact" : _ref2$display,
98
+ onToggleDisplay = _ref2.onToggleDisplay;
99
+ const status = unfurl.status,
100
+ tier = unfurl.tier,
101
+ data = unfurl.data,
102
+ fetchedAt = unfurl.fetchedAt,
103
+ retry = unfurl.retry,
104
+ reunfurl = unfurl.reunfurl;
105
+
106
+ // ── Error: favicon + raw URL + retry, no media ──────────────────
107
+ if (status === "error") {
108
+ return /*#__PURE__*/React.createElement(StyledErrorBody, null, /*#__PURE__*/React.createElement("div", {
109
+ className: "err-head"
110
+ }, /*#__PURE__*/React.createElement(WarningTriangleIcon, null), /*#__PURE__*/React.createElement(Caption1, {
111
+ weight: "bold",
112
+ color: "tertiary"
113
+ }, "Couldn\u2019t load a preview")), /*#__PURE__*/React.createElement("div", {
114
+ className: "err-url"
115
+ }, /*#__PURE__*/React.createElement(StyledFavicon, {
116
+ $bg: "var(--color-theme-400)",
117
+ "data-fixed": true
118
+ }), /*#__PURE__*/React.createElement(Caption1, {
119
+ color: "secondary"
120
+ }, data.url)), /*#__PURE__*/React.createElement(StyledRetry, {
121
+ type: "button",
122
+ onClick: retry
123
+ }, /*#__PURE__*/React.createElement(ArrowRefreshIcon, null), /*#__PURE__*/React.createElement(Typography, {
124
+ as: "span",
125
+ variant: "Caption 1"
126
+ }, "Retry")));
127
+ }
128
+ const hasBasic = tier === "basic" || tier === "full";
129
+ const hasFull = tier === "full";
130
+ const toggle = onToggleDisplay != null ? onToggleDisplay : () => undefined;
131
+
132
+ // ── Expanded: hero + tinted footer band (title + domain) ────────
133
+ if (display === "expanded") {
134
+ var _data$heroColor, _data$faviconColor;
135
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cover, {
136
+ aspectRatio: COVER_RATIO_HERO,
137
+ centerSlot: hasFull && data.playable ? playControl : undefined,
138
+ topRightSlot: coverManagement()
139
+ }, hasFull ? /*#__PURE__*/React.createElement(StyledColorCover, {
140
+ $color: (_data$heroColor = data.heroColor) != null ? _data$heroColor : "#1D9E75"
141
+ }) : /*#__PURE__*/React.createElement(SkeletonLoader, {
142
+ style: {
143
+ width: "100%",
144
+ height: "100%"
145
+ }
146
+ })), /*#__PURE__*/React.createElement(StackRow, {
147
+ role: "footer",
148
+ direction: "column",
149
+ background: "var(--color-theme-200)"
150
+ }, /*#__PURE__*/React.createElement(StyledDomainRow, null, hasBasic ? /*#__PURE__*/React.createElement(StyledFavicon, {
151
+ $bg: (_data$faviconColor = data.faviconColor) != null ? _data$faviconColor : "#0F6E56",
152
+ "data-fixed": true
153
+ }) : /*#__PURE__*/React.createElement(SkeletonLoader, {
154
+ "data-fixed": true,
155
+ style: {
156
+ width: 16,
157
+ height: 16,
158
+ borderRadius: 4
159
+ }
160
+ }), hasBasic ? /*#__PURE__*/React.createElement(Caption1, {
161
+ color: "tertiary"
162
+ }, data.domain) : /*#__PURE__*/React.createElement(Caption1, {
163
+ color: "tertiary"
164
+ }, data.url), /*#__PURE__*/React.createElement("span", {
165
+ style: {
166
+ flex: "1 1 auto"
167
+ }
168
+ }), /*#__PURE__*/React.createElement(DisplayToggle, {
169
+ display: display,
170
+ onToggle: toggle
171
+ })), hasBasic ? /*#__PURE__*/React.createElement(StyledFooterTitle, {
172
+ weight: "bold"
173
+ }, data.title) : /*#__PURE__*/React.createElement(SkeletonLoader, {
174
+ style: {
175
+ height: 14,
176
+ width: "90%"
177
+ }
178
+ }), hasFull ? /*#__PURE__*/React.createElement(Caption1, {
179
+ color: "tertiary"
180
+ }, data.description) : /*#__PURE__*/React.createElement(SkeletonLoader, {
181
+ style: {
182
+ height: 10,
183
+ width: "70%"
184
+ }
185
+ })), status === "stale" ? /*#__PURE__*/React.createElement(StackRow, {
186
+ role: "meta"
187
+ }, /*#__PURE__*/React.createElement(StaleStrip, {
188
+ fetchedAt: fetchedAt,
189
+ onReunfurl: reunfurl
190
+ })) : null);
191
+ }
192
+
193
+ // ── Compact: cover + favicon/domain + title + chips ─────────────
194
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cover, {
195
+ aspectRatio: COVER_RATIO,
196
+ centerSlot: hasFull && data.playable ? playControl : undefined
197
+ }, hasFull ? /*#__PURE__*/React.createElement(StyledColorCover, {
198
+ $color: (_data$heroColor2 = data.heroColor) != null ? _data$heroColor2 : "#1D9E75"
199
+ }) : /*#__PURE__*/React.createElement(SkeletonLoader, {
200
+ style: {
201
+ width: "100%",
202
+ height: "100%"
203
+ }
204
+ })), /*#__PURE__*/React.createElement(StackRow, {
205
+ role: "custom"
206
+ }, /*#__PURE__*/React.createElement(StyledDomainRow, null, hasBasic ? /*#__PURE__*/React.createElement(StyledFavicon, {
207
+ $bg: (_data$faviconColor2 = data.faviconColor) != null ? _data$faviconColor2 : "#0F6E56",
208
+ "data-fixed": true
209
+ }) : /*#__PURE__*/React.createElement(SkeletonLoader, {
210
+ "data-fixed": true,
211
+ style: {
212
+ width: 16,
213
+ height: 16,
214
+ borderRadius: 4
215
+ }
216
+ }), hasBasic ? /*#__PURE__*/React.createElement(Caption1, {
217
+ color: "tertiary"
218
+ }, data.domain) : /*#__PURE__*/React.createElement(Caption1, {
219
+ color: "tertiary"
220
+ }, data.url), /*#__PURE__*/React.createElement("span", {
221
+ style: {
222
+ flex: "1 1 auto"
223
+ }
224
+ }), /*#__PURE__*/React.createElement(DisplayToggle, {
225
+ display: display,
226
+ onToggle: toggle
227
+ }))), /*#__PURE__*/React.createElement(StackRow, {
228
+ role: "title"
229
+ }, hasBasic ? /*#__PURE__*/React.createElement(StyledClamp, null, data.title) : /*#__PURE__*/React.createElement("div", {
230
+ style: {
231
+ width: "100%"
232
+ }
233
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
234
+ style: {
235
+ height: 14,
236
+ width: "92%"
237
+ }
238
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
239
+ style: {
240
+ height: 14,
241
+ width: "60%",
242
+ marginTop: 6
243
+ }
244
+ }))), /*#__PURE__*/React.createElement(StackRow, {
245
+ role: "custom"
246
+ }, /*#__PURE__*/React.createElement(StyledChips, null, hasFull ? /*#__PURE__*/React.createElement(React.Fragment, null, data.kind ? /*#__PURE__*/React.createElement(StyledChip, {
247
+ "data-fixed": true
248
+ }, data.kind) : null, data.duration ? /*#__PURE__*/React.createElement(StyledChip, {
249
+ "data-fixed": true
250
+ }, data.duration) : null) : /*#__PURE__*/React.createElement(SkeletonLoader, {
251
+ style: {
252
+ height: 18,
253
+ width: 96,
254
+ borderRadius: 10
255
+ }
256
+ }))), status === "stale" ? /*#__PURE__*/React.createElement(StackRow, {
257
+ role: "meta"
258
+ }, /*#__PURE__*/React.createElement(StaleStrip, {
259
+ fetchedAt: fetchedAt,
260
+ onReunfurl: reunfurl
261
+ })) : null);
262
+ };
263
+
264
+ /* The stale affordance — fetch time + a manual re-unfurl button. */
265
+ const StaleStrip = _ref3 => {
266
+ let fetchedAt = _ref3.fetchedAt,
267
+ onReunfurl = _ref3.onReunfurl;
268
+ return /*#__PURE__*/React.createElement(StyledStaleStrip, null, /*#__PURE__*/React.createElement(Typography, {
269
+ as: "span",
270
+ variant: "Caption 1",
271
+ color: "tertiary"
272
+ }, "Preview may be out of date \xB7 fetched ", formatFetchedAt(fetchedAt)), /*#__PURE__*/React.createElement(StyledReunfurl, {
273
+ type: "button",
274
+ onClick: onReunfurl
275
+ }, /*#__PURE__*/React.createElement(ArrowRefreshIcon, null), "Re-unfurl"));
276
+ };
277
+
278
+ /* ---- skeleton ---- */
279
+
280
+ /* Mirrors the compact anatomy row for row (this is the `resolving` render at
281
+ tier `url`), so a resolving link never reflows as it climbs the ladder. */
282
+ export const LinkSkeleton = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cover, {
283
+ aspectRatio: COVER_RATIO
284
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
285
+ style: {
286
+ width: "100%",
287
+ height: "100%"
288
+ }
289
+ })), /*#__PURE__*/React.createElement(StackRow, {
290
+ role: "custom"
291
+ }, /*#__PURE__*/React.createElement(StyledDomainRow, null, /*#__PURE__*/React.createElement(SkeletonLoader, {
292
+ "data-fixed": true,
293
+ style: {
294
+ width: 16,
295
+ height: 16,
296
+ borderRadius: 4
297
+ }
298
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
299
+ style: {
300
+ height: 10,
301
+ width: "40%"
302
+ }
303
+ }))), /*#__PURE__*/React.createElement(StackRow, {
304
+ role: "title"
305
+ }, /*#__PURE__*/React.createElement("div", {
306
+ style: {
307
+ width: "100%"
308
+ }
309
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
310
+ style: {
311
+ height: 14,
312
+ width: "92%"
313
+ }
314
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
315
+ style: {
316
+ height: 14,
317
+ width: "60%",
318
+ marginTop: 6
319
+ }
320
+ }))), /*#__PURE__*/React.createElement(StackRow, {
321
+ role: "custom"
322
+ }, /*#__PURE__*/React.createElement(StyledChips, null, /*#__PURE__*/React.createElement(SkeletonLoader, {
323
+ style: {
324
+ height: 18,
325
+ width: 96,
326
+ borderRadius: 10
327
+ }
328
+ }))));
329
+
330
+ /* ---- placeholder ---- */
331
+
332
+ export const LinkPlaceholder = props => /*#__PURE__*/React.createElement(Placeholder, _extends({
333
+ icon: /*#__PURE__*/React.createElement(InsertLinkIcon, null),
334
+ label: "Add a link"
335
+ }, props));
336
+ //# sourceMappingURL=LinkCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkCard.js","names":["React","styled","StyledChip","StyledClamp","StyledColorCover","StyledFavicon","coverManagement","playControl","Placeholder","formatFetchedAt","ArrowRefreshIcon","InsertLinkIcon","WarningTriangleIcon","SkeletonLoader","Body2","Caption1","Typography","Cover","StackRow","COVER_RATIO","COVER_RATIO_HERO","StyledDomainRow","div","withConfig","displayName","componentId","StyledChips","StyledStaleStrip","StyledReunfurl","button","StyledErrorBody","StyledRetry","StyledFooterTitle","StyledDisplayToggle","DisplayToggle","_ref","display","onToggle","createElement","type","className","onClick","LinkCard","_ref2","_data$heroColor2","_data$faviconColor2","unfurl","_ref2$display","onToggleDisplay","status","tier","data","fetchedAt","retry","reunfurl","weight","color","$bg","url","as","variant","hasBasic","hasFull","toggle","undefined","_data$heroColor","_data$faviconColor","Fragment","aspectRatio","centerSlot","playable","topRightSlot","$color","heroColor","style","width","height","role","direction","background","faviconColor","borderRadius","domain","flex","title","description","StaleStrip","onReunfurl","marginTop","kind","duration","_ref3","LinkSkeleton","LinkPlaceholder","props","_extends","icon","label"],"sources":["../../../../../src/presentation/stackedCard/content/LinkCard.tsx"],"sourcesContent":["import React, { ReactElement } from \"react\";\n\nimport styled from \"styled-components\";\n\nimport {\n StyledChip,\n StyledClamp,\n StyledColorCover,\n StyledFavicon,\n coverManagement,\n playControl,\n Placeholder,\n} from \"./shared\";\nimport { UnfurlController, formatFetchedAt } from \"./unfurl\";\nimport {\n ArrowRefreshIcon,\n InsertLinkIcon,\n WarningTriangleIcon,\n} from \"../../../components/Icons\";\nimport { SkeletonLoader } from \"../../../components/Loaders\";\nimport { Body2, Caption1 } from \"../../../components/Typography\";\nimport { Typography } from \"../../../components/Typography/Typography\";\nimport { Cover, StackRow } from \"../primitives\";\nimport { COVER_RATIO, COVER_RATIO_HERO } from \"../shell\";\n\n/**\n * LinkCard — a link preview as a LIFECYCLE, not two static layouts.\n *\n * Data climbs a progressive ladder (url → basic → full); the anatomy is\n * CONSTANT at every tier, so each slot swaps a skeleton for real content in\n * place and the card never reflows on upgrade. Four statuses layer on top:\n * resolving — climbing the ladder, aspect + rows reserved by skeletons\n * resolved — the full card\n * stale — resolved, but past its cache window: shows `fetchedAt` and a\n * re-unfurl affordance\n * error — the unfurl failed: favicon + raw URL + retry, NO media\n *\n * Compact ↔ expanded is a user-switchable DISPLAY LEVEL on the same link\n * entity (the data lives in the controller, so switching never refetches or\n * loses it) — not two separate card types.\n */\n\nexport type LinkDisplay = \"compact\" | \"expanded\";\n\n/* ------------------------------------------------------------------ */\n/* Small building blocks */\n/* ------------------------------------------------------------------ */\n\nconst StyledDomainRow = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n min-height: 16px;\n`;\n\nconst StyledChips = styled.div`\n display: flex;\n align-items: center;\n gap: 6px;\n min-height: 18px;\n`;\n\n/* The stale strip — a re-unfurl affordance with the fetch time. */\nconst StyledStaleStrip = styled.div`\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--color-theme-600);\n\n > span {\n flex: 1 1 auto;\n min-width: 0;\n }\n`;\n\nconst StyledReunfurl = styled.button`\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex: 0 0 auto;\n padding: 3px 8px;\n border: 1px solid var(--border-primary);\n border-radius: 6px;\n background: var(--page-paper-main);\n color: var(--color-theme-800);\n font-size: 11px;\n cursor: pointer;\n\n svg {\n width: 12px;\n height: 12px;\n }\n\n &:hover {\n background: var(--color-theme-200);\n border-color: var(--sc-selection-ring);\n }\n`;\n\n/* The error body — favicon + raw URL + retry, no media (per spec §5). */\nconst StyledErrorBody = styled.div`\n display: flex;\n flex-direction: column;\n gap: 10px;\n padding: 12px;\n\n .err-head {\n display: flex;\n align-items: center;\n gap: 8px;\n color: var(--red-alert);\n }\n\n .err-head svg {\n width: 16px;\n height: 16px;\n flex: 0 0 auto;\n }\n\n .err-url {\n display: flex;\n align-items: center;\n gap: 8px;\n word-break: break-all;\n }\n`;\n\nconst StyledRetry = styled.button`\n align-self: flex-start;\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border: 1px solid var(--border-primary);\n border-radius: 6px;\n background: var(--page-paper-main);\n color: var(--color-theme-800);\n cursor: pointer;\n\n svg {\n width: 14px;\n height: 14px;\n }\n\n &:hover {\n background: var(--color-theme-200);\n border-color: var(--sc-selection-ring);\n }\n`;\n\n/* The expanded footer band — tinted, holds the title + domain under the hero. */\nconst StyledFooterTitle = styled(Body2)`\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n`;\n\n/* ------------------------------------------------------------------ */\n/* The display-level switch — lives in the entity \"…\" slot */\n/* ------------------------------------------------------------------ */\n\nconst StyledDisplayToggle = styled.button`\n display: inline-flex;\n align-items: center;\n padding: 2px 8px;\n border: 1px solid var(--border-primary);\n border-radius: 10px;\n background: var(--color-theme-200);\n color: var(--color-theme-700);\n font-size: 11px;\n cursor: pointer;\n white-space: nowrap;\n\n &:hover {\n background: var(--color-theme-300);\n }\n`;\n\nconst DisplayToggle = ({\n display,\n onToggle,\n}: {\n display: LinkDisplay;\n onToggle: () => void;\n}): ReactElement => (\n <StyledDisplayToggle\n type=\"button\"\n data-fixed\n className=\"sc-control\"\n aria-label=\"Switch display level\"\n onClick={onToggle}\n >\n {display === \"compact\" ? \"Expand ▾\" : \"Compact ▴\"}\n </StyledDisplayToggle>\n);\n\n/* ------------------------------------------------------------------ */\n/* LinkCard */\n/* ------------------------------------------------------------------ */\n\nexport interface LinkCardProps {\n unfurl: UnfurlController;\n display?: LinkDisplay;\n onToggleDisplay?: () => void;\n}\n\nexport const LinkCard = ({\n unfurl,\n display = \"compact\",\n onToggleDisplay,\n}: LinkCardProps): ReactElement => {\n const { status, tier, data, fetchedAt, retry, reunfurl } = unfurl;\n\n // ── Error: favicon + raw URL + retry, no media ──────────────────\n if (status === \"error\") {\n return (\n <StyledErrorBody>\n <div className=\"err-head\">\n <WarningTriangleIcon />\n <Caption1 weight=\"bold\" color=\"tertiary\">\n Couldn’t load a preview\n </Caption1>\n </div>\n <div className=\"err-url\">\n <StyledFavicon $bg=\"var(--color-theme-400)\" data-fixed />\n <Caption1 color=\"secondary\">{data.url}</Caption1>\n </div>\n <StyledRetry type=\"button\" onClick={retry}>\n <ArrowRefreshIcon />\n <Typography as=\"span\" variant=\"Caption 1\">\n Retry\n </Typography>\n </StyledRetry>\n </StyledErrorBody>\n );\n }\n\n const hasBasic = tier === \"basic\" || tier === \"full\";\n const hasFull = tier === \"full\";\n const toggle = onToggleDisplay ?? (() => undefined);\n\n // ── Expanded: hero + tinted footer band (title + domain) ────────\n if (display === \"expanded\") {\n return (\n <>\n <Cover\n aspectRatio={COVER_RATIO_HERO}\n centerSlot={hasFull && data.playable ? playControl : undefined}\n topRightSlot={coverManagement()}\n >\n {hasFull ? (\n <StyledColorCover $color={data.heroColor ?? \"#1D9E75\"} />\n ) : (\n <SkeletonLoader style={{ width: \"100%\", height: \"100%\" }} />\n )}\n </Cover>\n <StackRow\n role=\"footer\"\n direction=\"column\"\n background=\"var(--color-theme-200)\"\n >\n <StyledDomainRow>\n {hasBasic ? (\n <StyledFavicon $bg={data.faviconColor ?? \"#0F6E56\"} data-fixed />\n ) : (\n <SkeletonLoader\n data-fixed\n style={{ width: 16, height: 16, borderRadius: 4 }}\n />\n )}\n {hasBasic ? (\n <Caption1 color=\"tertiary\">{data.domain}</Caption1>\n ) : (\n <Caption1 color=\"tertiary\">{data.url}</Caption1>\n )}\n <span style={{ flex: \"1 1 auto\" }} />\n <DisplayToggle display={display} onToggle={toggle} />\n </StyledDomainRow>\n {hasBasic ? (\n <StyledFooterTitle weight=\"bold\">{data.title}</StyledFooterTitle>\n ) : (\n <SkeletonLoader style={{ height: 14, width: \"90%\" }} />\n )}\n {hasFull ? (\n <Caption1 color=\"tertiary\">{data.description}</Caption1>\n ) : (\n <SkeletonLoader style={{ height: 10, width: \"70%\" }} />\n )}\n </StackRow>\n {status === \"stale\" ? (\n <StackRow role=\"meta\">\n <StaleStrip fetchedAt={fetchedAt} onReunfurl={reunfurl} />\n </StackRow>\n ) : null}\n </>\n );\n }\n\n // ── Compact: cover + favicon/domain + title + chips ─────────────\n return (\n <>\n <Cover\n aspectRatio={COVER_RATIO}\n centerSlot={hasFull && data.playable ? playControl : undefined}\n >\n {hasFull ? (\n <StyledColorCover $color={data.heroColor ?? \"#1D9E75\"} />\n ) : (\n <SkeletonLoader style={{ width: \"100%\", height: \"100%\" }} />\n )}\n </Cover>\n\n <StackRow role=\"custom\">\n <StyledDomainRow>\n {hasBasic ? (\n <StyledFavicon $bg={data.faviconColor ?? \"#0F6E56\"} data-fixed />\n ) : (\n <SkeletonLoader\n data-fixed\n style={{ width: 16, height: 16, borderRadius: 4 }}\n />\n )}\n {hasBasic ? (\n <Caption1 color=\"tertiary\">{data.domain}</Caption1>\n ) : (\n <Caption1 color=\"tertiary\">{data.url}</Caption1>\n )}\n <span style={{ flex: \"1 1 auto\" }} />\n <DisplayToggle display={display} onToggle={toggle} />\n </StyledDomainRow>\n </StackRow>\n\n <StackRow role=\"title\">\n {hasBasic ? (\n <StyledClamp>{data.title}</StyledClamp>\n ) : (\n <div style={{ width: \"100%\" }}>\n <SkeletonLoader style={{ height: 14, width: \"92%\" }} />\n <SkeletonLoader\n style={{ height: 14, width: \"60%\", marginTop: 6 }}\n />\n </div>\n )}\n </StackRow>\n\n <StackRow role=\"custom\">\n <StyledChips>\n {hasFull ? (\n <>\n {data.kind ? (\n <StyledChip data-fixed>{data.kind}</StyledChip>\n ) : null}\n {data.duration ? (\n <StyledChip data-fixed>{data.duration}</StyledChip>\n ) : null}\n </>\n ) : (\n <SkeletonLoader\n style={{ height: 18, width: 96, borderRadius: 10 }}\n />\n )}\n </StyledChips>\n </StackRow>\n\n {status === \"stale\" ? (\n <StackRow role=\"meta\">\n <StaleStrip fetchedAt={fetchedAt} onReunfurl={reunfurl} />\n </StackRow>\n ) : null}\n </>\n );\n};\n\n/* The stale affordance — fetch time + a manual re-unfurl button. */\nconst StaleStrip = ({\n fetchedAt,\n onReunfurl,\n}: {\n fetchedAt: number | null;\n onReunfurl: () => void;\n}): ReactElement => (\n <StyledStaleStrip>\n <Typography as=\"span\" variant=\"Caption 1\" color=\"tertiary\">\n Preview may be out of date · fetched {formatFetchedAt(fetchedAt)}\n </Typography>\n <StyledReunfurl type=\"button\" onClick={onReunfurl}>\n <ArrowRefreshIcon />\n Re-unfurl\n </StyledReunfurl>\n </StyledStaleStrip>\n);\n\n/* ---- skeleton ---- */\n\n/* Mirrors the compact anatomy row for row (this is the `resolving` render at\n tier `url`), so a resolving link never reflows as it climbs the ladder. */\nexport const LinkSkeleton = (): ReactElement => (\n <>\n <Cover aspectRatio={COVER_RATIO}>\n <SkeletonLoader style={{ width: \"100%\", height: \"100%\" }} />\n </Cover>\n <StackRow role=\"custom\">\n <StyledDomainRow>\n <SkeletonLoader\n data-fixed\n style={{ width: 16, height: 16, borderRadius: 4 }}\n />\n <SkeletonLoader style={{ height: 10, width: \"40%\" }} />\n </StyledDomainRow>\n </StackRow>\n <StackRow role=\"title\">\n <div style={{ width: \"100%\" }}>\n <SkeletonLoader style={{ height: 14, width: \"92%\" }} />\n <SkeletonLoader style={{ height: 14, width: \"60%\", marginTop: 6 }} />\n </div>\n </StackRow>\n <StackRow role=\"custom\">\n <StyledChips>\n <SkeletonLoader style={{ height: 18, width: 96, borderRadius: 10 }} />\n </StyledChips>\n </StackRow>\n </>\n);\n\n/* ---- placeholder ---- */\n\nexport const LinkPlaceholder = (\n props: React.ButtonHTMLAttributes<HTMLButtonElement>\n): ReactElement => (\n <Placeholder icon={<InsertLinkIcon />} label=\"Add a link\" {...props} />\n);\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import React, { ReactElement } from "react";
2
+ export declare const SAMPLE_NOTE = "Kickoff open questions before we lock the columns:\n\n\u2022 Who owns the migration off react-dnd, and does it block the canvas work or run in parallel?\n\u2022 Confirm the outline-placeholder choreography reads the same in a scrolled column.\n\u2022 Do we ship the note type in v1, or defer inline editing?";
3
+ export interface NoteCardProps {
4
+ title?: string;
5
+ body?: string;
6
+ }
7
+ export declare const NoteCard: ({ title, body, }: NoteCardProps) => ReactElement;
8
+ export declare const NotePlaceholder: (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => ReactElement;
9
+ export declare const NoteSkeleton: () => ReactElement;
10
+ //# sourceMappingURL=NoteCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoteCard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/stackedCard/content/NoteCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AA4B5C,eAAO,MAAM,WAAW,wTAImC,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,QAAQ,GAAI,kBAGtB,aAAa,KAAG,YAUlB,CAAC;AAIF,eAAO,MAAM,eAAe,GAC1B,OAAO,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KACnD,YAEF,CAAC;AAGF,eAAO,MAAM,YAAY,QAAO,YAY/B,CAAC"}
@@ -0,0 +1,82 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import React from "react";
3
+ import styled from "styled-components";
4
+ import { EntityDots, Placeholder } from "./shared";
5
+ import { NoteIcon } from "../../../components/Icons";
6
+ import { SkeletonLoader } from "../../../components/Loaders";
7
+ import { Body2 } from "../../../components/Typography";
8
+ import { StackRow } from "../primitives";
9
+
10
+ /**
11
+ * NoteCard — the new fifth type. A multi-line text card (Milanote-style): a
12
+ * title row that owns the "…" menu, then padded body rows. The body clamps at a
13
+ * line limit and fades out; auto-height, so the card grows with its content.
14
+ * Inline editing lands in task 4/8 — this is the read view + placeholder.
15
+ */
16
+
17
+ /* The body clamps at a max height and fades out with a mask so long notes end
18
+ softly instead of hard-cropping. white-space: pre-line keeps authored breaks. */
19
+ const StyledNoteBody = styled(Body2).withConfig({
20
+ displayName: "NoteCard__StyledNoteBody",
21
+ componentId: "sc-e2a7no-0"
22
+ })(["display:block;max-height:132px;overflow:hidden;white-space:pre-line;-webkit-mask-image:linear-gradient(180deg,#000 72%,transparent);mask-image:linear-gradient(180deg,#000 72%,transparent);"]);
23
+ export const SAMPLE_NOTE = "Kickoff open questions before we lock the columns:\n\n\u2022 Who owns the migration off react-dnd, and does it block the canvas work or run in parallel?\n\u2022 Confirm the outline-placeholder choreography reads the same in a scrolled column.\n\u2022 Do we ship the note type in v1, or defer inline editing?";
24
+ export const NoteCard = _ref => {
25
+ let _ref$title = _ref.title,
26
+ title = _ref$title === void 0 ? "Kickoff notes" : _ref$title,
27
+ _ref$body = _ref.body,
28
+ body = _ref$body === void 0 ? SAMPLE_NOTE : _ref$body;
29
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StackRow, {
30
+ role: "title"
31
+ }, /*#__PURE__*/React.createElement(Body2, {
32
+ weight: "bold"
33
+ }, title), /*#__PURE__*/React.createElement(EntityDots, {
34
+ "aria-label": "Note options"
35
+ })), /*#__PURE__*/React.createElement(StackRow, {
36
+ role: "custom",
37
+ direction: "column"
38
+ }, /*#__PURE__*/React.createElement(StyledNoteBody, {
39
+ color: "secondary"
40
+ }, body)));
41
+ };
42
+
43
+ /* ---- placeholder + skeleton ---- */
44
+
45
+ export const NotePlaceholder = props => /*#__PURE__*/React.createElement(Placeholder, _extends({
46
+ icon: /*#__PURE__*/React.createElement(NoteIcon, null),
47
+ label: "Write a note"
48
+ }, props));
49
+
50
+ /* Skeleton mirrors the note anatomy: a title line, then several body lines. */
51
+ export const NoteSkeleton = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(StackRow, {
52
+ role: "title"
53
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
54
+ style: {
55
+ height: 14,
56
+ width: "50%"
57
+ }
58
+ })), /*#__PURE__*/React.createElement(StackRow, {
59
+ role: "custom",
60
+ direction: "column"
61
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
62
+ style: {
63
+ height: 10,
64
+ width: "100%"
65
+ }
66
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
67
+ style: {
68
+ height: 10,
69
+ width: "96%"
70
+ }
71
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
72
+ style: {
73
+ height: 10,
74
+ width: "88%"
75
+ }
76
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
77
+ style: {
78
+ height: 10,
79
+ width: "70%"
80
+ }
81
+ })));
82
+ //# sourceMappingURL=NoteCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NoteCard.js","names":["React","styled","EntityDots","Placeholder","NoteIcon","SkeletonLoader","Body2","StackRow","StyledNoteBody","withConfig","displayName","componentId","SAMPLE_NOTE","NoteCard","_ref","_ref$title","title","_ref$body","body","createElement","Fragment","role","weight","direction","color","NotePlaceholder","props","_extends","icon","label","NoteSkeleton","style","height","width"],"sources":["../../../../../src/presentation/stackedCard/content/NoteCard.tsx"],"sourcesContent":["import React, { ReactElement } from \"react\";\n\nimport styled from \"styled-components\";\n\nimport { EntityDots, Placeholder } from \"./shared\";\nimport { NoteIcon } from \"../../../components/Icons\";\nimport { SkeletonLoader } from \"../../../components/Loaders\";\nimport { Body2 } from \"../../../components/Typography\";\nimport { StackRow } from \"../primitives\";\n\n/**\n * NoteCard — the new fifth type. A multi-line text card (Milanote-style): a\n * title row that owns the \"…\" menu, then padded body rows. The body clamps at a\n * line limit and fades out; auto-height, so the card grows with its content.\n * Inline editing lands in task 4/8 — this is the read view + placeholder.\n */\n\n/* The body clamps at a max height and fades out with a mask so long notes end\n softly instead of hard-cropping. white-space: pre-line keeps authored breaks. */\nconst StyledNoteBody = styled(Body2)`\n display: block;\n max-height: 132px;\n overflow: hidden;\n white-space: pre-line;\n -webkit-mask-image: linear-gradient(180deg, #000 72%, transparent);\n mask-image: linear-gradient(180deg, #000 72%, transparent);\n`;\n\nexport const SAMPLE_NOTE = `Kickoff open questions before we lock the columns:\n\n• Who owns the migration off react-dnd, and does it block the canvas work or run in parallel?\n• Confirm the outline-placeholder choreography reads the same in a scrolled column.\n• Do we ship the note type in v1, or defer inline editing?`;\n\nexport interface NoteCardProps {\n title?: string;\n body?: string;\n}\n\nexport const NoteCard = ({\n title = \"Kickoff notes\",\n body = SAMPLE_NOTE,\n}: NoteCardProps): ReactElement => (\n <>\n <StackRow role=\"title\">\n <Body2 weight=\"bold\">{title}</Body2>\n <EntityDots aria-label=\"Note options\" />\n </StackRow>\n <StackRow role=\"custom\" direction=\"column\">\n <StyledNoteBody color=\"secondary\">{body}</StyledNoteBody>\n </StackRow>\n </>\n);\n\n/* ---- placeholder + skeleton ---- */\n\nexport const NotePlaceholder = (\n props: React.ButtonHTMLAttributes<HTMLButtonElement>\n): ReactElement => (\n <Placeholder icon={<NoteIcon />} label=\"Write a note\" {...props} />\n);\n\n/* Skeleton mirrors the note anatomy: a title line, then several body lines. */\nexport const NoteSkeleton = (): ReactElement => (\n <>\n <StackRow role=\"title\">\n <SkeletonLoader style={{ height: 14, width: \"50%\" }} />\n </StackRow>\n <StackRow role=\"custom\" direction=\"column\">\n <SkeletonLoader style={{ height: 10, width: \"100%\" }} />\n <SkeletonLoader style={{ height: 10, width: \"96%\" }} />\n <SkeletonLoader style={{ height: 10, width: \"88%\" }} />\n <SkeletonLoader style={{ height: 10, width: \"70%\" }} />\n </StackRow>\n </>\n);\n"],"mappings":";AAAA,OAAOA,KAAK,MAAwB,OAAO;AAE3C,OAAOC,MAAM,MAAM,mBAAmB;AAEtC,SAASC,UAAU,EAAEC,WAAW,QAAQ,UAAU;AAClD,SAASC,QAAQ,QAAQ,2BAA2B;AACpD,SAASC,cAAc,QAAQ,6BAA6B;AAC5D,SAASC,KAAK,QAAQ,gCAAgC;AACtD,SAASC,QAAQ,QAAQ,eAAe;;AAExC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,MAAMC,cAAc,GAAGP,MAAM,CAACK,KAAK,CAAC,CAAAG,UAAA;EAAAC,WAAA;EAAAC,WAAA;AAAA,oMAOnC;AAED,OAAO,MAAMC,WAAW,wTAImC;AAO3D,OAAO,MAAMC,QAAQ,GAAGC,IAAA;EAAA,IAAAC,UAAA,GAAAD,IAAA,CACtBE,KAAK;IAALA,KAAK,GAAAD,UAAA,cAAG,eAAe,GAAAA,UAAA;IAAAE,SAAA,GAAAH,IAAA,CACvBI,IAAI;IAAJA,IAAI,GAAAD,SAAA,cAAGL,WAAW,GAAAK,SAAA;EAAA,oBAElBjB,KAAA,CAAAmB,aAAA,CAAAnB,KAAA,CAAAoB,QAAA,qBACEpB,KAAA,CAAAmB,aAAA,CAACZ,QAAQ;IAACc,IAAI,EAAC;EAAO,gBACpBrB,KAAA,CAAAmB,aAAA,CAACb,KAAK;IAACgB,MAAM,EAAC;EAAM,GAAEN,KAAa,CAAC,eACpChB,KAAA,CAAAmB,aAAA,CAACjB,UAAU;IAAC,cAAW;EAAc,CAAE,CAC/B,CAAC,eACXF,KAAA,CAAAmB,aAAA,CAACZ,QAAQ;IAACc,IAAI,EAAC,QAAQ;IAACE,SAAS,EAAC;EAAQ,gBACxCvB,KAAA,CAAAmB,aAAA,CAACX,cAAc;IAACgB,KAAK,EAAC;EAAW,GAAEN,IAAqB,CAChD,CACV,CAAC;AAAA,CACJ;;AAED;;AAEA,OAAO,MAAMO,eAAe,GAC1BC,KAAoD,iBAEpD1B,KAAA,CAAAmB,aAAA,CAAChB,WAAW,EAAAwB,QAAA;EAACC,IAAI,eAAE5B,KAAA,CAAAmB,aAAA,CAACf,QAAQ,MAAE,CAAE;EAACyB,KAAK,EAAC;AAAc,GAAKH,KAAK,CAAG,CACnE;;AAED;AACA,OAAO,MAAMI,YAAY,GAAGA,CAAA,kBAC1B9B,KAAA,CAAAmB,aAAA,CAAAnB,KAAA,CAAAoB,QAAA,qBACEpB,KAAA,CAAAmB,aAAA,CAACZ,QAAQ;EAACc,IAAI,EAAC;AAAO,gBACpBrB,KAAA,CAAAmB,aAAA,CAACd,cAAc;EAAC0B,KAAK,EAAE;IAAEC,MAAM,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAM;AAAE,CAAE,CAC9C,CAAC,eACXjC,KAAA,CAAAmB,aAAA,CAACZ,QAAQ;EAACc,IAAI,EAAC,QAAQ;EAACE,SAAS,EAAC;AAAQ,gBACxCvB,KAAA,CAAAmB,aAAA,CAACd,cAAc;EAAC0B,KAAK,EAAE;IAAEC,MAAM,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAO;AAAE,CAAE,CAAC,eACxDjC,KAAA,CAAAmB,aAAA,CAACd,cAAc;EAAC0B,KAAK,EAAE;IAAEC,MAAM,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAM;AAAE,CAAE,CAAC,eACvDjC,KAAA,CAAAmB,aAAA,CAACd,cAAc;EAAC0B,KAAK,EAAE;IAAEC,MAAM,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAM;AAAE,CAAE,CAAC,eACvDjC,KAAA,CAAAmB,aAAA,CAACd,cAAc;EAAC0B,KAAK,EAAE;IAAEC,MAAM,EAAE,EAAE;IAAEC,KAAK,EAAE;EAAM;AAAE,CAAE,CAC9C,CACV,CACH","ignoreList":[]}
@@ -0,0 +1,14 @@
1
+ import React, { ReactElement } from "react";
2
+ /**
3
+ * SwatchCard — the cover IS the colour; a title row states its name and hex.
4
+ * The swatch value is a literal data colour by design (not a theme token).
5
+ */
6
+ export interface SwatchCardProps {
7
+ color?: string;
8
+ name?: string;
9
+ hex?: string;
10
+ }
11
+ export declare const SwatchCard: ({ color, name, hex, }: SwatchCardProps) => ReactElement;
12
+ export declare const SwatchPlaceholder: (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => ReactElement;
13
+ export declare const SwatchSkeleton: () => ReactElement;
14
+ //# sourceMappingURL=SwatchCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwatchCard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/stackedCard/content/SwatchCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAS5C;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,UAAU,GAAI,uBAIxB,eAAe,KAAG,YAYpB,CAAC;AAIF,eAAO,MAAM,iBAAiB,GAC5B,OAAO,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KACnD,YAEF,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,YAUjC,CAAC"}
@@ -0,0 +1,64 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import React from "react";
3
+ import { StyledColorCover, Placeholder } from "./shared";
4
+ import { ImageIcon } from "../../../components/Icons";
5
+ import { SkeletonLoader } from "../../../components/Loaders";
6
+ import { Body2, Caption1 } from "../../../components/Typography";
7
+ import { Cover, StackRow } from "../primitives";
8
+ import { COVER_RATIO_SWATCH } from "../shell";
9
+
10
+ /**
11
+ * SwatchCard — the cover IS the colour; a title row states its name and hex.
12
+ * The swatch value is a literal data colour by design (not a theme token).
13
+ */
14
+
15
+ export const SwatchCard = _ref => {
16
+ let _ref$color = _ref.color,
17
+ color = _ref$color === void 0 ? "#1D9E75" : _ref$color,
18
+ _ref$name = _ref.name,
19
+ name = _ref$name === void 0 ? "Teal" : _ref$name,
20
+ _ref$hex = _ref.hex,
21
+ hex = _ref$hex === void 0 ? "#1D9E75" : _ref$hex;
22
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cover, {
23
+ aspectRatio: COVER_RATIO_SWATCH
24
+ }, /*#__PURE__*/React.createElement(StyledColorCover, {
25
+ $color: color
26
+ })), /*#__PURE__*/React.createElement(StackRow, {
27
+ role: "title"
28
+ }, /*#__PURE__*/React.createElement(Body2, null, name), /*#__PURE__*/React.createElement(Caption1, {
29
+ color: "tertiary",
30
+ "data-fixed": true,
31
+ style: {
32
+ fontFamily: "monospace"
33
+ }
34
+ }, hex)));
35
+ };
36
+
37
+ /* ---- placeholder + skeleton ---- */
38
+
39
+ export const SwatchPlaceholder = props => /*#__PURE__*/React.createElement(Placeholder, _extends({
40
+ icon: /*#__PURE__*/React.createElement(ImageIcon, null),
41
+ label: "Pick a colour"
42
+ }, props));
43
+ export const SwatchSkeleton = () => /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cover, {
44
+ aspectRatio: COVER_RATIO_SWATCH
45
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
46
+ style: {
47
+ width: "100%",
48
+ height: "100%"
49
+ }
50
+ })), /*#__PURE__*/React.createElement(StackRow, {
51
+ role: "title"
52
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
53
+ style: {
54
+ height: 14,
55
+ width: "40%"
56
+ }
57
+ }), /*#__PURE__*/React.createElement(SkeletonLoader, {
58
+ "data-fixed": true,
59
+ style: {
60
+ height: 12,
61
+ width: 60
62
+ }
63
+ })));
64
+ //# sourceMappingURL=SwatchCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SwatchCard.js","names":["React","StyledColorCover","Placeholder","ImageIcon","SkeletonLoader","Body2","Caption1","Cover","StackRow","COVER_RATIO_SWATCH","SwatchCard","_ref","_ref$color","color","_ref$name","name","_ref$hex","hex","createElement","Fragment","aspectRatio","$color","role","style","fontFamily","SwatchPlaceholder","props","_extends","icon","label","SwatchSkeleton","width","height"],"sources":["../../../../../src/presentation/stackedCard/content/SwatchCard.tsx"],"sourcesContent":["import React, { ReactElement } from \"react\";\n\nimport { StyledColorCover, Placeholder } from \"./shared\";\nimport { ImageIcon } from \"../../../components/Icons\";\nimport { SkeletonLoader } from \"../../../components/Loaders\";\nimport { Body2, Caption1 } from \"../../../components/Typography\";\nimport { Cover, StackRow } from \"../primitives\";\nimport { COVER_RATIO_SWATCH } from \"../shell\";\n\n/**\n * SwatchCard — the cover IS the colour; a title row states its name and hex.\n * The swatch value is a literal data colour by design (not a theme token).\n */\n\nexport interface SwatchCardProps {\n color?: string;\n name?: string;\n hex?: string;\n}\n\nexport const SwatchCard = ({\n color = \"#1D9E75\",\n name = \"Teal\",\n hex = \"#1D9E75\",\n}: SwatchCardProps): ReactElement => (\n <>\n <Cover aspectRatio={COVER_RATIO_SWATCH}>\n <StyledColorCover $color={color} />\n </Cover>\n <StackRow role=\"title\">\n <Body2>{name}</Body2>\n <Caption1 color=\"tertiary\" data-fixed style={{ fontFamily: \"monospace\" }}>\n {hex}\n </Caption1>\n </StackRow>\n </>\n);\n\n/* ---- placeholder + skeleton ---- */\n\nexport const SwatchPlaceholder = (\n props: React.ButtonHTMLAttributes<HTMLButtonElement>\n): ReactElement => (\n <Placeholder icon={<ImageIcon />} label=\"Pick a colour\" {...props} />\n);\n\nexport const SwatchSkeleton = (): ReactElement => (\n <>\n <Cover aspectRatio={COVER_RATIO_SWATCH}>\n <SkeletonLoader style={{ width: \"100%\", height: \"100%\" }} />\n </Cover>\n <StackRow role=\"title\">\n <SkeletonLoader style={{ height: 14, width: \"40%\" }} />\n <SkeletonLoader data-fixed style={{ height: 12, width: 60 }} />\n </StackRow>\n </>\n);\n"],"mappings":";AAAA,OAAOA,KAAK,MAAwB,OAAO;AAE3C,SAASC,gBAAgB,EAAEC,WAAW,QAAQ,UAAU;AACxD,SAASC,SAAS,QAAQ,2BAA2B;AACrD,SAASC,cAAc,QAAQ,6BAA6B;AAC5D,SAASC,KAAK,EAAEC,QAAQ,QAAQ,gCAAgC;AAChE,SAASC,KAAK,EAAEC,QAAQ,QAAQ,eAAe;AAC/C,SAASC,kBAAkB,QAAQ,UAAU;;AAE7C;AACA;AACA;AACA;;AAQA,OAAO,MAAMC,UAAU,GAAGC,IAAA;EAAA,IAAAC,UAAA,GAAAD,IAAA,CACxBE,KAAK;IAALA,KAAK,GAAAD,UAAA,cAAG,SAAS,GAAAA,UAAA;IAAAE,SAAA,GAAAH,IAAA,CACjBI,IAAI;IAAJA,IAAI,GAAAD,SAAA,cAAG,MAAM,GAAAA,SAAA;IAAAE,QAAA,GAAAL,IAAA,CACbM,GAAG;IAAHA,GAAG,GAAAD,QAAA,cAAG,SAAS,GAAAA,QAAA;EAAA,oBAEfhB,KAAA,CAAAkB,aAAA,CAAAlB,KAAA,CAAAmB,QAAA,qBACEnB,KAAA,CAAAkB,aAAA,CAACX,KAAK;IAACa,WAAW,EAAEX;EAAmB,gBACrCT,KAAA,CAAAkB,aAAA,CAACjB,gBAAgB;IAACoB,MAAM,EAAER;EAAM,CAAE,CAC7B,CAAC,eACRb,KAAA,CAAAkB,aAAA,CAACV,QAAQ;IAACc,IAAI,EAAC;EAAO,gBACpBtB,KAAA,CAAAkB,aAAA,CAACb,KAAK,QAAEU,IAAY,CAAC,eACrBf,KAAA,CAAAkB,aAAA,CAACZ,QAAQ;IAACO,KAAK,EAAC,UAAU;IAAC,kBAAU;IAACU,KAAK,EAAE;MAAEC,UAAU,EAAE;IAAY;EAAE,GACtEP,GACO,CACF,CACV,CAAC;AAAA,CACJ;;AAED;;AAEA,OAAO,MAAMQ,iBAAiB,GAC5BC,KAAoD,iBAEpD1B,KAAA,CAAAkB,aAAA,CAAChB,WAAW,EAAAyB,QAAA;EAACC,IAAI,eAAE5B,KAAA,CAAAkB,aAAA,CAACf,SAAS,MAAE,CAAE;EAAC0B,KAAK,EAAC;AAAe,GAAKH,KAAK,CAAG,CACrE;AAED,OAAO,MAAMI,cAAc,GAAGA,CAAA,kBAC5B9B,KAAA,CAAAkB,aAAA,CAAAlB,KAAA,CAAAmB,QAAA,qBACEnB,KAAA,CAAAkB,aAAA,CAACX,KAAK;EAACa,WAAW,EAAEX;AAAmB,gBACrCT,KAAA,CAAAkB,aAAA,CAACd,cAAc;EAACmB,KAAK,EAAE;IAAEQ,KAAK,EAAE,MAAM;IAAEC,MAAM,EAAE;EAAO;AAAE,CAAE,CACtD,CAAC,eACRhC,KAAA,CAAAkB,aAAA,CAACV,QAAQ;EAACc,IAAI,EAAC;AAAO,gBACpBtB,KAAA,CAAAkB,aAAA,CAACd,cAAc;EAACmB,KAAK,EAAE;IAAES,MAAM,EAAE,EAAE;IAAED,KAAK,EAAE;EAAM;AAAE,CAAE,CAAC,eACvD/B,KAAA,CAAAkB,aAAA,CAACd,cAAc;EAAC,kBAAU;EAACmB,KAAK,EAAE;IAAES,MAAM,EAAE,EAAE;IAAED,KAAK,EAAE;EAAG;AAAE,CAAE,CACtD,CACV,CACH","ignoreList":[]}
@@ -0,0 +1,29 @@
1
+ import React, { ReactElement } from "react";
2
+ export interface TaskCardProps {
3
+ title?: string;
4
+ /** Optional cover — task cards in a column usually have none. */
5
+ cover?: boolean;
6
+ playable?: boolean;
7
+ coverControls?: boolean;
8
+ /** Config-gated task-number prefix (mirrors `show_task_id`). */
9
+ showTaskId?: boolean;
10
+ taskId?: number;
11
+ dateLabel?: string;
12
+ /** Overdue date — colours the date red, but only when NOT completed. */
13
+ overdue?: boolean;
14
+ /** Dependency counter, gated behind a feature flag. */
15
+ showDependencies?: boolean;
16
+ dependencyCount?: number;
17
+ /** The task's hidden-from-clients flag. */
18
+ hiddenFromClients?: boolean;
19
+ /** The project default for client visibility; the signifier shows on a diff. */
20
+ projectDefaultHidden?: boolean;
21
+ /** Whether the task has an assignee (avatar) or shows the add affordance. */
22
+ assigned?: boolean;
23
+ /** Completed — teal tint, no "…" menu, no overdue colour. */
24
+ completed?: boolean;
25
+ }
26
+ export declare const TaskCard: ({ title, cover, playable, coverControls, showTaskId, taskId, dateLabel, overdue, showDependencies, dependencyCount, hiddenFromClients, projectDefaultHidden, assigned, completed, }: TaskCardProps) => ReactElement;
27
+ export declare const TaskPlaceholder: (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => ReactElement;
28
+ export declare const TaskSkeleton: () => ReactElement;
29
+ //# sourceMappingURL=TaskCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TaskCard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/stackedCard/content/TaskCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AA+I5C,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,gEAAgE;IAChE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2CAA2C;IAC3C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gFAAgF;IAChF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,QAAQ,GAAI,qLAetB,aAAa,KAAG,YA+FlB,CAAC;AAIF,eAAO,MAAM,eAAe,GAC1B,OAAO,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KACnD,YAMF,CAAC;AAGF,eAAO,MAAM,YAAY,QAAO,YAiB/B,CAAC"}