Javascript
Global
Global

Javascript

Import the javascript file with import { Xt } from 'xtendui'.

Usability

Activate usability logs with import 'xtendui/src/usability'. Xtend UI will sends warning messages with website usability suggestions.

SyntaxDefault / ArgumentsDescription
VariableXt.usabilityHostnames:Boolean|String'127.0.0.1 localhost'Enable usability checks on hostnames separated by space
VariableXt.usabilityIgnore:String'.sf-toolbar, .gm-style'Disable usability checks inside this query

Xt.ready

You can execute a function on Document.readyState, by default it listens when document is ready.

SyntaxDefault / ArgumentsDescription
VariableXt.ready:Function{ func:Function, state:String = 'interactive complete', raf:Boolean = false }Execute a function on Document.readyState, states separated by space, can be 'loading''interactive''complete'

Xt.mount

You can add Javascript code as a vanilla component with Xt.mount.

Mount listens and execute the query with Mutation Obsever. So the code gets executed also if the Node is added on the DOM asynchronously.

You can return a function to execute when the Node is removed from the DOM.

You can also use the class .xt-ignore when moving objects to prevent mount and unmount.

Xt.mount doesn't unmount/remount nodes not removed from html (e.g. when moving nodes inside DOM).

SyntaxDefault / ArgumentsDescription
Optionmatches:QuerynullQuery to match for mount
Optionroot:NodenullOnly if added nodes are inside a root node
Optionraf:BooleanfalseUse requestAnimationFrame for mount as with Xt.ready
OptionignoreMount:Query|false'.xt-ignore'Ignore mount on nodes with closest this query.
OptionignoreUnmount:Query|false'.xt-ignore'Ignore unmount on nodes with closest this query.
Optionmount:FunctionnullFunction to execute on mount, returned function will be executed on unmount

Here's mount function arguments.

SyntaxDescription
Variableref:NodeMounted node
Variableobj:ObjectMounted object
Variableindex:NumberMounted index on the same mount
Xt.mount({
  matches: '.my-query',
  mount: ({ ref, obj, index }) => {
    // logic

    console.debug('mounted', ref, obj, index)

    // unmount

    return () => {
      console.debug('unmounted', ref)
    }
  },
})

Xt.on and Xt.off

To show/hide and animate nodes we use custom Tailwind CSS variants that react to classes.

Use off:hidden out:pointer-events-none to hide with display: none; the node when not activated or animating.

Alternatively you can use your own custom style, for example off:invisible off:pointer-events-none out:pointer-events-none.

Use absolute top-0 left-0 right-0 on:relative to position the node in absolute mode when not activated.

You can toggle activations with javascript.

SyntaxDescription
MethodXt.on({ el:Node, ns:String = '', duration:Number|null = null, raf:Boolean = true, initial:Boolean = false, callback:Function|null })Activate node with .on.in.out.done, set initial for instant animations
MethodXt.off({ el:Node, ns:String = '', duration:Number|null = null, raf:Boolean = true, initial:Boolean = false, callback:Function|null })Dectivate node with .on.in.out.done, set initial for instant animations

You can also assign duration on single nodes with data-xt-duration="Milliseconds" or data-xt-duration-in="Milliseconds" and data-xt-duration-out="Milliseconds"

Use Tailwind CSS variants off:, group-off:, on:, group-on:, in:, group-in:, out:, group-out: to assign animations.

You can use also css animations, just add them with class names .on, .in, .out, .done, .dir-before and .dir-after.

Xt.get

You can get self object from DOM node on Xtend UI components.

SyntaxDescription
MethodXt.get({ name:String, el:Node })Get self object on DOM node for that component name (e.g. 'xt-toggle')

For example if you want to get the drop object on a particular node.

let self = Xt.get({ name: 'xt-drop', el: document.querySelector('.my-container') })

The components initialization of data-xt- or Xt.mount is ready after document ready, so if you use react use useLayoutEffect hook or Xt.ready or Xt.mount or init.xt. event to access the data after document ready.

