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 Observer. 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.observe

You can execute Javascript code only when a container is inside inside viewport with Xt.observe.

Observe listens and execute the query with Intersection Observer. So it's executed asynchronously.

SyntaxDefault / ArgumentsDescription
Optioncontainer:NodenullResolve the promise only when this node is inside viewport
Optionpromise:Promise|nullnullPromise to resolve when container is inside viewport
Optionfunc:Function|nullnullFunction to resolve when container is inside viewport
Optionobserver:Boolean|nullnullForce enable or disable intersection observer, by default only if container is visible (not display: none)
Optionid:String|nullnullId for observer removal

And here's a example usage of Intersection Observer that resolves only one time than disconnects.

Xt.observe({
  container: el,
  observer: true,
}).then(() => {
  // code to execute when element is inside viewport only 1 time
})

And here's a example usage of Intersection Observer that execute code on entering and leaving the viewport and doesn't disconnect.

Xt.observe({
  container: el,
  id: 'my-id',
  func: intersecting => {
    if (intersecting) {
      // code to execute when element is inside viewport
    } else {
      // code to execute when element leave viewport
    }
  },
})

And here's the example of removing the observe above.

Xt.unobserve({
  container: el,
  id: 'my-id',
})

Globals

You can change this method and all the components default options of Xt.observer and Xt.observerOptions and Xt.observerCheck.

SyntaxDefault / ArgumentsDescription
OptionXt.observer:Boolean|nullnullGlobal force enable or disable intersection observer
OptionXt.observerOptions:Object{ root: null, threshold: [0.001] }Global intersection observer options
OptionXt.observerCheck:Functionentry => { return entry.intersectionRatio > 0 }Global intersection observer entry check

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 a promise with 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.

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

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,
}

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

You can sanitize a html strings added with Xt.node or internally by Xtend UI setting a function as Xt.sanitizeFnc.

SyntaxDescription
MethodXt.sanitizeFnc(str:String)Sanitize strings, returns String

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

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')

Xt.get({ name: 'xt-componentname', el: container }).then(self => {
  const on = e => {
    const tr = e.target
    // useCapture event propagation check
    if (self.targets.includes(tr)) {
      // logic
    }
  }

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