ö.js - a small collection of useful stuff.
Usage:
(p)npm install ouml
import { random } from 'ouml'
let oneOrZero = random()
or, with treeshaking:
import * as ö from 'ouml'
let oneOrZero = ö.random()
Most methods are runnable within node/deno. Some methods require browser API:s, those are marked with [browser].
Includes modules chain, a method for chaining calls on any type, öbservable, a basic implementation of reactive values, and övents, a collection of useful custom browser events.
Import them from
import { chain, chainAsync } from 'ouml/chain'
import { observable, isObservable, observe } from 'ouml/öbservable'
import {
resize,
enterview,
exitview,
sticktotop,
sticktobottom,
swipe,
clickoutside,
} from 'ouml/övents'
Helper methods for iterations, less verbose than regular loops.
Yields Number
s within specified range. Parameters end
and step
are optional. If end
is not provided, range starts with 0
, and ends with start
. Handles negative values. Useful in for of
loops, for example
for (let i of ö.range(100)) doStuff(i)
Yields Object
with x, y
coordinates. If height
is omitted, width
is assumed. Use like so:
for (let i of ö.grid(8)) drawChessboard(i.x, i.y)
Calls a function times
times, with index
as argument. Additional arguments are passed on to f
like so:
ö.times(100, (i, a, b) => i + a + b, 'a', 'b')
Returns an array containing the return values of f
, or an array containing index values if f
is undefined
.
Methods for manipulating arrays or array-like objects. Inputs are coerced to Array
, so String
, Set
and the like works as input as well. All methods are non-mutating.
Returns an Array
populated with given range.
Same as a normal map, except it accepts a string
as a shorthand for retrieving values from an object property, if given an iterable that contains objects. Oh, and it accepts all iterables, and returns String
, Map
, Set
and TypedArray
as appropriate. It's a map
for Map
! Edge case iterables such as NodeList
get converted to an array.
Oh, and it's a map
for Object
s! In the rare case that you would mant to map over the own properties of an object, that also works.
ö.map({ a: 1, b: 2 }, ([k, v]) => [k, v + 1]) // returns { a: 2, b: 3 }
And in the even rarer case that you would want to use this method as a contrived getter for a single property on an object, that also works:
ö.map({ a: 1, b: 2 }, 'a') // returns 1
Mapping functions for Map
s and Object
s receive an array in the form of [key, val]
as a value argument, and must return an array in the same format.
Returns an Array
with unique entries.
Returns a new shuffled Array
.
Returns random sample from arr
, or an array of samples if samples
is larger than one.
Sums arr
, with Number
coercion.
Calculates mean value of arr
, with Number
coercion.
Returns product of arr
, with Number
coercion. Reaches Number.MAX_VALUE
rather quickly for large arrays, so use with some caution.
Calculates the geometric mean of arr
, with Number
coercion. May return Infinity
for large arrays or large numbers, since it uses ö.product
.
Calculates median value of arr
, with Number
coercion.
Returns largest value in arr
.
Returns smallest value in arr
.
Returns a Map
with keys corresponding to prop
values, holding grouped values as arrays. Optionally returns an object
if asObject
is set to true.
If prop
is a string, takes an iterable of object
s with a common property. If prop
is a function, takes a function returning keys for grouping based on arr
contents. The function receives value, index, array
as arguments.
Maps a flat array of objects to a tree structure. Objects with children get a new children
property, unsurprisingly containing an array of children 🙄. Leaf nodes have no children
property. Works in one of two ways:
Either you provide an idProp
and a parentProp
, where the ìdProp
holds a value unique to every item in the array, and parentProp
holds a reference to the parent's idProp
value (useful for example if you get a flattened hierarchic list from an api).
Or, you provide a mapping function responsible for providing a unique key for the item, and a unique key for the parent. The function receives value, index, array
as arguments, and should produce an array with [ ownKey, parentKey ]
. If the item has no parent, set parentKey
to null
. Useful for example for mapping urls to a hierarchy.
Parentless children (orphans) will be discarded.
Example:
let flat = [
{ id: '1' },
{ id: '1.1', parent: '1' },
{ id: '1.1.1', parent: '1.1' },
{ id: '2' },
{ id: '2.2', parent: '2' },
]
let tree = mapToTree(flat, 'id', 'parent')
// or
let sameTree = mapToTree(flat, item => [
item.id,
item.id.split('.').slice(0, -1).join('.'),
])
Reduces arrays of nested objects to a single value. subArrayProp
is a string
matching the property containing nested arrays.
The reducer function f
receives accumulator, value, index, array
as arguments. initial
can be omitted, just like the native reduce
, in that case the first item of arr
is used as the initial value.
Example:
let arr = [
{
value: 1,
children: [
{ value: 1 },
{ value: 1 },
{ value: 1, children: [{ value: -4 }] },
],
},
]
ö.reduceDeep(arr, (acc, v) => acc + v.value, 'children', 0) // returns 0
Maps over arrays of nested objects. subArrayProp
is a string
matching the property containing nested arrays.
If f
is a function, its return value is mapped to a new array. The function receives value, index, array
as arguments. If f
returns an object
, and flatten
is false
, the structure of the original arr
is preserved, and a property matching subArrayProp
is added to the object, containing its children.
If f
is a string
, the value of the property matching f
is returned, in a flattened array.
Finds items that match f
in arrays of nested objects. subArrayProp
is a string
matching the property containing nested arrays.
If f
is a function, returns items where f
returns true
. The function receives value, index, array
as arguments. If f
is a function, prop
can be omitted.
If f
is not a function, the value of f
is compared to the value of property prop
.
Returns a flat array with matching items, regardless of depth.
Same as ö.filterDeep
, except it returns first match.
Methods for comparing arrays or array-like objects. Inputs are coerced to Set
. All methods return a new Array
, or Boolean
.
The outputs adhere to strict set logic. If the inputs are Array
s, duplicate items are removed. All these methods are wrappers around internal Set
methods, but returns arrays. (Available in evergreens and in node 22+)
Intersection, returns elements that are members of both a
and b
.
Example:
ö.intersect([0, 1], [1, 2]) // returns [1]
Difference, returns members of a
but not members of b
, i.e. subtracts b
from a
.
Example:
ö.subtract([0, 1], [1, 2]) // returns [0]
Symmetric difference, returns elements that are members of a
or b
, but not both.
Example:
ö.exclude([0, 1], [1, 2]) // returns [0, 2]
Returns (unique) members of both a
and b
.
Example:
ö.union([0, 1], [1, 2]) // returns [0, 1, 2]
Returns true
if a
is a subset of b
.
Returns true
if a
is a superset of b
.
Returns true
if a
and b
share no members.
Checks equality by value rather than reference. Compares prototypes, and uses Reflect.ownKeys
to compare all own keys, including symbols. Works for all basic types and most built in classes, but may produce unexpected results in edge cases. Equality is tricky, and depends on what you personally beleive to be equal 😇. Does deep comparison by default, and may be slow for large data structures. If deep == false
, does flat comparison instead.
Performs cloning of most common types, including Array
and typed arrays, Map
, Set
, Date
and objects. Defaults to deep cloning, set deep
to false
for shallow cloning. Tries to preserve prototype
when cloning objects, but may fail in untested edge cases. Set preservePrototype
to false to disable this (this is somewhat faster). Does not clone functions, and doesn't handle circular references. Use with some caution 🤫.
The native structuredClone
is probably slower (by alot!) in most cases, errors on functions, and doesn't preserve prototype, but it handles circular references. Choose wisely!
Returns a freezed clone of v
. Set deep
to false
to make only top level immutable.
Pipes function calls for a value. For multiple arguments, use closures. Usage:
ö.pipe(
1,
x => x * 6,
x => x ** 2,
x => x + 6,
ö.log,
) // logs 42
Pipes function calls, and returns a function that takes the value to pipe. The data last save for later version of pipe. Usage:
const myPipe = ö.toPiped(
x => x * 6,
x => x ** 2,
x => x + 6,
ö.log,
)
myPipe(1) // logs 42
Same as ö.pipe
, but awaits functions and returns a Promise
.
Pipes function calls, and returns a function that takes the value to pipe. That function returns a Promise
.
Returns a curried version of f
, allowing partial application of arguments. If f
takes three arguments, it can be called like so:
const f = (a, b, c) => a + b + c
const curried = ö.curry(f)
curried(1)(2)(3) // returns 6
// or
const partial = curried(1, 2)
partial(3) // also 6
Creates and returns memoised functions. By default, the arguments to the memoised function are used as key for storing the result (If only one argument, the raw input is used as key, if more than one, the arguments are joined to a string). If the arguments are objects instead of primitive values, you should provide a keymaker
. keymaker
receives all inputs from the memoised function, and should return something unique to use as a Map
key for a given set of inputs. Use for example JSON.stringify
when you expect objects as input.
Creates and returns an enumerable, i.e. a frozen object where the keys have unique values. Lets you create kinda sorta vanilla typechecking light, but at runtime 🤪. Takes an object, or strings, or an array of strings, as input. In order for codehinting to work, you need to provide an explicit object. Example:
const SIZES = ö.createEnum('small', 'medium', 'large')
// or:
const SIZES = ö.createEnum(['small', 'medium', 'large'])
// or:
const SIZES = ö.createEnum({
small: Symbol(),
medium: Symbol(),
large: Symbol(),
})
giveMeIcecream(SIZES.large)
Associates obj
(Can be an Object
or a Symbol
) with data via a WeakMap
. With only key
set, acts as a getter for key
. With key
and value
set, acts as a setter. Useful for associating data with DOM elements. If given an Element
, it parses the dataset
property and adds its properties to data
.
If no key
, returns data
object.
Shorthand for random integers between min
and max
-1. If max
is omitted or Boolean
, assumes a min
value of 0. If max
is Boolean
, float
is assumed. If float
is true, returns float instead of integer.
Returns random number from reasonably approximated normal distribution, centered around mean
, with more or less 68.2% of the sample set within ± sigma
. Values max out at a bit above ± 3 sigma
, with extreme outliers up to about ± 4 sigma
. There are more mathematically accurate methods to do this, but this method is fast, and good enough for most people. Use it for fun and visuals, not for statistical analysis 🤓.
Returns n
rounded to precision
decimals.
Clamps n
between min
and max
.
Checks if n
is between min
and up to, but not including, max
.
Normalises n
to a value between 0 and 1, within range given by min
and max
. If clamp == true
and value of n
is out of range, the value is clamped.
Interpolates linearly between a
and b
. t
is a percentage value between 0 and 1.
Interpolates smoothly between a
and b
. t
is a percentage value between 0 and 1.
Eases in from a
to b
. t
is a percentage value between 0 and 1.
Eases out from a
to b
. t
is a percentage value between 0 and 1.
Returns nth root of positive number, for example
ö.nthRoot(256, 8) === 2
Returns the factorial of n
.
Returns the number of ways to choose k
elements from a set of n
elements, i.e. the binomial coefficient.
Converts cartesian coordinates to polar.
Converts polar coordinates to cartesian.
Returns n
rounded to precision
decimals and formatted by n.toLocaleString()
. Defaults to swedish formatting, because why not! locale
is optional, if second argument is Number
, precision
is set instead.
ö.wrapFirstWords( s, numWords? = 3, startWrap? = '<span>', endWrap? = '</span>', startAtChar? = 0 ) → String
Returns s
with first numWords
words wrapped in startWrap
and endWrap
. Matches first words up to and including first punctuation. Optionally starts matching at index startAtChar
. Matches special chars for nordic languages as well as ', ’ and -.
Returns regular sentence, kebab-case or snake_case string converted to camelCase. Leaves --custom-properties
alone.
Capitalises first letter. No fuss!
Returns regular sentence or camelCase string converted to kebab-case. Leaves --customProperties
alone.
Returns numChars
random characters. Max for numChars
is 100. Useful for producing unique values (Or, to be precise, with a 1/426 825 223 812 027 400 796 974 891 518 773 732 340 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 chance of being a dupe 🤯).
Returns a string without html tags.
A slightly more readable wrapper around a ternary expression. Returns whenTrue
if bool
is true, otherwise returns the empty string. Optionally returns whenFalse
if specified. Useful primarily in template strings.
Hsla lets you use colour in an understandable way. hsla
is great! Use hsla
!
Returns colour
converted to an object with hsla
values. Optionally returns a colour string in hsla
format. Takes hex values, as well as all valid forms of rgb/rgba strings.
Hsla is really easy to work with compared to rgb. For example, a darken
method could look like this, given a hsla
object as input:
const darken = (c, amount) => ({ ...c, l: c.l - amount })
Returns colour string in hsla
format, for css input. Takes separate values, or a single object with properties { h, s, l, a }
.
Awaitable wrappers for setTimeout
, requestAnimationFrame
and events. Takes an optional awaited f
with no arguments. If f
is provided, returns result from f
, otherwise returns undefined
. (Except for ö.waitFrames
, which calls f
every frame if everyFrame
is true
, but only returns the result of the final call.)
Waits t
milliseconds. If resetPrevCall == true
, previous pending call is rejected.
[browser] Waits one frame.
[browser] Waits n
frames. If everyFrame == true
, callback is executed every frame.
[browser] Waits for specified event. Takes only one element, and one event type.
[browser (Alternatively: Use node 18+)] Loads (and parses) JSON. Optionally loads HTML. Super simple fetch wrapper. On error, simply returns the error message, or optionally returns your custom error message. If you need to pass headers or other settings to the fetch call, use the settings
object.
See ö.pipe
.
Throttles execution of f
to one call per t
milliseconds. If called multiple times per period, the last call gets executed.
Debounces execution of f
until no calls are made within t
milliseconds. If called multiple times per period, the last call gets executed. If immediately
is set to true
, the first call gets executed as well.
[browser] Defers execution of f
to next animation frame. If called multiple times per frame, the last call gets executed.
All logging methods can be silenced globally by calling ö.verbose(false)
.
Set isVerbose
, turns off error/message logging when set to false
. Defaults to true
. Optionally set isThrowing
to true
, in order to throw errors instead of logging them.
Returns an object containing the current state of { isThrowing, isVerbose }
.
Logs errors to console, optionally throws instead. Returns single argument, or multiple arguments as an array.
Outputs arguments to console. Returns single argument, or multiple arguments as an array.
Outputs arguments to console. Returns single argument, or multiple arguments as an array. Can be used like so: let x = ö.log( y*z );
or to tap into a call chain.
The basic usecase is as a simple wrapper for console.time
, optionally with a label. If f
is a string, it is used as a label. In that case, the timer ends when calling ö.timeEnd
with a matching label.
Optionally, it accepts a function with no arguments, which gets timed, called and its value returned. In this case console.timeEnd
is called internally.
Simple wrapper for console.timeEnd
.
Wrapper for internal messages.
Less verbose than typeof
/Array.isArray
/instanceof
:
ö.isObj
excludes Array
, Map
, Set
, Date
and RegExp
. And null
, of course.
Checks if v
is a plain object a.k.a. pojo, that is, has the same prototype as Object
.
Checks if v
is a naked object, that is, has null
as prototype.
Checks for [Symbol.iterator]
in v
.
Any iterable except strings work, but produce arraylike objects without a length
.
[browser] Gets item
from local storage, if any. Converts item to Object
via JSON.parse
.
[browser] Sets item
in local storage to v
, and returns v
.
[browser] Gets prop
on selected element, or from document.documentElement
if selector
is unset. and returns v
. Mainly used for getting global --props
, using css as master for global variables.
[browser] Sets prop
to v
, optionally on selected element, and returns v
.
[browser] Creates an Element
from an html string. Optionally creates an SVGElement
.
Parses a DOMStringMap
as JSON
. Used internally when reading from Element.dataset
.
[browser] Finds deepest Element
in element
, optionally matching selector
.
Converts string to Rövarspråket.
Chain a.k.a TypelessScript lets you chain any method calls, on any type, kind of like a pipe on speed 🧙, or a jQuery for any object. It simply shoves the return value around, allowing you to think about more important stuff than intermediate variables.
Here's an example:
import { chain } from 'ouml/chain'
let guessWhat = chain(11)
.f(v => [...Array(v).keys()])
.map(v => v ** v)
.sum()
.toString()
.length()
.return()
It takes the number 11, makes an array of integers using the .f()
directive, maps the values to the power of themselves, sums them using an ö
method, converts the resulting number to a string, gets the length of the string, and returns it.
Here's another:
import { chainAsync } from 'ouml/chain'
let errorMessage = 'error'
let nameOfPriciestProduct = await chainAsync('https://dummyjson.com/products')
.load(true, errorMessage)
.returnIf(v => v === errorMessage)
.products()
.sort((a, b) => a.price > b.price)
.at(0)
.title()
.return()
It takes a url, loads it as json using an ö
method, handles the error case, gets the products property of the json object, sorts it, gets the first one, gets the title, and returns it. Simple as that!
chain
chains method calls, but with some quirks and gotchas. For example, properties on objects can be retrieved by calling the property name as a function. Methods on objects in the global scope can be accessed by an underscore, for example Object_groupBy()
. Also, if a method in the chain creates an error, the step is skipped by default (and the error is logged), guaranteeing a return value. You can override this by setting isThrowing
to true.
Use like so:
import { chain, chainAsync } from 'ouml/chain'
let processedValue = chain('AnyValueOfAnyType')
.anyMethodOnCurrentType()
.anyPropertyOnCurrentValue()
.anyMethodInÖ()
.anyMethodInGlobalScope()
.AnyObjectInGlobalScope_anyMethod()
.f(anyFunction)
.peek() // Logs current value and type
.returnIf(anyFunctionReturningABoolean)
.return()
A quick note on performance: chain
does string matching, proxying and other fun stuff that adds some overhead. It adds a small hit performance-wise, and might not be the best option in a game loop 😇. It's mainly a proof of concept, but since it produces some really nice, terse and readable code, it might come in handy in some situations!
Chain exports two methods:
Chain wraps a value, and creates a Proxy
that handles the chaining. chain
evaluates lazily, so nothing is calculated until .return()
or .value
is called. Errors are skipped by default, set isThrowing
to true to throw errors instead. Optionally, set isAsync
to true
to handle async values, or use:
Same as chain
, but results in a Promise
.
The chain proxy defines a few special cases, that looks and behaves like methods:
Executes call chain, and returns computed value.
Same as .return()
, executes call chain, and returns computed value.
A method call with no arguments has the same effect as .return()
or .value
, executes call chain, and returns computed value.
Guard clause, lets you exit the call chain early. The function receives the current value as argument, and is expected to return a boolean. Returns current value on truthy values, otherwise continues call chain.
Lets you peek into the call chain, logging current value and type to the console.
f
allows arbitrary functions to be passed into the call chain. The function receives the current value as argument. f
is particularly useful for methods defined in a function or module scope, since these scopes are unreachable otherwise.
A variant for passing in arbitrary functions is directly with parentheses, in effect calling the proxy as a function, with your function as the argument. This in turn can be chained, like so:
let v = chain('Hi')(letsDo)(cool)(stuff)()
This doesn't play that nicely with Prettier, if you happen to use that, but it's cool!
Lets you call a method of the current value. Methods are called "as is", so for exemple a .map(v => v)
on an array takes a function, .toUpperCase()
on a string takes no argument, and .toUpperCase()
on a number is skipped along with a warning to the console, since no such method exists on a number.
Lets you access properties on the current value as a method call, for example .length()
to get the length of a string or an array. If newVal
is provided, sets the property to newVal
, and passes newVal
along the chain.
Lets you pass any ö
method into the chain. The current value is passed as the first argument, so if you would normally call ö.sum(arr)
, in a chain you need only call .sum()
.
Lets you pass any global method into the chain. The current value is passed as the first argument, so if you would normally call fetch('http://some.url')
, in a chain you need only call .fetch()
.
Lets you pass any method on a global object into the chain. The current value is passed as the first argument, so if you would normally call JSON.parse(someString)
or Array.from(someIterable)
, in a chain you need only call .JSON_parse()
or .Array_from()
.
If you have defined any methods in the global scope that have underscores in their names, use .f(v => my_global_method(v))
instead, since underscores get parsed out by the proxy.
öbservable is loosely based on how vue.js handles reactivity, but it is much simpler, and, truthfully, not as good 🤪. It is, however, shockingly small, 1Kb minified.
öbservable uses Proxy
to intercept changes to observable values, and in doing so detects for exemple direct array manipulation.
Use like so:
import { observable, isObservable, observe } from 'ouml/öbservable'
let obs = observable(['a', 'b', 'c'])
let lengthObserver = observe(
() => obs.length,
v => ö.log(`The length is ${v}`),
)
let firstItemObserver = observe(
() => obs[0],
v => ö.log(`The first item is ${v}`),
)
// Logs The length is 3, The first item is a
await ö.wait(666)
obs.shift()
// Logs The length is 2, The first item is b, after 666ms
You can also use the raw observable as input to observe
, or call observe
directly on the observable (due to some Proxy
trickery):
let thisGuy = observable({ name: 'Guy', surname: 'This' })
observe(thisGuy, (val, oldVal, changedProp) =>
ö.log(`${changedProp} has changed`),
)
thisGuy.observe(v => ö.log(`Name: ${v.name} Surname: ${v.surname}`))
thisGuy.surname = 'Fawkes'
When called as a method, the getter argument to observe
is omitted.
öbservable exports three methods:
Takes a value
, and returns it wrapped in an observable Proxy
, recursively wrapping nested objects as well. If you add a new property to an observable, the new property is made observable as well (if it's not a primitive value).
If value
is a primitive (String
, Number
, Boolean
etc), the value is wrapped in an object with a single property: value
. You cannot assign to a primitive observable value directly, you need to use the value
prop instead, or else you'd overwite the proxy.
let x = observable('foo')
observe(x, ö.log)
x = 'bar' // Won't work.
let x = observable('foo')
observe(x, ö.log)
x.value = 'bar' // Assign to value instead.
Takes a getter
, responsible for reading an observable and producing a value, and a callback
that acts on the value.
The getter
can be either a raw observable, or a function returning the processed value of an observable.
The callback
receives value
, prevValue
, updatedKey
and observer
as arguments. The values passed to callback
are copied from the observable, so you can't mutate the observable value in the callback (that would create an infinite loop anyways, so don't try it 🤯).
If you're observing an object, updatedKey
can be useful in order to retrieve and act on only the property that changed. However, if you're destructuring multiple properties from a nested object, updatedKey
refers to the key local to the updated object, so in this case make sure not to use the same property name on different levels
.
observer
is a reference to the observer object, giving access to primarily the stop()
method.
If the getter is a raw primitive observable, the value is unwrapped before the callback is called, like so:
let o = observable(0)
observe(o, v => ö.log(`The value is ${v}`)) // logs 'The value is 0'
or
let o = observable(0)
o.observe(v => ö.log(`The value is ${v}`)) // logs 'The value is 0'
If the getter is a function, you need to access the value
prop, like so:
let o = observable(0)
observe(() => `The value is ${o.value}`, ö.log) // logs 'The value is 0'
It's a matter of taste, really.
When working with deep data structures, you can observe an entire object structure, and receive updates when properties on child objects change, like so:
let deep = observable({
a: { b: { c: { d: "What's the purpose of it all?" } } },
})
observe(deep, ö.log)
deep.a.b.c.d = 'Deep stuff'
The drawback with this, however, is that the entire object returned from the getter gets deep cloned every time the observer is triggered (to avoid recursion among other things). This is fairly untested with regards to performance, so try to keep the data structure fairly small. There are possible optimisations to be done here, maybe in the future...
When working with larger data structures, try to be as specific as possible in the getter. As a rule of thumb, get the values you output in the callback, nothing more. Maybe something like this:
let bigAssObservable = observable(bigAssObject)
observe(() => {
let {
stuff,
that,
we,
childObject: { really, need },
} = bigAssObservable
return { stuff, that, we, really, need }
}, renderSmallPartOfBigAssObject)
Checks whether a value is observable or not, just in case you'd forgotten.
observable()
returns observables, responsible for notifying observers when their value changes. When an observable is read by an observer, the observer is added to an internal Set
of observers. These get updated when values change.
If the observable holds a primitive value, it has a value
property, otherwise values are accessed just like a regular object or array.
The observable also holds Symbol
s for observable
and primitive
, used internally, and for easier debugging.
You can also call observe
directly on an observable object (observe
is not a proper property on the object though, this is handled by the getter in the Proxy
).
observe()
returns observers, holding the current value of the observed observable, and a few methods and properties for flow control. You don't need to save a reference to the object, but it might come in handy if you want to stop observing later on.
let x = observable(0)
let o = observe(x, ö.log)
x.value = 666 // logs 666
o.stop()
Pauses the observer.
You'll never guess.
Stops the observer from receiving updates, and unsubscribes the observer from observables.
Updates current value and calls callback if the value has changed. Called internally by the observable.
Holds the most currently returned value from the getter
. Usable mostly for debugging.
Holds the previous value. Usable mostly for debugging.
Set to true
if paused, otherwise undefined
.
Set to true
if stopped, otherwise undefined
.
övents is a collection of should've-been-in-the-browser-already custom events.
Övents implements she svelte/action
interface, and are usable as svelte actions, but can be used in any browser context like so:
let el = document.querySelector('#someElement')
resize(el)
// or, if you need cleanup:
let resizer = resize(el)
el.addEventListener('resize', someCallback)
// When you're done:
resizer.destroy()
Emit when an Element
gets resized, as observed by ResizeObserver
. Relays the ResizeObserverEntry
in the details
object.
Emit when an Element
's bounding box enters or exits the viewport.
Emit when an Element
's bounding box touches the top/bottom of the viewport. Useful for detecting when an Element
with position: sticky
sticks to the viewport. One caveat: This works only if the sticky elements have top: 0
or bottom: 0
.
Event status is passed via a sticky
prop on the details
object.
Emits swipeleft
, swiperight
, swipeup
, swipedown
when user swipes on a touch device.
Emits on click or tap outside Element
.