rabbit-design
Version:
A lightweight UI plugin library written in TypeScript and based on JavaScript
131 lines (107 loc) • 3.62 kB
text/typescript
import PREFIX from '../prefix';
import {
$el,
createElem,
getBooleanTypeAttr,
getStrTypeAttr,
removeAttrs,
setHtml
} from '../../dom-utils';
import { type, validComps } from '../../utils';
interface PublicMethods {
config(
el: string
): {
title: string;
extra: string;
};
}
class Card implements PublicMethods {
readonly VERSION: string;
readonly COMPONENTS: NodeListOf<Element>;
constructor() {
this.VERSION = 'v1.0';
this.COMPONENTS = $el('r-card', { all: true });
this._create(this.COMPONENTS);
}
public config(
el: string
): {
title: string;
extra: string;
} {
const target = $el(el);
validComps(target, 'card');
const CardTitle = target.querySelector(`.${PREFIX.card}-head`);
const CardExtra = target.querySelector(`.${PREFIX.card}-extra`);
return {
get title() {
return setHtml(CardTitle);
},
set title(newVal: string) {
if (type.isStr(newVal)) setHtml(CardTitle, newVal);
},
get extra() {
return setHtml(CardExtra);
},
set extra(newVal: string) {
if (type.isStr(newVal)) setHtml(CardExtra, newVal);
}
};
}
private _create(COMPONENTS: NodeListOf<Element>): void {
COMPONENTS.forEach((node) => {
this._createCardNodes(node);
removeAttrs(node, ['title', 'extra', 'shadow']);
});
}
private _createCardNodes(node: Element): void {
const CardHead = createElem('div');
const CardExtra = createElem('div');
const CardBody = createElem('div');
this._setCls(CardHead, CardExtra, CardBody);
this._setContent(node, CardBody);
this._setTitle(node, CardHead);
this._setExtra(node, CardExtra);
this._setShadow(node);
}
private _setCls(node1: HTMLElement, node2: HTMLElement, node3: HTMLElement): void {
node1.className = `${PREFIX.card}-head`;
node2.className = `${PREFIX.card}-extra`;
node3.className = `${PREFIX.card}-body`;
}
private _setTitle(parent: Element, children: HTMLElement): void {
const { title } = this._attrs(parent);
if (!title) return;
setHtml(children, title);
// 这里如果用 appendChild 会把头部节点放到内容节点后面
parent.prepend(children);
}
private _setContent(parent: Element, children: HTMLElement): void {
const contentNode: Element[] = Array.from(parent.children);
contentNode.forEach((node) => {
children.appendChild(node);
});
parent.appendChild(children);
}
private _setExtra(parent: Element, children: HTMLElement): void {
const { extra } = this._attrs(parent);
if (!extra) return;
setHtml(children, extra);
parent.appendChild(children);
}
private _setShadow(node: Element): void {
const { shadow } = this._attrs(node);
if (shadow) {
node.classList.add(`${PREFIX.card}-shadow`);
}
}
private _attrs(node: Element) {
return {
title: getStrTypeAttr(node, 'title', ''),
extra: getStrTypeAttr(node, 'extra', ''),
shadow: getBooleanTypeAttr(node, 'shadow')
};
}
}
export default Card;