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

feat: add grid #800

Merged
merged 1 commit into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion tdesign/desktop/src/divider/divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ export default class Divider extends WeElement<DividerProps> {
[`${classPrefix}-divider--with-text`]: showText,
[`${classPrefix}-divider--with-text-${props.align}`]: showText,
})
console.log('props.children', props.children)
return (
<>
<div class={dividerClassNames} style={props.style}>
Expand Down
31 changes: 31 additions & 0 deletions tdesign/desktop/src/grid/_example/base.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { h, tag, WeElement } from 'omi'

import '../index'
import * as css from '../style/index'
const demoCols = [
Array(12).fill(1),
Array(6).fill(2),
Array(4).fill(3),
Array(3).fill(4),
Array(2).fill(6),
Array(1).fill(12),
]
@tag('grid-base')
export default class GridBase extends WeElement {
static css = css
render() {
return (
<div style={{ width: '200px' }}>
{demoCols.map((cols, i) => (
<t-row>
{cols.map((col, j) => (
<t-col span={col}>
<div>{col}</div>
</t-col>
))}
</t-row>
))}
</div>
)
}
}
131 changes: 131 additions & 0 deletions tdesign/desktop/src/grid/col.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { h, tag, WeElement, OmiProps, classNames } from 'omi'
import { ColProps, RowProps } from './type'
import css from './style/index'
import isObject from 'lodash/isObject';
type FlexType = number | 'none' | 'auto' | string;

const calcColPadding = (gutter: RowProps['gutter'], currentSize: string) => {
const paddingObj = {};
if (typeof gutter === 'number') {
Object.assign(paddingObj, {
paddingLeft: `${gutter / 2}px`,
paddingRight: `${gutter / 2}px`,
});
} else if (Array.isArray(gutter) && gutter.length) {
if (typeof gutter[0] === 'number') {
Object.assign(paddingObj, {
paddingLeft: `${gutter[0] / 2}px`,
paddingRight: `${gutter[0] / 2}px`,
});
}

if (isObject(gutter[0]) && gutter[0][currentSize]) {
Object.assign(paddingObj, {
paddingLeft: `${gutter[0][currentSize] / 2}px`,
paddingRight: `${gutter[0][currentSize] / 2}px`,
});
}
} else if (isObject(gutter) && gutter[currentSize]) {
Object.assign(paddingObj, {
paddingLeft: `${gutter[currentSize] / 2}px`,
paddingRight: `${gutter[currentSize] / 2}px`,
});
}
return paddingObj;
};

const parseFlex = (flex: FlexType) => {
if (typeof flex === 'number') {
return `${flex} ${flex} auto`;
}

if (/^\d+(\.\d+)?(px|r?em|%)$/.test(flex)) {
return `0 0 ${flex}`;
}

return flex;
};

@tag('t-col')
export default class Col extends WeElement<ColProps> {
static css = css as string

static defaultProps = { offset: 0, order: 0, pull: 0, push: 0, tag: 'div' };

static propTypes = {
flex: [String, Number],
lg: [Number, Object],
md: [Number, Object],
offset: Number,
order: Number,
pull: Number,
push: Number,
sm: [Number, Object],
span: Number,
tag: String,
xl: [Number, Object],
xs: [Number, Object],
xxl: [Number, Object],
}
inject = [
'gutter', 'size'
]
render(props: OmiProps<ColProps>) {
const {
flex,
offset,
order,
pull,
push,
span,
tag,
class,
children,
style,
...otherColProps
} = props
const classPrefix = 't'
const allSizes = ['xs', 'sm', 'md', 'lg', 'xl', 'xxl'];
const sizeClasses = allSizes.reduce((acc, currSize) => {
const sizeProp = props[currSize];
let sizeObj: any = {};
if (typeof sizeProp === 'number') {
sizeObj.span = sizeProp;
} else if (isObject(sizeProp)) {
sizeObj = sizeProp || {};
}

return {
...acc,
[`${classPrefix}-col-${currSize}-${sizeObj.span}`]: sizeObj.span !== undefined,
[`${classPrefix}-col-${currSize}-order-${sizeObj.order}`]: parseInt(sizeObj.order, 10) >= 0,
[`${classPrefix}-col-${currSize}-offset-${sizeObj.offset}`]: parseInt(sizeObj.offset, 10) >= 0,
[`${classPrefix}-col-${currSize}-push-${sizeObj.push}`]: parseInt(sizeObj.push, 10) >= 0,
[`${classPrefix}-col-${currSize}-pull-${sizeObj.pull}`]: parseInt(sizeObj.pull, 10) >= 0,
};
}, {});
const colClassNames = classNames(
`${classPrefix}-col`,
props.class,
{
[`${classPrefix}-col-${span}`]: span !== undefined,
[`${classPrefix}-col-offset-${offset}`]: parseInt(offset as unknown as string, 10) >= 0,
[`${classPrefix}-col-pull-${pull}`]: parseInt(pull as unknown as string, 10) >= 0,
[`${classPrefix}-col-push-${push}`]: parseInt(push as unknown as string, 10) >= 0,
[`${classPrefix}-col-order-${order}`]: parseInt(order as unknown as string, 10) >= 0,
},
sizeClasses,
);

const colStyle = {
...calcColPadding(this.injection.gutter, this.injection.size),
...style
};
flex && (colStyle.flex = parseFlex(flex));
return (
<props.tag class={colClassNames} style={colStyle} {...otherColProps}>
{children}
</props.tag>
)
}
}
7 changes: 7 additions & 0 deletions tdesign/desktop/src/grid/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<script type="module" src="_example/base.tsx"></script>
</html>

<body>
<grid-base></grid-base>
</body>
8 changes: 8 additions & 0 deletions tdesign/desktop/src/grid/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import _Row from './row'
import _Col from './col'

import './style/index.js'
export * from './type'

export const Row = _Row
export const Col = _Col
140 changes: 140 additions & 0 deletions tdesign/desktop/src/grid/row.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { h, tag, WeElement, OmiProps, classNames } from 'omi'
import { RowProps } from './type'
import isObject from 'lodash/isObject';
import css from './style/index'
import { canUseDocument, getCssVarsValue } from '../utils/dom';


const calcSize = (width: number) => {
const smWidth = getCssVarsValue('--td-screen-sm') || 768;
const mdWidth = getCssVarsValue('--td-screen-md') || 992;
const lgWidth = getCssVarsValue('--td-screen-lg') || 1200;
const xlWidth = getCssVarsValue('--td-screen-xl') || 1400;
const xxlWidth = getCssVarsValue('--td-screen-xxl') || 1880;

let size = 'xs';
if (width >= xxlWidth) {
size = 'xxl';
} else if (width >= xlWidth) {
size = 'xl';
} else if (width >= lgWidth) {
size = 'lg';
} else if (width >= mdWidth) {
size = 'md';
} else if (width >= smWidth) {
size = 'sm';
} else {
size = 'xs';
}
return size;
};

const calcRowStyle = (gutter: RowProps['gutter'], currentSize: string): object => {
const rowStyle = {};
if (typeof gutter === 'number') {
Object.assign(rowStyle, {
marginLeft: `${gutter / -2}px`,
marginRight: `${gutter / -2}px`,
});
} else if (Array.isArray(gutter) && gutter.length) {
if (typeof gutter[0] === 'number') {
Object.assign(rowStyle, {
marginLeft: `${gutter[0] / -2}px`,
marginRight: `${gutter[0] / -2}px`,
});
}
if (typeof gutter[1] === 'number') {
Object.assign(rowStyle, { rowGap: `${gutter[1]}px` });
}

if (isObject(gutter[0]) && gutter[0][currentSize] !== undefined) {
Object.assign(rowStyle, {
marginLeft: `${gutter[0][currentSize] / -2}px`,
marginRight: `${gutter[0][currentSize] / -2}px`,
});
}
if (isObject(gutter[1]) && gutter[1][currentSize] !== undefined) {
Object.assign(rowStyle, { rowGap: `${gutter[1][currentSize]}px` });
}
} else if (isObject(gutter) && gutter[currentSize]) {
if (Array.isArray(gutter[currentSize]) && gutter[currentSize].length) {
Object.assign(rowStyle, {
marginLeft: `${gutter[currentSize][0] / -2}px`,
marginRight: `${gutter[currentSize][0] / -2}px`,
});
Object.assign(rowStyle, { rowGap: `${gutter[currentSize][1]}px` });
} else {
Object.assign(rowStyle, {
marginLeft: `${gutter[currentSize] / -2}px`,
marginRight: `${gutter[currentSize] / -2}px`,
});
}
}
return rowStyle;
};

@tag('t-row')
export default class Row extends WeElement<RowProps> {
static css = css as string

static defaultProps = { align: 'top', gutter: 0, justify: 'start', tag: 'div' };

static propTypes = {
align: String,
gutter: [Number, Object, Array],
justify: String,
tag: String,
class: String,
style: Object
}

size = canUseDocument ? calcSize(window.innerWidth) : 'md'
updateSize = () => {
const currentSize = calcSize(window.innerWidth)
if(currentSize !== this.size) {
//???
this.update()
}
}

install() {
window.addEventListener('resize', this.updateSize)
}

unintall() {
window.removeEventListener('resize', this.updateSize)
}

provide = {
gutter: this.props.gutter,
size: this.size
}

render(props: OmiProps<RowProps>) {
const {
align,
gutter,
justify,
tag,
children,
class,
style,
...otherRowProps} = props
const classPrefix = 't'
const rowClassNames = classNames(`${classPrefix}-row`, props.class, {
[`${classPrefix}-row-${props.justify}`]: true,
[`${classPrefix}-row-${props.align}`]: true
})

const rowStyle = {
...calcRowStyle(props.gutter, this.size),
// ...{props.style ? props.style : {}}
}

return (
<props.tag class={rowClassNames} style={rowStyle} {...otherRowProps} >
{children}
</props.tag>
)
}
}
3 changes: 3 additions & 0 deletions tdesign/desktop/src/grid/style/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import gridStyle from '../../_common/style/web/components/grid/_index.less'
import theme from '../../_common/style/web/theme/_index.less'
export default gridStyle + theme
Loading