@tomnez/ashbe-inline-style-menu
v0.1.0-alpha.18
Published

Readme
ASHBE Inline Style Menu
A lightweight, inline style popup menu for contenteditable containers, designed to toggle common formatting tags on selected text. The menu provides a clean and semantic approach to text styling without relying on deprecated browser APIs.
Features
Semantic HTML: The menu provides clean, semantic HTML by using descriptive tags like
<strong>,<em>,<u>,<s>,<a>, and<code>to style selected text. No non-semantic or presentational elements are used, ensuring that the resulting content is accessible and meaningful.No Deprecated Browser APIs: Unlike some other text editors and libraries that rely on the deprecated
document.execCommandAPI, this menu avoids using outdated and unreliable browser features. It leverages pure JavaScript to toggle HTML tags directly, ensuring consistent behavior across browsers and a more stable experience for users.Cross-browser Compatibility: The menu has been tested to work consistently across modern browsers, providing a robust solution that doesn't depend on outdated functionality. Say goodbye to the inconsistencies often caused by legacy APIs.
How It Works
The menu allows users to toggle the following tag types on selected text within a contenteditable container:
<strong>for bold text<em>for italicized text<u>for underlined text<s>for strikethrough text<a>for adding links<code>for inline code snippets
Each tag is applied and removed with a single click, offering a smooth user experience similar to that of popular online editors like Medium and Notion.
Why This Menu?
Cleaner HTML: By using semantic HTML tags, this menu ensures the content is both human-readable and machine-readable. It's the right choice for accessibility, SEO, and maintaining a clean structure.
Avoids Document.execCommand: Many existing inline text editors rely on
document.execCommand, an API that has been deprecated by modern browsers. This menu's implementation bypasses the need for this outdated method, which is no longer guaranteed to function consistently across different browsers and could cause compatibility issues.Future-proof: With modern JavaScript and a focus on web standards, this menu avoids the pitfalls of deprecated technologies, making it a more reliable choice for current and future web applications.
Installation
npm i @tomnez/ashbe-inline-style-menuExample Usage
Import the AshbeInlineStyleMenu class and styles, then create a new instance with the (optional) options:
import AshbeInlineStyleMenu from '@tomnez/ashbe-inline-style-menu';
import '@tomnez/ashbe-inline-style-menu/styles';
const menuOptions = {
menuPosition: 'bottom',
menuLinkInputPosition: 'bottom',
appendToSelector: 'body',
contentBoundsSelector: '#my-editor-container'
preventOpenWhen: (selectionChangeEvent, range) => {
// Example: hide menu unless 5 or
// more characters are selected.
return range.toString().length < 5;
},
beforeToggle: (closestEditableContainer) => {
// Called before selected text is mutated.
},
afterToggle: (closestEditableContainer) => {
// Called after selected text is mutated.
}
};
const menu = new AshbeInlineStyleMenu(menuOptions);To destroy the menu (which removes event listeners and removes the template from the DOM), call destroy():
menu.destroy();Options API
The following options are available when creating a new menu instance. None are required, as they are all given default values if none are provided.
menuPosition
Determines the location of the menu, relative to the text selection.
Available positions are:
'top''bottom'(default)
menuLinkInputPosition
Determines the location of the URL input that gets toggled when clicking the "link" icon in the menu.
Available positions are:
'top''bottom'(default)'left''right'
appendToSelector
Selector used to determine where the menu container should be appended in the DOM.
Defaults to 'body'.
contentBoundsSelector
Selector to specify bounds that menu should stay within. If not specified, the menu will use the window and ensure that the popup menu doesn't go too far left or right outside the window bounds.
preventOpenWhen
A function that receives the selectionchange Event and the current Range. Return true to disable the menu from appearing.
Defaults to undefined.
beforeToggle
A function that will be called before the chosen styles or link are added/removed to the selected text. Called before any DOM updates are made and receives the selection's closest parent [contenteditable] node.
Defaults to undefined.
afterToggle
A function that will be called after the chosen styles or link are added/removed to the selected text. Called after the DOM is updated and receives the selection's closest parent [contenteditable] node.
Defaults to undefined.
Styles
For all IDs and class names used, see the menu-styles.css sheet. Target and override in your project if you'd like to make any tweaks.
Contributing
Currently this is a solo project, but bug reports and feature requests are more than welcome. This project is licensed under the MIT License, so feel free to fork and go to town 🤓
Development
npm i
npm run devVisit http://127.0.0.1:5173/ (or whatever URL Vite gives you from the dev command output, duh)
Unit Testing
npm run teste2e Testing
Run app in test mode first (set to run on port 3000 in test mode):
npm run cy:ci:startto run the tests headless:
npm run cy:runor to open Cypress and view the tests running in a browser:
npm run cy:openPublishing
npm run build
npm pack
npm publishLicense
This project is licensed under the MIT License - see the LICENSE file for details.
