Skip to main content

Utility Functions & API

The full source lives in assets/bao-custom-element.js. Below is a reference for the properties, getters, and methods available to any element that extends the base class.

Static getters (override these)

These are the declaration points for a component. Override them on your subclass to opt into behaviour.

GetterReturnsPurpose
requiredElementsstring[]Internal data-<id>-el names that must be present, or construction throws.
requiredExternalElementsstring[]External data-<id>-external-el names that must be present, or construction throws.
requiredAttributesstring[]Attribute names that must be set on the element, or construction throws.
stylesstringCSS applied via a shadow root. When empty (the default), no shadow root is attached.
class Modal extends window.BAO.CustomElement() {
static get requiredElements () {
return ['closeButton', 'panel']
}

static get requiredAttributes () {
return ['id']
}
}

Lifecycle methods

MethodWhen it runsNotes
connectedCallback()On insertion into the DOMGuarded so it only initialises once; calls setupListeners() then applyStyles().
disconnectedCallback()On removal from the DOMCalls this.listeners.removeAll() to clean up bound events.
setupListeners()Called from connectedCallbackOverride this to bind your event listeners. Empty by default.
applyStyles()Called from connectedCallbackWrites static styles into the shadow <style>. No-op when styles is empty.

Because connectedCallback is guarded by _hasBeenInitialised, an element that is moved around the DOM (or re-attached) will not re-run its setup.

Elements

getElements(identifiers, elementIdentifier?, { context? })

The workhorse behind els and externalEls. Takes an array of identifier strings and returns an object keyed by identifier, where each value is an El object.

  • Space-separated identifiers (e.g. 'item row') are treated as multiple sub-identifiers and matched with a *= (contains) selector; single identifiers use an exact = match.
  • When the element has a key attribute and you're resolving external elements, the key is included in the selector so keyed instances don't collide.
// Usually you don't call this directly — use the getters:
this.els // getElements(this._getElementIdentifiers())
this.externalEls // getElements(this._getExternalElementIdentifiers(), this._externalElIdentifier, { context: document })

Section Rendering

renderSections(stateSections)

For components tied to Shopify's Section Rendering API. Given an object of { sectionId: html } (as returned by the Cart AJAX API), it re-renders any sections registered in this.sections. It also preserves focus — the currently focused element's id is captured and re-focused (and re-selected, for inputs) after the re-render, so keyboard/typing state isn't lost.

class PushCart extends window.BAO.CustomElement() {
onAfterCartAdd (event) {
if ('sections' in event.detail.state) {
this.renderSections(event.detail.state.sections)
}

this.loading = false
}
}

handleCartErrorRender()

Re-fetches and re-renders the push-cart section from sectionRenderer.pushCartSections. Used to recover the cart UI when a cart operation errors.

Debugging

log(groupName, ...items)

A scoped console logger. Groups the output under groupName and logs each item — but only when this.debug is true (i.e. on a dev theme). This keeps production consoles clean while giving rich local output.

this.log('ProductForm: add to cart', payload, response)

throwError(message)

Throws an error prefixed with the element's identifier, e.g. <product-form>: needs a 'key' attribute. Used internally by checkValidity() and available for your own guard clauses.

Getters

GetterReturnsDescription
identifierstringThe element's name — the is attribute or localName, suffixed with key when present.
keystring \| nullThe key attribute, used to disambiguate multiple instances of the same element.
debugbooleantrue on a dev theme (window.theme.isDevTheme). Gates log().
hasBeenInitialisedbooleanWhether connectedCallback has already run.
elsObject<string, El>All internal elements, resolved from data-<id>-el attributes.
externalElsObject<string, El>All external elements, resolved from data-<id>-external-el attributes across the document.

The key attribute

Several helpers are key-aware. When you render the same element type more than once on a page, add a unique key attribute so that its identifier, external element lookups, and selectors are scoped to that instance and don't clash with its siblings.

<price-display key="pdp">...</price-display>
<price-display key="cart">...</price-display>