@duboseweb/motus 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -30
- package/dist/motus.cjs +17 -2
- package/dist/motus.js +17 -2
- package/dist/motus.umd.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -318,36 +318,6 @@ npm run test:pack # pack, install into a throwaway project, assert it works
|
|
|
318
318
|
npm run check:pkg # publint + are-the-types-wrong
|
|
319
319
|
```
|
|
320
320
|
|
|
321
|
-
### Releasing
|
|
322
|
-
|
|
323
|
-
Publishing runs from CI on a version tag, using npm
|
|
324
|
-
[trusted publishing](https://docs.npmjs.com/trusted-publishers) — there is no npm token stored
|
|
325
|
-
anywhere, and npm generates a provenance attestation automatically, linking the published tarball
|
|
326
|
-
to the exact commit and workflow that built it.
|
|
327
|
-
|
|
328
|
-
Work lands on `develop`. `main` is protected and takes pull requests only, so the version bump is
|
|
329
|
-
made on `develop` and the tag is cut from `main` after the merge:
|
|
330
|
-
|
|
331
|
-
```sh
|
|
332
|
-
# on develop — bump the version without tagging yet
|
|
333
|
-
npm version patch --no-git-tag-version # or minor / major
|
|
334
|
-
git commit -am "Release v1.0.1"
|
|
335
|
-
git push
|
|
336
|
-
|
|
337
|
-
# open a pull request from develop to main and merge it
|
|
338
|
-
|
|
339
|
-
git checkout main && git pull
|
|
340
|
-
git tag v1.0.1
|
|
341
|
-
git push origin v1.0.1 # this is what triggers the release
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
Tags are not covered by the branch protection, so the final push is what starts the publish.
|
|
345
|
-
|
|
346
|
-
The workflow refuses to publish if the tagged commit is not reachable from `main`, or if the tag
|
|
347
|
-
and `package.json` disagree. It fails loudly rather than skipping, so a release that did not happen
|
|
348
|
-
is never mistaken for one that did. `prepublishOnly` then runs lint, typecheck, tests, the build,
|
|
349
|
-
`check:pkg` and the package smoke test before anything reaches the registry.
|
|
350
|
-
|
|
351
321
|
---
|
|
352
322
|
|
|
353
323
|
## License
|
package/dist/motus.cjs
CHANGED
|
@@ -385,6 +385,18 @@ const getThreshold = (anchorPlacement) => {
|
|
|
385
385
|
}
|
|
386
386
|
};
|
|
387
387
|
|
|
388
|
+
/**
|
|
389
|
+
* The target sits entirely above the trigger zone.
|
|
390
|
+
*
|
|
391
|
+
* A reload restores the scroll position before `init()`, so the browser's first
|
|
392
|
+
* record for anything already scrolled past reports it as not intersecting. It
|
|
393
|
+
* will never cross the zone again, and the stylesheet keeps `[data-motus]`
|
|
394
|
+
* hidden until it animates — without this those sections stay blank. Reads the
|
|
395
|
+
* entry only: no layout. A null `rootBounds` (cross-origin iframe) is not past.
|
|
396
|
+
*/
|
|
397
|
+
const isPast = (entry) => !entry.isIntersecting &&
|
|
398
|
+
entry.rootBounds !== null &&
|
|
399
|
+
entry.boundingClientRect.bottom <= entry.rootBounds.top;
|
|
388
400
|
/**
|
|
389
401
|
* Creates the IntersectionObservers for a set of resolved configs.
|
|
390
402
|
*
|
|
@@ -411,7 +423,10 @@ windowHeight = window.innerHeight) => {
|
|
|
411
423
|
if (!targets)
|
|
412
424
|
return;
|
|
413
425
|
for (const config of targets) {
|
|
414
|
-
|
|
426
|
+
// A config that can animate out treats "past" as out, so it only reveals
|
|
427
|
+
// inside the zone. Everything else counts scrolling past as reaching it.
|
|
428
|
+
const reversible = config.mirror && !config.once;
|
|
429
|
+
if (entry.isIntersecting || (!reversible && isPast(entry))) {
|
|
415
430
|
if (!config.animated) {
|
|
416
431
|
addClasses(config.node, config.animatedClassNames);
|
|
417
432
|
fireEvent(EVENT_IN, config.node, config.id);
|
|
@@ -419,7 +434,7 @@ windowHeight = window.innerHeight) => {
|
|
|
419
434
|
setAnimated(config.node, true);
|
|
420
435
|
}
|
|
421
436
|
}
|
|
422
|
-
else if (config.animated &&
|
|
437
|
+
else if (config.animated && reversible) {
|
|
423
438
|
removeClasses(config.node, config.animatedClassNames);
|
|
424
439
|
fireEvent(EVENT_OUT, config.node, config.id);
|
|
425
440
|
config.animated = false;
|
package/dist/motus.js
CHANGED
|
@@ -381,6 +381,18 @@ const getThreshold = (anchorPlacement) => {
|
|
|
381
381
|
}
|
|
382
382
|
};
|
|
383
383
|
|
|
384
|
+
/**
|
|
385
|
+
* The target sits entirely above the trigger zone.
|
|
386
|
+
*
|
|
387
|
+
* A reload restores the scroll position before `init()`, so the browser's first
|
|
388
|
+
* record for anything already scrolled past reports it as not intersecting. It
|
|
389
|
+
* will never cross the zone again, and the stylesheet keeps `[data-motus]`
|
|
390
|
+
* hidden until it animates — without this those sections stay blank. Reads the
|
|
391
|
+
* entry only: no layout. A null `rootBounds` (cross-origin iframe) is not past.
|
|
392
|
+
*/
|
|
393
|
+
const isPast = (entry) => !entry.isIntersecting &&
|
|
394
|
+
entry.rootBounds !== null &&
|
|
395
|
+
entry.boundingClientRect.bottom <= entry.rootBounds.top;
|
|
384
396
|
/**
|
|
385
397
|
* Creates the IntersectionObservers for a set of resolved configs.
|
|
386
398
|
*
|
|
@@ -407,7 +419,10 @@ windowHeight = window.innerHeight) => {
|
|
|
407
419
|
if (!targets)
|
|
408
420
|
return;
|
|
409
421
|
for (const config of targets) {
|
|
410
|
-
|
|
422
|
+
// A config that can animate out treats "past" as out, so it only reveals
|
|
423
|
+
// inside the zone. Everything else counts scrolling past as reaching it.
|
|
424
|
+
const reversible = config.mirror && !config.once;
|
|
425
|
+
if (entry.isIntersecting || (!reversible && isPast(entry))) {
|
|
411
426
|
if (!config.animated) {
|
|
412
427
|
addClasses(config.node, config.animatedClassNames);
|
|
413
428
|
fireEvent(EVENT_IN, config.node, config.id);
|
|
@@ -415,7 +430,7 @@ windowHeight = window.innerHeight) => {
|
|
|
415
430
|
setAnimated(config.node, true);
|
|
416
431
|
}
|
|
417
432
|
}
|
|
418
|
-
else if (config.animated &&
|
|
433
|
+
else if (config.animated && reversible) {
|
|
419
434
|
removeClasses(config.node, config.animatedClassNames);
|
|
420
435
|
fireEvent(EVENT_OUT, config.node, config.id);
|
|
421
436
|
config.animated = false;
|
package/dist/motus.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/*! dwg-motus | MIT License | https://github.com/dubose-web/dwg-motus */
|
|
2
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Motus=t()}(this,function(){"use strict";const e="data-motus",t="data-motus-inactive",n="motus-ready",o="--motus-duration",s="--motus-delay",a="--motus-easing",r="[dwg-motus]",i=Object.freeze({sm:576,md:768,lg:992,xl:1200,xxl:1400}),c=["sm","md","lg","xl","xxl"],u=Object.freeze({offset:120,delay:0,easing:"ease",duration:400,disable:"lg",breakpoints:i,once:!1,mirror:!1,anchorPlacement:"top-bottom",startEvent:"DOMContentLoaded",animatedClassName:"motus-animate",initClassName:"motus-init",useClassNames:!1,disableMutationObserver:!1,debounceDelay:50}),d=["top-bottom","top-center","top-top","center-bottom","center-center","center-top","bottom-bottom","bottom-center","bottom-top"];const l=()=>matchMedia("(pointer: coarse) and (hover: none) and (max-width: 767px)").matches,m=()=>matchMedia("(pointer: coarse) and (hover: none)").matches,b={"ease-in-back":"cubic-bezier(.6, -.28, .735, .045)","ease-out-back":"cubic-bezier(.175, .885, .32, 1.275)","ease-in-out-back":"cubic-bezier(.68, -.55, .265, 1.55)","ease-in-sine":"cubic-bezier(.47, 0, .745, .715)","ease-out-sine":"cubic-bezier(.39, .575, .565, 1)","ease-in-out-sine":"cubic-bezier(.445, .05, .55, .95)","ease-in-quad":"cubic-bezier(.55, .085, .68, .53)","ease-out-quad":"cubic-bezier(.25, .46, .45, .94)","ease-in-out-quad":"cubic-bezier(.455, .03, .515, .955)","ease-in-cubic":"cubic-bezier(.55, .055, .675, .19)","ease-out-cubic":"cubic-bezier(.215, .61, .355, 1)","ease-in-out-cubic":"cubic-bezier(.645, .045, .355, 1)","ease-in-quart":"cubic-bezier(.895, .03, .685, .22)","ease-out-quart":"cubic-bezier(.165, .84, .44, 1)","ease-in-out-quart":"cubic-bezier(.77, 0, .175, 1)"},f=e=>{var t;return null!==(t=b[e])&&void 0!==t?t:e},p=(e,t)=>{for(const n of t)e.classList.add(n)},v=(e,t)=>{for(const n of t)e.classList.remove(n)},h=(e,t,n)=>{const o={node:t};document.dispatchEvent(new CustomEvent(e,{detail:o})),n&&document.dispatchEvent(new CustomEvent(`${e}:${n}`,{detail:o}))},y=[o,s,a],g=e=>{if(e)for(const t of y)e.style.removeProperty(t)},w=e=>g(e);let $=new WeakMap;const E=(e,t)=>{$.set(e,t)},x=(e,t)=>t?e.classList.contains(t):!0===$.get(e);function N(t,n,o){const s=t.getAttribute((t=>`${e}-${t}`)(n));return"true"===s||"false"!==s&&(null!=s?s:o)}const
|
|
2
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Motus=t()}(this,function(){"use strict";const e="data-motus",t="data-motus-inactive",n="motus-ready",o="--motus-duration",s="--motus-delay",a="--motus-easing",r="[dwg-motus]",i=Object.freeze({sm:576,md:768,lg:992,xl:1200,xxl:1400}),c=["sm","md","lg","xl","xxl"],u=Object.freeze({offset:120,delay:0,easing:"ease",duration:400,disable:"lg",breakpoints:i,once:!1,mirror:!1,anchorPlacement:"top-bottom",startEvent:"DOMContentLoaded",animatedClassName:"motus-animate",initClassName:"motus-init",useClassNames:!1,disableMutationObserver:!1,debounceDelay:50}),d=["top-bottom","top-center","top-top","center-bottom","center-center","center-top","bottom-bottom","bottom-center","bottom-top"];const l=()=>matchMedia("(pointer: coarse) and (hover: none) and (max-width: 767px)").matches,m=()=>matchMedia("(pointer: coarse) and (hover: none)").matches,b={"ease-in-back":"cubic-bezier(.6, -.28, .735, .045)","ease-out-back":"cubic-bezier(.175, .885, .32, 1.275)","ease-in-out-back":"cubic-bezier(.68, -.55, .265, 1.55)","ease-in-sine":"cubic-bezier(.47, 0, .745, .715)","ease-out-sine":"cubic-bezier(.39, .575, .565, 1)","ease-in-out-sine":"cubic-bezier(.445, .05, .55, .95)","ease-in-quad":"cubic-bezier(.55, .085, .68, .53)","ease-out-quad":"cubic-bezier(.25, .46, .45, .94)","ease-in-out-quad":"cubic-bezier(.455, .03, .515, .955)","ease-in-cubic":"cubic-bezier(.55, .055, .675, .19)","ease-out-cubic":"cubic-bezier(.215, .61, .355, 1)","ease-in-out-cubic":"cubic-bezier(.645, .045, .355, 1)","ease-in-quart":"cubic-bezier(.895, .03, .685, .22)","ease-out-quart":"cubic-bezier(.165, .84, .44, 1)","ease-in-out-quart":"cubic-bezier(.77, 0, .175, 1)"},f=e=>{var t;return null!==(t=b[e])&&void 0!==t?t:e},p=(e,t)=>{for(const n of t)e.classList.add(n)},v=(e,t)=>{for(const n of t)e.classList.remove(n)},h=(e,t,n)=>{const o={node:t};document.dispatchEvent(new CustomEvent(e,{detail:o})),n&&document.dispatchEvent(new CustomEvent(`${e}:${n}`,{detail:o}))},y=[o,s,a],g=e=>{if(e)for(const t of y)e.style.removeProperty(t)},w=e=>g(e);let $=new WeakMap;const E=(e,t)=>{$.set(e,t)},x=(e,t)=>t?e.classList.contains(t):!0===$.get(e);function N(t,n,o){const s=t.getAttribute((t=>`${e}-${t}`)(n));return"true"===s||"false"!==s&&(null!=s?s:o)}const C=(e,t)=>{const n=N(e,t);return"string"==typeof n?n:void 0},M=(e,t)=>{var n;const o=C(e,"anchor");if(!o)return e;if(t.has(o))return null!==(n=t.get(o))&&void 0!==n?n:e;let s=null;try{s=document.querySelector(o)}catch(e){console.warn(`${r} Invalid data-motus-anchor selector: ${o}`)}return t.set(o,s),null!=s?s:e},k=(t,n)=>{const r=new Map,i=n.animatedClassName?[n.animatedClassName]:[];return t.map(t=>{var c,u;const d=Boolean(N(t,"mirror",n.mirror)),l=Boolean(N(t,"once",n.once)),m=null!==(c=C(t,"id"))&&void 0!==c?c:null,b=null!==(u=C(t,"anchor-placement"))&&void 0!==u?u:n.anchorPlacement,p=Number(N(t,"offset",n.offset)),v=Number.isFinite(p)?p:n.offset;var h,y;h=t,(y={duration:C(t,"duration"),delay:C(t,"delay"),easing:C(t,"easing")}).duration&&h.style.setProperty(o,`${y.duration}ms`),y.delay&&h.style.setProperty(s,`${y.delay}ms`),y.easing&&h.style.setProperty(a,f(y.easing)),n.initClassName&&t.classList.add(n.initClassName);const g=n.useClassNames?t.getAttribute(e):null,w=g?i.concat(g.split(" ").filter(e=>""!==e)):i;return{node:t,observeTarget:M(t,r),mirror:d,once:l,id:m,animatedClassNames:w,animated:x(t,n.animatedClassName),anchorPlacement:b,offset:v}})},z=(e,t,n=window.innerHeight)=>{switch(e){case"top-center":case"center-center":case"bottom-center":{const e=Math.max(Math.round(n/2)-t,1);return`${-e}px 0px ${-e}px 0px`}case"top-top":case"center-top":case"bottom-top":return`${Math.max(t,1)}px 0px ${-(n-t)}px 0px`;default:return`0px 0px ${-t}px 0px`}},O=e=>{switch(e){case"center-bottom":case"center-center":case"center-top":return.5;default:return 0}},P=e=>!e.isIntersecting&&null!==e.rootBounds&&e.boundingClientRect.bottom<=e.rootBounds.top,L=t=>{let n=!1;const o=new MutationObserver(o=>{if(n)return;o.some(t=>(t=>{for(const n of t){if(n.nodeType!==Node.ELEMENT_NODE)continue;const t=n;if(t.hasAttribute(e)||t.querySelector(`[${e}]`))return!0}return!1})(t.addedNodes))&&(n=!0,requestAnimationFrame(()=>{n=!1,t()}))});return o.observe(document.documentElement,{childList:!0,subtree:!0}),o},q=[...c,"phone","tablet","mobile"],A=e=>"number"==typeof e&&Number.isFinite(e)&&e>=0;let j=[],D=null,T=null,I=[],S=!1,F=null,U=Object.assign({},u);const H=(e,t,n)=>{e.addEventListener(t,n),I.push({target:e,event:t,fn:n})},B=()=>[...document.querySelectorAll(`[${e}]`)],R=e=>{const{disable:t}=e;return document.documentElement.hasAttribute("data-motus-disabled")||!0===t||"string"==typeof t&&t in e.breakpoints&&(n=e.breakpoints[t],matchMedia(`(max-width: ${n-.02}px)`).matches)||"mobile"===t&&m()||"phone"===t&&l()||"tablet"===t&&m()&&!l()||"function"==typeof t&&!0===t();var n},W=()=>{S&&(F=window.innerHeight,j=B(),null==D||D.disconnect(),D=((e,t=window.innerHeight)=>{let n=!1;const o=new Map,s=(e,t)=>{const n=t.targets.get(e.target);if(n){for(const t of n){const n=t.mirror&&!t.once;e.isIntersecting||!n&&P(e)?t.animated||(p(t.node,t.animatedClassNames),h("motus:in",t.node,t.id),t.animated=!0,E(t.node,!0)):t.animated&&n&&(v(t.node,t.animatedClassNames),h("motus:out",t.node,t.id),t.animated=!1,E(t.node,!1))}n.every(e=>e.once&&e.animated)&&t.observer.unobserve(e.target)}};for(const a of e){if(a.once&&a.animated)continue;const e=`${a.anchorPlacement}-${a.offset}`;let r=o.get(e);if(!r){const i=new Map,c=new IntersectionObserver(e=>{if(n)for(const t of e)s(t,r);else r.buffered.push(...e)},{rootMargin:z(a.anchorPlacement,a.offset,t),threshold:O(a.anchorPlacement)});r={observer:c,targets:i,buffered:[]},o.set(e,r)}const i=r.targets.get(a.observeTarget);i?i.push(a):(r.targets.set(a.observeTarget,[a]),r.observer.observe(a.observeTarget))}return{disconnect:()=>{for(const e of o.values())e.observer.disconnect();o.clear()},activate:()=>{n=!0;for(const e of o.values()){const t=e.buffered.concat(e.observer.takeRecords());e.buffered.length=0;for(const n of t)s(n,e)}}}})(k(j,U),F),document.body.classList.contains(n)?null==D||D.activate():requestAnimationFrame(()=>{requestAnimationFrame(()=>{document.body.classList.add(n),null==D||D.activate()})}))},_=()=>{S=!0,W()},G=()=>{S&&F!==window.innerHeight&&W()},J=()=>{R(U)?K():S?(document.documentElement.removeAttribute(t),W()):V(U)},K=()=>{var e;document.documentElement.setAttribute(t,""),null==T||T.disconnect(),T=null,null==D||D.disconnect(),D=null,null===(e=document.body)||void 0===e||e.classList.remove(n);for(const e of j)w(e),U.initClassName&&e.classList.remove(U.initClassName),U.animatedClassName&&e.classList.remove(U.animatedClassName);$=new WeakMap},Q=()=>{K();for(const{target:e,event:t,fn:n}of I)e.removeEventListener(t,n);I=[],g(document.body),j=[],S=!1,F=null},V=e=>(S&&Q(),U=((e={})=>{const t=[];for(const n of Object.keys(e))n in u||t.push(`Unknown option "${n}".`);const n=Object.assign({},u,e);for(const e of["duration","delay","offset"])A(n[e])||(t.push(`"${e}" must be a non-negative number, received ${String(n[e])}. Using ${u[e]}.`),n[e]=u[e]);d.includes(n.anchorPlacement)||(t.push(`"anchorPlacement" must be one of ${d.join(", ")}. Using ${u.anchorPlacement}.`),n.anchorPlacement=u.anchorPlacement),"string"!=typeof n.disable||q.includes(n.disable)||(t.push(`"disable" must be a boolean, a function, or one of ${q.join(", ")}. Using ${String(u.disable)}.`),n.disable=u.disable),n.breakpoints=Object.assign({},u.breakpoints,e.breakpoints);for(const e of c){const o=n.breakpoints[e];("number"!=typeof o||!Number.isFinite(o)||o<=0)&&(t.push(`"breakpoints.${e}" must be a positive number, received ${String(o)}. Using ${u.breakpoints[e]}.`),n.breakpoints[e]=u.breakpoints[e])}"string"==typeof n.startEvent&&""!==n.startEvent||(t.push(`"startEvent" must be a non-empty string. Using ${u.startEvent}.`),n.startEvent=u.startEvent);const o=n.debounceDelay,s=Number.isFinite(o)?Math.min(500,Math.max(16,o)):u.debounceDelay;return s!==o&&t.push(`"debounceDelay" clamped from ${String(o)} to ${s} (allowed range 16–500ms).`),n.debounceDelay=s,t.length>0&&console.warn(`${r} Invalid options:\n - ${t.join("\n - ")}`),n})(e),document.documentElement.removeAttribute(t),"undefined"!=typeof window&&"function"==typeof window.IntersectionObserver&&"function"==typeof window.IntersectionObserverEntry&&"intersectionRatio"in window.IntersectionObserverEntry.prototype?(j=B(),R(U)?void K():(U.disableMutationObserver||(T=L(J)),(e=>{const{body:t}=document;t&&(t.style.setProperty(o,`${e.duration}ms`),t.style.setProperty(s,`${e.delay}ms`),t.style.setProperty(a,f(e.easing)))})(U),"DOMContentLoaded"===U.startEvent||"load"===U.startEvent?H(window,"load",()=>{S||_()}):H(document,U.startEvent,()=>_()),"DOMContentLoaded"!==U.startEvent||"complete"!==document.readyState&&"interactive"!==document.readyState||_(),H(window,"resize",function(e,t){let n;return(...o)=>{clearTimeout(n),n=setTimeout(()=>e(...o),t)}}(G,U.debounceDelay)),j)):(console.warn(`${r} IntersectionObserver is not supported in this browser; animations are disabled.`),void document.documentElement.setAttribute(t,"")));return Object.freeze({init:V,refresh:()=>W(),refreshHard:J,destroy:Q})});
|