Many UI libraries and CSS frameworks used to enable special functionality by resorting to CSS classes or item IDs.
This was especially trendy at the time of jQuery plugins.
Despite being a very popular choice, it's definitely a programming anti-pattern.
Today we have several alternative ways. One approach from the functional-reactive land makes it possible to just "merge" functionality into an existing element. No CSS classes, no id
attribute abuse.
Suppose we want to enable drag'n'drop in an HTML list by means of a separate reusable module we can add or remove at will.
<ul ...${Sortable(options)}>
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
<li>item 5</li>
</ul>
This Sortable
is going to be implemented in what's known as a Mixin. What a mixin does is exporting attributes, styles, classes, event handlers or other attribuends in a so called "DOM Object": whatever it contains, will be merged in the target element.
// sortable.ts
import { Subject, map, withLatestFrom } from 'rxjs';
export const Sortable = ({ onOrderChange }) => {
const dragStart = new Subject<HTMLLIElement>();
const drop = new Subject<HTMLLIElement>();
drop.pipe(
withLatestFrom(dragStart),
map(([dropEvt, dragEvt]) => {
const list = [...dragEvt.target.closest('ol,ul').children];
return [
list.indexOf(dragEvt.target),
list.indexOf(dropEvt.target.closest('li')),
];
}),
).subscribe(([src, dst])=>onOrderChange(src, dst));
// Export a DOM Object for a framework or UI library
// to take care of and merge into the target element
return {
ondragstart: dragStart,
ondragover: e=>e.preventDefault(),
ondrop: drop,
};
};
What is ObservableTypes?
ObservableTypes is a tiny little library combining together a few modern design patterns to facilitate zero-boilerplate development using repeatable UI elements.
In other words its main feature — the Collection — is a hybrid between the Array, the Observable and the Obsever, so it can be seamlessly connected to any streaming utility library and framework. RxJS and Rimmel.js are two great examples, where the former is best to manage any sort of stream in general (yes, everything that happens on a UI is just streams of events and data) and Rimmel is best at displaying them using the same Observable/Observer format.
ObservableTypes removes the burden of repeated code actions.
Go play with a working example here. It's easier done than said!
Top comments (0)