DOM Utilities
DOM composables from @praxisjs/composables. Use them with the @Compose decorator to bind reactive DOM state directly to component properties.
npm install @praxisjs/composablespnpm add @praxisjs/composablesyarn add @praxisjs/composablesbun add @praxisjs/composablesWindowSize
Tracks the browser window's inner dimensions.
import { Compose } from '@praxisjs/decorators'
import { WindowSize } from '@praxisjs/composables'
@Component()
class App extends StatefulComponent {
@Compose(WindowSize)
window!: WindowSize
render() {
return <p>Viewport: {() => this.window.width} × {() => this.window.height}</p>
}
}Properties: width: number, height: number
ScrollPosition
Tracks scroll position. Pass an element to track its scroll, or omit for the window.
@Compose(ScrollPosition)
scroll!: ScrollPosition
// Track a specific element:
@Compose(ScrollPosition, document.getElementById('feed'))
feedScroll!: ScrollPositionProperties: x: number, y: number
ElementSize
Tracks an element's dimensions via ResizeObserver.
@Component()
class ResizeWatcher extends StatefulComponent {
containerRef = { current: null as HTMLDivElement | null }
@Compose(ElementSize, 'containerRef')
size!: ElementSize
render() {
return (
<div ref={(el) => { this.containerRef.current = el }}>
<p>Width: {() => this.size.width}, Height: {() => this.size.height}</p>
</div>
)
}
}String arguments to @Compose resolve to instance properties at bind time.
Properties: width: number, height: number
Intersection
Tracks whether an element is in the viewport via IntersectionObserver.
@Component()
class LazySection extends StatefulComponent {
sectionRef = { current: null as HTMLElement | null }
@Compose(Intersection, 'sectionRef', { threshold: 0.5 })
visibility!: Intersection
render() {
return (
<section ref={(el) => { this.sectionRef.current = el }}>
{() => this.visibility.visible ? <HeavyContent /> : <Placeholder />}
</section>
)
}
}Constructor: new Intersection(ref, options?) — options matches IntersectionObserverInit.
Properties: visible: boolean
Focus
Tracks whether an element currently has focus.
@Component()
class SearchBar extends StatefulComponent {
inputRef = { current: null as HTMLInputElement | null }
@Compose(Focus, 'inputRef')
focus!: Focus
render() {
return (
<div>
<input ref={(el) => { this.inputRef.current = el }} />
{() => this.focus.focused && <span>Typing...</span>}
</div>
)
}
}Properties: focused: boolean