@pilotiq/pilotiq 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +8 -0
- package/dist/react/AppShell.d.ts +1 -1
- package/dist/react/AppShell.d.ts.map +1 -1
- package/dist/react/AppShell.js +7 -1
- package/dist/react/AppShell.js.map +1 -1
- package/dist/react/CollabTextRendererRegistry.d.ts +75 -0
- package/dist/react/CollabTextRendererRegistry.d.ts.map +1 -0
- package/dist/react/CollabTextRendererRegistry.js +18 -0
- package/dist/react/CollabTextRendererRegistry.js.map +1 -0
- package/dist/react/CurrentUserContext.d.ts +39 -0
- package/dist/react/CurrentUserContext.d.ts.map +1 -0
- package/dist/react/CurrentUserContext.js +27 -0
- package/dist/react/CurrentUserContext.js.map +1 -0
- package/dist/react/FormCollabBindingRegistry.d.ts +31 -17
- package/dist/react/FormCollabBindingRegistry.d.ts.map +1 -1
- package/dist/react/FormCollabBindingRegistry.js.map +1 -1
- package/dist/react/fields/MarkdownInput.d.ts.map +1 -1
- package/dist/react/fields/MarkdownInput.js +60 -1
- package/dist/react/fields/MarkdownInput.js.map +1 -1
- package/dist/react/fields/TextLikeInput.d.ts.map +1 -1
- package/dist/react/fields/TextLikeInput.js +83 -6
- package/dist/react/fields/TextLikeInput.js.map +1 -1
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +2 -0
- package/dist/react/index.js.map +1 -1
- package/package.json +5 -5
- package/src/react/AppShell.tsx +11 -1
- package/src/react/CollabTextRendererRegistry.ts +84 -0
- package/src/react/CurrentUserContext.tsx +50 -0
- package/src/react/FormCollabBindingRegistry.ts +31 -17
- package/src/react/fields/MarkdownInput.tsx +118 -1
- package/src/react/fields/TextLikeInput.tsx +129 -5
- package/src/react/index.ts +12 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
3
|
import { useFieldState } from '../FormStateContext.js';
|
|
4
|
+
import { useCollabRoom } from '../CollabRoomContext.js';
|
|
5
|
+
import { getCollabTextRenderer } from '../CollabTextRendererRegistry.js';
|
|
4
6
|
import { Input } from '../ui/input.js';
|
|
5
7
|
import { Textarea } from '../ui/textarea.js';
|
|
6
8
|
import { computeDelta, preserveCursor } from './textDelta.js';
|
|
@@ -23,6 +25,8 @@ import { computeDelta, preserveCursor } from './textDelta.js';
|
|
|
23
25
|
*/
|
|
24
26
|
export function TextLikeInput({ el, name, common, type, extraProps, multiline, applyMask, }) {
|
|
25
27
|
const fs = useFieldState(name);
|
|
28
|
+
const room = useCollabRoom();
|
|
29
|
+
const collabRenderer = getCollabTextRenderer();
|
|
26
30
|
const liveCfg = el['live'];
|
|
27
31
|
const liveOpts = (typeof liveCfg === 'object' && liveCfg !== null
|
|
28
32
|
? liveCfg
|
|
@@ -36,6 +40,23 @@ export function TextLikeInput({ el, name, common, type, extraProps, multiline, a
|
|
|
36
40
|
// `useCallback`-wrapped fn that's *always* defined (identity when no
|
|
37
41
|
// mask), so its truthiness can't gate the branch.
|
|
38
42
|
const hasMask = typeof el['mask'] === 'string';
|
|
43
|
+
// Phase B — Tiptap-backed plain-text editor for collab text fields.
|
|
44
|
+
// When a `<RecordCollabRoom>` is mounted up-tree AND `@pilotiq/tiptap`'s
|
|
45
|
+
// `registerTiptap()` registered a collab text renderer, take the new path:
|
|
46
|
+
// the editor anchors selections to Yjs `RelativePosition` (via y-prosemirror)
|
|
47
|
+
// instead of integer string offsets, fixing the cursor-jump + two-peer
|
|
48
|
+
// concurrent-insert races that the legacy `Y.Text` + `computeDelta` path
|
|
49
|
+
// can't resolve. Dotted-path row leaves (Repeater / Builder) stay on the
|
|
50
|
+
// legacy `fs.textBinding` path — per-row collab editor support is a
|
|
51
|
+
// separate follow-up.
|
|
52
|
+
const fieldCollab = el['collab'];
|
|
53
|
+
if (room &&
|
|
54
|
+
collabRenderer &&
|
|
55
|
+
fieldCollab !== false &&
|
|
56
|
+
!hasMask &&
|
|
57
|
+
!name.includes('.')) {
|
|
58
|
+
return (_jsx(CollabTextField, { Renderer: collabRenderer, name: name, multiline: multiline, defaultValue: stringValue(common['defaultValue']), ...(common['placeholder'] !== undefined ? { placeholder: String(common['placeholder']) } : {}), disabled: Boolean(common['disabled']), triggerLive: fs.triggerLive, setValue: fs.setValue, controlled: fs.controlled, onBlurMode: onBlurMode }));
|
|
59
|
+
}
|
|
39
60
|
if (fs.textBinding && !hasMask) {
|
|
40
61
|
return (_jsx(BoundTextInput, { binding: fs.textBinding, name: name, triggerLive: fs.triggerLive, onBlurMode: onBlurMode, common: common, extraProps: extraProps, type: type, multiline: multiline }));
|
|
41
62
|
}
|
|
@@ -183,13 +204,18 @@ function BoundTextInput({ binding, name, triggerLive, onBlurMode, common, extraP
|
|
|
183
204
|
const delta = computeDelta(before, after);
|
|
184
205
|
if (!delta)
|
|
185
206
|
return;
|
|
207
|
+
// Pre-stamp `valueRef.current = after` BEFORE `applyDelta`. Y.Text's
|
|
208
|
+
// observe fires synchronously inside `applyDelta` for our own write,
|
|
209
|
+
// so without this the observer would see `prev=before, next=after`
|
|
210
|
+
// and run `preserveCursor` — which is designed for *remote* edits
|
|
211
|
+
// and clobbers the user's caret on local typing (typed '1' at pos 0
|
|
212
|
+
// would jump cursor forward by delta-length and the next keystroke
|
|
213
|
+
// would insert at the wrong index, producing scrambled output).
|
|
214
|
+
// With `valueRef` already at `after`, the observer's `next === prev`
|
|
215
|
+
// short-circuit fires and the cursor is left alone for local echoes.
|
|
216
|
+
valueRef.current = after;
|
|
186
217
|
binding.applyDelta(delta);
|
|
187
|
-
// Eager local + form-map update so the controlled input doesn't
|
|
188
|
-
// wait on the observer echo to render the new keystroke. Observer
|
|
189
|
-
// will fire with the same string and short-circuit via the equality
|
|
190
|
-
// check above.
|
|
191
218
|
setValueLocal(after);
|
|
192
|
-
valueRef.current = after;
|
|
193
219
|
mirrorRef.current(after);
|
|
194
220
|
if (!onBlurMode)
|
|
195
221
|
triggerLive(after);
|
|
@@ -229,6 +255,57 @@ function BoundTextInput({ binding, name, triggerLive, onBlurMode, common, extraP
|
|
|
229
255
|
return _jsx(Textarea, { ...props });
|
|
230
256
|
return _jsx(Input, { ...props, type: type });
|
|
231
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Phase B — wrapper around the registered Tiptap-backed collab editor.
|
|
260
|
+
* Owns the local text mirror so the hidden `<input>` always carries the
|
|
261
|
+
* editor's current value for FormData submission. When `FormStateProvider`
|
|
262
|
+
* is mounted up-tree, also mirrors every update into the values map via
|
|
263
|
+
* `fs.setValue` so `$get/$set` computations and any Y.Map LWW path (kept
|
|
264
|
+
* for non-text consumers) stay in sync.
|
|
265
|
+
*
|
|
266
|
+
* No IME / cursor-preservation gymnastics in here — the underlying Tiptap
|
|
267
|
+
* editor handles composition natively and y-prosemirror anchors selections
|
|
268
|
+
* to `Yjs.RelativePosition`, so the cursor survives concurrent + mid-word
|
|
269
|
+
* remote edits without any client-side bookkeeping.
|
|
270
|
+
*/
|
|
271
|
+
function CollabTextField({ Renderer, name, multiline, defaultValue, placeholder, disabled, triggerLive, setValue, controlled, onBlurMode, }) {
|
|
272
|
+
const [text, setText] = useState(defaultValue);
|
|
273
|
+
const textRef = useRef(text);
|
|
274
|
+
useEffect(() => { textRef.current = text; }, [text]);
|
|
275
|
+
const handleChange = useCallback((next) => {
|
|
276
|
+
setText(next);
|
|
277
|
+
if (controlled)
|
|
278
|
+
setValue(next);
|
|
279
|
+
if (!onBlurMode)
|
|
280
|
+
triggerLive(next);
|
|
281
|
+
}, [controlled, onBlurMode, setValue, triggerLive]);
|
|
282
|
+
const handleBlur = useCallback(() => {
|
|
283
|
+
if (onBlurMode)
|
|
284
|
+
triggerLive(textRef.current);
|
|
285
|
+
}, [onBlurMode, triggerLive]);
|
|
286
|
+
// Match the visual chrome of `<Input>` / `<Textarea>` so the editor reads
|
|
287
|
+
// as a drop-in replacement. The adapter forwards this class to its
|
|
288
|
+
// contenteditable wrapper; `whitespace-nowrap` on the single-line variant
|
|
289
|
+
// keeps the editor from wrapping into a second line if a stray paragraph
|
|
290
|
+
// split somehow makes it through.
|
|
291
|
+
//
|
|
292
|
+
// `overflow-x-clip` (not `auto`) on the single-line variant matters for
|
|
293
|
+
// `CollaborationCaret` presence labels: per the CSS overflow spec, setting
|
|
294
|
+
// either axis to a non-visible / non-clip value (`auto` / `scroll` /
|
|
295
|
+
// `hidden`) forces the other axis to compute as `auto` too — so
|
|
296
|
+
// `overflow-x-auto` would clip the caret's user-name label, which renders
|
|
297
|
+
// `-1.4em` above the line. `clip` is the one non-visible value that does
|
|
298
|
+
// NOT force the other axis, so `overflow-y` stays `visible` and the label
|
|
299
|
+
// escapes the chrome upward as designed. Trade-off: long text gets clipped
|
|
300
|
+
// on the right rather than horizontally scrollable (native `<input>`
|
|
301
|
+
// semantics) — acceptable for plain-text fields, where typing past the
|
|
302
|
+
// visible width is rare and the caret presence label is the higher-value
|
|
303
|
+
// affordance.
|
|
304
|
+
const className = multiline
|
|
305
|
+
? 'flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm whitespace-pre-wrap break-words'
|
|
306
|
+
: 'flex h-9 w-full items-center rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm whitespace-nowrap overflow-x-clip';
|
|
307
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { type: "hidden", name: name, value: text }), _jsx(Renderer, { name: name, multiline: multiline, defaultValue: defaultValue, ...(placeholder !== undefined ? { placeholder } : {}), disabled: disabled, onChange: handleChange, onBlur: handleBlur, className: className })] }));
|
|
308
|
+
}
|
|
232
309
|
function identity(v) { return v; }
|
|
233
310
|
function stringValue(v) {
|
|
234
311
|
if (v === undefined || v === null)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextLikeInput.js","sourceRoot":"","sources":["../../../src/react/fields/TextLikeInput.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAGhF,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE7D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAYzD;IACC,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,CAAA;IAC1B,MAAM,QAAQ,GAAG,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAC/D,CAAC,CAAC,OAAkD;QACpD,CAAC,CAAC,EAAE,CAAC,CAAA;IACP,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAA;IAC3C,MAAM,IAAI,GAAG,SAAS,IAAI,QAAQ,CAAA;IAElC,uEAAuE;IACvE,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,qEAAqE;IACrE,kDAAkD;IAClD,MAAM,OAAO,GAAG,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"TextLikeInput.js","sourceRoot":"","sources":["../../../src/react/fields/TextLikeInput.tsx"],"names":[],"mappings":"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"}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { PendingSuggestionsContext, usePendingSuggestions, usePendingSuggestions
|
|
|
8
8
|
export { registerPendingSuggestionApplier, getPendingSuggestionApplier, type PendingSuggestionApplier, } from './PendingSuggestionApplierRegistry.js';
|
|
9
9
|
export { CollabRoomContext, useCollabRoom, type CollabRoom, } from './CollabRoomContext.js';
|
|
10
10
|
export { registerCollabExtensions, getCollabExtensions, type CollabExtensionFactory, type CollabExtensionFactoryArgs, } from './CollabExtensionFactoryRegistry.js';
|
|
11
|
+
export { registerCollabTextRenderer, getCollabTextRenderer, type CollabTextRenderer, type CollabTextRendererProps, } from './CollabTextRendererRegistry.js';
|
|
11
12
|
export { registerFormCollabBinding, getFormCollabBinding, type FormCollabBinding, type FormCollabBindingFactory, type FormCollabBindingFactoryArgs, type TextBinding, type TextDelta, type RowsEvent, type RowBindingApi, } from './FormCollabBindingRegistry.js';
|
|
12
13
|
export { registerFieldPresenceComponent, getFieldPresenceComponent, type FieldPresenceProps, } from './FieldPresenceRegistry.js';
|
|
13
14
|
export { registerFieldFocusReporter, getFieldFocusReporter, type FieldFocusReporter, type FieldFocusEvent, } from './FieldFocusReporterRegistry.js';
|
|
@@ -26,6 +27,7 @@ export { RightSidebar, type RightSidebarProps, } from './RightSidebar.js';
|
|
|
26
27
|
export { RightSidebarTrigger } from './RightSidebarTrigger.js';
|
|
27
28
|
export { SearchTrigger } from './SearchTrigger.js';
|
|
28
29
|
export { useResizableWidth, clampPanelWidth, type UseResizableWidthOptions, type UseResizableWidthApi, } from './useResizableWidth.js';
|
|
30
|
+
export { CurrentUserProvider, useCurrentUser, type CurrentUser, } from './CurrentUserContext.js';
|
|
29
31
|
export { ThemeProvider, useTheme } from './ThemeProvider.js';
|
|
30
32
|
export { ThemeToggle } from './ThemeToggle.js';
|
|
31
33
|
export { ThemeSettingsPage } from './ThemeSettingsPage.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
|
package/dist/react/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { PendingSuggestionsContext, usePendingSuggestions, usePendingSuggestions
|
|
|
8
8
|
export { registerPendingSuggestionApplier, getPendingSuggestionApplier, } from './PendingSuggestionApplierRegistry.js';
|
|
9
9
|
export { CollabRoomContext, useCollabRoom, } from './CollabRoomContext.js';
|
|
10
10
|
export { registerCollabExtensions, getCollabExtensions, } from './CollabExtensionFactoryRegistry.js';
|
|
11
|
+
export { registerCollabTextRenderer, getCollabTextRenderer, } from './CollabTextRendererRegistry.js';
|
|
11
12
|
export { registerFormCollabBinding, getFormCollabBinding, } from './FormCollabBindingRegistry.js';
|
|
12
13
|
export { registerFieldPresenceComponent, getFieldPresenceComponent, } from './FieldPresenceRegistry.js';
|
|
13
14
|
export { registerFieldFocusReporter, getFieldFocusReporter, } from './FieldFocusReporterRegistry.js';
|
|
@@ -26,6 +27,7 @@ export { RightSidebar, } from './RightSidebar.js';
|
|
|
26
27
|
export { RightSidebarTrigger } from './RightSidebarTrigger.js';
|
|
27
28
|
export { SearchTrigger } from './SearchTrigger.js';
|
|
28
29
|
export { useResizableWidth, clampPanelWidth, } from './useResizableWidth.js';
|
|
30
|
+
export { CurrentUserProvider, useCurrentUser, } from './CurrentUserContext.js';
|
|
29
31
|
export { ThemeProvider, useTheme } from './ThemeProvider.js';
|
|
30
32
|
export { ThemeToggle } from './ThemeToggle.js';
|
|
31
33
|
export { ThemeSettingsPage } from './ThemeSettingsPage.js';
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,eAAe,CAAA;AAC5D,OAAO,EACL,yBAAyB,EACzB,oBAAoB,EACpB,UAAU,GAEX,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,cAAc,EAEd,UAAU,GAEX,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAA2B,MAAM,eAAe,CAAA;AAChG,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAA4B,MAAM,6BAA6B,CAAA;AACjH,OAAO,EACL,gCAAgC,EAChC,2BAA2B,GAE5B,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,yBAAyB,EACzB,qBAAqB,EACrB,6BAA6B,GAI9B,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,gCAAgC,EAChC,2BAA2B,GAE5B,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,iBAAiB,EACjB,aAAa,GAEd,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,wBAAwB,EACxB,mBAAmB,GAGpB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EACL,yBAAyB,EACzB,oBAAoB,GAQrB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EACL,8BAA8B,EAC9B,yBAAyB,GAE1B,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,GAGtB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EACL,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EACL,iBAAiB,GAElB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EACL,kBAAkB,EAClB,kBAAkB,GAInB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAElB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,YAAY,EACZ,aAAa,GAId,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AAE7D,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAmB,MAAM,eAAe,CAAA;AAE9E,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAExD,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,GAId,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,sBAAsB,GAEvB,MAAM,2BAA2B,CAAA;AAElC,OAAO,EACL,oBAAoB,EACpB,eAAe,EACf,uBAAuB,GAGxB,MAAM,0BAA0B,CAAA;AACjC,OAAO,EACL,YAAY,GAEb,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAY,oBAAoB,CAAA;AACxD,OAAO,EACL,iBAAiB,EACjB,eAAe,GAGhB,MAAM,wBAAwB,CAAA;AAE/B,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,SAAS,EAAE,MAAW,gBAAgB,CAAA;AAE/C,OAAO,EACL,eAAe,GAKhB,MAAM,sBAAsB,CAAA;AAG7B,iHAAiH;AACjH,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAElD,mBAAmB;AACnB,OAAO,EAAE,QAAQ,IAAI,UAAU,EAAyC,MAAM,eAAe,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pilotiq/pilotiq",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "View-based admin panel for RudderJS",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -81,10 +81,10 @@
|
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@base-ui/react": "^1",
|
|
84
|
-
"@rudderjs/contracts": "^1.
|
|
85
|
-
"@rudderjs/core": "^1.1.
|
|
86
|
-
"@rudderjs/router": "^1.
|
|
87
|
-
"@rudderjs/view": "^1.0
|
|
84
|
+
"@rudderjs/contracts": "^1.6.0",
|
|
85
|
+
"@rudderjs/core": "^1.1.4",
|
|
86
|
+
"@rudderjs/router": "^1.2.0",
|
|
87
|
+
"@rudderjs/view": "^1.1.0",
|
|
88
88
|
"@types/node": "^20",
|
|
89
89
|
"@types/react": "^19",
|
|
90
90
|
"@types/sanitize-html": "^2.16.1",
|
package/src/react/AppShell.tsx
CHANGED
|
@@ -16,6 +16,7 @@ import type { NavItem, UserMenuMeta, DatabaseNotificationsMeta, RightSidebarMeta
|
|
|
16
16
|
import type { RenderHookMap } from '../RenderHook.js'
|
|
17
17
|
import { RenderHookSlot } from './RenderHookSlot.js'
|
|
18
18
|
import type { ComponentSlotRegistry } from './component-slots.js'
|
|
19
|
+
import { CurrentUserProvider } from './CurrentUserContext.js'
|
|
19
20
|
|
|
20
21
|
export interface AppShellProps {
|
|
21
22
|
panel: {
|
|
@@ -180,7 +181,16 @@ export function AppShell({ layout = 'sidebar', notifications, componentRegistry,
|
|
|
180
181
|
props.basePath,
|
|
181
182
|
)
|
|
182
183
|
|
|
183
|
-
|
|
184
|
+
// `CurrentUserProvider` sits OUTSIDE the layout-provider chain so
|
|
185
|
+
// plugin-registered providers (e.g. `@pilotiq-pro/collab`'s
|
|
186
|
+
// CollabProvider, which threads the user into CollaborationCaret
|
|
187
|
+
// presence labels) can read the active user via `useCurrentUser()`.
|
|
188
|
+
// Value source mirrors what the top-right user dropdown renders.
|
|
189
|
+
return (
|
|
190
|
+
<CurrentUserProvider value={props.panel.userMenu?.user ?? null}>
|
|
191
|
+
{wrapped}
|
|
192
|
+
</CurrentUserProvider>
|
|
193
|
+
)
|
|
184
194
|
}
|
|
185
195
|
|
|
186
196
|
/**
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { ComponentType } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Module-level registry slot for the collab-aware plain-text editor renderer.
|
|
5
|
+
*
|
|
6
|
+
* Wiring posture (mirrors `CollabExtensionFactoryRegistry` /
|
|
7
|
+
* `FormCollabBindingRegistry`):
|
|
8
|
+
* - `@pilotiq/tiptap`'s `registerTiptap(...)` calls `registerCollabTextRenderer(...)`
|
|
9
|
+
* once at boot. The registered component closes over `@tiptap/*` imports so
|
|
10
|
+
* pilotiq core stays free of any tiptap peer dep — same posture as the
|
|
11
|
+
* existing rich-text renderer registry.
|
|
12
|
+
* - `TextLikeInput` checks for the registered component when a `<RecordCollabRoom>`
|
|
13
|
+
* is mounted up-tree AND the field hasn't opted out via `.collab(false)` AND
|
|
14
|
+
* the field has no `.mask()`. If present, the legacy `BoundTextInput`
|
|
15
|
+
* (Y.Text + `computeDelta` + heuristic `preserveCursor`) is bypassed in
|
|
16
|
+
* favour of a y-prosemirror-backed Tiptap editor that anchors selections to
|
|
17
|
+
* `Yjs.RelativePosition` — the architectural fix for the cursor-jump and
|
|
18
|
+
* two-peer concurrent-insert races documented in
|
|
19
|
+
* `docs/plans/text-fields-tiptap-backed-collab.md`.
|
|
20
|
+
*
|
|
21
|
+
* Wire props are deliberately framework-agnostic — the renderer doesn't take a
|
|
22
|
+
* `binding` since it consumes the room's `ydoc` directly via the existing
|
|
23
|
+
* `useCollabRoom()` + `getCollabExtensions()` plumbing on its own side. Core
|
|
24
|
+
* keeps the seam narrow: handler callbacks + DOM chrome only.
|
|
25
|
+
*/
|
|
26
|
+
export interface CollabTextRendererProps {
|
|
27
|
+
/** Field name — drives the `Y.XmlFragment` selector inside the collab adapter. */
|
|
28
|
+
name: string
|
|
29
|
+
/** `true` for textarea-like (multiple paragraphs); `false` for input-like. */
|
|
30
|
+
multiline: boolean
|
|
31
|
+
/**
|
|
32
|
+
* Server-rendered default value. The renderer is expected to seed the
|
|
33
|
+
* `Y.XmlFragment` from this on first connect when the room has no
|
|
34
|
+
* persisted state for this field (i.e. brand-new record).
|
|
35
|
+
*/
|
|
36
|
+
defaultValue: string
|
|
37
|
+
/** Optional placeholder hint. */
|
|
38
|
+
placeholder?: string
|
|
39
|
+
/** Disabled / read-only state. */
|
|
40
|
+
disabled?: boolean
|
|
41
|
+
/** Fired on every editor `update` with the editor's current plain text. */
|
|
42
|
+
onChange: (text: string) => void
|
|
43
|
+
/** Fired on editor blur — host wires this to live-onBlur trigger semantics. */
|
|
44
|
+
onBlur: () => void
|
|
45
|
+
/**
|
|
46
|
+
* Single-line submit — fired when `multiline: false` AND the user presses
|
|
47
|
+
* Enter. The renderer is expected to blur the editor after invoking this.
|
|
48
|
+
* Multiline mode ignores it (Enter inserts a paragraph instead).
|
|
49
|
+
*/
|
|
50
|
+
onSubmit?: () => void
|
|
51
|
+
/**
|
|
52
|
+
* Tailwind className applied to the editor's contenteditable wrapper so the
|
|
53
|
+
* rendered editor matches the native `<input>` / `<textarea>` chrome it
|
|
54
|
+
* replaces. The host owns the styling — the adapter just forwards.
|
|
55
|
+
*/
|
|
56
|
+
className?: string
|
|
57
|
+
/**
|
|
58
|
+
* Additional DOM attributes for the editor's contenteditable wrapper —
|
|
59
|
+
* typically `id`, `aria-*`, `autocomplete`, etc.
|
|
60
|
+
*/
|
|
61
|
+
editorAttributes?: Record<string, string>
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type CollabTextRenderer = ComponentType<CollabTextRendererProps>
|
|
65
|
+
|
|
66
|
+
let _renderer: CollabTextRenderer | null = null
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Register the collab plain-text editor component. Called once at boot by
|
|
70
|
+
* `@pilotiq/tiptap`'s `registerTiptap()` (or directly by an app that imports
|
|
71
|
+
* the renderer). Calling with `null` clears the registry — useful for tests.
|
|
72
|
+
*
|
|
73
|
+
* No-op behaviour when no renderer is registered: `TextLikeInput` falls back
|
|
74
|
+
* to the legacy `BoundTextInput` path (or the plain controlled / uncontrolled
|
|
75
|
+
* input when no collab room is mounted).
|
|
76
|
+
*/
|
|
77
|
+
export function registerCollabTextRenderer(component: CollabTextRenderer | null): void {
|
|
78
|
+
_renderer = component
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Returns the registered component, or `null` when no adapter is installed. */
|
|
82
|
+
export function getCollabTextRenderer(): CollabTextRenderer | null {
|
|
83
|
+
return _renderer
|
|
84
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createContext, useContext, type ReactNode } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolved identity of the user driving the current page. Mirrors the
|
|
5
|
+
* `UserMenuMeta.user` shape that `panelInfo()` ships to the renderer —
|
|
6
|
+
* whichever fields the `Pilotiq.user(req => …)` resolver populated.
|
|
7
|
+
*
|
|
8
|
+
* `null` is the no-user state: either the panel never wired a resolver,
|
|
9
|
+
* or the resolver returned `null` for this request. Consumers should
|
|
10
|
+
* gracefully fall back (no avatar, no presence label, etc.) rather than
|
|
11
|
+
* treating absence as an error.
|
|
12
|
+
*/
|
|
13
|
+
export interface CurrentUser {
|
|
14
|
+
name?: string
|
|
15
|
+
email?: string
|
|
16
|
+
avatar?: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const CurrentUserContext = createContext<CurrentUser | null>(null)
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Mounted by `AppShell` around the layout-provider chain so plugins
|
|
23
|
+
* (collab user presence, audit-trail attribution, analytics
|
|
24
|
+
* client-side opt-outs, …) can read the active user via
|
|
25
|
+
* `useCurrentUser()` without prop-drilling through `panel`.
|
|
26
|
+
*
|
|
27
|
+
* Value source is `viewProps.panel.userMenu?.user` — the same shape the
|
|
28
|
+
* top-right dropdown renders. The provider sits OUTSIDE
|
|
29
|
+
* `layoutProviderRegistry` so plugin-registered layout providers can
|
|
30
|
+
* subscribe.
|
|
31
|
+
*/
|
|
32
|
+
export function CurrentUserProvider({
|
|
33
|
+
value,
|
|
34
|
+
children,
|
|
35
|
+
}: {
|
|
36
|
+
value: CurrentUser | null
|
|
37
|
+
children: ReactNode
|
|
38
|
+
}): ReactNode {
|
|
39
|
+
return <CurrentUserContext.Provider value={value}>{children}</CurrentUserContext.Provider>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Read the active user inside any descendant of `<AppShell>`. Returns
|
|
44
|
+
* `null` outside an `AppShell` mount (defensive — keeps storybook /
|
|
45
|
+
* isolated-render tests from throwing) and when no user resolved for
|
|
46
|
+
* the request.
|
|
47
|
+
*/
|
|
48
|
+
export function useCurrentUser(): CurrentUser | null {
|
|
49
|
+
return useContext(CurrentUserContext)
|
|
50
|
+
}
|
|
@@ -55,11 +55,18 @@ export interface TextBinding {
|
|
|
55
55
|
* - `subscribe(fn)` registers a listener that fires when REMOTE
|
|
56
56
|
* changes land; `fn(snapshot)` receives the full updated map.
|
|
57
57
|
* The provider re-applies this snapshot onto its React state.
|
|
58
|
-
* - `getTextBinding(name)` (Phase F.6)
|
|
59
|
-
* handle for
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
58
|
+
* - `getTextBinding(name)` (Phase F.6) was the per-field `Y.Text`
|
|
59
|
+
* handle for character-level CRDT on top-level text inputs. After
|
|
60
|
+
* the Tiptap-backed text-collab swap (Phase D, 2026-05), bindings
|
|
61
|
+
* are expected to return `null` for every top-level field —
|
|
62
|
+
* character-level CRDT now lives in the Tiptap renderer's
|
|
63
|
+
* `Collaboration` extension (`Y.XmlFragment` per field). Returning
|
|
64
|
+
* a non-null `TextBinding` here is still supported for legacy
|
|
65
|
+
* bindings, but the active `@pilotiq-pro/collab` impl no longer
|
|
66
|
+
* allocates `Y.Text` for top-level fields. Row-text leaves under
|
|
67
|
+
* Repeater / Builder continue to route through Y.Text via
|
|
68
|
+
* `getRowTextBinding` — the Tiptap-backed renderer only handles
|
|
69
|
+
* top-level (non-dotted-path) field names today.
|
|
63
70
|
* - `destroy()` is called on unmount — gives the plugin a chance to
|
|
64
71
|
* remove its CRDT observer. Implementations are expected to cascade
|
|
65
72
|
* into every `TextBinding` they issued.
|
|
@@ -74,11 +81,16 @@ export interface FormCollabBinding {
|
|
|
74
81
|
set(name: string, value: unknown): void
|
|
75
82
|
/** Subscribe to remote changes. Returns an unsubscribe function. */
|
|
76
83
|
subscribe(fn: (snapshot: Record<string, unknown>) => void): () => void
|
|
77
|
-
/** Phase F.6 — per-field text-CRDT handle.
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
84
|
+
/** Phase F.6 / Phase D — per-field text-CRDT handle. Post Phase D,
|
|
85
|
+
* `@pilotiq-pro/collab` returns `null` for every top-level text
|
|
86
|
+
* field (character-level CRDT moved into `@pilotiq/tiptap`'s
|
|
87
|
+
* `CollabTextRenderer`, which mounts its own `Y.XmlFragment` per
|
|
88
|
+
* field via the `Collaboration` extension). The method is preserved
|
|
89
|
+
* on the contract for legacy bindings and for the row-text leaves
|
|
90
|
+
* routed through `getRowTextBinding` (under Repeater / Builder).
|
|
91
|
+
* Optional so existing F1-era plugins keep type-checking without a
|
|
92
|
+
* no-op stub; absent reads as "binding has no top-level text CRDT
|
|
93
|
+
* surface," same as returning `null` for every field. */
|
|
82
94
|
getTextBinding?(name: string): TextBinding | null
|
|
83
95
|
/** Cleanup hook called when the form unmounts. */
|
|
84
96
|
destroy(): void
|
|
@@ -233,13 +245,15 @@ export interface FormCollabBindingFactoryArgs {
|
|
|
233
245
|
initial: Record<string, unknown>
|
|
234
246
|
/**
|
|
235
247
|
* Phase F.6 — initial form meta from the server. The binding walks
|
|
236
|
-
* this once at construction to
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
241
|
-
*
|
|
242
|
-
*
|
|
248
|
+
* this once at construction to index Repeater / Builder array names
|
|
249
|
+
* for row-level CRDT and to identify which row leaves are text-shaped
|
|
250
|
+
* (`fieldType ∈ { text, textarea, email, slug, markdown }` and not
|
|
251
|
+
* `.collab(false)`). Post Phase D, top-level text fields no longer
|
|
252
|
+
* need to be partitioned here — their character-level CRDT lives in
|
|
253
|
+
* the Tiptap renderer's `Y.XmlFragment`, not in a binding-allocated
|
|
254
|
+
* `Y.Text`. The meta is captured at mount; later structural changes
|
|
255
|
+
* from `live()` re-resolves aren't re-walked (rare in practice —
|
|
256
|
+
* dynamic field add/remove is an F-followup).
|
|
243
257
|
*/
|
|
244
258
|
formMeta: ElementMeta
|
|
245
259
|
}
|
|
@@ -6,6 +6,8 @@ import {
|
|
|
6
6
|
CodeIcon, PaperclipIcon, Loader2Icon,
|
|
7
7
|
} from 'lucide-react'
|
|
8
8
|
import { useFieldState } from '../FormStateContext.js'
|
|
9
|
+
import { useCollabRoom } from '../CollabRoomContext.js'
|
|
10
|
+
import { getCollabTextRenderer, type CollabTextRenderer } from '../CollabTextRendererRegistry.js'
|
|
9
11
|
import { useToast } from '../Toaster.js'
|
|
10
12
|
import { Button } from '../ui/button.js'
|
|
11
13
|
import { computeDelta, preserveCursor } from './textDelta.js'
|
|
@@ -46,6 +48,35 @@ export function MarkdownInput({
|
|
|
46
48
|
uploadUrl: string | undefined
|
|
47
49
|
}): React.ReactElement {
|
|
48
50
|
const fs = useFieldState(name)
|
|
51
|
+
const room = useCollabRoom()
|
|
52
|
+
const collabRenderer = getCollabTextRenderer()
|
|
53
|
+
|
|
54
|
+
// Phase B follow-up — Tiptap-backed plain-text editor for markdown source
|
|
55
|
+
// when collab is on. Same architectural fix as `TextLikeInput`'s
|
|
56
|
+
// CollabTextField: y-prosemirror's `RelativePosition` cursor anchoring
|
|
57
|
+
// replaces the broken `Y.Text` + `computeDelta` + `preserveCursor` heuristic.
|
|
58
|
+
//
|
|
59
|
+
// Tradeoff: the markdown toolbar + Cmd-shortcuts + paste-image upload all
|
|
60
|
+
// operate on a `<textarea>`'s DOM selection — they don't have a way to
|
|
61
|
+
// reach into the Tiptap editor's selection without exposing the editor
|
|
62
|
+
// instance, which would widen the renderer seam. For now those features
|
|
63
|
+
// are write-mode-only on the native path; collab users type markdown
|
|
64
|
+
// syntax directly (`**bold**`, `## heading`). The preview tab keeps
|
|
65
|
+
// working since it reads `value` from local state.
|
|
66
|
+
if (room && collabRenderer) {
|
|
67
|
+
return (
|
|
68
|
+
<MarkdownCollabInput
|
|
69
|
+
Renderer={collabRenderer}
|
|
70
|
+
name={name}
|
|
71
|
+
defaultValue={defaultValue}
|
|
72
|
+
disabled={disabled}
|
|
73
|
+
{...(placeholder !== undefined ? { placeholder } : {})}
|
|
74
|
+
{...(minHeight !== undefined ? { minHeight } : {})}
|
|
75
|
+
{...(maxHeight !== undefined ? { maxHeight } : {})}
|
|
76
|
+
/>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
49
80
|
const { notify } = useToast()
|
|
50
81
|
const textareaRef = useRef<HTMLTextAreaElement | null>(null)
|
|
51
82
|
// Phase F.6 — IME composition gate. Set between `compositionstart` /
|
|
@@ -124,9 +155,19 @@ export function MarkdownInput({
|
|
|
124
155
|
const before = binding.read()
|
|
125
156
|
if (next !== before) {
|
|
126
157
|
const delta = computeDelta(before, next)
|
|
158
|
+
// Pre-stamp `boundValueRef.current = next` BEFORE `applyDelta`.
|
|
159
|
+
// Y.Text's `observe` fires synchronously inside `applyDelta` for
|
|
160
|
+
// our own write; without this the observer would see
|
|
161
|
+
// `prev=before, next=after` and run `preserveCursor` — designed
|
|
162
|
+
// for *remote* edits — which clobbers the user's caret on local
|
|
163
|
+
// typing (scrambled output on mid-string inserts). With
|
|
164
|
+
// `boundValueRef` already at `next`, the observer's
|
|
165
|
+
// `next === prev` short-circuit fires and the cursor is left
|
|
166
|
+
// alone for local echoes. Mirror of the same fix in
|
|
167
|
+
// `BoundTextInput.commitDelta`.
|
|
168
|
+
boundValueRef.current = next
|
|
127
169
|
if (delta) binding.applyDelta(delta)
|
|
128
170
|
setBoundValue(next)
|
|
129
|
-
boundValueRef.current = next
|
|
130
171
|
}
|
|
131
172
|
fs.setValue(next)
|
|
132
173
|
fs.triggerLive(next)
|
|
@@ -422,6 +463,82 @@ function TabButton({ active, onClick, children }: {
|
|
|
422
463
|
)
|
|
423
464
|
}
|
|
424
465
|
|
|
466
|
+
/**
|
|
467
|
+
* Phase B follow-up — collab-aware markdown editor. Mounts the registered
|
|
468
|
+
* Tiptap-backed plain-text renderer for the Write pane and reuses the
|
|
469
|
+
* existing `marked` pipeline for Preview. No toolbar, no Cmd-shortcuts, no
|
|
470
|
+
* paste-image upload — those features depend on textarea-DOM splicing that
|
|
471
|
+
* doesn't translate to Tiptap's selection model. The cursor-bug fix is the
|
|
472
|
+
* load-bearing change; markdown-syntax authors keep typing as before.
|
|
473
|
+
*/
|
|
474
|
+
function MarkdownCollabInput({
|
|
475
|
+
Renderer, name, defaultValue, disabled, placeholder, minHeight, maxHeight,
|
|
476
|
+
}: {
|
|
477
|
+
Renderer: CollabTextRenderer
|
|
478
|
+
name: string
|
|
479
|
+
defaultValue: unknown
|
|
480
|
+
disabled: boolean
|
|
481
|
+
placeholder?: string
|
|
482
|
+
minHeight?: string
|
|
483
|
+
maxHeight?: string
|
|
484
|
+
}): React.ReactElement {
|
|
485
|
+
const fs = useFieldState(name)
|
|
486
|
+
const initial = useMemo(() => stringValue(defaultValue), [])
|
|
487
|
+
const [text, setText] = useState<string>(initial)
|
|
488
|
+
const [tab, setTab] = useState<'write' | 'preview'>('write')
|
|
489
|
+
const textRef = useRef(text)
|
|
490
|
+
useEffect(() => { textRef.current = text }, [text])
|
|
491
|
+
|
|
492
|
+
const handleChange = (next: string): void => {
|
|
493
|
+
setText(next)
|
|
494
|
+
if (fs.controlled) fs.setValue(next)
|
|
495
|
+
fs.triggerLive(next)
|
|
496
|
+
}
|
|
497
|
+
const handleBlur = (): void => { /* fire-and-forget — live trigger already ran on change */ }
|
|
498
|
+
|
|
499
|
+
const previewHtml = useMemo(
|
|
500
|
+
() => tab === 'preview' ? marked.parse(text, { gfm: true, breaks: false, async: false }) as string : '',
|
|
501
|
+
[tab, text],
|
|
502
|
+
)
|
|
503
|
+
|
|
504
|
+
const wrapperStyle: React.CSSProperties = {}
|
|
505
|
+
if (minHeight) wrapperStyle.minHeight = minHeight
|
|
506
|
+
if (maxHeight) wrapperStyle.maxHeight = maxHeight
|
|
507
|
+
|
|
508
|
+
return (
|
|
509
|
+
<div className="flex flex-col rounded-md border bg-background">
|
|
510
|
+
<div className="flex items-center border-b px-2 py-1">
|
|
511
|
+
<TabButton active={tab === 'write'} onClick={() => setTab('write')}>Write</TabButton>
|
|
512
|
+
<TabButton active={tab === 'preview'} onClick={() => setTab('preview')}>Preview</TabButton>
|
|
513
|
+
</div>
|
|
514
|
+
{tab === 'write' ? (
|
|
515
|
+
<div style={wrapperStyle} className="overflow-auto">
|
|
516
|
+
<input type="hidden" name={name} value={text} />
|
|
517
|
+
<Renderer
|
|
518
|
+
name={name}
|
|
519
|
+
multiline={true}
|
|
520
|
+
defaultValue={initial}
|
|
521
|
+
{...(placeholder !== undefined ? { placeholder } : {})}
|
|
522
|
+
disabled={disabled}
|
|
523
|
+
onChange={handleChange}
|
|
524
|
+
onBlur={handleBlur}
|
|
525
|
+
className="w-full bg-transparent px-3 py-2 text-sm font-mono leading-relaxed outline-none disabled:opacity-50 whitespace-pre-wrap break-words"
|
|
526
|
+
/>
|
|
527
|
+
</div>
|
|
528
|
+
) : (
|
|
529
|
+
<>
|
|
530
|
+
<input type="hidden" name={name} value={text} readOnly />
|
|
531
|
+
<div
|
|
532
|
+
className="prose prose-sm dark:prose-invert max-w-none px-3 py-2"
|
|
533
|
+
style={wrapperStyle}
|
|
534
|
+
dangerouslySetInnerHTML={{ __html: previewHtml || '<p class="text-muted-foreground italic">Nothing to preview</p>' }}
|
|
535
|
+
/>
|
|
536
|
+
</>
|
|
537
|
+
)}
|
|
538
|
+
</div>
|
|
539
|
+
)
|
|
540
|
+
}
|
|
541
|
+
|
|
425
542
|
function stringValue(v: unknown): string {
|
|
426
543
|
if (v === undefined || v === null) return ''
|
|
427
544
|
if (typeof v === 'string') return v
|