
Security News
GitHub Actions Pricing Whiplash: Self-Hosted Actions Billing Change Postponed
GitHub postponed a new billing model for self-hosted Actions after developer pushback, but moved forward with hosted runner price cuts on January 1.
@productboard/slate-edit-list
Advanced tools
A Slate plugin to handle keyboard events in lists. List items can contain blocks.
Compatible with slate version ^0.50.
Demo: gitbookio.github.io/slate-edit-list/
npm install @productboard/slate-edit-list
Natural keybindings:
Simple validation/normalization (see assumptions about the schema):
Useful transforms: see Utilities and Transforms.
import { EditListPlugin } from '@productboard/slate-edit-list'
const options = {} // additional options
const [
withEditList, // applies normalization to editor
onKeyDown, // keyDown handler for keyboard shortcuts
{ Editor, Element, Transforms } // Slate classes with added utility functions and transforms this package provides
] = EditListPlugin(options);
const editor = useMemo(() => withEditList(withReact(createEditor())), []);
const [value, setValue] = useState([]);
return (
<Slate editor={editor} value={value} onChange={newValue => setValue(newValue)}>
<Editable onKeyDown={onKeyDown(editor)} />
</Slate>
);
This plugin accepts options to redefine the following block types:
types: string = ["ul_list", "ol_list"] — the array of possible types for list containers. First value will be used as default.typeItem: string = "list_item" — type for list items.typeDefault: string = "paragraph" — type for default block in list items.canMerge: (Node, Node) => boolean — controls which list can be merged automatically (for example when they are adjacent). Defaults to merging list with identical typesYou can use this plugin with custom list block types (using plugin arguments). But your list structure should still conform to a few rules. These rules are implemented as normalizations.
Here is what a minimal list would look like:
nodes:
- kind: block
type: ul_list # Default type for bulleted lists container
nodes:
- kind: block
type: list_item # List containers can only contain list items
nodes:
# List items contain blocks. They cannot be the direct container of text.
- kind: block
type: paragraph # Default type of blocks in a list item
nodes:
- kind: text
text: Hello World
And here is an example of a multi-level list:
nodes:
- kind: block
type: ol_list
nodes:
- kind: block
type: list_item
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: Item 1
- kind: block
type: ol_list
nodes:
- kind: block
type: list_item
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: Item 1.1
- kind: block
type: list_item
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: Item 1.2
slate-edit-list exports utilities and transforms:
Element.isList(node: Node) => booleanReturn true if the type of the node is one of the list types from options.
Element.isItem(node: Node) => booleanReturn true if the type of the node is the list item type from options.
Editor.isSelectionInList(editor: Editor) => booleanReturn true if selection is inside a list (and it can be unwrapped).
Editor.getItemDepth(editor: Editor, path?: Path) => numberReturns the depth of the current item (or the depth of the given path) in a list. 0 means not in a list.
Editor.getDeepestItemDepth(editor: Editor, path: Path) => numberReturns the depth of the deepest list item in a path.
Editor.getCurrentItem(editor: Editor, path?: Path) => NodeEntry<Element> || nullReturns the current item at selection (or at the given path).
Editor.getCurrentList(editor: Editor, path?: Path) => NodeEntry<Element> || nullReturns the current list at selection (or at the given path).
Editor.getPreviousItem(editor: Editor, path?: Path) => NodeEntry<Element> || nullReturns the list item preceding the item at selection (or at the given path).
Editor.getListForItem(editor: Editor, path: Path) => NodeEntry<Element> || nullReturns the list element the item at the specified path belongs to.
Editor.getItemsAtRange(editor: Editor, range?: Range) => Array<NodeEntry<Element>>Return an array of items at the given range. The returned items are the highest list of successive items that cover the given range.
The returned array is empty if no such list can be found.
Transforms.increaseItemDepth(editor: Editor) => voidIncrease the depth of the current item.
Transforms.decreaseItemDepth(editor: Editor) => voidDecrease the depth of the current item.
Transforms.wrapInList(editor: Editor, type?: string, data?: {}) => voidWrap the current blocks in list items of a list container of the given type. You can pass optional data for the created list container.
Transforms.unwrapList(editor: Editor) => voidUnwrap all items at range from their list.
Transforms.splitListItem(editor: Editor) => voidSplit current block into a new list item.
Transforms.toggleList(editor: Editor) => voidToggle (wrap/unwrap) list at selection.
FAQs
A Slate plugin to handle keyboard events in lists.
The npm package @productboard/slate-edit-list receives a total of 145 weekly downloads. As such, @productboard/slate-edit-list popularity was classified as not popular.
We found that @productboard/slate-edit-list demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 9 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
GitHub postponed a new billing model for self-hosted Actions after developer pushback, but moved forward with hosted runner price cuts on January 1.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.