Xt.options

You can set default options for all components of the same type, they get applied after default options and before custom options.

SyntaxDescription
VariableXt.options:ObjectSet default options for that component name (e.g. 'xt-toggle')

For example if you want all drops to have a duration of 500.

Xt.options['xt-drop'] = {
  duration: 500,
}

Be sure to assing Xt.options in a imported setup file before all other components imports or the data-xt- initialized components doesn't have those options.

Xt.sanitize

You can sanitize a html string with DOMPurify using Xt.sanitize. This method is used also internally to sanitize content added to DOM.

SyntaxDescription
MethodXt.sanitize(str:String)Sanitize string with DOMPurify, returns String

Xt.node

You can create DOM node from string with this method. The string is automatically sanitized with Xt.sanitize.

SyntaxDescription
MethodXt.node({ str:String, sanitize:Boolean = true })Create DOM node from string, returns Node
MethodXt.nodes({ str:String, sanitize:Boolean = true })Create DOM nodes from string, returns NodeList

Xt.visible

You can check if node is visible with display with this method.

SyntaxDescription
MethodXt.visible({ el:Node })Check if node is visible with display, returns Boolean

Xt.script

You can add external scripts to document with this method that gets executed immediately.

SyntaxDescription
MethodXt.script({ url:String, callback:Function = null, defer:Boolean = true, async:Boolean = true })Add script to body

Xt.queryAll

You can query multiple nodes at once with this method.

SyntaxDescription
Method`Xt.queryAll({ els:NodeListArray, query:String })`

Xt.getTranslate

You can get translate values with this method.

SyntaxDescription
MethodXt.getTranslate({ el:Node })Get [x, y] translate values on a DOM node, returns Array

Xt.innerHeight

You have some utilities for viewport height that changes only on horizontal resize, useful to have mobile viewport height that doesn't resize on vertical scroll.

SyntaxDescription
VariableXt.innerHeight:NumberGet window height without mobile resize on page scroll

Or also use css variables for viewport height --vh.

.my-selector {
  height: 100vh;
  height: calc(var(--vh, 1vh) * 100);
}

resize.xt

For resize event we use a special event resize.xt that gets triggered only once after a delay. Also fixes interaction jumping on mobile devices because it doesn't trigger on vertical scroll/resize on mobile when viewport width doesn't change and matchMedia('(hover: none)').matches.

To force the resize.xt event you can dispatch resize event with detail.force = true.

dispatchEvent(new CustomEvent('resize', { detail: { force: true } }))

You can customize the delay of resize and medialoaded events.

SyntaxDefault / ArgumentsDescription
VariableXt.resizeSkip:Function() => matchMedia('(hover: none), (pointer: coarse)').matchesSkip trigger resize.xt on vertical only resize if this condition is met
VariableXt.resizeDelay:Number|false200Delay for the resize.xt event
VariableXt.medialoadedDelay:Number|falsefalseDelay for the mediaLoaded event

Globals

If you need to access Xt variable in the global window use window.XtSetGlobal in a script tag before the main application or in your testing environment.

SyntaxDefault / ArgumentsDescription
Variablewindow.XtSetGlobal:Boolean|StringnullEnable window.Xt global variable

Listeners

Listen to events on a single Node.

const node = document.querySelector('.my-node')

const on = e => {
  // logic
}

node.addEventListener('eventname.xt.componentname', on)

Listen to events on multiple Nodes.

for (const node of document.querySelectorAll('.my-node')) {
  const on = e => {
    // logic
  }

  node.addEventListener('eventname.xt.componentname', on)
}

Listen to events on multiple Nodes with events delegation useCapture.

This method is useful to capture events also if child nodes gets added in future.

const container = document.querySelector('.my-container')

let self = Xt.get({ name: 'xt-componentname', el: container })

const on = e => {
  const tr = e.target
  // useCapture event propagation check
  if (self.targets.includes(tr)) {
    // logic
  }
}

container.addEventListener('eventname.xt.componentname', on, true) // useCapture event propagation