dojo / meta

:rocket: Dojo - meta information for the project.
Other
226 stars 50 forks source link

Provide layout.css #138

Closed rishson closed 6 years ago

rishson commented 7 years ago

@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 7 years ago

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 7 years ago

@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 7 years ago

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 7 years ago

@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 7 years ago

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 7 years ago

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

rishson commented 7 years ago

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 7 years ago

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 7 years ago

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 7 years ago

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

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

sebilasse commented 7 years ago

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 6 years ago

Issue moved to dojo/widgets #337 via ZenHub