frend / frend.co

Frend — A collection of accessible, modern front-end components.
http://frend.co
MIT License
635 stars 25 forks source link

Feature request: tree view #85

Open gunzip opened 8 years ago

gunzip commented 8 years ago

Maybe a 'navigable nested accordion' would suffice to implement something alike: http://apps.komposta.net/jquery/navgoco/demo/

(actually nesting accordion(s) works with mouse clicks but not with keyboard navigation).

adamduncan commented 8 years ago

Yeah, there's some good TreeView examples over on the ARIA Authoring Practices Guide: https://www.w3.org/TR/wai-aria-practices/#TreeView

Something along those lines? Could be a good addition to the collection.

gunzip commented 8 years ago

I'm trying to port https://www.w3.org/TR/wai-aria-practices/#TreeView and I'm experiencing some troubles in embracing the frend-ly like architecture.

  1. Missing utility library: while I get the point of the minimalist approach, I see little, if none, added value in avoiding using an utility library (ie. zepto, jquery). The risk is to rewrite them inside each component. Moreover they abstract browser incompatibilities and we would get older browser support for free as well. Finally, the components code would be even shorter and maintainable.
  2. Hardcoded loop: whenever you call init() method the dynamic behavior gets attached to every component because of the hardcoded loop (accordionContainers.forEach). IMHO that would be more useful to allow the user a fine grained control (ie. calling init(componentInstance) in a self coded loop outside frend methods). Aside, it's hard to use instance state variables for a component: you either have to wrap the DOM node (accordionContainer) in some javascript object only to store the component state or use some tricky memoizing technique to cache, for example, returned NodeList from selectors.
adamduncan commented 8 years ago

Thanks for the feedback, @gunzip. We've been talking about point 2 a lot this week. We realise that looping within the component initialisation is less than ideal for state, callbacks, etc. We're working on a v1.1 (or v2 depending on the API impact) of these components, which will, like you say, see a restructure to better handle multiple instances as separate objects.

Point 1 is a fair point, so happy to discuss that more. Just wanted to jump in and give you a heads up on the restructure, so you're aware before getting too far into a new component. Will come back to elaborate on point 1 asap. Cheers!

gunzip commented 8 years ago

Is there any date scheduled for the next release ? (even approximately).

About the 1st point I would just add that functions like getPanelHeight / unsetPanelHeight are useful for the Treeview as well, so I had to copy the whole code from Accordion, which of course will be a maintenance nightmare in the long run. Moreover - including some jquery like library - the whole part just reduces to a couple of slideUp() / slideDown() calls.

Even if I like the new ES6 features, I try hard to resist my temptation to embrace the new brand techniques and be more pragmatic ;)

adamduncan commented 8 years ago

I'd say a new release in the next couple of weeks. We'll shortly be merging improvements into the v2 branch, so keep an eye on that. Will let you know when it's close. v2 will have component looping removed, so instead we'll pass through a single element as a mandatory parameter, and any custom options in the second. That should resolve your valid concerns with the looping, state etc. For example:

var tabsEl = document.getElementById('tabs');

var myTabs = frtabs(tabsEl, {
  onTab: function (tabs) {
    console.log(tabs.activeIndex);
  }
});

Dependencies Regarding the utilities, we'd like to retain a zero-third-party-dependency collection. There are only a couple of helpers required throughout the components, so we'd prefer to lift these out and maintain them as frend-utils modules we can import as required. parents() and closest() would be perfect candidates for this, as they're used in more than one component. get/unsetPanelHeight() could be another. That way we can keep the footprint as light as possible for developers who are already using a modern bundling workflow, and mightn't necessarily have/want a utility library available in their projects. For developers loading precompiled scripts as is (from the dist directories), any duplication of these utils should be negligible, or negated by the use of Gzip compression. Hope that helps to clarify. We'll keep you posted on how this progresses, and would be keen to hear your feedback. Cheers.