jiro-ui
Version:
A Mithril.js UI library based from construct-ui
97 lines (77 loc) • 2.48 kB
text/typescript
import m from 'mithril';
import classnames from 'classnames';
import { IAttrs, Classes, normalizeStyle } from '../../_shared';
import { IColAttrs } from './Col';
import { ResponsiveManager } from '../../utils';
ResponsiveManager.initialize();
export interface IBreakpointMap {
xs?: number;
sm?: number;
md?: number;
lg?: number;
xl?: number;
}
export interface IGridAttrs extends IAttrs {
/** HTML element to render into */
element?: string;
/** Space between columns */
gutter?: number | IBreakpointMap;
/** Flexbox column alignment */
align?: 'top' | 'middle' | 'bottom';
/** Flexbox column justify */
justify?: 'start' | 'end' | 'center' | 'space-around' | 'space-between';
[htmlAttrs: string]: any;
}
export class Grid implements m.Component<IGridAttrs> {
public view({ attrs, children }: m.Vnode<IGridAttrs>) {
const {
align,
class: className,
element,
justify,
gutter,
style,
...htmlAttrs
} = attrs;
const classes = classnames(
Classes.GRID,
align && `${Classes.GRID}-align-${align}`,
justify && `${Classes.GRID}-justify-${justify}`,
className
);
const breakPointGutter = this.getGutter(attrs);
const styles = {
...normalizeStyle(style),
marginLeft: `-${breakPointGutter / 2}px`,
marginRight: `-${breakPointGutter / 2}px`
};
return m(element || '', {
...htmlAttrs,
class: classes,
style: styles
}, this.renderCols(children as m.ChildArray, breakPointGutter));
}
private getGutter(attrs: IGridAttrs) {
const breakPoints = ResponsiveManager.breakpoints;
if (typeof attrs.gutter === 'object' && breakPoints) {
const activeBreakpoints = Object.keys(breakPoints).filter((x) => breakPoints[x]);
const currentBreakpoint = activeBreakpoints[activeBreakpoints.length - 1];
return (attrs.gutter as any)[currentBreakpoint] || 0;
} else return attrs.gutter;
}
private renderCols(children: m.ChildArray, gutter: number): any {
return children.map((col: m.Vnode<IColAttrs>) => {
if (col == null || col.tag === '#') return;
if (col.tag === '[') {
return this.renderCols(col.children as m.ChildArray, gutter);
}
col.attrs = col.attrs || {};
col.attrs.style = {
...normalizeStyle(col.attrs.style),
paddingLeft: `${gutter / 2}px`,
paddingRight: `${gutter / 2}px`
};
return col;
});
}
}