Skip to content

Block-based editing: selection, drag-and-drop, and actions menu - #13

Closed
jondkinney wants to merge 18 commits into
mainfrom
block-based-editing-focused
Closed

Block-based editing: selection, drag-and-drop, and actions menu#13
jondkinney wants to merge 18 commits into
mainfrom
block-based-editing-focused

Conversation

@jondkinney

Copy link
Copy Markdown
Member

Summary

Block-based editing extension for Lexxy, built on top of the standalone feature PRs (code blocks, H1, link dialog, highlights, mixed lists, slash commands, attachments).

Block selection

  • Click drag handle or Cmd+click to select blocks
  • Notion-style translucent highlight on selected blocks
  • Inline format shortcuts (Cmd+B/I/U) and Cmd+K suppression in block mode

Drag and drop

  • Depth-aware drops with visual drop indicators
  • Drag handle aligned with first line of text for all block types
  • Ghost width matches source block

Block actions menu

  • Cmd+/ to open block actions menu
  • Duplicate (Cmd+D), delete, turn-into submenu
  • Scroll anchoring, viewport clamping

Indent/outdent and movement

  • Tab/Shift+Tab indent/outdent for selected blocks
  • Keyboard block movement (Cmd+Shift+Arrow)
  • Max nesting depth (10)

Highlight color inheritance

  • Cascade to children on color, indent, move, drop
  • Bullet marker color sync
  • Enter on wrapped list items creates sibling with inherited color

Turn-into for wrapped blocks

  • Wraps content in-place when inside list items
  • Code block and table exit creates list item sibling when wrapped

Dependencies

This PR includes all standalone features (PRs #4-#10) merged together, plus the block editing extension on top. The standalone PRs should be reviewed and merged individually first.

Test plan

  • Click drag handle — block selected with highlight
  • Drag block to new position — drops correctly
  • Cmd+/ opens block actions menu
  • Cmd+D duplicates block
  • Tab indents selected block, Shift+Tab outdents
  • Cmd+Shift+Arrow moves block up/down
  • Highlight color cascades to children on indent/move/drop
  • Build passes, lint clean, browser tests pass

🤖 Generated with Claude Code

jondkinney and others added 18 commits March 27, 2026 13:52
- Clear highlight color on Enter: new paragraphs start with default styling
  unless parent list item is uniformly highlighted (parent retention)
- Bullet marker color sync: ListItemNode transform sets <li> element color
  from text content so ::before markers match via currentColor
- Highlight propagation: applying color to a parent list item cascades to
  all children in the structural wrapper
- Highlight inheritance: Tab-indenting under a highlighted parent inherits
  the parent's color
- Mark padding sync: data-pad-start/data-pad-end attributes on <mark>
  elements for word-boundary-aware padding
- CSS parsing helpers ($extractHighlightFromCSS, $mergeHighlightIntoCSS,
  $removeHighlightFromCSS) that handle var() values safely in Rollup builds
- All inheritance functions exported for reuse by other extensions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Switch Yarn to node-modules linker (.yarnrc.yml) for Prism compat
- Add inlineDynamicImports to Rollup for single-file bundle
- Add 28 new Prism language components for syntax highlighting
- Detect CommonMark <pre><code class="language-*"> format on paste
- Add triple-backtick code fence keyboard shortcut
- CSS for code blocks, syntax tokens, and blockquotes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New dispatchSetFormatHeadingXLarge command
- H1 icon added to toolbar
- Heading 1/2/3/4 in toolbar dropdown with pressed state tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Position link dialog near selected text using saved selection rect
- Auto-prepend https:// for bare domains
- Change input from type=url to type=text for looser validation
- Overlay-based selection highlight with pixel-perfect positioning
- Pin dropdown open via data-pinned to prevent toolbar auto-close
- Guard against missing input element in connectedCallback
- Update test selector for new input type

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Action buttons:
- Preview, download, edit, and collapse/expand buttons on attachment overlay
- Buttons appear on hover/selection with proper positioning

Card view:
- Collapsed card layout with icon, name, caption, and file size
- Toggle between preview and card via attachment--collapsed class

Toolbar:
- Download button and caption pass-through to preview

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Type / at start of line to open command palette
- Sections: "Basic blocks" (insert below) and "Turn into" (convert)
- Fuzzy search via fuzzysort dependency
- Markdown shortcuts: --- for HR, | and " for blockquote
- Viewport-aware positioning with flip-above and scroll anchoring
- Add browser globals to eslint config

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Allow individual list items to independently display as bullet or numbered
within the same list, matching Notion's mixed list behavior. The feature
is opt-in via the mixedLists configuration flag (default: true), and can
be disabled per-editor with mixed-lists="false".

Node model:
- EarlyEscapeListItemNode gains __listItemType property
- getEffectiveListType() resolves: explicit override → parent list type
- createDOM/updateDOM set data-list-item-type on <li> for CSS targeting

Per-item toggling:
- Command dispatcher toggles just the current item's type
- Toolbar pressed state reflects per-item effective type

Keyboard shortcuts:
- "- " or "* " in a numbered item toggles to bullet
- "1. " in a bullet item toggles to numbered

Wrapped blocks in list items:
- Turn-into wraps content in-place (headings, code, quotes)
- Code block and table exit creates sibling list item when wrapped

Configuration:
- mixedLists: true in default preset, opt-out with mixed-lists="false"
- FormatEscapeExtension gates features behind supportsMixedLists

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/elements/editor.js
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Block selection, drag-and-drop, block actions menu, indent/outdent,
keyboard movement, highlight color inheritance, and turn-into for
wrapped blocks.

This commit represents the delta between block-qa-deps (PRs 4-10
merged) and the full block-based-editing branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- KEY_SPACE_COMMAND instead of TextNode transform (perf)
- Null guard on link dropdown connectedCallback
- Only export collapsed="true" (not "false") in attachment exportDOM
- Scope toolbar test selectors to lexxy-toolbar
- .first() on strict-mode attachment locators
- ESLint browser globals
- .yarnrc.yml for node-modules linker

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove #findDeepestLastItem from block_drag_and_drop.js (unused)
- Remove #autoRevealSubmenuForFocused from block_actions_menu.js (unused)
- Remove duplicate $clearHighlightOnNewBlock from highlight_extension.js
- Remove unused imports: $isHeadingNode, COMMAND_PRIORITY_LOW, KEY_ENTER_COMMAND
- Convert arrow function assignments to declarations (func-style)
- Suppress intentional no-unused-vars and no-misleading-character-class

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jondkinney jondkinney closed this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant