@linttrapmedia/oem-element v1.0.4
oem-element
oem-element is part of OEM. OEM is a UI/UX ecosystem of 100% dependency-free ui libraries implemented as light abstraction layers on top of the already existing native browser javascript objects. This makes for incredibly small, easy-to-understand libraries that leverage your pre-existing knowledge of html, css and javascript.
OEM.Element
is OEM's "templating engine". It enables you to manage html, styling and behavior with a clean, declarative syntax implemented as a light abstraction on top of the native Element object.
Get Started
Using it as a Typescript dependency
Install
npm i @linttrapmedia/oem-element
Import and use
import { DIV } from "@linttrapmedia/oem-element";
DIV.innerText("Hello World");
Using when loaded from a CDN - ~3kb
Gzipped
Load in html head
<script src="https://unpkg.com/@linttrapmedia/oem-element"></script>
Destructure and use in plain javascript
const { DIV } = OEM.Element;
DIV.innerText("Hello World");
API
Tags
There is a single html tag function per html tag. All tag functions exist in the OEM.Element
object.
A
, AREA
, ARTICLE
, ASIDE
, AUDIO
, B
, BASE
, BDI
, BDO
, BLOCKQUOTE
, BODY
, BR
, BUTTON
, CANVAS
, CAPTION
, CITE
, CODE
, COL
, COLGROUP
, DATA
, DATALIST
, DD
, DEL
, DETAILS
, DFN
, DIALOG
, DIV
, DL
, DT
, EM
, EMBED
, FIELDSET
, FIGCAPTION
, FIGURE
, FOOTER
, FORM
, H1
, H2
, H3
, H4
, H5
, H6
, HEAD
, HEADER
, HGROUP
, HR
, HTML
, I
, IFRAME
, IMG
, INPUT
, INS
, KBD
, LABEL
, LEGEND
, LI
, LINK
, MAIN
, MAP
, MARK
, MENU
, META
, METER
, NAV
, NOSCRIPT
, OBJECT
, OL
, OPTGROUP
, OPTION
, OUTPUT
, P
, PICTURE
, PRE
, PROGRESS
, Q
, RP
, RT
, RUBY
, S
, SAMP
, SCRIPT
, SECTION
, SELECT
, SLOT
, SMALL
, SOURCE
, SPAN
, STRONG
, STYLE
, SUB
, SUMMARY
, SUP
, TABLE
, TBODY
, TD
, TEMPLATE
, TEXTAREA
, TFOOT
, TH
, THEAD
, TIME
, TITLE
, TR
, TRACK
, U
, UL
, VAR
, VIDEO
, WBR
Methods
Each tag function uses the "builder pattern" which allows you to quickly and easily write html in javascript that is every bit as declarative and readable as regular html but with the added benefit of declaring styling and behavior inline in a clean and scalable way. There are two types of methods: Non-Rendering (which configure the element) and Rendering (which render the element).
addEventListener(ev, cb)
- adds an event listenerattr(name, val, condition)
- adds an attributeclassName(className, condition)
- adds an css class namesubscribe(subscriptionFunction, handler)
- subscribes to an event busstyle(prop, val, condition)
- adds a styleappend(...nodes)
- appends nodes to element and rendersinnerHTML(html)
- sets innerHTML and rendersinnerText(text)
- sets innerText and rendersrender()
- renders empty element
Non Rendering Methods
addEventListener(ev, cb)
- adds an event listener
ev: keyof GlobalEventHandlers,
cb: (e: Event) => any
attr(name, val, condition)
- adds an attribute
name: string // name of attribute
val: string | (() => string) // value of attribute, string or callback
condition?: boolean | (() => boolean) // condition check
className(className, condition)
- adds an css class name
className: string // name of class
condition?: boolean | (() => boolean) // condition check
subscribe(subscriptionFunction, handler)
- subscribes to an event bus
Subscribing to event buses causes the element rerender each time the event bus broadcasts.
subscriptionFunction: (cb: () => void) => void,
handler?: (el: ThisType<OEM_ELEMENT<T>>) => void
style(prop, val, condition)
- adds a style
prop: keyof CSSStyleDeclaration // css property
val: string | (() => string) // css value
condition?: boolean | (() => boolean) | "hover" // condition check
Rendering Methods - These must be called last in the chain
append(...nodes)
- appends nodes to element and renders
nodes: (string | Node)[]
innerHTML(html)
- sets innerHTML and renders
html: HTMLElement | (() => HTMLElement)
innerText(text)
- sets innerText and renders
text: (string | number) | (() => string | number)
render()
- renders empty element
// no args
Examples
Basic Usage
Rendering DOM elements is easy. Configure the object with non-rendering methods and then call one of the rendering methods.
Render an empty element
DIV.render(); // <div></div>
Render element with inner text
DIV.innerText("example"); // <div>example</div>
// --- or ---
DIV.innerText(() => "example"); // <div>example</div>
Render element with html
DIV.innerHTML(DIV.innerText("example")); // <div><div>example</div></div>
// --- or ---
DIV.innerHTML(() => DIV.innerText("example")); // <div><div>example</div></div>
Render element with multiple attributes and styles and conditions.
Notice how we can define multiples of the same attribute or style and add a condition? This allows us to dynamically declare state inline without the code falling apart.
UL.attr("id", "example")
.style("list-style", "none")
.append(
LI.style("color", "blue").innerText("A"),
LI.style("color", "red").innerText("B")
);
// <ul id="example" style="list-style:none;">
// <li style="color:blue;">A</li>
// <li style="color:red;">A</li>
// </ul>
// --- or ---
UL.attr("id", "example")
.style("list-style", "square", isSquareTheme()) // let's pretend isSquareTheme() is true
.style("list-style", "none", !isSquareTheme())
.append(
LI.style("color", "blue").innerText("A"),
LI.style("color", "red").innerText("B")
);
// <ul id="example" style="list-style:square;">
// <li style="color:blue;">A</li>
// <li style="color:red;">A</li>
// </ul>
Events
Attach events using the addEventListener
method.
BUTTON.addEventListener("click", () => alert("hi")).innerText(
"Click me to show alert"
);
// <button>Click me to show alert</button>
Reactivity
Reactivity is achieved by using callbacks for the values you provide to attr
, style
, innerText
and innerHTML
and subscribing to an event bus. You can use your own event bus but we recommend one of OEM's data type libraries which map to each data type in javascript (String
, Number
, Array
, etc...) in keeping with OEM's core concept.
Basic Concept
// using the oem-string lib
// OEM.STRING - creates a String object that is an event bus
const greeting = OEM.STRING("hello");
// greeting.val - returns the current value
// greeting.set - sets the value and broadcasts
// create greeter element
DIV.subscribe(greeting.sub).innerText(greeting.val);
// greeter element is currently: <div>hello</div>
greeting.set("goodbye");
// greeter element has now changed to: <div>goodbye</div>
Example
const greeting = OEM.STRING("hello");
const handleInput = (evt) => greeting.set(evt.target.value);
DIV.subscribe(greeting.sub).innerText(greeting.val);
INPUT.addEventListener("input", handleInput).render();
// Result: The div outputs whatever's typed into the input
DEMO
Visit oem.js.org for full tutorials, demos, etc.