feat(blocks): Notion-like block editor with keyboard navigation, block operations, and drag-and-drop#146
Conversation
- Introduced new block operations: addBlock, deleteBlock, and duplicateBlock for improved block management. - Updated BlockContainer and DraggableBlock components to support new operations with corresponding UI interactions. - Enhanced splitTokensIntoBlocks function to handle trailing newlines as empty blocks. - Updated Storybook documentation to reflect new functionality and UI changes for draggable blocks. - Improved test coverage for block operations and UI interactions in both React and Vue components.
- Changed package version links for '@markput/react', '@markput/vue', and '@markput/react' in pnpm-lock.yaml to reference the 'dist' directories instead of the root. - Added new package entries for 'packages/react/markput/dist' and 'packages/vue/markput/dist' with their respective dependencies. - Introduced a new test file for block operations, enhancing test coverage for add, delete, and duplicate block functionalities.
…ions - Removed redundant newline handling in addBlock function. - Added error handling for missing markup in createMarkFromOverlay function. - Updated filterSuggestions to use includes for better readability. - Refactored BlockContainer to integrate a new BlockMenu for block actions (duplicate, delete). - Enhanced DraggableBlock to support menu requests for block actions. - Improved Suggestions component to utilize refs for better performance during keyboard navigation. - Cleaned up various components by removing unused code and ensuring consistent formatting.
|
Deployment failed with the following error: Learn More: https://vercel.com/nowelys-projects?upgradeToPro=build-rate-limit |
- Modified version links for '@markput/react' and '@markput/vue' in pnpm-lock.yaml to point directly to the package directories instead of the 'dist' subdirectories. - Removed unnecessary package entries for 'packages/react/markput/dist' and 'packages/vue/markput/dist' to streamline the lock file. - Ensured consistency in package linking across the project.
|
Deployment failed with the following error: Learn More: https://vercel.com/nowelys-projects?upgradeToPro=build-rate-limit |
- Introduced new Storybook stories for the DraggableBlock component in both React and Vue, showcasing various use cases including basic draggable functionality, read-only mode, and plain text blocks. - Updated styles in DraggableBlock components to ensure consistent appearance across frameworks, including adjustments to background and user interaction properties. - Enhanced documentation to provide clear descriptions of draggable block features and interactions.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Added a new constant, BLOCK_SEPARATOR, to standardize the separator used between blocks, enhancing consistency across block operations. - Updated addBlock, deleteBlock, and duplicateBlock functions to utilize BLOCK_SEPARATOR instead of hardcoded newlines, improving maintainability. - Refactored tests and related components to accommodate the new block separator, ensuring all functionalities align with the updated structure. - Enhanced splitTokensIntoBlocks to handle double newlines as separate blocks, improving the handling of empty lines in text. - Updated documentation to reflect changes in block operations and their expected behaviors.
…er key - Added a new method, #handleEnter, to the KeyDownController to handle the Enter key event. - The method inserts a BLOCK_SEPARATOR at the current caret position when the Enter key is pressed, enhancing block management. - Updated the Store and shared types to include a block state, ensuring proper handling of block-related functionalities. - Adjusted MarkedInput components in both React and Vue to support the new block property. - Updated documentation to reflect changes in block operations and their expected behaviors.
- Updated the marginLeft property in DraggableBlock components for both React and Vue to ensure consistent behavior in read-only mode. - Modified drop indicator positioning to align with the read-only state, enhancing the user interface and interaction experience.
- Added a new constant, COMPLEX_MARKDOWN, to provide rich markdown content for Storybook examples. - Updated MarkdownDocument and ComplexMarkdown stories to utilize COMPLEX_MARKDOWN, improving the demonstration of markdown capabilities in the UI. - Removed hardcoded markdown strings from stories, enhancing maintainability and consistency across examples.
… and Vue - Introduced an 'Add below' option in the BlockMenu component for both React and Vue, allowing users to add new blocks directly from the menu. - Updated BlockContainer to handle the new onAdd prop, linking the menu action to the block addition functionality. - Adjusted styles in DraggableBlock components to maintain consistent UI across frameworks, including padding and width modifications. - Removed deprecated add button functionality from DraggableBlock to streamline the interface.
…t and Vue - Introduced DuplicateIcon and TrashIcon components for better visual representation of actions in the BlockMenu. - Updated styles for menu items to enhance UI consistency, including padding adjustments and transition effects. - Replaced text-based icons with SVGs for improved scalability and design consistency across both React and Vue implementations.
…for React and Vue - Updated SVG icon sizes and styles for Add, Duplicate, and Trash icons to ensure consistency across both React and Vue implementations. - Adjusted padding and color properties for menu items to enhance visual coherence and user experience. - Introduced a separator style to improve the layout of the BlockMenu, providing better separation between menu items.
…React and Vue - Added new CSS styles for icons, including Add, Duplicate, Trash, and Grip icons, to ensure consistent appearance across both frameworks. - Replaced inline SVGs in BlockMenu and DraggableBlock components with styled span elements for improved maintainability and styling coherence. - Updated relevant components to utilize the new icon styles, enhancing the overall user interface and experience.
…k components - Replaced template literals with the `cx` utility for className assignments in BlockMenu to enhance readability and maintainability. - Introduced a constant for the Grip icon in DraggableBlock to standardize icon class usage, improving code consistency across components.
- Updated ContentEditableController to support block mode, allowing for proper handling of DraggableBlock divs. - Refined KeyDownController's #handleEnter method to insert BLOCK_SEPARATOR at the correct position within blocks, improving user experience during text input. - Modified MarkedInput and related components to accept a new block configuration object, enabling features like always-visible drag handles for mobile devices. - Enhanced DraggableBlock and BlockContainer components to utilize the new block properties, ensuring consistent behavior across frameworks. - Added comprehensive tests for block interactions in Storybook, validating the new functionalities and ensuring robust performance.
…ue handling - Introduced getAlwaysShowHandle function to determine visibility of drag handles based on block properties. - Updated BlockContainer and BlockContainer.vue to utilize getAlwaysShowHandle for improved readability and maintainability. - Refactored KeyDownController and Store to streamline value application logic, enhancing block management across components. - Adjusted tests to ensure compatibility with the new functionality and maintain robust performance.
- Added a new utility function, getEditableInBlock, to simplify test interactions with editable blocks. - Updated tests to verify behavior when adding blocks below empty blocks, ensuring correct block count and content rendering. - Improved assertions to reflect expected outcomes when manipulating block structures in the editor.
- Updated test descriptions for clarity and consistency, aligning with best practices. - Consolidated test cases for rendering blocks in various components, ensuring accurate block count assertions. - Improved readability of test structure by organizing related tests under descriptive sections.
…enhance block operations - Added functionality in KeyDownController to delete an empty block when Backspace is pressed, improving user experience. - Updated BlockContainer to handle null checks for value and onChange, ensuring robust block operations. - Enhanced tests to verify the behavior of block deletion and focus management after adding new blocks, ensuring accurate block count and content rendering.
- Fix Caret.setIndex to use TreeWalker for accurate text node positioning, handling non-text firstChild and Infinity offset (fixes IndexSizeError) - Add Caret.getCaretRect, isCaretOnFirstLine/LastLine, setAtX for ArrowUp/Down cross-block navigation with x-position preservation - Add mergeBlocks() to blockOperations for Backspace/Delete block merging - Fix navigation/index.ts shiftFocusPrev/Next to correctly skip non-editable marks and cross block boundaries - Add #handleArrowUpDown in KeyDownController for cross-block Up/Down - Fix #handleEnter to use raw value offset (via getCaretRawPosInBlock) instead of visual caret offset, fixing Enter with marks present - Add Backspace merge: non-empty block at pos 0 merges with previous block - Add Delete merge: caret at end of non-last block merges with next block - Fix #handleDelete to skip mark/span logic in block mode (focus target is a block div, not a span/mark), preventing wrongful deleteMark calls on odd-indexed blocks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…k navigation - Updated splitTokensIntoBlocks to ensure three empty blocks are created for two separators, improving block structure handling. - Modified flushBlock logic to allow for empty block creation based on the canCreateEmpty flag, enhancing flexibility in block management. - Enhanced BlockContainer to return an EMPTY_BLOCK when no tokens are present, ensuring consistent rendering and user experience. - Added new tests for block keyboard navigation, verifying correct focus movement across blocks and merging behavior with Backspace/Delete.
- Implemented `handleBlockBeforeInput` to manage text insertions and deletions in block mode, ensuring proper state updates. - Updated `selectAllText` to allow native browser handling of Ctrl+A in block mode, preventing unintended selection across blocks. - Added tests to verify correct behavior for typing and deleting within blocks, addressing previous bugs related to raw value updates and selection management.
…itor - Refactored getCaretRawPosInBlock to streamline caret position calculation, ensuring accurate placement within text and mark tokens. - Enhanced handleBlockBeforeInput to correctly manage text insertions and deletions, addressing issues with caret behavior at mark boundaries. - Introduced focusAndSetCaret function to simplify caret management after input events. - Added tests for new input handling scenarios, verifying correct behavior for typing and pasting in blocks, particularly with mark tokens.
- Enhanced getDomRawPos to provide more accurate caret positioning at element boundaries, particularly when dealing with comment nodes. - Updated getDomRawPosInMark to correctly map cursor positions when marks end with block separators, ensuring proper placement of the caret. - Added a data-testid attribute to DraggableBlock for improved testing capabilities. - Introduced comprehensive tests for block rendering and interaction scenarios in the new Block.spec.ts file, validating the expected behavior across various use cases.
- Changed the data-testid attribute in DraggableBlock to use v-bind for better Vue integration. - Updated the MarkedInput documentation to reflect the correct line number and enhanced block prop definition, allowing for an object configuration to control drag handle visibility.
Nowely
pushed a commit
that referenced
this pull request
Mar 15, 2026
🤖 I have created a release *beep* *boop* --- ## [0.6.0](0.5.0...0.6.0) (2026-03-15) ### Features * **blocks:** add block merging via Backspace/Delete and TodoList story ([#148](#148)) ([0685033](0685033)) * **blocks:** Notion-like block editor with keyboard navigation, block operations, and drag-and-drop ([#146](#146)) ([4bd5534](4bd5534)) * **drag:** replace block mode with drag-and-drop row management ([#149](#149)) ([83034e8](83034e8)) * **storybook:** add withPlainValue decorator and enhance drag/text stories ([#151](#151)) ([1d76c1f](1d76c1f)) ### Refactoring * **storybook:** standardize stories with PlainValuePanel and StoryObj types across React and Vue ([#152](#152)) ([42d21f3](42d21f3)) ### Miscellaneous * upgrade to Vite 8, Vitest 4.1, and Astro 6 ([#150](#150)) ([693966d](693966d)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.
Summary
Introduces a experimental full block editing experience (Notion-style) for both React and Vue, enabled via the
blockprop onMarkedInput.Features
BLOCK_SEPARATOR(\n\n) as canonical delimiter between blocksgetAlwaysShowHandleutility for conditional handle visibilityFixes
#handleDelete(odd-indexed blocks no longer treated as marks)DraggableBlockTests