UNPKG

rabbit-simple-ui

Version:

A simple UI component library based on JavaScript

205 lines (169 loc) 6.26 kB
import { $el, bind, getBooleanTypeAttr, getStrTypeAttr, removeAttrs, setCss, setHtml } from '../../dom-utils'; import { destroyElem, validComps } from '../../utils'; import { isFn } from '../../utils/check-type'; import PREFIX from '../prefix'; interface Config { config( el: string ): { events({ onClose, onChange }: TagEvents): void; }; } interface TagEvents { onClose?: ($this: Element) => void; onChange?: (checked: boolean) => void; } class Tag implements Config { readonly VERSION: string; readonly COMPONENTS: NodeListOf<Element>; constructor() { this.VERSION = '1.0'; this.COMPONENTS = $el('r-tag', { all: true }); this._create(this.COMPONENTS); } public config( el: string ): { events({ onClose, onChange }: TagEvents): void; } { const target = $el(el); validComps(target, 'tag'); const CloseIcon = target.querySelector(`.${PREFIX.icon}-ios-close`); const $this = target; let checked: boolean; return { events({ onClose, onChange }: TagEvents) { bind(target, 'click', () => { checked = target.dataset.checked === 'true' ? true : false; onChange && isFn(onChange, checked); }); if (!CloseIcon) return; bind(CloseIcon, 'click', (e: Event) => { e.stopPropagation(); onClose && isFn(onClose, $this); }); } }; } private _create(COMPONENTS: NodeListOf<Element>): void { COMPONENTS.forEach((node) => { const { type, size, color, checked, checkable, closable } = this._attrs(node); this._setMainTemplate(node); this._setType(node, type); this._setIsChecked(node, checked); this._setSize(node, size); this._setColor(node, type, checkable, color); this._setClosable(node, closable); this._setCheckable(node, checkable); this._handleClose(node, closable); removeAttrs(node, ['type', 'size', 'color', 'checked', 'checkable', 'closable']); }); } private _setMainTemplate(node: Element): void { const content = setHtml(node); setHtml(node, `<span class="${PREFIX.tag}-text">${content}</span>`); } private _setType(node: Element, type: string) { if (type) node.classList.add(`${PREFIX.tag}-${type}`); if (type === 'dot') { node.insertAdjacentHTML('afterbegin', `<span class="${PREFIX.tag}-dot-inner"></span>`); } } private _setIsChecked(node: Element, checkable: string): void { if (checkable !== 'true') return; node.classList.add(`${PREFIX.tag}-checked`); } private _setColor(node: Element, type: string, checkable: boolean, color: string): void { const { _defaultColors } = this; const isUseDefaultColor = _defaultColors().includes(color); const TagText = node.querySelector(`.${PREFIX.tag}-text`); if (!color) return; if (isUseDefaultColor) { node.classList.add(`${PREFIX.tag}-${color}`); } else { setCss(node, 'background', `${color}`); setCss(node, 'borderColor', `${color}`); } if (color !== 'default' && type !== 'dot' && type !== 'border' && !checkable) { TagText?.classList.add(`${PREFIX.tag}-color-white`); } if (isUseDefaultColor && type === 'border') { TagText?.classList.add(`${PREFIX.tag}-color-${color}`); } else { setCss(TagText, 'color', `${color}`); } } private _setSize(node: Element, size: string): void { if (!size) return; node.classList.add(`${PREFIX.tag}-size-${size}`); } private _setClosable(node: Element, closable: boolean): void { if (!closable) return; node.classList.add(`${PREFIX.tag}-closable`); node.insertAdjacentHTML( 'beforeend', `<i class="${PREFIX.icon} ${PREFIX.icon}-ios-close"></i>` ); } private _setCheckable(node: Element, checkable: boolean): void { if (!checkable) return; node.classList.remove(`${PREFIX.tag}-checked`); const TagText = node.querySelector(`.${PREFIX.tag}-text`); bind(node, 'click', () => { const isChecked = node.classList.contains(`${PREFIX.tag}-checked`); // @ts-ignore node.dataset.checked = !isChecked; node.classList[isChecked ? 'remove' : 'add'](`${PREFIX.tag}-checked`); TagText?.classList[isChecked ? 'remove' : 'add'](`${PREFIX.tag}-color-white`); }); } private _handleClose(node: Element, closable: boolean): void { if (!closable) return; const CloseIcon = node.querySelector(`.${PREFIX.icon}-ios-close`); bind(CloseIcon, 'click', () => { destroyElem(node, { fadeOut: true }); }); } private _defaultColors(): string[] { const COLORS = [ 'default', 'primary', 'success', 'warning', 'error', 'blue', 'green', 'red', 'yellow', 'pink', 'magenta', 'volcano', 'orange', 'gold', 'lime', 'cyan', 'geekblue', 'purple' ]; return COLORS; } private _attrs(node: Element) { return { type: getStrTypeAttr(node, 'type', ''), size: getStrTypeAttr(node, 'size', ''), color: getStrTypeAttr(node, 'color', 'default'), checked: getStrTypeAttr(node, 'checked', 'true'), closable: getBooleanTypeAttr(node, 'closable'), checkable: getBooleanTypeAttr(node, 'checkable') }; } } export default Tag;