提交 d6d20a34 编写于 作者: fly丶知秋's avatar fly丶知秋

feat: 增加宫格组件

上级 06888afa
......@@ -82,6 +82,14 @@ export namespace Components {
}
interface IvyEmpty {
}
interface IvyGrid {
"border": boolean;
"col": string;
"square": boolean;
}
interface IvyGridItem {
"col": string;
}
interface IvyImage {
"alt": string;
"lazy": boolean;
......@@ -93,8 +101,6 @@ export namespace Components {
}
interface IvyRow {
}
interface IvySpace {
}
interface IvyTag {
"size": string;
"theme": string;
......@@ -233,6 +239,18 @@ declare global {
prototype: HTMLIvyEmptyElement;
new (): HTMLIvyEmptyElement;
};
interface HTMLIvyGridElement extends Components.IvyGrid, HTMLStencilElement {
}
var HTMLIvyGridElement: {
prototype: HTMLIvyGridElement;
new (): HTMLIvyGridElement;
};
interface HTMLIvyGridItemElement extends Components.IvyGridItem, HTMLStencilElement {
}
var HTMLIvyGridItemElement: {
prototype: HTMLIvyGridItemElement;
new (): HTMLIvyGridItemElement;
};
interface HTMLIvyImageElement extends Components.IvyImage, HTMLStencilElement {
}
var HTMLIvyImageElement: {
......@@ -251,12 +269,6 @@ declare global {
prototype: HTMLIvyRowElement;
new (): HTMLIvyRowElement;
};
interface HTMLIvySpaceElement extends Components.IvySpace, HTMLStencilElement {
}
var HTMLIvySpaceElement: {
prototype: HTMLIvySpaceElement;
new (): HTMLIvySpaceElement;
};
interface HTMLIvyTagElement extends Components.IvyTag, HTMLStencilElement {
}
var HTMLIvyTagElement: {
......@@ -305,10 +317,11 @@ declare global {
"ivy-divider": HTMLIvyDividerElement;
"ivy-drawer": HTMLIvyDrawerElement;
"ivy-empty": HTMLIvyEmptyElement;
"ivy-grid": HTMLIvyGridElement;
"ivy-grid-item": HTMLIvyGridItemElement;
"ivy-image": HTMLIvyImageElement;
"ivy-pager": HTMLIvyPagerElement;
"ivy-row": HTMLIvyRowElement;
"ivy-space": HTMLIvySpaceElement;
"ivy-tag": HTMLIvyTagElement;
"ivy-timeline": HTMLIvyTimelineElement;
"ivy-timeline-item": HTMLIvyTimelineItemElement;
......@@ -391,6 +404,14 @@ declare namespace LocalJSX {
}
interface IvyEmpty {
}
interface IvyGrid {
"border"?: boolean;
"col"?: string;
"square"?: boolean;
}
interface IvyGridItem {
"col"?: string;
}
interface IvyImage {
"alt"?: string;
"lazy"?: boolean;
......@@ -403,8 +424,6 @@ declare namespace LocalJSX {
}
interface IvyRow {
}
interface IvySpace {
}
interface IvyTag {
"size"?: string;
"theme"?: string;
......@@ -445,10 +464,11 @@ declare namespace LocalJSX {
"ivy-divider": IvyDivider;
"ivy-drawer": IvyDrawer;
"ivy-empty": IvyEmpty;
"ivy-grid": IvyGrid;
"ivy-grid-item": IvyGridItem;
"ivy-image": IvyImage;
"ivy-pager": IvyPager;
"ivy-row": IvyRow;
"ivy-space": IvySpace;
"ivy-tag": IvyTag;
"ivy-timeline": IvyTimeline;
"ivy-timeline-item": IvyTimelineItem;
......@@ -477,10 +497,11 @@ declare module "@stencil/core" {
"ivy-divider": LocalJSX.IvyDivider & JSXBase.HTMLAttributes<HTMLIvyDividerElement>;
"ivy-drawer": LocalJSX.IvyDrawer & JSXBase.HTMLAttributes<HTMLIvyDrawerElement>;
"ivy-empty": LocalJSX.IvyEmpty & JSXBase.HTMLAttributes<HTMLIvyEmptyElement>;
"ivy-grid": LocalJSX.IvyGrid & JSXBase.HTMLAttributes<HTMLIvyGridElement>;
"ivy-grid-item": LocalJSX.IvyGridItem & JSXBase.HTMLAttributes<HTMLIvyGridItemElement>;
"ivy-image": LocalJSX.IvyImage & JSXBase.HTMLAttributes<HTMLIvyImageElement>;
"ivy-pager": LocalJSX.IvyPager & JSXBase.HTMLAttributes<HTMLIvyPagerElement>;
"ivy-row": LocalJSX.IvyRow & JSXBase.HTMLAttributes<HTMLIvyRowElement>;
"ivy-space": LocalJSX.IvySpace & JSXBase.HTMLAttributes<HTMLIvySpaceElement>;
"ivy-tag": LocalJSX.IvyTag & JSXBase.HTMLAttributes<HTMLIvyTagElement>;
"ivy-timeline": LocalJSX.IvyTimeline & JSXBase.HTMLAttributes<HTMLIvyTimelineElement>;
"ivy-timeline-item": LocalJSX.IvyTimelineItem & JSXBase.HTMLAttributes<HTMLIvyTimelineItemElement>;
......
:host {
display: block;
box-sizing: border-box;
border-right: var(--ivy-grid-item-border);
border-bottom: var(--ivy-grid-item-border);
width: var(--ivy-grid-item-width);
height: var(--ivy-grid-item-height);
}
import { Component, Host, h, State, Prop, Watch, Element } from '@stencil/core';
@Component({
tag: 'ivy-grid-item',
styleUrl: 'ivy-grid-item.css',
shadow: true,
})
export class IvyGridItem {
@Element() $el: HTMLElement;
@State() _col: number = 3;
@Prop() col: string = '3';
@Watch('col')
watchColHandler(val: string) {
const tmp = parseInt(val);
if (tmp !== this._col) {
throw new Error(`type attr is must be string number`);
}
this._col = tmp;
}
render() {
return (
<Host>
<slot></slot>
</Host>
);
}
}
import { newE2EPage } from '@stencil/core/testing';
describe('ivy-grid-item', () => {
it('renders', async () => {
const page = await newE2EPage();
await page.setContent('<ivy-grid-item></ivy-grid-item>');
const element = await page.find('ivy-grid-item');
expect(element).toHaveClass('hydrated');
});
});
import { newSpecPage } from '@stencil/core/testing';
import { IvyGridItem } from '../ivy-grid-item';
describe('ivy-grid-item', () => {
it('renders', async () => {
const page = await newSpecPage({
components: [IvyGridItem],
html: `<ivy-grid-item></ivy-grid-item>`,
});
expect(page.root).toEqualHtml(`
<ivy-grid-item>
<mock:shadow-root>
<slot></slot>
</mock:shadow-root>
</ivy-grid-item>
`);
});
});
:host {
display: flex;
box-sizing: border-box;
flex-wrap: wrap;
}
:host([border]) {
border-left: 1px solid var(--ivy-border-color, #dcdfe6);
border-top: 1px solid var(--ivy-border-color, #dcdfe6);
--ivy-grid-item-border: 1px solid var(--ivy-border-color, #dcdfe6);
}
import { Component, Host, h, Prop, Watch, State, Element, writeTask } from '@stencil/core';
@Component({
tag: 'ivy-grid',
styleUrl: 'ivy-grid.css',
shadow: true,
})
export class IvyGrid {
@Element() $el: HTMLElement;
@State() styles: { [key: string]: string } = {
'--ivy-grid-item-width': `33.3333333%`,
};
@Prop() square: boolean = false;
@Prop({
attribute: 'border',
reflect: true,
})
border: boolean = false;
@Prop() col: string = '3';
@Watch('col')
watchColHandler(val: string) {
const tmp = parseInt(val);
if (tmp.toString() !== val) {
throw new Error(`type attr is must be string number`);
}
}
componentWillLoad() {
writeTask(() => {
let wrapWidth = this.$el.getBoundingClientRect().width;
if (this.border) {
wrapWidth -= 1;
}
const widthNumber = wrapWidth / parseInt(this.col);
const width = parseInt((widthNumber * 1000).toString()) / 1000;
if (this.square) {
this.styles = {
'--ivy-grid-item-width': `${width}px`,
'--ivy-grid-item-height': `${width}px`,
};
} else {
this.styles = { '--ivy-grid-item-width': `${width}px` };
}
});
}
render() {
return (
<Host style={this.styles}>
<slot></slot>
</Host>
);
}
}
import { newE2EPage } from '@stencil/core/testing';
describe('ivy-space', () => {
describe('ivy-grid', () => {
it('renders', async () => {
const page = await newE2EPage();
await page.setContent('<ivy-space></ivy-space>');
await page.setContent('<ivy-grid></ivy-grid>');
const element = await page.find('ivy-space');
const element = await page.find('ivy-grid');
expect(element).toHaveClass('hydrated');
});
});
import { newSpecPage } from '@stencil/core/testing';
import { IvySpace } from '../ivy-space';
import { IvyGrid } from '../ivy-grid';
describe('ivy-space', () => {
describe('ivy-grid', () => {
it('renders', async () => {
const page = await newSpecPage({
components: [IvySpace],
html: `<ivy-space></ivy-space>`,
components: [IvyGrid],
html: `<ivy-grid></ivy-grid>`,
});
expect(page.root).toEqualHtml(`
<ivy-space>
<ivy-grid>
<mock:shadow-root>
<slot></slot>
</mock:shadow-root>
</ivy-space>
</ivy-grid>
`);
});
});
:host {
display: inline-flex;
box-sizing: border-box;
}
:host(vertical) {
flex-direction: column;
}
.space {
display: inline-flex;
box-sizing: border-box;
}
.space-item {
margin-right: 12px;
box-sizing: border-box;
}
.space-item:last-child {
margin-right: 0;
}
:host([align='center']),
:host([align]) {
align-items: center;
}
:host([align='start']) {
align-items: flex-start;
}
:host([align='end']) {
align-items: flex-end;
}
:host([align='baseline']) {
align-items: baseline;
}
.hidden {
display: none;
}
import { Component, Host, h, Element, State } from '@stencil/core';
@Component({
tag: 'ivy-space',
styleUrl: 'ivy-space.css',
shadow: true,
})
export class IvySpace {
@State() children = [];
@Element() el: HTMLElement;
render() {
return (
<Host>
<div class="space">
{this.children.map(c => {
return (
<div class="space-item">
{c.nodeType === 3
? c.textContent
: h(
c.nodeName.toLowerCase(),
{
...c,
},
c.textContent,
)}
</div>
);
})}
</div>
<div class="hidden">
<slot></slot>
</div>
</Host>
);
}
componentWillLoad() {
this.children = [];
this.el.childNodes.forEach(el => {
console.log(el.nodeType);
if (el.nodeType === 1) {
this.children.push(el);
} else if (el.nodeType === 3 && el.textContent.trim() !== '') {
this.children.push(el);
}
});
console.log(this.children);
}
}
......@@ -55,12 +55,22 @@
</div>
<div>
<ivy-space>
Text 文字
<ivy-button>
<span>Button</span>
</ivy-button>
</ivy-space>
<ivy-grid border square col="4">
<ivy-grid-item>
<span>Button 1</span>
</ivy-grid-item>
<ivy-grid-item>
Button 2 <br>324324
</ivy-grid-item>
<ivy-grid-item>
<span>Button 3</span>
</ivy-grid-item>
<ivy-grid-item>
Button 2 <br>324324
</ivy-grid-item>
</ivy-grid>
<ivy-aspect-ratio width="40vw" js>312312</ivy-aspect-ratio>
</div>
......
......@@ -31,3 +31,14 @@ export const getBrotherElements = (self: HTMLElement, isSelf: Boolean = false) =
}
return list;
};
/**
* 查询当前元素下符合条件的所有元素
* @param self
* @param tag 合法的css选择器
* @returns
*/
export const findChildrenElements = (self: HTMLElement, tag: string) => {
const children = self.querySelectorAll(tag);
return children as unknown as Array<HTMLElement>;
};
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册