jiro-ui
Version:
A Mithril.js UI library based from construct-ui
81 lines (65 loc) • 2.13 kB
text/typescript
import m from 'mithril';
import classnames from 'classnames';
import { Classes, IAttrs, getClosest, safeCall } from '../../_shared';
import { isFunction } from 'util';
export interface IListItemAttrs extends IAttrs {
/** Toggles active state */
active?: boolean;
/** Allow onclick event to be processed for contentLeft/contentRight */
allowOnContentClick?: boolean;
/** Left-justified content */
contentLeft?: m.Children;
/** Right-justified content */
contentRight?: m.Children;
/** Toggles disabled state */
disabled?: boolean;
/** Toggles selected state */
selected?: boolean;
/** Inner text or content */
label?: m.Children;
/** Callback invoked on click */
onclick?: (e: Event) => void;
[htmlAttrs: string]: any;
}
export class ListItem implements m.Component<IListItemAttrs> {
public view({ attrs }: m.Vnode<IListItemAttrs>) {
const {
active,
class: className,
contentLeft,
contentRight,
disabled,
selected,
label,
onclick,
...htmlAttrs
} = attrs;
const classes = classnames(
Classes.LIST_ITEM,
active && Classes.ACTIVE,
disabled && Classes.DISABLED,
selected && Classes.SELECTED,
className
);
const content = [
contentLeft && m(`.${Classes.LIST_ITEM_CONTENT_LEFT}`, contentLeft),
label,
contentRight && m(`.${Classes.LIST_ITEM_CONTENT_RIGHT}`, contentRight)
];
return m('', {
...htmlAttrs,
class: classes,
onclick: (e: Event) => this.handleClick(e, attrs)
}, content);
}
private handleClick(e: Event, attrs: IListItemAttrs) {
const { allowOnContentClick, onclick } = attrs;
const el = e.target as HTMLElement;
const isLeftContentClick = getClosest(el, `.${Classes.LIST_ITEM_CONTENT_LEFT}`);
const isRightContentClick = getClosest(el, `.${Classes.LIST_ITEM_CONTENT_RIGHT}`);
const allowContentClick = allowOnContentClick || (!isLeftContentClick && !isRightContentClick);
if (isFunction(onclick) && allowContentClick) {
safeCall(onclick, e);
} else (e as any).redraw = false;
}
}