DEV Community

Discussion on: Vanilla JavaScript and HTML - No frameworks. No libraries. No problem.

Collapse
 
zanehannanau profile image
ZaneHannanAU

Little annoying so with gitlab.com/zeen3/z3util-dom:

import { $cc, $cec, filter_map, noemp } from 'z3util-dom';

function createListWithTemplate(heroes: Hero[]) {
  return $cec(
    "ul",
    filter_map(
      heroes,
      hero => hero && $cec("li", [
        $cc("name", [hero.name]),
        $cc("description", [hero.description]),
      ]
    )
  );
}

though what's doing the work may end up a bit excessive:

/** Map an iterable list, filtering as necessary */
export function* filter_map<T, U>(list: T[] | IterableIterator<T>, f: ((t: T) => U | null | undefined)): IterableIterator<U> {
    let v, k
    for (k of list) if ((v = f(k)) != null) yield v;
}
export type Omit<T, K> = Pick<T, Exclude<keyof T, K>>;
type Appendable = HTMLElement | DocumentFragment | string;
type Queryable = Document | DocumentFragment | Element;
export type MaybeOr<T> = T | false | 0 | null | '' | undefined;
export type IterableOrNot<T> = MaybeOr<Iterable<MaybeOr<T>>>;
interface createelement<E> {
    <T extends keyof E>(el: T, o: Partial<Omit<E[T], "children" | "childNodes" | "classList" | "style">>): E[T];
}
/** Create element (with attributes) */
export const $ce: createelement<HTMLElementTagNameMap> = (el, o) => Object["assign"](document["createElement"](el), o);
/** Create element (with children, attributes) */
export const $cec = <T extends keyof HTMLElementTagNameMap>(
    name: T,
    children?: IterableOrNot<Appendable>,
    attrs?: Omit<Partial<HTMLElementTagNameMap[T]>, "children" | "childNodes" | "innerHTML" | "innerText" | "outerHTML">,
) => {
    let container = $ce(name, (attrs || {}) as unknown as any), el: MaybeOr<Appendable>;
    if (children) for (el of children) el && container["append"](el);
    return container
};
/** Create container (with classlist) */
export const $cc = (n: string, c?: IterableOrNot<Appendable>) => $cec("div", c, {"className": n});

But then again it's there to be specifically generic.

Collapse
 
themightyt_v3 profile image
theMightiestT

seems excessive.

Collapse
 
zanehannanau profile image
ZaneHannanAU

There's actually very little that's generated.

It's mostly typing information but even then...

Most of it is just expansion. If you expand all of it, it ends up being really short and roughly the same space as the template option.