@motorcycle/dom v17.0.0
@motorcycle/dom -- 16.1.0
Declarative, functional, reactive abstractions for the DOM
Get it
yarn add @motorcycle/dom
# or
npm install --save @motorcycle/dom
API Documentation
All functions are curried!
DomSource
A DOM source interface for objects to declaratively query the DOM.
interface DomSource {
query(cssSelector: CssSelector): DomSource
elements<El extends Element = Element>(): Stream<ReadonlyArray<El>>
events<Ev extends Event = Event>(eventType: StandardEvents, options?: EventListenerOptions): Stream<Ev>
cssSelectors(): ReadonlyArray<CssSelector>
}
DomSource.cssSelectors(): ReadonlyArray\<CssSelector>
Retrieves a list of all previously queried CSS selectors.
console.log(cssSelectors0) // .myCssSelector
</details>
<details>
<summary>See the code</summary>
```typescript
cssSelectors(): ReadonlyArray<CssSelector>
}
export type CssSelector = string
DomSource.elements\(): Stream\<ReadonlyArray\<El>>
Retrieves a stream of a list of elements matching previous queries.
NOTE: Elements will emit every single time the DOM is updated.
elements(): Stream<ReadonlyArray<A>>
DomSource.events\(eventType: StandardEvents, options?: EventListenerOptions): Stream\<Ev>
Retrieves a stream of events from elements matching previous queries.
DomSource.events
optionally takes a second parameter of EventListernerOptions
,
which specifies whether event listeners will listen to events during the
capturing phase. If not provided, all event listeners will use bubbling phase.
events<Ev extends B = B>(eventType: StandardEvents, options?: EventListenerOptions): Stream<Ev>
DomSource.query(cssSelector: CssSelector): DomSource
Queries for elements and events for a specified CSS selector.
query<C extends A = A>(cssSelector: CssSelector): DomSource<C, B>
HistoryEffect
export type HistoryEffect = (history: History) => void
HistorySinks
export type HistorySinks = {
readonly history$: Stream<HistoryEffect>
}
HistorySources
export type HistorySources<State = any> = {
readonly location$: Stream<Readonly<Location>>
readonly state$: Stream<State>
}
StandardEvents
Standard event types defined by MDN. All browser should have these implemented the same.
export type StandardEvents =
// name - Event Types
| 'abort' // UIEvent, ProgressEvent, Event
| 'afterprint' // Event;
| 'animationend' // AnimationEvent
| 'animationiteration' // AnimationEvent
| 'animationstart' // AnimationEvent
| 'audioprocess' // AudioProcessingEvent
| 'audioend' // Event
| 'audiostart' // Event
| 'beforprint' // Event
| 'beforeunload' // BeforeUnloadEvent
| 'beginEvent' // TimeEvent
| 'blocked' // Event
| 'blur' // FocusEvent
| 'boundary' // SpeechsynthesisEvent
| 'cached' // Event
| 'canplay' // Event
| 'canplaythrough' // Event
| 'change' // Event
| 'chargingchange' // Event
| 'chargingtimechange' // Event
| 'checking' // Event
| 'click' // MouseEvent
| 'close' // Event
| 'complete' // Event, OfflineAudioCompletionEvent
| 'compositionend' // CompositionEvent
| 'compositionstart' // CompositionEvent
| 'compositionupdate' // CompositionEvent
| 'contextmenu' // MoustEvent
| 'copy' // ClipboardEvent
| 'cut' // ClipboardEvent
| 'dblclick' // MouseEvent
| 'devicechange' // Event
| 'devicelight' // DeviceLightEvent
| 'devicemotion' // DeviceMotionEvent
| 'deviceorientation' // DeviceOrientationEvent
| 'deviceproximity' // DeviceProximityEvent
| 'dischargingtimechange' // Event
| 'DOMActivate' // UIEvent
| 'DOMAttributeNameChanged' // MutationNameEvent
| 'DOMAttrModified' // Mutationevent
| 'DOMCharacterDataModified' // MutationEvent
| 'DOMContentLoaded' // Event
| 'DOMElementNamedChanged' // MutationNameEvent
| 'DOMNodeInserted' // MutationEvent
| 'DOMNodeInsertedIntoDocument' // MutationEvent
| 'DOMNodeRemoved' // MutationEvent
| 'DOMNodeRemovedFromDocument' // MutationEvent
| 'DOMSubtreeModified' // MutationEvent
| 'downloaded' // Event
| 'drag' // DragEvent
| 'dragend' // DragEvent
| 'dragenter' // DragEvent
| 'dragleave' // DragEvent
| 'dragover' // DragEvent
| 'dragstart' // DragEvent
| 'drop' // DragEvent
| 'durationchange' // Event
| 'emptied' // Event
| 'end' // Event, SpeechSynthesisEvent
| 'ended' // Event
| 'endEvent' // TimeEvent
| 'error' // UIEvent | ProgressEvent | Event
| 'focus' // FocusEvent
| 'fullscreenchange' // Event
| 'fullscreenerror' // Event
| 'gamepadconnected' // GamepadEvent
| 'gamepaddisconnected' // GamepadEvent
| 'gotpointercapture' // PointerEvent
| 'hashchange' // HashChangEvent
| 'lostpointercapture' // PointerEvent
| 'input' // event
| 'invalid' // Event
| 'keydown' // KeyboardEvent
| 'keypress' // KeyboardEvent
| 'keyup' // KeyboardEvent
| 'languagechange' // Event
| 'levelchange' // Event
| 'load' // UIEvent, ProgressEvent
| 'loadeddata' // Event
| 'loadedmetadata' // Event
| 'loadend' // ProgressEvent
| 'loadstart' // ProgressEvent
| 'mark' // SpeechSynthesisEvent
| 'message' // MessageEvent, ServiceWorkerMessageEvent, ExtendableMessageEvent
| 'mousedown' // MouseEvent
| 'mouseenter' // MouseEvent
| 'mouseleave' // MouseEvent
| 'mousemove' // MouseEvent
| 'mouseout' // MouseEvent
| 'mouseover' // Mouseevent
| 'nomatch' // SpeechRecognitionEvent
| 'notificationclick' // NotificationEvent
| 'noupdate' // event
| 'obsolete' // Event
| 'offline' // event
| 'online' // Event
| 'open' // event
| 'orientationchange' // Event
| 'pagehide' // PageTransitionEvent
| 'pageshow' // PageTransitionEvent
| 'paste' // ClipboardEvent
| 'pause' // Event, SpeechSynthesisEvent
| 'pointercancel' // PointerEvent
| 'pointerdown' // PointerEvent
| 'pointerenter' // PointerEvent
| 'pointerleave' // PointerEvent
| 'pointerlockchange' // Event
| 'pointerlockerror' // Event
| 'pointermove' // PointerEvent
| 'pointerout' // PointerEvent
| 'pointerover' // PointerEvent
| 'pointerup' // PointerEvent
| 'play' // Event
| 'playing' // Event
| 'popstate' // PopStateEvent
| 'progress' // ProgressEvent
| 'push' // PushEvent
| 'pushsubscriptionchange' // PushEvent
| 'ratechange' // Event
| 'readystatechange' // Event
| 'repeatEvent' // TimeEvent
| 'reset' // Event
| 'resize' // UIEvent
| 'resourcetimingbufferfull' // Performance
| 'result' // SpeechRecognitionEvent
| 'resume' // SpeechSynthesisEvent
| 'scroll' // UIEvent
| 'seeked' // Event
| 'seeking' // Event
| 'select' // UIEvent
| 'selectstart' // UIEvent
| 'selectionchange' // Event
| 'show' // MouseEvent
| 'soundend' // Event
| 'soundstart' // Event
| 'speechend' // Event
| 'speechstart' // Event
| 'stalled' // Event
| 'start' // SpeechSynthesisEvent
| 'storage' // StorageEvent
| 'submit' // Event
| 'success' // Event
| 'suspend' // Event
| 'SVGAbort' // SvgEvent
| 'SVGError' // SvgEvent
| 'SVGLoad' // SvgEvent
| 'SVGResize' // SvgEvent
| 'SVGScroll' // SvgEvent
| 'SVGUnload' // SvgEvent
| 'SVGZoom' // SvgEvent
| 'timeout' // ProgressEvent
| 'timeupdate' // Event
| 'touchcancel' // TouchEvent
| 'touchend' // TouchEvent
| 'touchenter' // TouchEvent
| 'touchleave' // TouchEvent
| 'touchmove' // TouchEvent
| 'touchstart' // TouchEvent ;
| 'transitionend' // Transitionevent
| 'unload' // UIEvent
| 'updateready' // Event
| 'upgradeneeded' // Event
| 'userproximity' // UserProximityEvent
| 'voiceschanged' // Event
| 'versionchange' // Event
| 'visibilitychange' // Event
| 'volumechange' // Event
| 'vrdisplayconnected' // Event
| 'vrdisplaydisconnected' // Event
| 'vrdisplaypresentchange' // Event
| 'waiting' // Event
| 'wheel' // WheelEvent
createDocumentDomSource(document$: Stream\<Document>): DocumentDomSource
Takes in Stream\<Document\>
and produces a DocumentDomSource.
Stream\<Document\>
is required and allows for the developer to decide which
events cause the stream to emit.
const element = document.querySelector('#app-container') as Element
const Dom = makeDomComponent(element)
function Effects(sinks) { const { view$ } = sinks
const document$ = constant(document, view$)
const { dom } = Dom({ view$ })
return { dom, document: createDocumentDomSource(document$) } }
</details>
<details>
<summary>See the code</summary>
```typescript
export function createDocumentDomSource(document$: Stream<Document>): DomSource<Document, Event> {
return new DocumentDomSource(document$)
}
createDomSource(element$: Stream\<Element>): DomSource
Takes a stream of DOM Elements an returns a DomSource. This DomSource makes use of event delegation.
const dom = createDomSource(element$)
</details>
<details>
<summary>See the code</summary>
```typescript
export function createDomSource(element$: Stream<Element>): DomSource {
return new EventDelegationDomSource(element$, [])
}
createWindowDomSource(window$: Stream\<Window>): WindowDomSource
Takes in Stream\<Window\>
and produces a WindowDomSource
.
Stream\<Document\>
is required and allows for the developer to decide which
events cause the stream to emit.
const element = document.querySelector('#app-container') as Element
const Dom = makeDomComponent(element)
function Effects(sinks) { const { view$ } = sinks
const window$ = constant(window, view$)
const { dom } = Dom({ view$ })
return { dom, window: createWindowDomSource(window$) } }
</details>
<details>
<summary>See the code</summary>
```typescript
export class WindowDomSource implements DomSource<Window, Event> {
public window$: Stream<Window>
constructor(window$: Stream<Window>) {
this.window$ = window$
}
public query(): DomSource<Window, Event> {
return this
}
public elements(): Stream<ReadonlyArray<Window>> {
return map(Array, this.window$)
}
public events<Ev extends Event = Event>(
eventType: StandardEvents,
options: EventListenerOptions = {}
): Stream<Ev> {
const { window$ } = this
const event$$ = map(window => new EventStream(eventType, window, options), window$)
return multicast(switchLatest(event$$))
}
public cssSelectors(): ReadonlyArray<CssSelector> {
return WINDOW_CSS_SELECTORS
}
}
elements\<A = Element, B = Event>>(dom: DomSource\<A, B>): Stream\<ReadonlyArray\<A>>
Takes a DomSource and returns a stream of Array of elements matches previous queries.
type Sources = { dom: DomSource }
function Component(sources: Sources) { const { dom } = sources
const elements$ = elements(dom)
... }
</details>
<details>
<summary>See the code</summary>
```typescript
export function elements<A = Element, B = Event>(dom: DomSource<A, B>): Stream<ReadonlyArray<A>> {
return dom.elements()
}
event\<A = Element, B = Event>>(type: StandardEvents, dom: DomSource\<A, B>): Stream\<B>
Takes an event type and a DomSource and returns a stream of events.
const click$ = events('click', dom)
</details>
<details>
<summary>See the code</summary>
```typescript
export const events: Events = curry2(function<A = Element, B = Event>(
eventType: StandardEvents,
dom: DomSource<A, B>
): Stream<B> {
return dom.events<B>(eventType)
})
export interface Events {
<A = Element, B = Event>(eventType: StandardEvents, dom: DomSource<A, B>): Stream<B>
<A = Element, B = Event>(eventType: StandardEvents): (dom: DomSource<A, B>) => Stream<B>
(eventType: StandardEvents): <A = Element, B = Event>(dom: DomSource<A, B>) => Stream<B>
}
export const abortEvent = events<Element, UIEvent | ProgressEvent | Event>('abort')
export const afterPrintEvent = events<Element, Event>('afterprint')
export const animationEndEvent = events<Element, AnimationEvent>('animationend')
export const animationIterationEvent = events<Element, AnimationEvent>('animationiteration')
export const animationStartEvent = events<Element, AnimationEvent>('animationstart')
export const audioProcessEvent = events<Element, AudioProcessingEvent>('audioprocess')
export const audioEndEvent = events<Element, Event>('audioend')
export const audioStartEvent = events<Element, Event>('audiostart')
export const beforeUnloadEvent = events<Element, BeforeUnloadEvent>('beforeunload')
export const beginEvent = events<Element, Event>('beginEvent')
export const blockedEvent = events<Element, Event>('blocked')
export const blurEvent = events<Element, FocusEvent>('blur')
export const boundaryEvent = events<Element, SpeechSynthesisEvent>('boundary')
export const cachedEvent = events<Element, Event>('cached')
export const canPlayThroughEvent = events<Element, Event>('canplaythrough')
export const changeEvent = events<Element, Event>('change')
export const chargingChangeEvent = events<Element, Event>('chargingchange')
export const chargingTimeChangeEvent = events<Element, Event>('chargingtimechange')
export const checkingEvent = events<Element, Event>('checking')
export const clickEvent = events<Element, MouseEvent>('click')
export const closeEvent = events<Element, Event>('close')
export const completeEvent = events<Element, OfflineAudioCompletionEvent | Event>('complete')
export const compositionEndEvent = events<Element, CompositionEvent>('compositionend')
export const compositionStartEvent = events<Element, CompositionEvent>('compositionstart')
export const compositionUpdateEvent = events<Element, CompositionEvent>('compositionupdate')
export const contextMenuEvent = events<Element, MouseEvent>('contextmenu')
export const copyEvent = events<Element, ClipboardEvent>('copy')
export const cutEvent = events<Element, ClipboardEvent>('cut')
export const dblclickEvent = events<Element, MouseEvent>('dblclick')
export const deviceChangeEvent = events<Element, Event>('devicechange')
export const deviceLightEvent = events<Element, DeviceLightEvent>('devicelight')
export const deviceMotionEvent = events<Element, DeviceMotionEvent>('devicemotion')
export const deviceOrientationEvent = events<Element, DeviceOrientationEvent>('deviceorientation')
export const deviceProximityEvent = events<Element, DeviceMotionEvent>('deviceproximity')
export const dischargingTimeChangeEvent = events<Element, Event>('dischargingtimechange')
export const downloadedEvent = events<Element, Event>('downloaded')
export const dragEvent = events<Element, DragEvent>('drag')
export const dragEndEvent = events<Element, DragEvent>('dragend')
export const dragEnterEvent = events<Element, DragEvent>('dragenter')
export const dragLeaveEvent = events<Element, DragEvent>('dragleave')
export const dragOverEvent = events<Element, DragEvent>('dragover')
export const dragstartEvent = events<Element, DragEvent>('dragstart')
export const dropEvent = events<Element, DragEvent>('drop')
export const durationChangeEvent = events<Element, Event>('durationchange')
export const emptiedEvent = events<Element, Event>('emptied')
export const endEvent = events<Element, Event | SpeechSynthesisEvent>('end')
export const endedEvent = events<Element, Event>('ended')
export const focusEvent = events<Element, FocusEvent>('focus')
export const fullScreenChangeEvent = events<Element, Event>('fullscreenchange')
export const fullScreenErrorEvent = events<Element, Event>('fullscreenerror')
export const gamepadConnectedEvent = events<Element, GamepadEvent>('gamepadconnected')
export const gamepadDisconnectedEvent = events<Element, GamepadEvent>('gamepaddisconnected')
export const hashChangeEvent = events<Element, HashChangeEvent>('hashchange')
export const lostPointerCaptureEvent = events<Element, PointerEvent>('lostpointercapture')
export const inputEvent = events<Element, Event>('input')
export const invalidEvent = events<Element, Event>('invalid')
export const keyDownEvent = events<Element, KeyboardEvent>('keydown')
export const keyPressEvent = events<Element, KeyboardEvent>('keypress')
export const keyUpEvent = events<Element, KeyboardEvent>('keyup')
export const languageChangeEvent = events<Element, Event>('languagechange')
export const levelChangeEvent = events<Element, Event>('levelchange')
export const loadEvent = events<Element, UIEvent | ProgressEvent>('load')
export const loadedDataEvent = events<Element, Event>('loadeddata')
export const loadedMetadataEvent = events<Element, Event>('loadedmetadata')
export const loadEndEvent = events<Element, ProgressEvent>('loadend')
export const loadStartEvent = events<Element, ProgressEvent>('loadstart')
export const markEvent = events<Element, SpeechSynthesisEvent>('mark')
export const messageEvent = events<Element, MessageEvent | ServiceWorkerMessageEvent>('message')
export const mouseDownEvent = events<Element, MouseEvent>('mousedown')
export const mouseEnterEvent = events<Element, MouseEvent>('mouseenter')
export const mouseLeaveEvent = events<Element, MouseEvent>('mouseleave')
export const mouseMoveEvent = events<Element, MouseEvent>('mousemove')
export const mouseOutEvent = events<Element, MouseEvent>('mouseout')
export const mouseOverEvent = events<Element, MouseEvent>('mouseover')
export const noMatchEvent = events<Element, SpeechSynthesisEvent>('nomatch')
export const notificationClickEvent = events<Element, Event>('notificationclick')
export const noUpdateEvent = events<Element, Event>('noupdate')
export const obsoleteEvent = events<Element, Event>('obsolete')
export const offlineEvent = events<Element, Event>('offline')
export const onlineEvent = events<Element, Event>('online')
export const openEvent = events<Element, Event>('open')
export const orientationChangeEvent = events<Element, Event>('orientationchange')
export const pageShowEvent = events<Element, PageTransitionEvent>('pageshow')
export const pasteEvent = events<Element, ClipboardEvent>('paste')
export const pauseEvent = events<Element, Event | SpeechSynthesisEvent>('pause')
export const pointerCancelEvent = events<Element, PointerEvent>('pointercancel')
export const pointerDownEvent = events<Element, PointerEvent>('pointerdown')
export const pointerLockChangeEvent = events<Element, Event>('pointerlockchange')
export const pointerLockErrorEvent = events<Element, Event>('pointerlockerror')
export const pointerMoveEvent = events<Element, PointerEvent>('pointermove')
export const pointerOutEvent = events<Element, PointerEvent>('pointerout')
export const pointerOverEvent = events<Element, PointerEvent>('pointerover')
export const pointerUpEvent = events<Element, PointerEvent>('pointerup')
export const playEvent = events<Element, Event>('play')
export const playingEvent = events<Element, Event>('playing')
export const popStateEvent = events<Element, PopStateEvent>('popstate')
export const progressEvent = events<Element, ProgressEvent>('progress')
export const pushEvent = events<Element, Event>('push')
export const pushSubscriptionChangeEvent = events<Element, Event>('pushsubscriptionchange')
export const rateChangeEvent = events<Element, Event>('ratechange')
export const readyStateChangeEvent = events<Element, Event>('readystatechange')
export const resetEvent = events<Element, Event>('reset')
export const resizeEvent = events<Element, UIEvent>('resize')
export const resourceTimingBufferFullEvent = events<Element, Event>('resourcetimingbufferfull')
export const resultEvent = events<Element, Event>('result')
export const resumeEvent = events<Element, SpeechSynthesisEvent>('resume')
export const scrollEvent = events<Element, UIEvent>('scroll')
export const seekedEvent = events<Element, Event>('seeked')
export const seekingEvent = events<Element, Event>('seeking')
export const selectEvent = events<Element, UIEvent>('select')
export const selectStartEvent = events<Element, UIEvent>('selectstart')
export const selectionChangeEvent = events<Element, Event>('selectionchange')
export const showEvent = events<Element, MouseEvent>('show')
export const soundEndEvent = events<Element, Event>('soundend')
export const soundStartEvent = events<Element, Event>('soundstart')
export const speechEndEvent = events<Element, Event>('speechend')
export const stalledEvent = events<Element, Event>('stalled')
export const startEvent = events<Element, SpeechSynthesisEvent>('start')
export const storageEvent = events<Element, StorageEvent>('storage')
export const submitEvent = events<Element, Event>('submit')
export const successEvent = events<Element, Event>('success')
export const suspendEvent = events<Element, Event>('suspend')
export const timeoutEvent = events<Element, ProgressEvent>('timeout')
export const timeUpdateEvent = events<Element, Event>('timeupdate')
export const touchCancelEvent = events<Element, TouchEvent>('touchcancel')
export const touchEndEvent = events<Element, TouchEvent>('touchend')
export const touchEnterEvent = events<Element, TouchEvent>('touchenter')
export const touchLeaveEvent = events<Element, TouchEvent>('touchleave')
export const touchMoveEvent = events<Element, TouchEvent>('touchmove')
export const touchStartEvent = events<Element, TouchEvent>('touchstart')
export const transitionEndEvent = events<Element, TransitionEvent>('transitionend')
export const unloadEvent = events<Element, UIEvent>('unload')
export const updateReadyEvent = events<Element, Event>('updateready')
export const upgradeNeededEvent = events<Element, Event>('upgradeneeded')
export const userProximityEvent = events<Element, Event>('userproximity')
export const voicesChangedEvent = events<Element, Event>('voiceschanged')
export const versionChangeEvent = events<Element, Event>('versionchange')
export const visibilityChangeEvent = events<Element, Event>('visibilitychange')
export const volumeChangeEvent = events<Element, Event>('volumechange')
export const vrDisplayConnectedEvent = events<Element, Event>('vrdisplayconnected')
export const vrDisplayDisconnectedEvent = events<Element, Event>('vrdisplaydisconnected')
export const waitingEvent = events<Element, Event>('waiting')
export const wheelEvent = events<Element, WheelEvent>('wheel')
makeHistoryComponent\<State = any>(location: Location, history: History): IOComponent\<HistorySinks, HistorySources\<State>>
Given implementations of the Location
and History
interfaces, it returns
an IOComponent function which facilitates performing side-effects with
the history API.
const rootElementSelector = '#app' const element = document.querySelector(rootElementSelector)
if (!element) throw new Error(Unable to find element by '${rootElementSelector}'
)
const Dom = makeDomComponent(element) const History = makeHistoryComponent(location, history)
function IO(sinks) { return { ...Dom(sinks), ...History(sinks), } }
run(UI, IO)
</details>
<details>
<summary>See the code</summary>
```typescript
export function makeHistoryComponent<State = any>(
location: Location,
history: History
): IOComponent<HistorySinks, HistorySources<State>> {
const popState$: Stream<PopStateEvent> =
typeof window === void 0 ? empty() : new EventStream('popstate', window, {})
return function History(sinks: HistorySinks): HistorySources {
const { history$ } = sinks
const performHistoryEffect$ = multicast(tap(historyEffect => historyEffect(history), history$))
const updateSignal$ = multicast(merge<any>(performHistoryEffect$, popState$))
const location$ = hold(startWith(location, constant(location, updateSignal$)))
const state$ = hold(
map(({ state }) => state, startWith(history, constant(history, updateSignal$)))
)
drain(performHistoryEffect$)
return { location$, state$ }
}
}
query\<A, B, C>(cssSelector: CssSelector, domSource: DomSource\<A, B>): DomSource\<C, B>
A curried function for building more specific queries for elements.
type Sources = { dom: DomSource }
function Component(sources: Sources) { const { dom } = sources
const button: DomSource = query('button', dom) const event$ = events('click', button)
... }
</details>
<details>
<summary>See the code</summary>
```typescript
export const query: Query = curry2(function queryWrapper<A = Element, B = Event, C extends A = A>(
cssSelector: CssSelector,
domSource: DomSource<A, B>
): DomSource<C, B> {
return domSource.query<C>(cssSelector)
})
export interface Query {
<A = Element, B = Event, C = Element>(
cssSelector: CssSelector,
domSource: DomSource<A, B>
): DomSource<C, B>
<A = Element, B = Event, C = Element>(cssSelector: CssSelector): (
domSource: DomSource<A, B>
) => DomSource<C, B>
(cssSelector: CssSelector): <A = Element, B = Event, C = Element>(
domSource: DomSource<A, B>
) => DomSource<C, B>
}
useCapture\<A = Element, B = Event>(dom: DomSource\<A, B>): DomSource\<A, B>
Creates a new DomSource that will default to using
capture when using events()
.
export function Component(sources) { const { dom } = sources
const click$ = events('click', useCapture(dom))
... }
</details>
<details>
<summary>See the code</summary>
```typescript
export function useCapture<A = Element, B = Event>(dom: DomSource<A, B>): DomSource<A, B> {
const useCaptureDomSource: DomSource<A, B> = {
query(cssSelector: CssSelector): DomSource<A, B> {
return dom.query(cssSelector)
},
elements(): Stream<ReadonlyArray<A>> {
return dom.elements()
},
events<Ev extends B = B>(
eventType: StandardEvents,
options: EventListenerOptions = { capture: true }
): Stream<Ev> {
return dom.events(eventType, options)
},
cssSelectors(): ReadonlyArray<CssSelector> {
return dom.cssSelectors()
},
}
return useCaptureDomSource
}
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago