Skip to content

feat(app): implement popover-based editor for inline and block math - #112

Open
Carter907 wants to merge 24 commits into
bluelearn-org:mainfrom
Carter907:feat/math-editor-popover
Open

feat(app): implement popover-based editor for inline and block math#112
Carter907 wants to merge 24 commits into
bluelearn-org:mainfrom
Carter907:feat/math-editor-popover

Conversation

@Carter907

@Carter907 Carter907 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Popover-Based Math Editing: reconfigured the math editing functionality so that the MathLive field shows up as a popover instead inside the component. This creates a separation between editing and previewing.
  • Virtual Keyboard Support: Keyboard functionality replaces the LaTeX menu as a method of inserting and working with math expressions for those who are unfamiliar. This replacement also leads to far fewer bugs, as event handling conflicts are greatly reduced.
  • Math Placeholders: Placeholders for empty math views were added so users know where where the nodes are. Previously, when you inserted an inline/block math field, it would become invisible as the styling is supposed to drop away when for better readability, however if there is no content, the field becomes indistinguishable from the background.
  • Mobile Support & Screen Testing: Currently, the editor has had minimal testing on other screen sizes, so this was another focus of this PR.

Type of change

  • Bug fix
  • Feature
  • Refactor (no behavior change)
  • Documentation
  • Build / tooling / CI
  • Other: _________

Verification

  • pnpm -r typecheck passes
  • pnpm -r build passes
  • Manually verified in a browser (for UI / behavior changes)
  • Followed the app layout conventions
  • No new dependencies, or new dependencies are justified and AGPL-compatible
  • Change does not violate any non-negotiable principle
  • Documentation only, no changes to the codebase, so no tests required

closes #111

@Carter907 Carter907 changed the title feature(app): implement popover-based editor for inline and block math feat(app): implement popover-based editor for inline and block math Jul 13, 2026
@andyrodrigues30 andyrodrigues30 added the area:frontend Tasks related to frontend (app) label Jul 13, 2026
@Carter907
Carter907 force-pushed the feat/math-editor-popover branch 2 times, most recently from a960977 to 5bfdaaf Compare July 14, 2026 03:28
@Carter907
Carter907 marked this pull request as ready for review July 14, 2026 03:39
@Carter907
Carter907 marked this pull request as draft July 15, 2026 02:11
@Carter907
Carter907 marked this pull request as ready for review July 15, 2026 15:28
@Carter907

Copy link
Copy Markdown
Contributor Author
firefox_rB2eat7j36 Here is an example of a block math field that is empty and displaying a placeholder and an inline math field that is showing the math-live element in a separate pop-over.

@andyrodrigues30 andyrodrigues30 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment and fix the following overflow styling issue:

Image

