feat(apollo-wind): add PromptEditor component [MST-10659]#784
Merged
Conversation
There was a problem hiding this comment.
Pull request overview
Ports a Lexical-based PromptEditor into @uipath/apollo-wind as a reusable component, including token-pill rendering, $-triggered variable autocomplete, formatting toolbar, and a sanitized markdown preview mode.
Changes:
- Added
PromptEditorpublic exports (+ supporting types) and integrated Lexical-based editor with token nodes + plugins. - Implemented toolbar actions, token copy/paste serialization,
$-autocomplete menu, validation, and rename-on-options-change behavior. - Added markdown preview rendering via
marked+dompurify, plus Storybook + unit tests; updated dependencies/lockfile.
Reviewed changes
Copilot reviewed 35 out of 36 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Locks new Lexical + markdown preview dependencies and transitive graph. |
| packages/apollo-wind/package.json | Adds Lexical + marked + dompurify runtime deps for the new component. |
| packages/apollo-wind/src/index.ts | Exports PromptEditor + types from the package root. |
| packages/apollo-wind/src/components/ui/prompt-editor/index.ts | Local barrel export for PromptEditor and its public types. |
| packages/apollo-wind/src/components/ui/prompt-editor/types.ts | Defines token/types API and token color/label helpers. |
| packages/apollo-wind/src/components/ui/prompt-editor/prompt-editor.tsx | Main component wiring Lexical composer, plugins, toolbar, preview, and imperative ref API. |
| packages/apollo-wind/src/components/ui/prompt-editor/prompt-editor.test.tsx | Unit tests for rendering, toolbar/preview toggling, and malformed-prop tolerance. |
| packages/apollo-wind/src/components/ui/prompt-editor/prompt-editor.stories.tsx | Storybook coverage for common modes (toolbar, autocomplete, preview, controlled, etc.). |
| packages/apollo-wind/src/components/ui/prompt-editor/utils/index.ts | Barrel export for prompt-editor utilities. |
| packages/apollo-wind/src/components/ui/prompt-editor/utils/serialization.ts | Token ↔ Lexical state conversion + clipboard string serialization/parsing + selection token extraction. |
| packages/apollo-wind/src/components/ui/prompt-editor/utils/insert-token.ts | Inserts token nodes at cursor / selection. |
| packages/apollo-wind/src/components/ui/prompt-editor/utils/comparison.ts | Token-array deep equality helper. |
| packages/apollo-wind/src/components/ui/prompt-editor/utils/autocomplete-segments.ts | $ trigger helpers (type inference, regex, dismissed-trigger sentinel). |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/ValueSyncPlugin.tsx | Controlled-value sync into Lexical state with focus-aware selection preservation. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/ValidateTokensPlugin.tsx | Marks token pills invalid if not present in autocomplete option set. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/RenameTokensPlugin.tsx | Renames token values when option-path trees indicate a rename. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/AutocompletePlugin.tsx | Drives $ trigger detection and commits selected/free-form variables as token pills. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/CopyPastePlugin.tsx | Custom copy/cut/paste integrating token clipboard format and Lexical mime payload. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/EditorRefPlugin.tsx | Exposes Lexical editor instance to parent wiring. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/MultilinePlugin.tsx | Enforces single-line vs multiline behavior (enter suppression, newline stripping). |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/NodeSelectionFixPlugin.tsx | Keyboard/cursor management for inline DecoratorNode “pill” selection. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/ToolbarActionsPlugin.tsx | Implements formatting actions by inserting markdown markers/prefixes. |
| packages/apollo-wind/src/components/ui/prompt-editor/plugins/shared/token-nodes.ts | Shared traversal helpers for finding token nodes in editor state. |
| packages/apollo-wind/src/components/ui/prompt-editor/nodes/index.ts | Barrel export for the custom Lexical token nodes. |
| packages/apollo-wind/src/components/ui/prompt-editor/nodes/InputTokenNode.tsx | Input token DecoratorNode implementation. |
| packages/apollo-wind/src/components/ui/prompt-editor/nodes/OutputTokenNode.tsx | Output token DecoratorNode implementation. |
| packages/apollo-wind/src/components/ui/prompt-editor/nodes/StateTokenNode.tsx | State token DecoratorNode implementation. |
| packages/apollo-wind/src/components/ui/prompt-editor/nodes/ResourceTokenNode.tsx | Resource token DecoratorNode implementation. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/EditorToolbar.tsx | Toolbar UI (edit/preview toggle + formatting buttons). |
| packages/apollo-wind/src/components/ui/prompt-editor/components/PromptEditorAutocompleteMenu.tsx | Caret-anchored command menu for variable selection. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/MarkdownPreview.tsx | Markdown preview rendering + sanitization + token-pill HTML injection. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/markdown-preview.css | Styles for preview output and token pills in sanitized HTML. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/TokenPill.tsx | Visual pill rendering (icons, remove button, selected outline). |
| packages/apollo-wind/src/components/ui/prompt-editor/components/TokenPillWithTooltip.tsx | Adds tooltips + NodeSelection mouse handling to token pills. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/token-icon-markup.ts | Inline lucide SVG markup builder for preview-mode token icons. |
| packages/apollo-wind/src/components/ui/prompt-editor/components/token-icon-markup.test.ts | Tests for SVG markup builder output. |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
b5f8a7a to
9168e44
Compare
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
Dependency License Review
License distribution
Excluded packages
|
9168e44 to
7fc6691
Compare
7fc6691 to
10b1152
Compare
10b1152 to
645a2fb
Compare
645a2fb to
676ed08
Compare
676ed08 to
d64f988
Compare
d64f988 to
b30a8cb
Compare
e1dd32d to
b47504a
Compare
Port the Lexical-based PromptEditor from flow-workbench into apollo-wind as a reusable, prop-driven component (value / onChange / autoCompleteOptions). It renders inline token pills (input/output/state/resource), a formatting toolbar, a markdown preview mode, and a $-triggered variable autocomplete rebuilt on apollo-wind Command/Popover/Tooltip — decoupled from flow-workbench's variables, schema, i18n, and theme systems. Adds lexical, @lexical/react, @lexical/utils, @lexical/clipboard, marked and dompurify. Token/option props are normalized to arrays so malformed input can't crash the editor, and token colors map to apollo-wind design tokens. Exports PromptEditor and its public types from the package root, with unit tests and Storybook stories. Refs: MST-10659
- Honor `borderless` in preview mode: drop the editor's own border/background there too, so borderless behaves consistently between edit and preview. - Remove dead `data-invalid` style rule + allowed attribute in MarkdownPreview (preview no longer emits it). - Fix stale lucide version reference (0.555.0 -> 0.577.0) in token-icon-markup.
apollo-react pins lexical 0.16.0 (its ApRichTextEditor); apollo-wind's PromptEditor requires lexical 0.42.0 (React 19 support + 0.42-only APIs). The two design-system packages intentionally track different lexical majors, so ignore the lexical/@lexical/* family in the consistency check rather than force-aligning and breaking one of the editors.
…focus, preview styles, exports) - PromptEditorAutocompleteMenu: preventDefault on container pointerdown so focus can't leave the editor before commit (review M1) - Move markdown-preview styles from an inline <style> into the shared package stylesheet (tailwind.utilities.css) consumers already import - Remove unused PromptEditorHighlightLocator/Item types (review M2) - Export prompt-editor from the components/ui barrel - Document the no-$ token value convention and that preview is visual-only re: validity
…lity + scope dep exemption - Narrow the dependency-consistency exemption from the repo-wide lexical family to just @uipath/apollo-wind, so lexical drift elsewhere is still caught (review) - Add unit tests for clipboard token serialization round-trip, free-form path type inference + VARIABLE_PATH_REGEX, dismissed-trigger suppression, and token equality (the extraction-risky logic; Lexical interaction paths stay limited under jsdom)
Deployed apollo-design Storybook already themes the autodocs story background, so the borderless PromptEditor preview is readable without this override. Reverts preview-head.html to match main (review).
…mption Bumps apollo-react's lexical + @lexical/* from 0.16.0 to 0.42.0 to match apollo-wind, so the dependency-version-consistency check passes without any ignore workaround (review). Fixes the one resulting breakage: LexicalErrorBoundary is a named export in 0.42, not default. apollo-react editor typechecks clean and its 18 tests pass on 0.42.
Adds a native HTML5 drag-drop VariableDropPlugin + `mapVarDropToToken` prop: a consumer's drag source sets the variable path on dataTransfer (VARIABLE_DRAG_MIME, now exported), and the editor inserts a token at the drop point (falling back to the end of the content when the drop caret can't be resolved). Only the custom MIME is handled, so ordinary text drops aren't hijacked. Wired through PromptEditor → EditorInner, with a WithVariableDragDrop story and tests.
- Free-form $path commit now happens in the picker (an 'Insert <path>' item) so Enter commits it, instead of an editor handler the focused menu never received. - VARIABLE_PATH_REGEX accepts state/resource namespaces; inferTokenTypeFromPath falls back to the leading namespace (state.*→state, resource.*→resource) so free-form chips get the correct node type. - wrapSelectionWithMarkers normalizes selection.isBackward() so right-to-left selections wrap correctly. - RenameTokensPlugin groups renames by type once (O(1) per-node lookup).
…tylesheet Splits the .prompt-editor-preview rules out of the shared tailwind.utilities.css into a dedicated styles/prompt-editor.css, @imported from tailwind.consumer.css and shipped via rslib's copy step (kept in styles/ for the same-dir import to survive the flat dist copy; a per-component JS .css import doesn't resolve in the bundless build). Review feedback.
…ns the security floor The hardcoded >=3.4.9 pin drifted behind main's override (now >=3.4.11), breaking frozen-lockfile on the PR merge. Let the pnpm-workspace dompurify override own the security floor and regenerate the lockfile (importer specifier >=3.4.11).
d6145e3 to
0735f4e
Compare
…ete text-diff - setTokens() no longer calls onChange directly when the editor is mounted; OnChangePlugin emits once from the resulting state, avoiding a duplicate onChange / feedback loops in controlled usage. - AutocompletePlugin's update listener tracks last text in a closure, reading the document once per update instead of traversing both prev and current states on every keystroke.
…iew) - ValidateTokensPlugin: move the constant node-type→token-type map to module scope instead of rebuilding it per node on every validation pass. - serialization: declare WORD_JOINER as an explicit \u2060 escape rather than an invisible literal char.
CalinaCristian
approved these changes
Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Jira: MST-10659
Summary
Ports the Lexical-based PromptEditor from flow-workbench into
@uipath/apollo-windas a reusable, fully prop-driven component. It renders inline variable token pills (input / output / state / resource), a formatting toolbar, a markdown preview mode, and a$-triggered variable autocomplete.The port deliberately decouples the editor from flow-workbench-specific systems that don't exist in a design system:
Command/Popover/Tooltip), driven by theautoCompleteOptionsprop — no flowVariablePickeror schema services.react-i18next).VariableDropPlugin+mapVarDropToTokenprop (the consumer owns the drag source and sets the path ondataTransferunder the exportedVARIABLE_DRAG_MIME) — no dnd-kit dependency, unlike flow-workbench's version.Public API
PromptEditor+ types (PromptEditorProps,PromptEditorRef,PromptEditorToken,PromptEditorTokenType,PromptEditorAutoCompleteOption,PromptEditorMode) exported from the package root. Controlled (value/onChange) and uncontrolled (initialValue) usage,multiline,minRows/maxRows,placeholder,disabled,showToolbar,mode/onModeChange,borderless,fillHeight, and an imperativeeditorRef.Dependencies
apollo-wind:
lexical,@lexical/react,@lexical/utils,@lexical/clipboard(0.42.0),marked,dompurify.apollo-react: its existing
lexical+@lexical/*packages are bumped 0.16.0 → 0.42.0 to align with apollo-wind so the repo-wide dependency-version-consistency check passes without an exemption (the only resulting code change is theLexicalErrorBoundarynamed-import fix). No new audit findings.Robustness
Token/option props are normalized to arrays so malformed input (e.g. a Storybook "Set object"
{}) can't crash the editor or preview.maxRowscaps the visible height and scrolls (clamped so it isn't overridden whenmaxRows ≤ minRows).Testing
vitest: 19 unit tests for PromptEditor (rendering, toolbar, preview, mode toggle, autocomplete mount, malformed-input tolerance) — full apollo-wind suite passes (928 tests).biome format/lintclean,test:coveragepasses, fullpnpm build(all 8 packages) succeeds, frozen lockfile in sync.$-autocomplete, chip insertion, light/dark, height capping) verified end-to-end in a headless browser.