feat(apollo-react): add formatting toolbar to sticky notes (2/3) [MST-7636]#429
Conversation
Current Stack
|
Dependency License Review
License distribution
Excluded packages
|
7b1fbea to
9b603ca
Compare
ca92f6e to
15037a1
Compare
Add FormattingToolbar component and integrate markdown formatting into the StickyNoteNode editor. - FormattingToolbar with bold, italic, strikethrough, bullet list, and numbered list buttons with ApTooltip - Keyboard shortcuts (Cmd+B, Cmd+I, Cmd+Shift+X) via useMarkdownShortcuts - Active format detection updates on cursor movement and selection - Enter key continues bullet and numbered lists with auto-increment - Updated StickyNoteNode layout to flex column for toolbar + textarea Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
9b603ca to
293d428
Compare
packages/apollo-react/src/canvas/components/StickyNoteNode/StickyNoteNode.tsx
Show resolved
Hide resolved
| onMouseDown={(e) => e.preventDefault()} | ||
| className="nodrag nowheel" | ||
| > | ||
| <ApTooltip content="Bold (⌘B)" placement="top" delay> |
There was a problem hiding this comment.
need plan for localization..
also the icons need to be platform specific, not all on ⌘
There was a problem hiding this comment.
some util..
/**
* Returns true if the current platform is macOS
*/
export const isMac = (): boolean => {
return typeof navigator !== 'undefined' && navigator.platform.includes('Mac');
};
/**
* Returns the platform-specific modifier key symbol
* - Mac: ⌘ (Command)
* - Windows/Linux: Ctrl
*/
export const getModifierKey = (): string => {
return isMac() ? '⌘' : 'Ctrl';
};
There was a problem hiding this comment.
Thanks for the guidance here (added platform-specific logic).
I created an exploratory PR (link here) adding localization scaffolding to apollo-react canvas components in general as a potential follow-up task, since we don't have any atm.
A Lingui config change was needed to ensure compatibility w/ Storybook (changing compilation from cjs -> esm so it's more readily compatible w/ Vite).
These changes are quite invasive; while this doesn't break/affect the ApChat component (only Lingui consumer atm), I want to understand why we had Lingui configured to compile to cjs to make sure I'm not introducing any regressions (can probably sync w/ Cristi on this next week, since it's not urgent imo).
Summary
NOTE: this PR is focused on the UI that consumes the logic added in the bottom PR.
Adds an opinionated markdown editor UI for sticky notes.
It supports bold, italic, strikethrough, bullet lists, and numbered lists.
Interaction modes:
2026-03-30.17.37.18.mp4
Changes
***combined***markers in toolbar state-andN.prefixes from being wrappedFlow
flowchart TD A[User action: click toolbar / keyboard shortcut] --> B{Has selection?} B -->|No| C{Cursor inside formatted region?} C -->|Yes| D[Remove surrounding markers] C -->|No| E{On list line?} E -->|Yes| F[Wrap line content after prefix] E -->|No| G[Insert empty markers at cursor] B -->|Yes| H{Multi-line with list items?} H -->|Yes| I[Apply formatting per-line, protect prefixes] H -->|No| J[Wrap/unwrap selection] D --> K[Update activeFormats + set cursor via rAF] F --> K G --> K I --> K J --> KTesting
pnpm run testpasses (67 suites, 1344 tests)pnpm run typecheckpassespnpm run lintpasses