// When math-field loses focus, MathLive visually hides the menu but leaves its internal state open.
// Force a clean reset by programmatically clicking its Scrim background,
// but only if focus actually left the math-field (not just a temporary blur from clicking the menu toggle).
const menuToggle = el.shadowRoot.querySelector(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does the menu toggle do. When testing in the browser it doesn't seem to do anything.

@Carter907 Carter907 Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey this code is for patching up the LaTeX menu, but it's getting pretty ugly and I'm having trouble getting the feature working across browsers, so I just removed it from the math field and added the virtual keyboard instead. Let me know what you think.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has this been tested on mobile? Would it work differently?

@Carter907 Carter907 Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has been tested on different screen sizes and functions the same, but maybe the layout of the UI for the contribution pages needs to be adjusted so it's not so cramped:
image

Carter907 added 15 commits July 18, 2026 16:48
…s, and rendering fixes

Signed-off-by: Carter <speers.carter@gmail.com>
Signed-off-by: Carter <speers.carter@gmail.com>
Transition math node editing to a popover-based model to resolve focus
conflicts, math-field collapsing, and keyboard event bubbling issues
between MathLive and Lexical.

- Render static equation previews using KaTeX.
- Embed the active math-field editor within a Popover.
- Handle click/focus outside events carefully using isTargetMathLive to
  prevent popover dismissal when interacting with MathLive overlays.
- Synchronize popover open state with Lexical node selection and
  properly return focus to Lexical on close.
- Release static MathLive focus references on adapter unmount.
- Keep the math-field menu toggle button visible when open.

Signed-off-by: Carter <speers.carter@gmail.com>
…n logic

Signed-off-by: Carter <speers.carter@gmail.com>
Signed-off-by: Carter <speers.carter@gmail.com>
…stener

Signed-off-by: Carter <speers.carter@gmail.com>
This commit introduces two major bug fixes for the MathLive integration within Lexical:
1. Submenu Crash Fix: MathLive throws an unhandled exception if it receives a click on a submenu that is already open. Added a capture-phase interceptor in MathView to block these clicks before MathLive receives them.
2. Singleton Scrim Rescue: When Lexical unmounts the math-field (e.g., clicking outside), MathLive's singleton 'Scrim' gets orphaned. The next time a menu is opened, MathLive calls showPopover on a disconnected element, crashing the editor. A monkey patch for HTMLElement.prototype.showPopover now rescues this orphaned Scrim by locating the newly active math-field and appending it to its shadow DOM.

AGENTS.md was also updated to document these exact workarounds.
This commit introduces architectural improvements to the math plugin:
1. Lazy Loading: MathView is now dynamically imported via React.lazy() inside MathNode, ensuring katex and popover dependencies are code-split and only downloaded when a math block actually renders.
2. Lazy Loading Flicker Fix: Fixed a 1-frame visual loading flicker in MathFieldAdapter by using a global flag to skip asynchronous resolution once MathLive is downloaded.
3. Patch Extraction: Moved all ugly global DOM workarounds (showPopover monkey patch, capture-phase submenu interceptor) out of MathView.tsx and into a standalone MathLivePatches.ts file.
4. Blur Logic Fix: Wrapped the onChange callback in a ref to prevent effect teardowns from triggering el.blur() on every keystroke, which previously stole focus.
5. Value Hydration: Initialized lastEmittedValue to null so the math-field successfully hydrates its initial value on mount.
6. Clean Focus Out: Ensured MathLive resets its internal state completely when losing focus by programmatically clicking its Scrim.
This commit introduces architectural improvements to the math plugin:
1. Lazy Loading: MathView is now dynamically imported via React.lazy() inside MathNode, ensuring katex and popover dependencies are code-split and only downloaded when a math block actually renders.
2. Lazy Loading Flicker Fix: Fixed a 1-frame visual loading flicker in MathFieldAdapter by using a global flag to skip asynchronous resolution once MathLive is downloaded.
3. Patch Extraction: Moved all ugly global DOM workarounds (showPopover monkey patch, capture-phase submenu interceptor) out of MathView.tsx and into a standalone MathLivePatches.ts file.
4. Blur Logic Fix: Wrapped the onChange callback in a ref to prevent effect teardowns from triggering el.blur() on every keystroke, which previously stole focus.
5. Value Hydration: Initialized lastEmittedValue to null so the math-field successfully hydrates its initial value on mount.
6. Clean Focus Out: Ensured MathLive resets its internal state completely when losing focus by programmatically clicking its Scrim.
Replaced text placeholder with SVG icon to match block nodes. Added dashed border and refined conditional padding to reduce height layout shifts.

Signed-off-by: Carter <speers.carter@gmail.com>
Signed-off-by: Carter <speers.carter@gmail.com>
Decouples the MathView popover from automatic Lexical selection state, allowing users to drag-select across math blocks without forcefully taking focus. Opening the popover now requires an explicit click or Enter key press.

Signed-off-by: Carter <speers.carter@gmail.com>
Signed-off-by: Carter <speers.carter@gmail.com>
Signed-off-by: Carter <speers.carter@gmail.com>
Sets math-virtual-keyboard-policy to manual and ensures programmatic focus
on the math-field during the toggle button onClick event. This fixes an
issue on mobile devices where the keyboard would refuse to display because
the mathfield lacked a trusted user focus gesture.

Signed-off-by: Carter <speers.carter@gmail.com>
@Carter907
Carter907 force-pushed the feat/math-editor-popover branch from e6318a3 to ff1a2eb Compare July 18, 2026 20:48
Changes the fixed height (h-) to a minimum height (min-h-) on the main
inner container of the contribute flow. This ensures the background and
layout fully encapsulate the content when it overflows vertically.

Signed-off-by: Carter <speers.carter@gmail.com>
@Carter907
Carter907 force-pushed the feat/math-editor-popover branch from 2fe415c to b263652 Compare July 18, 2026 21:38
@andyrodrigues30

Copy link
Copy Markdown
Collaborator

@tonylam0 - I have reviewed but would like you to have a look too

@Carter907

Carter907 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

This branch still has some bugs which were addressed in #187

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:frontend Tasks related to frontend (app)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Popover-based Editor for Inline and Block Math

2 participants