Search documentation v0.8.1

Utilities

Reusable functions for improved workflow

Source ↗️ Report Issue ↗️

Some components in Webcore comes with JavaScript API that let’s you dynamically handle components. Apart from this functionality, Webcore also exposes a couple of other utility functions that you can use in your own codebase to speed up your development workflow. You’ll find the following utility function in Webcore.

All utility functions can be imported directly from webcoreui. If you’d like to reuse some of the functionalities defined here in your own project without Webcore, you can find the implementations here.

ClassNames

Use the classNames function to dynamically and conditionally generate valid CSS class names. The function expects an array of elements. You can create conditions inside the array using logical operators. The array elements will be concatenated into a single class name.

import { classNames } from 'webcoreui'
classNames(['avatar', true && 'borderless']) -> 'avatar borderless'
classNames(['avatar', false && 'borderless', null]) -> 'avatar'
API
const classNames: (classes: any[]) => string

Cookies

To work with cookies, use the getCookie, setCookie, and removeCookie functions.

API
const setCookie: (name: string, value: string, days: number) => void
const getCookie: (name: string) => string | null
const removeCookie: (name: string) => void

Debounce

Use the debounce function to limit the rate at which a function is executed. Use for performance optimization for excessively executed functions, such as keyup, resize, or scroll events:

import { debounce } from 'webcoreui'
const callbackWithDebounce = debounce(() => {
console.log('called with debounce')
})
new ResizeObserver(() => {
callbackWithDebounce()
}).observe(document.body)
// Call `.cancel` to cancel a debounce earlier
callbackWithDebounce.cancel()

Pass the callback function to the debounce call that should be rate limited. Optionally, you can set a second parameter to configure the timeout for the debounce. By default, this is set to 100 milliseconds.

API
const debounce: <T extends (...args: any[]) => any>(
fn: T,
waitFor?: number
) => {
(...args: Parameters<T>): void
cancel: () => void
}

DOM Utilities

Webcore provides the following DOM utility functions to make the work with DOM elements easier in Astro components:

API
const get: (selector: string, all: boolean) => Element | NodeListOf<Element> | null
const on: (
selector: string | HTMLElement,
event: string,
callback: any,
all?: boolean
) => void

Events

To work with custom events, use the dispatch and listen functions:

import { listen, dispatch } from 'webcoreui'
listen('theme-switched', theme => {
console.log(theme) // 'theme-dark'
})
dispatch('theme-switched', 'theme-dark')

If you need to remove the listener later on, you can assign the listen function to a variable, and call the remove method:

How to remove a listener
import { listen, dispatch } from 'webcoreui'
const event = listen('theme-switched', theme => {
console.log(theme) // 'theme-dark'
})
dispatch('theme-switched', 'theme-dark')
// You can later remove the listener by calling .remove() on the event
event.remove()

Use the two utility functions in combination to share data between different parts of your application that are otherwise unrelated. This approach is known as the publish-subscribe design pattern, or pub/sub for short.

API
const dispatch: (event: string, detail: unknown) => void
const listen: (event: string, callback: (e: any) => unknown) => {
remove: () => void
}

Interpolate

You can use the following math functions if you need to transform numbers in various ways:

API
const clamp = (num: number, min: number, max: number) => number
const lerp = (start: number, end: number, value: number) => number
const invlerp = (start: number, end: number, value: number) => number
const interpolate = (
value: number,
input: [start: number, end: number],
output: [start: number, end: number],
) => number

Modals & Sheets

To open modals or sheets, you’ll need to create a Modal/Sheet component first:

<Button className="my-button">Open Modal</Button>
<Modal className="my-modal">
Modal with text only.
</Modal>
<Button className="my-button">Open Sheet</Button>
<Sheet className="my-sheet">
Sheet with text only.
</Sheet>

Based on the above selectors, you can target this component to trigger it using the modal function:

