Understanding HAXSchema, the API powering our editor
Bryan Ollendyke
Posted on November 17, 2021
In getting a colleague up to speed on how HAX works, I realized that in the 4 years since we initially started devloping and describing this idea, that the underlying API to power elements really hasn't changed. A talk from 2018 brought back into focus the power of building on APIs of giants; or in our case, JSON Schema.
HAXSchema's properties declarations for the "configure" and "advanced" form areas in HAX are built on this abstraction. It's broken down into it's simplest form as follows for each tuple:
{
"property": "source",
"title": "Source",
"description": "The URL for this video.",
"inputMethod": "textfield"
}
HAXSchema can either use the word attribute
, property
, or slot
as an attribute in its tuple in order to declare to the HAX editor what prop, attribute or slot the inputMethod
is to act upon. We have a ton of valid inputMethod
's for use but the most common ones are:
- textfield (text)
- select (which then requires
options: {}
be supplied) - boolean (checkbox)
- code-editor (a full VSCode instance)
- alt (alt text validated input w/ suggestions)
- number (numerical input)
- datepicker (date picker)
- colorpicker (simple colors selector)
- fileupload (upload file)
- iconpicker (icon picker based on simple icons)
We also have support for any input we want to supply the above. When inspecting the DOM we'd note that we don't just render a <input type="checkbox">
but instead a <simple-fields-field type="checkbox">
. This is because using JSON Schema below, HAXSchema is able to map inputMethod
to an element as long as it supplies a value-changed
response.
Record scratch dot gif
Wait. Not just input... but "element"? By actings like a <input>
element is any other web element, were able to wire anything to anything in hax. 😮
Effectively.. anything that supplies a value-changed
CustomEvent
will be able to talk to HAX using this abstraction of JSON Schema.
a11y-gif-player
Let's see how our gif player uses other web components to generate an input form that allows file uploading.
This web component has the following schema for the upload form:
{
"property": "src",
"title": "Animated GIF",
"description": "The URL to your animated GIF.",
"inputMethod": "haxupload",
"icon": "link",
"validationType": "url",
"required": true
}
This takes the property src
and then wires it up to "haxupload". "haxupload" inputMethod is defined by the JSON Schema abstraction to map to the the following form input element:
And it's DOM tree looks like:
All because hax-upload-field
can output an event of value-changed
, and we have an underlying standard JSON Schema, we're effectively able to wire it to HAX.
Abstraction over a life time
Three years ago when we gave a talk showing the a11y-gif-player
, the tag was wired to "textfield". At that time, hax-upload-field
didn't exist. The above screen shot shows how we translate calls for haxupload
inputMethod into a usable form input. This translation layer now allow us to build ANY form, hax or otherwise, out of this abstraction of HAXSchema. It's actually a stand alone project called simple-fields and it's anything but simple (as is the case with our simple-
namespace, making it simple for end users.
The point being, our design asset for a11y-gif-player never changed. The design has been the same for 4 years, regardless of iterations in HAX. The usage of HAXSchema to loosely couple the design to the editor has allowed us to progressively enhance the editorial experience while the design asset is used in production for years.
This is part of why we feel HAX is a living, sustainable application. The things it produces are preserved in a format that works with or without it. It's API for building the form and it's capabilities can evolve agnostic of the "bricks" implementing it.
Looking for more hax wired blocks to use in your project? Here's a tag we ship with our NPM packages. Happy building!
Posted on November 17, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.