Passing HTML element to addButtonByElement
aminya opened this issue · 4 comments
Proposal
Similar to Status-Bar that has a function that accepts an HTML element, we should allow this too. This feature in combination with the typical addButton
allows complex usage of Toolbar.
toolbar.addButtonByElement(element)
Then, the user can do whatever they wanna do with it. For example, define custom buttons like dropdowns, define click callbacks, hide it when they want, etc. It easily solves #43 and #192 by removing the limitations.
Implementation
This implementation is old. See the actual PR: https://github.com/suda/tool-bar/pull/294/files
we just need to define an addButtonByElement
:
In https://github.com/suda/tool-bar/blob/master/lib/tool-bar-manager.js#L11-L16
addButtonByElement(element) {
this.toolBarView.addElement(element);
this.touchBarManager.addElement(element);
return element;
}
and define toolBarView.addElement
which is edited from addItem
.
https://github.com/suda/tool-bar/blob/0b8a1ced016b852ed175f72d7a860b324ef438fd/lib/tool-bar-view.js#L65-L90
Similarly, touchBarManager.addElement
can also be defined.
Alternative implementation
Instead of defining a new function, we can use the curren addButton
and get the element as a property (named element or something), and instead of creating the element inside ToolBarButtonView, use the supplied element. User can use some desired features of addButton
regularly (if their element is compatible). callback
property should be optional in this case (we need to add if
for all of the options in ToolBarButtonView
. Even for onClick
)
toolbar.addButton({
element: myHTMLElement
icon: "play"
// etc
})
This implementation is easier to work with, since a lot of options are already available to use.
Usage Example
This could be a typical example of that button (similar to https://github.com/aminya/atom-indent-detective/blob/TypeScript/src/status.ts)
// Called only once for each Atom session
export function consumeToolBar(getToolBar) {
toolBar = getToolBar('packageName');
toolbarItem = new MyToolbarItem (toolBar )
return
}
export class MyToolbarItem {
button: ButtonElement | null
text: HTMLElement | null
view: HTMLElement
constructor(toolBar) {
// create an element and add stuff to it:
this.view = document.createElement("button")
this.view.classList.add("myclass")
this.text = document.createElement("a")
this.text.innerText = "Spaces (2)"
this.view.appendChild(this.text)
// add onclick callback
this.view.onclick = function () {
// ..........
}
// consumeToolBar
this.button = toolBar.addButtonByElement(this.view)
}
}
This basically allows the user to do whatever is done in https://github.com/suda/tool-bar/blob/master/lib/tool-bar-button-view.js by themselves.
References
Based on these:
https://github.com/atom/status-bar/blob/master/lib/status-bar-view.coffee#L64-L78
https://github.com/atom/status-bar/blob/master/lib/tile.coffee
@suda @ericcornelissen What do you think?
The feature request seems fine to me. I'm not a fan of your alternative implementation as, e.g. it's is very confusing to me what the icon
key is going to do with my element. Just passing the HTML element as an argument seems better to me. If you want this kind of freedom, than you will have to do everything yourself, in my opinion.
It does to some extend, but I don't think that means there should never be "native" support for those features 😉
The feature request seems fine to me. I'm not a fan of your alternative implementation as, e.g. it's is very confusing to me what the
icon
key is going to do with my element. Just passing the HTML element as an argument seems better to me. If you want this kind of freedom, than you will have to do everything yourself, in my opinion.
This seems fair.
It does to some extend, but I don't think that means there should never be "native" support for those features 😉
Once we implement this feature, we can make some ready HTML Toolbar components (like the class I showed under Usage Example), which user can just call with a simple syntax:
addButtonsByElement(new DropDown(options))
or export a wrapper function for the class, which just does the above under the hood:
addDropDown(options)