@internetarchive/shared-resize-observer v0.2.0
SharedResizeObserver
The SharedResizeObserver is an thin layer over the ResizeObserver to allow for WebComponents and other observers to use a single, shared ResizeObserver to provide performant resize observation.
It's more efficient to run a single ResizeObserver with many observations than many ResizeObservers, as noted in this performance comparison. A singleton of the SharedResizeObserver can be shared with any element that needs resize observation. Consumers register themselves with resizeObserver.addObserver({ handler, target }) and get a handleResize(entry: ResizeObserverEntry) callback when the target changes. See Usage section below for an example.
Installation
npm i @internetarchive/shared-resize-observerUsage
import { SharedResizeObserver } from '@internetarchive/shared-resize-observer';
import type {
ResizeObserverInterface,
SharedResizeObserverResizeHandlerInterface
} from '@internetarchive/shared-resize-observer';
@customElement('app-root')
export class AppRoot extends LitElement {
private resizeObserver: SharedResizeObserverInterface = new SharedResizeObserver();
render() {
return html`
<some-responsive-component
.resizeObserver=${this.resizeObserver}>
</some-responsive-component>
<other-responsive-component
.resizeObserver=${this.resizeObserver}>
</other-responsive-component>
`;
}
}
@customElement('some-responsive-component')
export class SomeResponsiveComponent extends LitElement
implements SharedResizeObserverResizeHandlerInterface {
@property({ type: Object })
resizeObserver?: SharedResizeObserverInterface;
updated(changed: PropertyValues): void {
// when we get a resizeObserver, set it up
if (changed.has('resizeObserver')) {
this.setupResizeObserver();
}
}
// when the component is disconnected, disconnect the resize observer
disconnectedCallback(): void {
this.disconnectResizeObserver();
}
// handle the resize event
handleResize(entry: ResizeObserverEntry): void {
// if you are observing multiple targets,
// you can distinguish them through `entry.target`
const target = entry.target;
if (target !== this.shadowRoot.host) return;
const contentRect = entry.contentRect;
// configure your view, ie:
if (contentRect.width < 600) {
// do something when component viewport is less than 600px wide
} else {
// do something when component viewport is 600px or more wide
}
}
// remove this component as an observer when disconnected
private disconnectResizeObserver(): void {
if (!this.shadowRoot) return;
this.resizeObserver?.removeObserver({
handler: this,
target: this.shadowRoot.host,
});
}
// observe the shadowRoot's viewport and
// make this component the handler of changes
private setupResizeObserver(): void {
this.disconnectResizeObserver();
if (!this.shadowRoot) return;
this.resizeObserver?.addObserver({
handler: this,
target: this.shadowRoot.host,
});
}
}Run npm run start for a full example and look in the demo directory for the sample code. See the docs in the docs directory.
Linting with ESLint, Prettier, and Types
To scan the project for linting errors, run
npm run lintYou can lint with ESLint and Prettier individually as well
npm run lint:eslintnpm run lint:prettierTo automatically fix many linting errors, run
npm run formatYou can format using ESLint and Prettier individually as well
npm run format:eslintnpm run format:prettierTesting with Web Test Runner
To run the suite of Web Test Runner tests, run
npm run testTo run the tests in watch mode (for TDD, for example), run
npm run test:watchTooling configs
For most of the tools, the configuration is in the package.json to reduce the amount of files in your project.
If you customize the configuration a lot, you can consider moving them to individual files.
Local Demo with web-dev-server
npm startTo run a local development server that serves the basic demo located in demo/index.html
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago