diff --git a/examples/container-queries.html b/examples/container-queries.html deleted file mode 100644 index ca045b7..0000000 --- a/examples/container-queries.html +++ /dev/null @@ -1,74 +0,0 @@ - - - - - Snabby Container Queries - - - -
- -

Inspect the main element in the dev console and resize the page. You'll see different classes being added/removed from the main tag based on the width the element is.

- -

Clicking on the element will toggle the container queries on and off.

- - - - diff --git a/index.js b/index.js index ded0590..968ac56 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,6 @@ // Inits with common modules out of the box // Also easier to use across multiple files import create from './create.js' -import containerQueryModule from './snabbdom-containerquery.js' import { attributesModule, classModule, propsModule, styleModule, eventListenersModule } from 'snabbdom' @@ -10,6 +9,5 @@ export default create([ eventListenersModule, classModule, propsModule, - styleModule, - containerQueryModule + styleModule ]) diff --git a/package.json b/package.json index c02cf07..3cb3e1e 100644 --- a/package.json +++ b/package.json @@ -9,18 +9,17 @@ "license": "MIT", "files": [ "index.js", - "create.js", - "snabbdom-containerquery.js" + "create.js" ], "scripts": { "examples": "serve .", "predeploy": "npm run test", "prepublishOnly": "npm run predeploy", - "test": "node test/index.js" + "test": "node test/test.js" }, "devDependencies": { "browser-env": "^3.3.0", - "resize-observer-polyfill": "^1.5.1", + "happy-dom": "^12.10.3", "serve": "^14.0.0", "tape": "^5.2.2" }, diff --git a/readme.md b/readme.md index a67146a..feaedf9 100644 --- a/readme.md +++ b/readme.md @@ -53,23 +53,6 @@ let node2 = greet('World') You have all the [modules documented by Snabbdom](https://github.com/snabbdom/snabbdom#modules-documentation) loaded by default. See [Directives](#directives) for how to use modules, and [`snabby/create`](#snabby_create) for loading custom modules -### Container Queries - -Container Queries are one of the most requested features of all time in CSS. It enables people that want to build responsive -components by allowing classes to be attached to DOM elements based on their width, as opposed to `@media` queries, which only -operate on the viewport width. - -In snabby you can specify a series of rules for setting classes on an element based on minimum width: - -```js -html`
Some content here
` -``` - -If the div is 700px wide, it will have `BP2` in it's classlist. Only the class with the highest matching rule will be added, regardless of what order the rules are declared in. - -Internally, this is implemented with a ResizeObserver. As of version 5, we no longer bundle a ResizeObserver ponyfill with snabby. You should polyfill ResizeObserver yourself if you plan on using snabby on very old browsers. https://www.npmjs.com/package/resize-observer-polyfill - - ### Directives Directives are attributes that begin with `@`, and let you interact with Snabbdom modules. In general, the form is `@:[prop]:...`. @@ -151,13 +134,12 @@ Create a `snabby` tag function with your own modules. Here is an equivalent to `snabby` for example: ```js -import create from './create.js' -import { attributesModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@2.1.0/build/package/modules/attributes.js'; -import { classModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@2.1.0/build/package/modules/class.js'; -import { propsModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@2.1.0/build/package/modules/props.js'; -import { styleModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@2.1.0/build/package/modules/style.js'; -import { eventListenersModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@2.1.0/build/package/modules/eventlisteners.js'; -import containerQueryModule from './snabbdom-containerquery.js'; +import create from './create.js' +import { attributesModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/attributes.js'; +import { classModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/class.js'; +import { propsModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/props.js'; +import { styleModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/style.js'; +import { eventListenersModule } from 'https://cdn.jsdelivr.net/npm/snabbdom@3/build/package/modules/eventlisteners.js'; const html = create([ @@ -165,8 +147,7 @@ const html = create([ eventListenersModule, classModule, propsModule, - styleModule, - containerQueryModule + styleModule ]) ``` diff --git a/snabbdom-containerquery.js b/snabbdom-containerquery.js deleted file mode 100644 index dab071f..0000000 --- a/snabbdom-containerquery.js +++ /dev/null @@ -1,62 +0,0 @@ -// inspired by https://philipwalton.com/articles/responsive-components-a-solution-to-the-container-queries-problem/ - - -// today it's more performant to have 1 resizeObserver observe multiple elements rather than 1 per element. -// see https://groups.google.com/a/chromium.org/g/blink-dev/c/z6ienONUb5A/m/F5-VcUZtBAAJ -const observer = new window.ResizeObserver(function (entries) { - for (const entry of entries) { - const breakpoints = JSON.parse(entry.target.dataset.breakpoints); - - // the rule iteration order depends on the order the object keys, and this varies from browser to browser. - // keep track of a high water mark so we always apply the widest matching rule regardless of iteration order. - let highWaterMark = 0; - - let selectedClass = ''; - - for (const breakpoint of Object.keys(breakpoints)) { - const minWidth = breakpoints[breakpoint]; - if (entry.contentRect.width >= minWidth && minWidth > highWaterMark) { - selectedClass = breakpoint; - highWaterMark = minWidth; - } - } - - for (const breakpoint of Object.keys(breakpoints)) { - if (breakpoint === selectedClass) { - if (!entry.target.classList.contains(breakpoint)) - entry.target.classList.add(breakpoint); - - } else if (entry.target.classList.contains(breakpoint)) { - entry.target.classList.remove(breakpoint); - } - } - } -}); - - -function update (oldVnode, vnode) { - if (vnode.elm.dataset && vnode.elm.dataset.breakpoints) { - try { - // ensure that the data attribute parses as valid json before we start observing it - JSON.parse(vnode.elm.dataset.breakpoints); - observer.observe(vnode.elm); - } catch (er) { - // TODO: should invalid json in the data-breakpoints attribute throw an error? - } - } else if (vnode.elm instanceof Element) { - observer.unobserve(vnode.elm); - } -} - - -function destroy (vnode/*, removeCallback*/) { - if (vnode.elm instanceof Element) - observer.unobserve(vnode.elm); -} - - -export default { - create: update, - update, - destroy -} diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 15d96da..0000000 --- a/test/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import browserEnv from 'browser-env' -import ResizeObserver from 'resize-observer-polyfill' - - -browserEnv() - -// browser-env doesn't provide browser APIs beyond pure DOM/window stuff -window.ResizeObserver = ResizeObserver -window.requestAnimationFrame = function () { } - -async function main () { - await import('./test.js'); -} - -main(); diff --git a/test/test.js b/test/test.js index 1232205..ea3a539 100644 --- a/test/test.js +++ b/test/test.js @@ -1,6 +1,11 @@ -import snabby from '../index.js' -import { h } from 'snabbdom' // helper function for creating vnodes -import test from 'tape' +import snabby from '../index.js' +import { h } from 'snabbdom' // helper function for creating vnodes +import test from 'tape' +import { Window } from 'happy-dom' + + +global.window = new Window() +global.document = window.document test('creation', function (t) {