Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Challenges of building a menu system in Polymer #382

Closed
jganetsk opened this issue Dec 18, 2013 · 5 comments
Closed

Challenges of building a menu system in Polymer #382

jganetsk opened this issue Dec 18, 2013 · 5 comments

Comments

@jganetsk
Copy link

So I'm building a menu system in Polymer.

I'm expressing the menu contents in HTML, using just custom elements, with something that looks like

<menubar>
  <menubar-item name="File">
    <menu>
      <menu-item name="Open" />
      <menu-item name="Save" />
    </menu>
  </menubar-item>
  <menubar-item name="Edit">
    <menu>
      <menu-item name="Undo" />
      <menu-item name="Redo" />
    </menu>
  </menubar-item>
</menubar>

I have certain simple constraints, like

  • At most one item in a menu can be selected
  • A closed menu has no selected children
  • A menu can only be open if it's parent menu item is selected

I have other more particular constraints regarding more subtle points about how people expect menus to work.

I have mainly implemented this with changed watchers, and it's fairly straightforward to understand how to respond to any given change, with bidirectionality (you can change either the parent, or the child, and the other responds correctly). But there are some gotchas:

  • The changedWatcher code is somewhat counter intuitive to read after it's been written. I'd love to write the constraints once in simple predicate logic and just be done with it. Or, if I could write them in Javascript, I could at least have them checked (like a contract system).
  • The DOM relationships are fragile. If I change the DOM, by reordering/deleting/adding new elements, I expect some cases to work, and some to fail. ideally, I would like to be able to define a property representing a related DOM element, and have data binding "just work" on it. So, for example, referring to "parentNode" or some child node based on a CSS selector.
  • I need "type-checking" on the DOM. I need to know that menus contain only menu items, and that menu items can only go into menus.
@sjmiles
Copy link
Contributor

sjmiles commented Dec 18, 2013

I'm afraid it's hard to comment because it seems your commentary is either too general (at least, for me) or represents opinions about how things work.

It's definitely true that if you dislike Polymer idioms in general, you will have a hard time using Polymer. For sure, where there are real specific things that Polymer just does not support in a reasonable way, we definitely want to understand those flaws, but this is different from simply wanting it to work differently.

Polymer already has an example menu system (polymer-ui-menu, polymer-ui-menu-item, and polymer-ui-submenu-item). I suspect you feel it doesn't meet your needs, which is reasonable, but at least it demonstrates that Polymer isn't somehow incapable of expressing such a system.

@sjmiles
Copy link
Contributor

sjmiles commented Dec 18, 2013

I need "type-checking" on the DOM. I need to know that menus contain only menu items, and that menu items can only go into menus.

Wrt to this specific question, ShadowDOM is particularly good at plucking out only nodes that match certain selectors.

Given,

<content select="menu-item"></content>

Non-menu-item elements are simply ignored.

@sorvell
Copy link
Contributor

sorvell commented Dec 18, 2013

I recommend investigating if polymer-selector would be useful. It exists to
help manage a selected state in dom.

To elaborate on what Scott said:

Menu can have a shadowDOM like this:

In that case the menu items are still the children of the menu as you've
indicated but only menu-items are distributed and rendered.

On Wed, Dec 18, 2013 at 2:14 PM, Scott J. Miles notifications@github.comwrote:

I need "type-checking" on the DOM. I need to know that menus contain only
menu items, and that menu items can only go into menus.

Wrt to this specific question, ShadowDOM is particularly good at plucking
out only nodes that match certain selectors.

Given,

Non-menu-item elements are simply ignored.


Reply to this email directly or view it on GitHubhttps://github.com//issues/382#issuecomment-30886501
.

@jganetsk
Copy link
Author

Selector is great. It confirms my intuitions, though, that it's actually hard to get these components really right. You have to take care of many cases, and I just started to think about this as well. I'm surprised with the use of MutationObserver. It has no specificity, correct? It's calling updateSelected on all DOM mutations in the entire document?

These things are not good at plucking, from my perspective, as I want to pluck based on superclass. Like, I have an "abstract-menuitem", which is sub-classed by "menupane-item" and "menubar-item". I'd like to select on that, and it's not easy. If I could pass in a selector that was a predicate function, that would be good. I would write a function that performs this type check. Else, I'd have to rely on CSS or some attribute... so I'd expose some internal details.

@sorvell
Copy link
Contributor

sorvell commented Dec 20, 2013

I'm surprised with the use of MutationObserver. It has no specificity,
correct?

Just mutations generated within the target element.

I want to pluck based on superclass

Yeah, that's not supported right now and instead you'll need either to list
the supported types in the select or use another signal, as you noted. It's
something we hope to add to ShadowDOM in the future.

On Thu, Dec 19, 2013 at 3:11 PM, jganetsk notifications@github.com wrote:

Selector is great. It confirms my intuitions, though, that it's actually
hard to get these components really right. You have to take care of many
cases, and I just started to think about this as well. I'm surprised with
the use of MutationObserver. It has no specificity, correct? It's calling
updateSelected on all DOM mutations in the entire document?

These things are not good at plucking, from my perspective, as I want to
pluck based on superclass. Like, I have an "abstract-menuitem", which is
sub-classed by "menupane-item" and "menubar-item". I'd like to select on
that, and it's not easy. If I could pass in a selector that was a predicate
function, that would be good. I would write a function that performs this
type check. Else, I'd have to rely on CSS or some attribute... so I'd
expose some internal details.


Reply to this email directly or view it on GitHubhttps://github.com//issues/382#issuecomment-30975768
.

@sorvell sorvell closed this as completed Aug 11, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants