Working node menu

This commit is contained in:
Magnus Åhall 2026-06-16 08:27:01 +02:00
parent 15bd742ef7
commit e71516fd76
3 changed files with 98 additions and 31 deletions

View file

@ -9,7 +9,10 @@
--line-color: #ccc;
--tree-expander: 0px;
--functions-width: 216px;
--functions-width: 150px;
--menu-color: #fff;
--menu-item-hover-color: #f4f4f4;
}
html {

View file

@ -2,14 +2,70 @@ import { ROOT_NODE, uuidv7 } from 'node_store'
import { CustomHTMLElement } from './lib/custom_html_element.mjs'
import { MarkedPosition } from './marked_position.mjs'
class N2NodeMenu extends CustomHTMLElement {
static {// {{{
this.tmpl = document.createElement('template')
this.tmpl.innerHTML = `
<style>
n2-nodemenu {
margin: 8px 0;
padding: 0;
position-anchor: --node-menu;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;
top: anchor(bottom);
right: anchor(right);
left: auto;
white-space: nowrap;
.menu-item {
padding: 8px 16px 8px 8px;
border-bottom: 1px solid var(--line-color);
display: grid;
grid-template-columns: min-content 1fr;
grid-gap: 16px;
align-items: center;
&:last-child {
border-bottom: unset;
}
&:hover {
background-color: var(--menu-item-hover-color);
}
}
}
</style>
<div class="node-menu">
<div class="menu-item" data-el="format-tables">
<img class="colorize" src="/images/${_VERSION}/icon_table.svg">
<div>Format tables</div>
</div>
<div class="menu-item" data-el="history">
<img class="colorize" src="/images/${_VERSION}/icon_history.svg">
<div>History</div>
</div>
</div>
`
}// }}}
constructor() {// {{{
super()
}// }}}
}
customElements.define('n2-nodemenu', N2NodeMenu)
export class N2PageNodeUI extends CustomHTMLElement {
static {// {{{
this.tmpl = document.createElement('template')
this.tmpl.innerHTML = `
<style>
.el-functions {
n2-nodeui > .el-functions {
display: grid;
grid-template-columns: 1fr repeat(5, min-content);
grid-template-columns: 1fr repeat(3, min-content);
grid-gap: 8px;
align-items: center;
justify-items: end;
@ -18,6 +74,14 @@ export class N2PageNodeUI extends CustomHTMLElement {
img {
height: 24px;
}
.el-menu {
anchor-name: --node-menu;
border: 0;
padding: 0;
background-color: unset;
}
}
</style>
<div data-el="name"></div>
@ -28,11 +92,13 @@ export class N2PageNodeUI extends CustomHTMLElement {
<div data-el="functions">
<img data-el="icon-save" src="/images/${_VERSION}/icon_save_disabled.svg">
<img data-el="icon-markdown">
<img data-el="icon-table-format" class="colorize" src="/images/${_VERSION}/icon_table.svg">
<img data-el="icon-history" class="colorize" src="/images/${_VERSION}/icon_history.svg">
<img data-el="icon-new-document" class="colorize" src="/images/${_VERSION}/icon_new_document.svg">
<img data-el="icon-menu" class="colorize" src="/images/${_VERSION}/icon_menu.svg" popovertarget="node-menu">
<button data-el="menu" popovertarget="node-functions-menu">
<img data-el="icon-menu" class="colorize" src="/images/${_VERSION}/icon_menu.svg">
</button>
<n2-nodemenu data-el="node-menu" id="node-functions-menu" popover></n2-nodemenu>
</div>
`
}// }}}
@ -41,7 +107,6 @@ export class N2PageNodeUI extends CustomHTMLElement {
this.node = null
this.style.display = 'contents'
this.classList.add('show-markdown') // TODO Should probably be moved to settings.
this.marked = new MarkedPosition()
_mbus.subscribe('NODE_UI_OPEN', event => {
@ -70,11 +135,27 @@ export class N2PageNodeUI extends CustomHTMLElement {
_mbus.subscribe('MARKDOWN_EDIT', ({ detail }) => this.editMarkdown(detail.data))
_mbus.subscribe('MARKDOWN_CHANGE_CHECKBOX', ({ detail }) => this.checkboxUpdated(detail.data))
// Binding the node rename handler.
this.elName.addEventListener('click', async () => this.renameNode())
// Bind handlers for content keyboard input and paste.
this.elNodeContent.addEventListener('input', event => this.contentChanged(event))
this.elNodeContent.addEventListener('paste', async (event) => this.pasteHandler(event))
// Bind node icon handlers.
this.elIconSave.addEventListener('click', () => this.saveNode())
this.elIconMarkdown.addEventListener('click', () => this.showMarkdown(!this.showMarkdown()))
this.elIconTableFormat.addEventListener('click', event => {
this.elIconNewDocument.addEventListener('click', event => {
if (event.shiftKey)
_app.createNode(this.node.ParentUUID)
else
_app.createNode()
})
// Bind node menu items to handlers.
this.elNodeMenu.elFormatTables.addEventListener('click', event => {
this.elNodeMenu.hidePopover()
if (!event.shiftKey)
this.elNodeContent.value = this.formatAllTables(this.elNodeContent.value)
else {
@ -88,15 +169,12 @@ export class N2PageNodeUI extends CustomHTMLElement {
this.node.setContent(this.elNodeContent.value)
})
this.elIconHistory.addEventListener('click', () => _mbus.dispatch('SHOW_PAGE', { page: 'history' }))
this.elIconSave.addEventListener('click', () => this.saveNode())
this.elIconNewDocument.addEventListener('click', event => {
if (event.shiftKey)
_app.createNode(this.node.ParentUUID)
else
_app.createNode()
this.elNodeMenu.elHistory.addEventListener('click', () => {
_mbus.dispatch('SHOW_PAGE', { page: 'history' })
})
// Default is to always show markdown.
this.classList.add('show-markdown') // TODO Should probably be moved to settings.
this.showMarkdown(true)
}// }}}
renderName() {// {{{
@ -309,7 +387,7 @@ export class N2PageNodeUI extends CustomHTMLElement {
// Node is modified with the new value. User has to save manually, otherwise other changes could be saved
// when a save wasn't expected.
const newValue =`[${checkbox.checked ? 'x' : ' '}] `
const newValue = `[${checkbox.checked ? 'x' : ' '}] `
const modifiedContent = this.node.content().slice(0, pos.start) + newValue + this.node.content().slice(pos.end)
this.node.setContent(modifiedContent)
@ -506,22 +584,10 @@ export class Node {
console.log('waiting')
await Promise.all([history, sendQueue, nodeStoreAdding])
console.log('waiting done')
return
}//}}}
}
class N2Menu extends CustomHTMLElement {
static {// {{{
this.tmpl = document.createElement('template')
this.tmpl.innerHTML = `
<div id="node-menu" popover>Popover content</div>
`
}// }}}
constructor() {// {{{
super()
}// }}}
}
customElements.define('n2-menu', N2Menu)
// vim: foldmethod=marker

View file

@ -6,8 +6,6 @@
<div id="notes2" class="page-history">
<div id="tree-expander" onclick="window._mbus.dispatch('TREE_EXPANSION', { expand: true })">&gt;</div>
<div id="tree" tabindex=0></div>
<n2-menu></n2-menu>
<div id="node-menu" popover>Popover content</div>
<div id="main-page">
<!-- Storage stats -->