@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,208 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useInlineEdit = 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
+ /**
15
+ * useInlineEdit — story-local click-to-edit state machine for StackedCard
16
+ * (task 4/8). Presentation-only; not exported from the design-system barrel.
17
+ *
18
+ * A card in preview/placeholder mode enters an EDITING state on click: a
19
+ * card-centered text field with confirm/cancel keyboard rules, an optional
20
+ * validator, and a single-line ↔ multi-line mode switch. The hook owns only the
21
+ * editing lifecycle (mode, working value, error, keyboard + outside-click); the
22
+ * card chrome and the async handoff after commit (e.g. the link unfurl ladder
23
+ * from task 3/8) live in the story that consumes it.
24
+ *
25
+ * ── The decided rules (AC task #454744) ──
26
+ * Single-line Enter confirms · click-outside confirms · Esc cancels + reverts
27
+ * Multi-line Enter = newline · Cmd/Ctrl+Enter saves · click-outside saves ·
28
+ * Esc cancels + reverts
29
+ * Validator validate(value) => true | errorMessage, run before every accept
30
+ * pass → commit + exit editing
31
+ * fail via a key → STAY editing, surface the message (retry)
32
+ * fail via outside → REVERT (acts as cancel) — user never trapped
33
+ *
34
+ * Keyboard is handled on the field's own keydown (never a global listener) and
35
+ * every keydown stops propagation, so the card focus model (task 2/8) can't
36
+ * swallow the Enter/Esc that belong to the editor.
37
+ */
38
+
39
+ /** Props to spread onto the `<input>` or `<textarea>` while editing. */
40
+
41
+ var useInlineEdit = exports.useInlineEdit = function useInlineEdit() {
42
+ var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
43
+ _ref$initialValue = _ref.initialValue,
44
+ initialValue = _ref$initialValue === void 0 ? "" : _ref$initialValue,
45
+ _ref$multiline = _ref.multiline,
46
+ multiline = _ref$multiline === void 0 ? false : _ref$multiline,
47
+ validate = _ref.validate,
48
+ onCommit = _ref.onCommit;
49
+ var _useState = (0, _react.useState)(false),
50
+ _useState2 = _slicedToArray(_useState, 2),
51
+ editing = _useState2[0],
52
+ setEditingState = _useState2[1];
53
+ var _useState3 = (0, _react.useState)(initialValue),
54
+ _useState4 = _slicedToArray(_useState3, 2),
55
+ value = _useState4[0],
56
+ setValueState = _useState4[1];
57
+ var _useState5 = (0, _react.useState)(initialValue),
58
+ _useState6 = _slicedToArray(_useState5, 2),
59
+ committed = _useState6[0],
60
+ setCommittedState = _useState6[1];
61
+ var _useState7 = (0, _react.useState)(null),
62
+ _useState8 = _slicedToArray(_useState7, 2),
63
+ error = _useState8[0],
64
+ setError = _useState8[1];
65
+
66
+ // Refs mirror the state that the (stable) event handlers read, so the handlers
67
+ // never go stale and never need to be re-created as the value changes.
68
+ var elRef = (0, _react.useRef)(null);
69
+ var valueRef = (0, _react.useRef)(value);
70
+ var committedRef = (0, _react.useRef)(committed);
71
+ var editingRef = (0, _react.useRef)(editing);
72
+ // Set right before a programmatic exit so the blur that follows the field
73
+ // unmounting is ignored (it isn't a real click-outside).
74
+ var skipBlurRef = (0, _react.useRef)(false);
75
+ var validateRef = (0, _react.useRef)(validate);
76
+ var onCommitRef = (0, _react.useRef)(onCommit);
77
+ (0, _react.useEffect)(function () {
78
+ validateRef.current = validate;
79
+ onCommitRef.current = onCommit;
80
+ });
81
+ var setValue = (0, _react.useCallback)(function (v) {
82
+ valueRef.current = v;
83
+ setValueState(v);
84
+ }, []);
85
+ var setCommitted = (0, _react.useCallback)(function (v) {
86
+ committedRef.current = v;
87
+ setCommittedState(v);
88
+ }, []);
89
+ var setEditing = (0, _react.useCallback)(function (v) {
90
+ editingRef.current = v;
91
+ setEditingState(v);
92
+ }, []);
93
+ var begin = (0, _react.useCallback)(function () {
94
+ skipBlurRef.current = false;
95
+ setValue(committedRef.current);
96
+ setError(null);
97
+ setEditing(true);
98
+ }, [setValue, setEditing]);
99
+ var cancel = (0, _react.useCallback)(function () {
100
+ skipBlurRef.current = true;
101
+ setValue(committedRef.current);
102
+ setError(null);
103
+ setEditing(false);
104
+ }, [setValue, setEditing]);
105
+ var reset = (0, _react.useCallback)(function () {
106
+ var next = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialValue;
107
+ skipBlurRef.current = true;
108
+ setCommitted(next);
109
+ setValue(next);
110
+ setError(null);
111
+ setEditing(false);
112
+ }, [initialValue, setCommitted, setValue, setEditing]);
113
+ var commit = (0, _react.useCallback)(function (v) {
114
+ var _onCommitRef$current;
115
+ skipBlurRef.current = true;
116
+ setCommitted(v);
117
+ setValue(v);
118
+ setError(null);
119
+ setEditing(false);
120
+ (_onCommitRef$current = onCommitRef.current) === null || _onCommitRef$current === void 0 || _onCommitRef$current.call(onCommitRef, v);
121
+ }, [setCommitted, setValue, setEditing]);
122
+
123
+ // Run the validator (if any) and accept, or handle the failure per source:
124
+ // a key retry keeps the user in the field with a message; an outside click
125
+ // reverts so the user is never trapped in an invalid editor.
126
+ var attempt = (0, _react.useCallback)(function (source) {
127
+ var v = valueRef.current;
128
+ var result = validateRef.current ? validateRef.current(v) : true;
129
+ if (result === true) {
130
+ commit(v);
131
+ return true;
132
+ }
133
+ if (source === "outside") {
134
+ cancel();
135
+ return false;
136
+ }
137
+ setError(result);
138
+ return false;
139
+ }, [commit, cancel]);
140
+ var onChange = (0, _react.useCallback)(function (e) {
141
+ setValue(e.target.value);
142
+ // Clear a stale error as the user edits; the next accept re-validates.
143
+ setError(function (prev) {
144
+ return prev == null ? prev : null;
145
+ });
146
+ }, [setValue]);
147
+ var onKeyDown = (0, _react.useCallback)(function (e) {
148
+ // Keep Enter/Esc from reaching the card's own keyboard model (task 2/8).
149
+ e.stopPropagation();
150
+ if (e.key === "Escape") {
151
+ e.preventDefault();
152
+ cancel();
153
+ return;
154
+ }
155
+ if (e.key === "Enter") {
156
+ var withMeta = e.metaKey || e.ctrlKey;
157
+ // Multi-line: a bare Enter is a newline; only Cmd/Ctrl+Enter saves.
158
+ if (multiline && !withMeta) return;
159
+ e.preventDefault();
160
+ attempt("key");
161
+ }
162
+ }, [attempt, cancel, multiline]);
163
+ var onBlur = (0, _react.useCallback)(function () {
164
+ if (skipBlurRef.current) {
165
+ skipBlurRef.current = false;
166
+ return;
167
+ }
168
+ if (!editingRef.current) return;
169
+ attempt("outside");
170
+ }, [attempt]);
171
+ var setRef = (0, _react.useCallback)(function (el) {
172
+ elRef.current = el;
173
+ }, []);
174
+
175
+ // On entering editing, focus the field and drop the caret at the end so the
176
+ // cursor is visible and existing text is ready to extend.
177
+ (0, _react.useEffect)(function () {
178
+ if (!editing) return;
179
+ var el = elRef.current;
180
+ if (!el) return;
181
+ el.focus();
182
+ var len = el.value.length;
183
+ try {
184
+ el.setSelectionRange(len, len);
185
+ } catch (_unused) {
186
+ /* some input types disallow setSelectionRange — harmless here. */
187
+ }
188
+ }, [editing]);
189
+ return {
190
+ editing,
191
+ value,
192
+ committed,
193
+ error,
194
+ multiline,
195
+ begin,
196
+ cancel,
197
+ reset,
198
+ bind: {
199
+ ref: setRef,
200
+ value,
201
+ onChange,
202
+ onKeyDown,
203
+ onBlur,
204
+ "aria-invalid": error != null
205
+ }
206
+ };
207
+ };
208
+ //# sourceMappingURL=useInlineEdit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInlineEdit.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","useInlineEdit","exports","_ref","arguments","undefined","_ref$initialValue","initialValue","_ref$multiline","multiline","validate","onCommit","_useState","useState","_useState2","editing","setEditingState","_useState3","_useState4","setValueState","_useState5","_useState6","committed","setCommittedState","_useState7","_useState8","error","setError","elRef","useRef","valueRef","committedRef","editingRef","skipBlurRef","validateRef","onCommitRef","useEffect","current","setValue","useCallback","v","setCommitted","setEditing","begin","cancel","reset","commit","_onCommitRef$current","attempt","source","result","onChange","target","prev","onKeyDown","stopPropagation","key","preventDefault","withMeta","metaKey","ctrlKey","onBlur","setRef","el","focus","len","setSelectionRange","_unused","bind","ref"],"sources":["../../../../src/presentation/stackedCard/useInlineEdit.ts"],"sourcesContent":["import {\n ChangeEvent,\n FocusEvent,\n KeyboardEvent,\n useCallback,\n useEffect,\n useRef,\n useState,\n} from \"react\";\n\n/**\n * useInlineEdit — story-local click-to-edit state machine for StackedCard\n * (task 4/8). Presentation-only; not exported from the design-system barrel.\n *\n * A card in preview/placeholder mode enters an EDITING state on click: a\n * card-centered text field with confirm/cancel keyboard rules, an optional\n * validator, and a single-line ↔ multi-line mode switch. The hook owns only the\n * editing lifecycle (mode, working value, error, keyboard + outside-click); the\n * card chrome and the async handoff after commit (e.g. the link unfurl ladder\n * from task 3/8) live in the story that consumes it.\n *\n * ── The decided rules (AC task #454744) ──\n * Single-line Enter confirms · click-outside confirms · Esc cancels + reverts\n * Multi-line Enter = newline · Cmd/Ctrl+Enter saves · click-outside saves ·\n * Esc cancels + reverts\n * Validator validate(value) => true | errorMessage, run before every accept\n * pass → commit + exit editing\n * fail via a key → STAY editing, surface the message (retry)\n * fail via outside → REVERT (acts as cancel) — user never trapped\n *\n * Keyboard is handled on the field's own keydown (never a global listener) and\n * every keydown stops propagation, so the card focus model (task 2/8) can't\n * swallow the Enter/Esc that belong to the editor.\n */\n\nexport type InlineEditValidator = (value: string) => true | string;\n\nexport interface UseInlineEditConfig {\n /** Seed value for the first edit; also the revert target until first commit. */\n initialValue?: string;\n /** Multi-line mode: Enter inserts a newline, Cmd/Ctrl+Enter saves. */\n multiline?: boolean;\n /** Optional validator, run before every accept. `true` passes; a string fails. */\n validate?: InlineEditValidator;\n /** Called with the committed value when an accept passes validation. */\n onCommit?: (value: string) => void;\n}\n\n/** Props to spread onto the `<input>` or `<textarea>` while editing. */\nexport interface InlineEditBind {\n /** Callback ref — assignable to both an input and a textarea. */\n ref: (el: HTMLInputElement | HTMLTextAreaElement | null) => void;\n value: string;\n onChange: (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onKeyDown: (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n onBlur: (e: FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void;\n \"aria-invalid\": boolean;\n}\n\nexport interface InlineEditController {\n /** Whether the field is currently shown. */\n editing: boolean;\n /** The working value (the draft being typed). */\n value: string;\n /** The last committed value — what a revert restores. */\n committed: string;\n /** The current validation message, or null when valid / untouched. */\n error: string | null;\n /** Whether this editor is in multi-line mode. */\n multiline: boolean;\n /** Enter editing, loading the last committed value. */\n begin: () => void;\n /** Cancel + revert to the committed value (the Esc / invalid-outside path). */\n cancel: () => void;\n /** Force a committed value without going through the field (repeat demos). */\n reset: (next?: string) => void;\n /** Spread onto the field element while `editing`. */\n bind: InlineEditBind;\n}\n\nexport const useInlineEdit = ({\n initialValue = \"\",\n multiline = false,\n validate,\n onCommit,\n}: UseInlineEditConfig = {}): InlineEditController => {\n const [editing, setEditingState] = useState(false);\n const [value, setValueState] = useState(initialValue);\n const [committed, setCommittedState] = useState(initialValue);\n const [error, setError] = useState<string | null>(null);\n\n // Refs mirror the state that the (stable) event handlers read, so the handlers\n // never go stale and never need to be re-created as the value changes.\n const elRef = useRef<HTMLInputElement | HTMLTextAreaElement | null>(null);\n const valueRef = useRef(value);\n const committedRef = useRef(committed);\n const editingRef = useRef(editing);\n // Set right before a programmatic exit so the blur that follows the field\n // unmounting is ignored (it isn't a real click-outside).\n const skipBlurRef = useRef(false);\n const validateRef = useRef(validate);\n const onCommitRef = useRef(onCommit);\n\n useEffect(() => {\n validateRef.current = validate;\n onCommitRef.current = onCommit;\n });\n\n const setValue = useCallback((v: string) => {\n valueRef.current = v;\n setValueState(v);\n }, []);\n\n const setCommitted = useCallback((v: string) => {\n committedRef.current = v;\n setCommittedState(v);\n }, []);\n\n const setEditing = useCallback((v: boolean) => {\n editingRef.current = v;\n setEditingState(v);\n }, []);\n\n const begin = useCallback(() => {\n skipBlurRef.current = false;\n setValue(committedRef.current);\n setError(null);\n setEditing(true);\n }, [setValue, setEditing]);\n\n const cancel = useCallback(() => {\n skipBlurRef.current = true;\n setValue(committedRef.current);\n setError(null);\n setEditing(false);\n }, [setValue, setEditing]);\n\n const reset = useCallback(\n (next: string = initialValue) => {\n skipBlurRef.current = true;\n setCommitted(next);\n setValue(next);\n setError(null);\n setEditing(false);\n },\n [initialValue, setCommitted, setValue, setEditing]\n );\n\n const commit = useCallback(\n (v: string) => {\n skipBlurRef.current = true;\n setCommitted(v);\n setValue(v);\n setError(null);\n setEditing(false);\n onCommitRef.current?.(v);\n },\n [setCommitted, setValue, setEditing]\n );\n\n // Run the validator (if any) and accept, or handle the failure per source:\n // a key retry keeps the user in the field with a message; an outside click\n // reverts so the user is never trapped in an invalid editor.\n const attempt = useCallback(\n (source: \"key\" | \"outside\"): boolean => {\n const v = valueRef.current;\n const result = validateRef.current ? validateRef.current(v) : true;\n if (result === true) {\n commit(v);\n return true;\n }\n if (source === \"outside\") {\n cancel();\n return false;\n }\n setError(result);\n return false;\n },\n [commit, cancel]\n );\n\n const onChange = useCallback(\n (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n setValue(e.target.value);\n // Clear a stale error as the user edits; the next accept re-validates.\n setError((prev) => (prev == null ? prev : null));\n },\n [setValue]\n );\n\n const onKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n // Keep Enter/Esc from reaching the card's own keyboard model (task 2/8).\n e.stopPropagation();\n\n if (e.key === \"Escape\") {\n e.preventDefault();\n cancel();\n return;\n }\n\n if (e.key === \"Enter\") {\n const withMeta = e.metaKey || e.ctrlKey;\n // Multi-line: a bare Enter is a newline; only Cmd/Ctrl+Enter saves.\n if (multiline && !withMeta) return;\n e.preventDefault();\n attempt(\"key\");\n }\n },\n [attempt, cancel, multiline]\n );\n\n const onBlur = useCallback(() => {\n if (skipBlurRef.current) {\n skipBlurRef.current = false;\n return;\n }\n if (!editingRef.current) return;\n attempt(\"outside\");\n }, [attempt]);\n\n const setRef = useCallback(\n (el: HTMLInputElement | HTMLTextAreaElement | null) => {\n elRef.current = el;\n },\n []\n );\n\n // On entering editing, focus the field and drop the caret at the end so the\n // cursor is visible and existing text is ready to extend.\n useEffect(() => {\n if (!editing) return;\n const el = elRef.current;\n if (!el) return;\n el.focus();\n const len = el.value.length;\n try {\n el.setSelectionRange(len, len);\n } catch {\n /* some input types disallow setSelectionRange — harmless here. */\n }\n }, [editing]);\n\n return {\n editing,\n value,\n committed,\n error,\n multiline,\n begin,\n cancel,\n reset,\n bind: {\n ref: setRef,\n value,\n onChange,\n onKeyDown,\n onBlur,\n \"aria-invalid\": error != null,\n },\n };\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,15 @@
1
+ import React, { ReactElement } from "react";
2
+ /**
3
+ * ImageCard — a full-bleed image and little else. Cover-management controls
4
+ * (collapse, remove) appear on hover; there is no other chrome. Fixed-box in
5
+ * production (host sets width AND height, the cover scales aspect-locked); shown
6
+ * here in the auto-height shell with a reserved image aspect ratio.
7
+ */
8
+ export interface ImageCardProps {
9
+ color?: string;
10
+ src?: string;
11
+ }
12
+ export declare const ImageCard: ({ color, src, }: ImageCardProps) => ReactElement;
13
+ export declare const ImagePlaceholder: (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => ReactElement;
14
+ export declare const ImageSkeleton: () => ReactElement;
15
+ //# sourceMappingURL=ImageCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageCard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/stackedCard/content/ImageCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAQ5C;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,eAAO,MAAM,SAAS,GAAI,iBAGvB,cAAc,KAAG,YAOnB,CAAC;AAKF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KACnD,YAQF,CAAC;AAEF,eAAO,MAAM,aAAa,QAAO,YAIhC,CAAC"}
@@ -0,0 +1,50 @@
1
+ import _extends from "@babel/runtime/helpers/esm/extends";
2
+ import React from "react";
3
+ import { StyledColorCover, coverManagement, Placeholder } from "./shared";
4
+ import { UploadIcon } from "../../../components/Icons";
5
+ import { SkeletonLoader } from "../../../components/Loaders";
6
+ import { Cover } from "../primitives";
7
+ import { COVER_RATIO_IMAGE } from "../shell";
8
+
9
+ /**
10
+ * ImageCard — a full-bleed image and little else. Cover-management controls
11
+ * (collapse, remove) appear on hover; there is no other chrome. Fixed-box in
12
+ * production (host sets width AND height, the cover scales aspect-locked); shown
13
+ * here in the auto-height shell with a reserved image aspect ratio.
14
+ */
15
+
16
+ export const ImageCard = _ref => {
17
+ let _ref$color = _ref.color,
18
+ color = _ref$color === void 0 ? "#F0997B" : _ref$color,
19
+ src = _ref.src;
20
+ return /*#__PURE__*/React.createElement(Cover, {
21
+ aspectRatio: COVER_RATIO_IMAGE,
22
+ topRightSlot: coverManagement({
23
+ removeLabel: "Remove image"
24
+ })
25
+ }, src ? /*#__PURE__*/React.createElement("img", {
26
+ src: src,
27
+ alt: ""
28
+ }) : /*#__PURE__*/React.createElement(StyledColorCover, {
29
+ $color: color
30
+ }));
31
+ };
32
+
33
+ /* ---- placeholder + skeleton ---- */
34
+
35
+ /* The placeholder doubles as the drop target (visual only here). */
36
+ export const ImagePlaceholder = props => /*#__PURE__*/React.createElement(Placeholder, _extends({
37
+ icon: /*#__PURE__*/React.createElement(UploadIcon, null),
38
+ label: "Drop an image or click to upload",
39
+ height: 168,
40
+ dashed: true
41
+ }, props));
42
+ export const ImageSkeleton = () => /*#__PURE__*/React.createElement(Cover, {
43
+ aspectRatio: COVER_RATIO_IMAGE
44
+ }, /*#__PURE__*/React.createElement(SkeletonLoader, {
45
+ style: {
46
+ width: "100%",
47
+ height: "100%"
48
+ }
49
+ }));
50
+ //# sourceMappingURL=ImageCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ImageCard.js","names":["React","StyledColorCover","coverManagement","Placeholder","UploadIcon","SkeletonLoader","Cover","COVER_RATIO_IMAGE","ImageCard","_ref","_ref$color","color","src","createElement","aspectRatio","topRightSlot","removeLabel","alt","$color","ImagePlaceholder","props","_extends","icon","label","height","dashed","ImageSkeleton","style","width"],"sources":["../../../../../src/presentation/stackedCard/content/ImageCard.tsx"],"sourcesContent":["import React, { ReactElement } from \"react\";\n\nimport { StyledColorCover, coverManagement, Placeholder } from \"./shared\";\nimport { UploadIcon } from \"../../../components/Icons\";\nimport { SkeletonLoader } from \"../../../components/Loaders\";\nimport { Cover } from \"../primitives\";\nimport { COVER_RATIO_IMAGE } from \"../shell\";\n\n/**\n * ImageCard — a full-bleed image and little else. Cover-management controls\n * (collapse, remove) appear on hover; there is no other chrome. Fixed-box in\n * production (host sets width AND height, the cover scales aspect-locked); shown\n * here in the auto-height shell with a reserved image aspect ratio.\n */\n\nexport interface ImageCardProps {\n color?: string;\n src?: string;\n}\n\nexport const ImageCard = ({\n color = \"#F0997B\",\n src,\n}: ImageCardProps): ReactElement => (\n <Cover\n aspectRatio={COVER_RATIO_IMAGE}\n topRightSlot={coverManagement({ removeLabel: \"Remove image\" })}\n >\n {src ? <img src={src} alt=\"\" /> : <StyledColorCover $color={color} />}\n </Cover>\n);\n\n/* ---- placeholder + skeleton ---- */\n\n/* The placeholder doubles as the drop target (visual only here). */\nexport const ImagePlaceholder = (\n props: React.ButtonHTMLAttributes<HTMLButtonElement>\n): ReactElement => (\n <Placeholder\n icon={<UploadIcon />}\n label=\"Drop an image or click to upload\"\n height={168}\n dashed\n {...props}\n />\n);\n\nexport const ImageSkeleton = (): ReactElement => (\n <Cover aspectRatio={COVER_RATIO_IMAGE}>\n <SkeletonLoader style={{ width: \"100%\", height: \"100%\" }} />\n </Cover>\n);\n"],"mappings":";AAAA,OAAOA,KAAK,MAAwB,OAAO;AAE3C,SAASC,gBAAgB,EAAEC,eAAe,EAAEC,WAAW,QAAQ,UAAU;AACzE,SAASC,UAAU,QAAQ,2BAA2B;AACtD,SAASC,cAAc,QAAQ,6BAA6B;AAC5D,SAASC,KAAK,QAAQ,eAAe;AACrC,SAASC,iBAAiB,QAAQ,UAAU;;AAE5C;AACA;AACA;AACA;AACA;AACA;;AAOA,OAAO,MAAMC,SAAS,GAAGC,IAAA;EAAA,IAAAC,UAAA,GAAAD,IAAA,CACvBE,KAAK;IAALA,KAAK,GAAAD,UAAA,cAAG,SAAS,GAAAA,UAAA;IACjBE,GAAG,GAAAH,IAAA,CAAHG,GAAG;EAAA,oBAEHZ,KAAA,CAAAa,aAAA,CAACP,KAAK;IACJQ,WAAW,EAAEP,iBAAkB;IAC/BQ,YAAY,EAAEb,eAAe,CAAC;MAAEc,WAAW,EAAE;IAAe,CAAC;EAAE,GAE9DJ,GAAG,gBAAGZ,KAAA,CAAAa,aAAA;IAAKD,GAAG,EAAEA,GAAI;IAACK,GAAG,EAAC;EAAE,CAAE,CAAC,gBAAGjB,KAAA,CAAAa,aAAA,CAACZ,gBAAgB;IAACiB,MAAM,EAAEP;EAAM,CAAE,CAC/D,CAAC;AAAA,CACT;;AAED;;AAEA;AACA,OAAO,MAAMQ,gBAAgB,GAC3BC,KAAoD,iBAEpDpB,KAAA,CAAAa,aAAA,CAACV,WAAW,EAAAkB,QAAA;EACVC,IAAI,eAAEtB,KAAA,CAAAa,aAAA,CAACT,UAAU,MAAE,CAAE;EACrBmB,KAAK,EAAC,kCAAkC;EACxCC,MAAM,EAAE,GAAI;EACZC,MAAM;AAAA,GACFL,KAAK,CACV,CACF;AAED,OAAO,MAAMM,aAAa,GAAGA,CAAA,kBAC3B1B,KAAA,CAAAa,aAAA,CAACP,KAAK;EAACQ,WAAW,EAAEP;AAAkB,gBACpCP,KAAA,CAAAa,aAAA,CAACR,cAAc;EAACsB,KAAK,EAAE;IAAEC,KAAK,EAAE,MAAM;IAAEJ,MAAM,EAAE;EAAO;AAAE,CAAE,CACtD,CACR","ignoreList":[]}
@@ -0,0 +1,28 @@
1
+ import React, { ReactElement } from "react";
2
+ import { UnfurlController } from "./unfurl";
3
+ /**
4
+ * LinkCard — a link preview as a LIFECYCLE, not two static layouts.
5
+ *
6
+ * Data climbs a progressive ladder (url → basic → full); the anatomy is
7
+ * CONSTANT at every tier, so each slot swaps a skeleton for real content in
8
+ * place and the card never reflows on upgrade. Four statuses layer on top:
9
+ * resolving — climbing the ladder, aspect + rows reserved by skeletons
10
+ * resolved — the full card
11
+ * stale — resolved, but past its cache window: shows `fetchedAt` and a
12
+ * re-unfurl affordance
13
+ * error — the unfurl failed: favicon + raw URL + retry, NO media
14
+ *
15
+ * Compact ↔ expanded is a user-switchable DISPLAY LEVEL on the same link
16
+ * entity (the data lives in the controller, so switching never refetches or
17
+ * loses it) — not two separate card types.
18
+ */
19
+ export type LinkDisplay = "compact" | "expanded";
20
+ export interface LinkCardProps {
21
+ unfurl: UnfurlController;
22
+ display?: LinkDisplay;
23
+ onToggleDisplay?: () => void;
24
+ }
25
+ export declare const LinkCard: ({ unfurl, display, onToggleDisplay, }: LinkCardProps) => ReactElement;
26
+ export declare const LinkSkeleton: () => ReactElement;
27
+ export declare const LinkPlaceholder: (props: React.ButtonHTMLAttributes<HTMLButtonElement>) => ReactElement;
28
+ //# sourceMappingURL=LinkCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkCard.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/stackedCard/content/LinkCard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAa5C,OAAO,EAAE,gBAAgB,EAAmB,MAAM,UAAU,CAAC;AAY7D;;;;;;;;;;;;;;;GAeG;AAEH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;AA+JjD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,eAAO,MAAM,QAAQ,GAAI,uCAItB,aAAa,KAAG,YAiKlB,CAAC;AAyBF,eAAO,MAAM,YAAY,QAAO,YA0B/B,CAAC;AAIF,eAAO,MAAM,eAAe,GAC1B,OAAO,KAAK,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,KACnD,YAEF,CAAC"}