Skip to content

Commit

Permalink
#99 List Menu and support for Ordered Lists (#104)
Browse files Browse the repository at this point in the history
* Initial POC

* Make dropdowns sticky by default, list icon enabling

* Add tab keybinding; code cleanup

* Rename numbered to ordered

* Fix linting issues

---------

Co-authored-by: Chris Millar <cmillar@apache.org>
  • Loading branch information
chrischrischris and auniverseaway committed Apr 16, 2024
1 parent 6c0a425 commit 3a0c21b
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 39 deletions.
16 changes: 14 additions & 2 deletions blocks/edit/da-editor/da-editor.css
Original file line number Diff line number Diff line change
Expand Up @@ -195,10 +195,22 @@ span.ProseMirror-menuseparator {
background: url('/blocks/edit/img/Smock_Unlink_18_N.svg') center / 18px no-repeat #EFEFEF;
}

.edit-list {
.bullet-list, .ProseMirror-menu-dropdown.list-menu {
background: url('/blocks/edit/img/Smock_TextBulleted_18_N.svg') center / 18px no-repeat #EFEFEF;
}

.ordered-list {
background: url('/blocks/edit/img/Smock_TextNumbered_18_N.svg') center / 18px no-repeat #EFEFEF;
}

.indent-list {
background: url('/blocks/edit/img/Smock_TextIndentIncrease_18_N.svg') center / 18px no-repeat #EFEFEF;
}

.outdent-list {
background: url('/blocks/edit/img/Smock_TextIndentDecrease_18_N.svg') center / 18px no-repeat #EFEFEF;
}

.insert-table {
background: url('/blocks/edit/img/Smock_TableAdd_18_N.svg') center / 18px no-repeat #EFEFEF;
}
Expand Down Expand Up @@ -263,7 +275,7 @@ span.ProseMirror-menuseparator {
background: url('/blocks/edit/img/Smock_Redo_18_N.svg') center / 18px no-repeat #EFEFEF;
}

/* Generic ProseMirror Styles */
/* Generic ProseMirror Styles */
.ProseMirror hr {
border-radius: 1px;
border: 1px solid #b3b3b3;
Expand Down
13 changes: 12 additions & 1 deletion blocks/edit/da-library/da-library.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ class DaLibrary extends LitElement {
<li class="da-library-type-item">
<button class="da-library-type-item-btn"
@click=${() => this.handleItemClick(item)}>
<div class="da-library-type-item-detail">
<div class="da-library-type-item-detail">
${item.icon ? until(this.renderIcon(item.icon)) : ''}
<span>${name}</span>
<svg class="icon">
Expand Down Expand Up @@ -193,13 +193,24 @@ class DaLibrary extends LitElement {

customElements.define('da-library', DaLibrary);

const CLOSE_DROPDOWNS_EVENT = 'pm-close-dropdowns';

export default function open() {
const palettePane = window.view.dom.nextElementSibling;
const existingPalette = palettePane.querySelector('da-library');
if (existingPalette) {
existingPalette.remove();
return;
}
// close any other dropdowns
window.dispatchEvent(new CustomEvent(CLOSE_DROPDOWNS_EVENT));

const palette = document.createElement('da-library');
palettePane.append(palette);

const closePaletteListener = () => {
palette.remove();
window.removeEventListener(CLOSE_DROPDOWNS_EVENT, closePaletteListener);
};
window.addEventListener(CLOSE_DROPDOWNS_EVENT, closePaletteListener);
}
15 changes: 15 additions & 0 deletions blocks/edit/img/Smock_TextIndentDecrease_18_N.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions blocks/edit/img/Smock_TextIndentIncrease_18_N.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions blocks/edit/prose/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {
goToNextCell,
tableNodes,
fixTables,
liftListItem,
sinkListItem,
gapCursor,
Y,
WebsocketProvider,
Expand Down Expand Up @@ -262,6 +264,8 @@ export default function initProse({ editor, path }) {
Tab: goToNextCell(1),
'Shift-Tab': goToNextCell(-1),
}),
keymap({ 'Shift-Tab': liftListItem(schema.nodes.list_item) }),
keymap({ Tab: sinkListItem(schema.nodes.list_item) }),
gapCursor(),
history(),
],
Expand Down
60 changes: 51 additions & 9 deletions blocks/edit/prose/plugins/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
undo,
redo,
wrapInList,
liftListItem,
sinkListItem,
// eslint-disable-next-line import/no-unresolved
} from 'da-y-wrapper';

Expand Down Expand Up @@ -55,10 +57,6 @@ function cmdItem(cmd, options) {
return new MenuItem(passedOptions);
}

function wrapListItem(nodeType, options) {
return cmdItem(wrapInList(nodeType, options.attrs), options);
}

function markActive(state, type) {
const { from, to, $from, $to, empty } = state.selection;
if (empty) {
Expand Down Expand Up @@ -284,6 +282,49 @@ function getTextBlocks(marks, nodes) {
];
}

function shouldEnableIndentOutdentIcon(state, listType) {
const { $from } = state.selection;
if ($from.node($from.depth - 1)?.type === listType) return true;
return false;
}

function getListMenu(nodes) {
return [
new MenuItem({
title: 'Bullet List',
label: 'Bullet List',
class: 'bullet-list',
run(initialState, dispatch) {
wrapInList(nodes.bullet_list)(initialState, dispatch);
},
}),
new MenuItem({
title: 'Ordered List',
label: 'Ordered List',
class: 'ordered-list',
run(state, dispatch) {
wrapInList(nodes.ordered_list)(state, dispatch);
},
}),
new MenuItem({
title: 'Indent List',
label: 'Indent List',
class: 'indent-list',
enable(state) { return shouldEnableIndentOutdentIcon(state, nodes.list_item); },
run(state, dispatch) {
sinkListItem(nodes.list_item)(state, dispatch);
},
}),
new MenuItem({
title: 'Outdent List',
label: 'Outdent List',
class: 'outdent-list',
enable(state) { return shouldEnableIndentOutdentIcon(state, nodes.list_item); },
run: liftListItem(nodes.list_item),
}),
];
}

function getMenu(view) {
const menu = document.createElement('div');
menu.className = 'ProseMirror-menubar';
Expand All @@ -302,10 +343,9 @@ function getMenu(view) {
];

const listMenu = [
wrapListItem(nodes.bullet_list, {
title: 'Wrap in bullet list',
label: 'List',
class: 'edit-list',
new Dropdown(getListMenu(nodes), {
label: 'List Menu',
class: 'list-menu',
}),
];

Expand All @@ -314,7 +354,9 @@ function getMenu(view) {
title: 'Open library',
label: 'Library',
enable() { return true; },
run() { openLibrary(); },
run() {
openLibrary();
},
class: 'open-library',
}),
new MenuItem({
Expand Down
2 changes: 0 additions & 2 deletions blocks/edit/utils/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,6 @@ async function saveJson(fullPath, sheet, dataType = 'blob') {
}
}

console.log(data);

const json = { total: data.length, offset: 0, limit: data.length, data, ':type': 'sheet' };

const formData = new FormData();
Expand Down
22 changes: 11 additions & 11 deletions deps/da-y-wrapper/dist/index.js

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion deps/da-y-wrapper/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Schema, DOMParser, Fragment } from 'prosemirror-model';
import { schema as baseSchema } from 'prosemirror-schema-basic';
import { baseKeymap, toggleMark } from 'prosemirror-commands';
import { history, undo, redo } from 'prosemirror-history';
import { addListNodes, wrapInList } from 'prosemirror-schema-list';
import { addListNodes, wrapInList, splitListItem, liftListItem, sinkListItem } from 'prosemirror-schema-list';
import { keymap } from 'prosemirror-keymap';
import { buildKeymap } from 'prosemirror-example-setup';
import { gapCursor } from 'prosemirror-gapcursor';
Expand Down Expand Up @@ -80,6 +80,9 @@ export {
blockTypeItem,
toggleMark,
wrapInList,
splitListItem,
liftListItem,
sinkListItem,
undo,
redo,
Y,
Expand Down
33 changes: 20 additions & 13 deletions deps/prosemirror-menu/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { Plugin } from 'prosemirror-state';
const SVG = "http://www.w3.org/2000/svg";
const XLINK = "http://www.w3.org/1999/xlink";
const prefix$2 = "ProseMirror-icon";
const CLOSE_DROPDOWNS_EVENT = 'pm-close-dropdowns';

function hashPath(path) {
let hash = 0;
for (let i = 0; i < path.length; i++)
Expand Down Expand Up @@ -136,12 +138,7 @@ class Dropdown {
/**
Create a dropdown wrapping the elements.
*/
constructor(content,
/**
@internal
*/
options = {}) {
this.options = options;
constructor(content, options = { sticky: true }) {
this.options = options || {};
this.content = Array.isArray(content) ? content : [content];
}
Expand All @@ -158,23 +155,33 @@ class Dropdown {
let wrap = crel("div", { class: prefix$1 + "-dropdown-wrap" }, label);
let open = null;
let listeningOnClose = null;
let closeDropdownListener = null;
let close = () => {
if (open && open.close()) {
open = null;
win.removeEventListener("mousedown", listeningOnClose);
if (!this.options.sticky) {
win.removeEventListener("mousedown", listeningOnClose);
}
win.removeEventListener(CLOSE_DROPDOWNS_EVENT, closeDropdownListener);
}
};

label.addEventListener("mousedown", e => {
e.preventDefault();
markMenuEvent(e);
if (open) {
close();
}
else {
} else {
win.dispatchEvent(new CustomEvent(CLOSE_DROPDOWNS_EVENT));
open = this.expand(wrap, content.dom);
win.addEventListener("mousedown", listeningOnClose = () => {
if (!isMenuEvent(wrap))
close();
if (!this.options.sticky) {
win.addEventListener("mousedown", listeningOnClose = () => {
if (!isMenuEvent(wrap))
close();
});
}
win.addEventListener(CLOSE_DROPDOWNS_EVENT, closeDropdownListener = () => {
close();
});
}
});
Expand Down Expand Up @@ -232,7 +239,7 @@ class DropdownSubmenu {
Creates a submenu for the given group of menu elements. The
following options are recognized:
*/
constructor(content,
constructor(content,
/**
@internal
*/
Expand Down

0 comments on commit 3a0c21b

Please sign in to comment.