Architecture
This page is a source map for maintainers and coding agents. Public consumers should rely on the API reference, not internal methods.
Repository map
| Path | Purpose |
|---|---|
gridwave.js |
Entire library source and published package entry point. |
package.json |
npm metadata; only gridwave.js is included in the package. |
examples/ |
PHP-served manual demos for core behaviors. |
.github/workflows/publish-npm.yml |
Publishes to npm when a GitHub release is created. |
docs/ |
Canonical user, API, and maintainer documentation. |
There is no compilation step, generated distribution, external runtime dependency, or automated test suite.
Runtime and exports
gridwave.js defines one GridWave class. At the end of the file it exports through CommonJS when module.exports is available; otherwise, it assigns GridWave to window.
The first constructed instance injects a shared <style> element into document.head and sets window.gridwaveInstalled to avoid injecting it again.
Instance lifecycle
- The constructor resolves a selector or stores the supplied element.
- If configuration was provided, the constructor calls
init(). init()stores the configuration, ensures the container is positioned, callsupdateConfig(), and installs a debounced window resize listener.updateConfig()marks configuration objects with internal IDs, selects the active configuration, updates animation properties, and renders.- Filtering, sorting, configuration updates, explicit rerenders, and window resizes all run the rendering path.
destroy()clears selected layout styles and item status, subject to the limitations below.
Call init() only once for an instance. It does not guard against duplicate resize listeners.
Configuration selection
The base configuration owns itemSelector and breakpoints. The active rendering configuration is either:
- the breakpoint with the smallest numeric key for which
window.innerWidth <= key; or - the base configuration when no breakpoint matches.
Breakpoint objects replace the active base layout configuration rather than inheriting from it. GridWave adds a private __memoryId property to the base and breakpoint objects to detect configuration changes.
Rendering pipeline
For built-in layouts, the effective data flow is:
container -> discover items -> mark/filter items -> sort visible items -> calculate dimensions and positions -> set container height
getItems() returns either all direct children or all descendants matching the base itemSelector.
Filtering updates data-gridwave-status and aria-hidden. Sorting mutates the temporary items array, not DOM order.
If the active configuration supplies renderer, rerender() invokes it immediately with all discovered items. The custom renderer bypasses the built-in filter, sort, and layout stages.
Layout strategies
Fixed columns
renderWithColumns() calculates a shared column width from container width and horizontal gaps. It measures item heights, tracks the tallest item in each row, positions rows, optionally applies equal heights, and sets the container height.
Dynamic columns
renderWithDynamicColumnAmount() derives a whole column count from container width, columnMinWidth, and horizontal gap, then delegates to the normal or masonry renderer.
Masonry
renderMasonryWithColumns() assigns items to columns, positions each item below the previous item in its column, and sizes the container from the tallest accumulated column height. Masonry is experimental and should be changed only with representative visual checks.
DOM and CSS effects
GridWave may change:
- container inline
position,height, and transition custom properties; - item inline
position,width,left,top, andheight; - container
data-gridwave-animations; - item
data-gridwave-statusandaria-hidden; and document.headby adding the shared transition stylesheet.
The animation variables implemented by the source are:
--gridwave-transition-duration--gridwave-transition-timing
Current limitations
destroy()does not remove the resize listener.destroy()clears container positioning instead of restoring its previous inline value.destroy()leaves item heights fromsameHeightand leaves container animation state in place.- The globally injected stylesheet is not removed.
- GridWave listens to window resize but does not use
ResizeObserverorMutationObserver. - Masonry is experimental and may produce uneven or unexpected ordering.
- Invalid container or selector input is not validated with a GridWave-specific error.
- Configuration objects are mutated and therefore cannot be frozen.
- No automated tests or declared browser support matrix currently protect behavior.
Treat these as compatibility facts when modifying the source. A fix that changes observable behavior should include documentation updates and, ideally, automated coverage.