dojo / widgets

:rocket: Dojo - UI widgets.
https://widgets.dojo.io
Other
89 stars 65 forks source link

Provide layout.css #337

Closed kitsonk closed 7 years ago

kitsonk commented 7 years ago

@rishson commented on Fri Jan 20 2017

@rishson commented on Mon Jan 16 2017

We need to consider what layout mechanisms we want to support in Dojo 2. We should consider css-grid support, flexbox support etc. We need to decide if we recommend 3rd party grid solutions, write our own, provide advice only...


@matt-gadd commented on Wed Jan 18 2017

@rishson I think this issue should be moved to dojo/meta.


@bitpshr commented on Fri Jan 20 2017

Thinking out loud, all our widgets are still rendered as DOM. Users can always write their own CSS to lay widgets out however they want. What would Dojo 2 provide as a framework to facilitate this? We should probably avoid anything resembling dojo/layout.


@rishson commented on Fri Jan 20 2017

Some possible approaches:

.fit {
  flex: 1;
}
.full-width {
  flex: 0 0 100%;
}
.half-width {
  flex: 0 0 50%;
}

and then provide a layout mixin for widgets that would convert layout props to classes, e.g.

[treat below as pseudocode]

getChildrenNodes: function (this: List): DNode[] {
  const layoutClasses = layout.get(this.properties);
  const classes = ['some-class'];
  return [ v('div', classes.concat(layoutClasses)) ];
}

where the layout would do something like:

get: function (props: WidgetProperties) {
  const classes = [];
  if(props.layout.fullWidth) {
    classes.push(LAYOUT_CLASSES.full-width);
  }
  if(props.layout.halfWidth) {
    classes.push(LAYOUT_CLASSES.full-width)  
  }
  ...
  //you could even make it more intelligent, by inspecting parent to make sure it had the correct enclosing classes, e.g. parent of `x-width` needs to have `fit`...
}

The above is similar to what angular material does for layout, e.g. component attributes are parsed by a directive and layout classes applied to the component root node.

Other musings: At the moment, I think providing widgets to do layout is overkill, but I've not really thought about this much - just getting down my thoughts. The only layout widget that I could see us having to provide would be a splitter widget. Layout css would need to provide sensible device breakpoints with @media queries, out of the box.


@rishson commented on Fri Jan 20 2017

@bitpshr @matt-gadd just adding you in a comment, in case you thought I'd just closed the previous issue for no reason 😄


@tomdye commented on Fri Jan 20 2017

I think that the best approach to this is to create a layout css-module that can be required into dojo widgets and custom widgets to apply layout rules. I don't believe there would be any need for a layout.ts mixin or similar. The layout classes can be mixed into the theme classes to provide the appropriate layout. Utilising the current css-module and postcss pipeline will provide browser prefix support and seamless css-properties integration by default.

// layout.css
.flex-container {
   display: flex;
   justify-content: space-between;
   flex-wrap: wrap;
}

.flex-grow-item {
   flex-grow: 1;
}
// tabpanel.ts
import * as layout from 'path/to/layout.css';

getChildrenNodes(this) {
   return [
      v(`ul`, { classes: { [ layout.flexContainer ]: true, ...this.theme.tabPanelTabs }  }, [
         v('li', { classes: { [ layout.flexItem ]: true, ...this.theme.tabPanelTab } }, [ 'tab1' ]),
         // ....
      ])
   ]
}

In a situation where it is desirable to mix these styles into the tabPanel css such that they can be changed via a theme or overrideClass, rather than applying separate classes, css-module compose function could be used instead. ie.

// tabpanel.css
.tabPanelTabs {
   composes: flex-container from 'path/to/layout.css';
}

.tabPanelTab {
   composes: flex-item from 'path/to/layout.css';
}

@rishson commented on Fri Jan 20 2017

@Tomdye but how do you pass the layout to the widget? Layout is something that happens to your top level widget node (usually), as in something higher in the tree, tells you how you should be layed out. I can see your solution can layout children by importing the classes and applying, but most often, you will have to reference a property passed to you, at least for getNode in your widget, and possibly when applying layout classes to children.


@tomdye commented on Fri Jan 20 2017

So for the outer class, ie. laying out the widget rather than laying out it's children, the parent of the widget would require in the layout.css module and apply the correct classes at creation time.

This would apply to any classes the widget user wishes to apply to the widgets outer class.

// main.ts
import * as layout from 'path/to/layout.css';
import createTabPanel from 'path/to/tabpanel';

// ...
w(createTabPanel, { classes: { 
   [ layout.flexItem ]: true, 
   [ layout.pull-right ]: true 
} });

@tomdye commented on Fri Jan 20 2017

This outstanding issue blocks the above: https://github.com/dojo/widgets/issues/221


@rishson commented on Fri Jan 20 2017

I'd much rather not have to use props for layout. I guess the use case in my head when I thought you needed them was something like:

you have a grid of items, where at the last render cycle, there were 3 items per row. the user deletes one of the items the remaining 2 items should now take up the remaining width, e.g. the items width goes from 33.3333% to 50% between render cycles.

But you are right, you could just inspect how many items there are in getChildrenNodesof the parent and apply the correct layout class. Its almost too easy 🤔


@tomdye commented on Fri Jan 20 2017

Ok but I think that kind of scenario is an edge case and would be addressed by a flex layout anyway which would not need to know about how many items there were etc... If not, it would likely be handled by inline styles within the widget logic itself.


@rishson commented on Wed Feb 08 2017

OK, I've changed to title. We should implement @tomdye 's solution and provide a simple layout.css file that can be imported and used with the themeing system.


@rorticus commented on Thu Mar 30 2017

Throwing this back because it looks like this is getting in the way,

https://github.com/dojo/cli-build/issues/112


@sebilasse commented on Sun May 28 2017

How about http://typestyle.io/#/ ?

What I liked the most in dojo1 was the Semantic theme which can be found here: http://websemantics.github.io/semantic-dojo/

I already recommended semantic ui and now I am working on semantic ui components for dojo2 similar to https://react.semantic-ui.com/introduction

kitsonk commented 7 years ago

@bitpshr we should figure out if this makes sense for Dojo 2 widgets or not and either figure out what work we need to do or close down this issue.

bitpshr commented 7 years ago

This is essentially a duplicate of #21. The decision was made that application-level CSS, including laying components out on a page, is outside the scope of a Dojo 2 widgets catalog.