import { modal } from 'webcoreui'
modal({
trigger: '.my-button',
modal: '.my-modal'
})
import { modal } from 'webcoreui'
const modalInstance = modal('.my-modal')
// On button click
modalInstance.open()
import { closeModal } from 'webcoreui'
closeModal('.my-modal')

You can open modals in two different ways:

  1. Open: Pass a configuration object with a trigger property that specifies a query selector for a trigger element, and pass a modal property to target the Modal/Sheet component. Clicking on the trigger element will now open the component.
  2. Open via JS: Pass a query selector to the modal function that targets the component, and assign the function to a variable. You can call the open method on the assigned variable. This lets you trigger the component programmatically, for example, after a network request finishes.
API
type ModalCallback = {
trigger: Element | null
modal: HTMLElement
}
type Modal = {
trigger: string
modal: string
onOpen?: (args: ModalCallback) => unknown
onClose?: (args: ModalCallback) => unknown
}
const modal: (config: Modal | string) => {
open: () => void
remove: () => void
} | void
const closeModal: (modal: string) => void

The JavaScript API of the Modal and Sheet components are identical. To learn more about how to use the Modal component, visit its documentation. To learn more about how to use the Sheet component, you can find its documentation here.

Popovers

To create popovers, you’ll need to create a Popover component first:

<Button className="trigger-popover">Open popover</Button>
<Popover className="my-popover">
Popover with text only.
</Popover>

As popovers are attached to interactive elements, you’ll also need to create an interactive element, such as a button, that can trigger the popover. In this example, a Button component is used. Based on the above selectors, you can target this popover to initialize it:

import { popover } from 'webcoreui'
popover({
trigger: '.trigger-popover', // Query selector for the button
popover: '.my-popover' // Query selector for the popover
})
import { closePopover } from 'webcoreui'
closePopover('.my-popover')
Remove popover instance
import { popover } from 'webcoreui'
const popoverInstance = popover({
trigger: '.trigger-popover',
popover: '.my-popover'
})
// Calling `.remove` will disable the popover
popoverInstance.remove()

Whenever the .trigger-popover button is clicked, it’ll open the .my-popover element. The popover function also returns a remove function that can be used to remove the created popover instance.

API
type PopoverPosition = 'top'
| 'top-start'
| 'top-end'
| 'left'
| 'left-start'
| 'left-end'
| 'right'
| 'right-start'
| 'right-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
type PopoverCallback = {
trigger: HTMLElement
popover: HTMLElement
position: PopoverPosition | undefined
}
type Popover = {
trigger: string
popover: string
position?: PopoverPosition
offset?: number
closeOnBlur?: boolean
onOpen?: (args: PopoverCallback) => unknown
onClose?: (args: PopoverCallback) => unknown
}
const closePopover: (selector: string) => void
const popover: (config: Popover) => {
remove: () => void
} | void

To learn more about how to use the Popover component, visit its documentation.

Toasts

To dynamically show toasts, you’ll need to create a Toast component first:

<Toast className="my-toast">
Toast with text only.
</Toast>

Based on a selector, you can target this toast to trigger it:

import { toast } from 'webcoreui'
toast('.my-toast')
import { hideToast } from 'webcoreui'
hideToast('.my-toast')
import { setDefaultTimeout } from 'webcoreui'
setDefaultTimeout(3000)

To configure the behavior of your toast, pass a configuration object to the toast function:

import { toast } from 'webcoreui'
toast({
element: '.my-toast',
timeout: 10_000,
title: 'Title set through JS',
content: 'Content updated with JavaScript',
position: 'bottom-left'
})
API
type Toast = {
element: string
timeout?: number
title?: string
content?: string
position?: 'bottom-left'
| 'top-left'
| 'top-right'
| 'bottom-full'
| 'top-full'
}
const setDefaultTimeout: (time: number) => number
const toast: (config: Toast | string) => void
const hideToast: (element: string) => void

To learn more about how to use the Toast component, visit its documentation.


Request improvement for this page