@suyongs/solid-utility
Advanced tools
Comparing version 0.1.1 to 0.2.0
export { default as Marquee } from './Marquee'; | ||
export * from './Marquee'; | ||
export { default as Transition } from './Transition'; | ||
export * from './Transition'; |
@@ -1,3 +0,3 @@ | ||
import { createComponent, Dynamic, mergeProps as mergeProps$1 } from "solid-js/web"; | ||
import { splitProps, mergeProps, children, createSignal, onMount, createEffect, on, onCleanup, Show } from "solid-js"; | ||
import { createComponent, Dynamic, mergeProps as mergeProps$1, memo } from "solid-js/web"; | ||
import { splitProps, mergeProps, children, createSignal, onMount, createEffect, on, onCleanup, Show, startTransition } from "solid-js"; | ||
const cx = (...classNames) => classNames.filter((it) => !!it).join(" "); | ||
@@ -243,4 +243,158 @@ let random = (bytes) => crypto.getRandomValues(new Uint8Array(bytes)); | ||
}; | ||
const yieldAsync = () => new Promise((resolve) => requestAnimationFrame(() => requestAnimationFrame(() => resolve()))); | ||
const Transition = (props) => { | ||
const [listeners, classes, leftProps] = splitProps(mergeProps({ | ||
appear: false, | ||
mode: "in-out" | ||
}, props), ["onBeforeEnter", "onEnter", "onAfterEnter", "onBeforeLeave", "onLeave", "onAfterLeave"], ["enterFromClass", "enterActiveClass", "enterToClass", "leaveFromClass", "leaveActiveClass", "leaveToClass"]); | ||
const childList = children(() => leftProps.children); | ||
const duplicatedChildList = children(() => leftProps.children); | ||
const firstChild = () => childList.toArray().at(0); | ||
const duplicatedFirstChild = () => duplicatedChildList.toArray().at(0); | ||
const [transition, setTransition] = createSignal(false); | ||
const [lastChild, setLastChild] = createSignal(duplicatedFirstChild()); | ||
const enterFromClassName = () => classes.enterFromClass ?? `${leftProps.name}-enter-from`; | ||
const enterActiveClassName = () => classes.enterActiveClass ?? `${leftProps.name}-enter-active`; | ||
const enterToClassName = () => classes.enterToClass ?? `${leftProps.name}-enter-to`; | ||
const leaveFromClassName = () => classes.leaveFromClass ?? `${leftProps.name}-leave-from`; | ||
const leaveActiveClassName = () => classes.leaveActiveClass ?? `${leftProps.name}-leave-active`; | ||
const leaveToClassName = () => classes.leaveToClass ?? `${leftProps.name}-leave-to`; | ||
const onBeforeEnter = (element) => { | ||
var _a; | ||
element.classList.add(enterFromClassName()); | ||
element.classList.add(enterActiveClassName()); | ||
(_a = listeners.onBeforeEnter) == null ? void 0 : _a.call(listeners, element); | ||
}; | ||
const onEnter = (element) => { | ||
var _a; | ||
element.classList.remove(enterFromClassName()); | ||
element.classList.add(enterToClassName()); | ||
(_a = listeners.onEnter) == null ? void 0 : _a.call(listeners, element); | ||
}; | ||
const onAfterEnter = (element) => { | ||
var _a; | ||
(_a = listeners.onAfterEnter) == null ? void 0 : _a.call(listeners, element); | ||
return () => { | ||
element.classList.remove(enterToClassName()); | ||
element.classList.remove(enterActiveClassName()); | ||
}; | ||
}; | ||
const onBeforeLeave = (element) => { | ||
var _a; | ||
if (!element) | ||
return; | ||
element.classList.add(leaveFromClassName()); | ||
element.classList.add(leaveActiveClassName()); | ||
(_a = listeners.onBeforeLeave) == null ? void 0 : _a.call(listeners, element); | ||
}; | ||
const onLeave = (element) => { | ||
var _a; | ||
if (!element) | ||
return; | ||
element.classList.remove(leaveFromClassName()); | ||
element.classList.add(leaveToClassName()); | ||
(_a = listeners.onLeave) == null ? void 0 : _a.call(listeners, element); | ||
}; | ||
const onAfterLeave = (element) => { | ||
var _a; | ||
if (!element) | ||
return () => { | ||
}; | ||
(_a = listeners.onAfterLeave) == null ? void 0 : _a.call(listeners, element); | ||
return () => { | ||
element.classList.remove(leaveToClassName()); | ||
element.classList.remove(leaveActiveClassName()); | ||
}; | ||
}; | ||
const runEnterTransition = async (element, onFinally = () => { | ||
}) => { | ||
onBeforeEnter(element); | ||
await yieldAsync(); | ||
const enterAfterListener = async () => { | ||
element.removeEventListener("animationend", enterAfterListener); | ||
element.removeEventListener("transitionend", enterAfterListener); | ||
element.removeEventListener("animationcancel", onFinally); | ||
element.removeEventListener("transitioncancel", onFinally); | ||
const cleanUp = onAfterEnter(element); | ||
cleanUp(); | ||
onFinally(); | ||
}; | ||
onEnter(element); | ||
element.addEventListener("animationend", enterAfterListener); | ||
element.addEventListener("transitionend", enterAfterListener); | ||
element.addEventListener("animationcancel", onFinally); | ||
element.addEventListener("transitioncancel", onFinally); | ||
}; | ||
const runLeaveTransition = async (element, onFinally = () => { | ||
}) => { | ||
onBeforeLeave(element); | ||
await yieldAsync(); | ||
const leaveAfterListener = async () => { | ||
element.removeEventListener("animationend", leaveAfterListener); | ||
element.removeEventListener("transitionend", leaveAfterListener); | ||
element.removeEventListener("animationcancel", onFinally); | ||
element.removeEventListener("transitioncancel", onFinally); | ||
const cleanUp = onAfterLeave(element); | ||
cleanUp(); | ||
onFinally(); | ||
}; | ||
onLeave(element); | ||
element.addEventListener("animationend", leaveAfterListener); | ||
element.addEventListener("transitionend", leaveAfterListener); | ||
element.removeEventListener("animationcancel", onFinally); | ||
element.removeEventListener("transitioncancel", onFinally); | ||
}; | ||
let isInit = false; | ||
createEffect(on(firstChild, async () => { | ||
if (!isInit && !leftProps.appear) { | ||
isInit = true; | ||
return; | ||
} | ||
const nowChild = firstChild(); | ||
const beforeChild = lastChild(); | ||
const onFinally = () => { | ||
startTransition(() => { | ||
setLastChild(duplicatedFirstChild()); | ||
setTransition(false); | ||
}); | ||
}; | ||
if (leftProps.mode === "in-out") { | ||
setTransition(true); | ||
if (nowChild instanceof HTMLElement) | ||
runEnterTransition(nowChild, onFinally); | ||
if (beforeChild instanceof HTMLElement) | ||
runLeaveTransition(beforeChild, onFinally); | ||
} else { | ||
setTransition(true); | ||
const onEnd = () => { | ||
setLastChild(duplicatedFirstChild()); | ||
const newChild = lastChild(); | ||
if (newChild instanceof HTMLElement) | ||
runEnterTransition(newChild, onFinally); | ||
}; | ||
if (beforeChild instanceof HTMLElement) | ||
runLeaveTransition(beforeChild, onEnd); | ||
else | ||
onEnd(); | ||
} | ||
})); | ||
return [createComponent(Show, { | ||
get when() { | ||
return memo(() => !!transition())() && lastChild(); | ||
}, | ||
get children() { | ||
return lastChild(); | ||
} | ||
}), createComponent(Show, { | ||
get when() { | ||
return leftProps.mode === "in-out" || !transition(); | ||
}, | ||
get children() { | ||
return firstChild(); | ||
} | ||
})]; | ||
}; | ||
export { | ||
Marquee | ||
Marquee, | ||
Transition | ||
}; |
@@ -1,1 +0,1 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("solid-js/web"),require("solid-js")):"function"==typeof define&&define.amd?define(["exports","solid-js/web","solid-js"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self)["solid-utility"]={},e.solid,e.solid)}(this,(function(e,n,t){"use strict";let r=e=>crypto.getRandomValues(new Uint8Array(e));const o=((e,n=21)=>((e,n,t)=>{let r=(2<<Math.log(e.length-1)/Math.LN2)-1,o=-~(1.6*r*n/e.length);return(i=n)=>{let a="";for(;;){let n=t(o),l=o;for(;l--;)if(a+=e[n[l]&r]||"",a.length===i)return a}}})(e,n,r))("1234567890abcdef",10),i=((e,n="solid-utilities")=>{const t=new CSSStyleSheet,r=`${n}-${o()}`;t.replaceSync(e(r));return()=>(document.adoptedStyleSheets.some((e=>e===t))||(document.adoptedStyleSheets=[t]),r)})((e=>`\n .${e} {\n position: relative;\n white-space: nowrap;\n\n display: flex;\n justify-content: flex-start;\n align-items: center;\n \n will-change: scroll-position;\n overflow: auto;\n }\n .${e}.left,\n .${e}.right {\n flex-direction: row;\n }\n \n .${e}.up,\n .${e}.down {\n flex-direction: column;\n }\n\n .${e} > .marquee {\n animation-duration: var(--duration, 10s);\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n }\n \n .${e}.left > .marquee {\n animation-name: marquee-left;\n }\n .${e}.right > .marquee {\n animation-name: marquee-right;\n }\n .${e}.up > .marquee {\n animation-name: marquee-up;\n }\n .${e}.down > .marquee {\n animation-name: marquee-down;\n }\n\n @keyframes marquee-left {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n }\n @keyframes marquee-right {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(0%);\n }\n }\n @keyframes marquee-up {\n 0% {\n transform: translateY(0%);\n }\n 100% {\n transform: translateY(-100%);\n }\n }\n @keyframes marquee-down {\n 0% {\n transform: translateY(-100%);\n }\n 100% {\n transform: translateY(0%);\n }\n }\n`));e.Marquee=e=>{const[r,o]=t.splitProps(t.mergeProps({component:"div",gap:0,speed:70,direction:"left",mode:"auto"},e),["mode","gap","speed","direction","component"]),a=t.children((()=>e.children)),l=t.children((()=>e.children));let s,c,u=!1;const[d,m]=t.createSignal(!1),[f,p]=t.createSignal(1e4),g=i(),h=()=>"left"===r.direction||"right"===r.direction,y=()=>{const e=h()?s.scrollWidth:s.scrollHeight,n=h()?s.clientWidth:s.clientHeight,t=d()?2:1,o=(e-(d()?r.gap:0))/t>n,i=!u;u=!1;const a=e/r.speed*1e3;p(Number.isFinite(a)?a:1e4),"auto"===r.mode&&o!==d()&&i&&(m(o),u=!0)},$=new MutationObserver(y);return t.onMount((()=>{const e=Date.now()+3e3,n=(null==s?void 0:s.parentElement)??s,t=()=>{Date.now()>e||requestAnimationFrame((()=>{0===s.clientWidth?t():(y(),u=!1)}))};t(),$.observe(n,{characterData:!0,childList:!0,subtree:!0,attributes:!0})})),t.createEffect(t.on([()=>r.speed,()=>r.direction],(()=>{y()}))),t.createEffect((()=>{"scroll"===r.mode&&m(!0)})),t.onCleanup((()=>{$.disconnect()})),n.createComponent(n.Dynamic,n.mergeProps(o,{ref(e){"function"==typeof s?s(e):s=e},get component(){return r.component},get style(){return(()=>{const e=(null==c?void 0:c.clientHeight)?`${c.clientHeight}px`:"auto";if("string"==typeof o.style){const n=h()?"":`height: ${e};`;return`${o.style}; overflow: hidden; --duration: ${f()}ms;${n}`}return{...o.style,overflow:"hidden",height:h()?"":`${e}`,"--duration":`${f()}ms`}})()},get class(){return((...e)=>e.filter((e=>!!e)).join(" "))(g,r.direction,o.class)},get children(){return[n.createComponent(n.Dynamic,{get component(){return r.component},ref(e){"function"==typeof c?c(e):c=e},get class(){return""+(d()?"marquee ignore":"")},get style(){return`padding-right: ${d()?r.gap:0}px`},get children(){return a()}}),n.createComponent(t.Show,{get when(){return d()},get children(){return n.createComponent(n.Dynamic,{get component(){return r.component},class:"marquee",get style(){return`padding-right: ${r.gap}px`},get children(){return l()}})}})]}}))},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})})); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("solid-js/web"),require("solid-js")):"function"==typeof define&&define.amd?define(["exports","solid-js/web","solid-js"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self)["solid-utility"]={},e.solid,e.solid)}(this,(function(e,n,t){"use strict";let r=e=>crypto.getRandomValues(new Uint8Array(e));const a=((e,n=21)=>((e,n,t)=>{let r=(2<<Math.log(e.length-1)/Math.LN2)-1,a=-~(1.6*r*n/e.length);return(o=n)=>{let i="";for(;;){let n=t(a),s=a;for(;s--;)if(i+=e[n[s]&r]||"",i.length===o)return i}}})(e,n,r))("1234567890abcdef",10),o=((e,n="solid-utilities")=>{const t=new CSSStyleSheet,r=`${n}-${a()}`;t.replaceSync(e(r));return()=>(document.adoptedStyleSheets.some((e=>e===t))||(document.adoptedStyleSheets=[t]),r)})((e=>`\n .${e} {\n position: relative;\n white-space: nowrap;\n\n display: flex;\n justify-content: flex-start;\n align-items: center;\n \n will-change: scroll-position;\n overflow: auto;\n }\n .${e}.left,\n .${e}.right {\n flex-direction: row;\n }\n \n .${e}.up,\n .${e}.down {\n flex-direction: column;\n }\n\n .${e} > .marquee {\n animation-duration: var(--duration, 10s);\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n }\n \n .${e}.left > .marquee {\n animation-name: marquee-left;\n }\n .${e}.right > .marquee {\n animation-name: marquee-right;\n }\n .${e}.up > .marquee {\n animation-name: marquee-up;\n }\n .${e}.down > .marquee {\n animation-name: marquee-down;\n }\n\n @keyframes marquee-left {\n 0% {\n transform: translateX(0%);\n }\n 100% {\n transform: translateX(-100%);\n }\n }\n @keyframes marquee-right {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(0%);\n }\n }\n @keyframes marquee-up {\n 0% {\n transform: translateY(0%);\n }\n 100% {\n transform: translateY(-100%);\n }\n }\n @keyframes marquee-down {\n 0% {\n transform: translateY(-100%);\n }\n 100% {\n transform: translateY(0%);\n }\n }\n`)),i=()=>new Promise((e=>requestAnimationFrame((()=>requestAnimationFrame((()=>e()))))));e.Marquee=e=>{const[r,a]=t.splitProps(t.mergeProps({component:"div",gap:0,speed:70,direction:"left",mode:"auto"},e),["mode","gap","speed","direction","component"]),i=t.children((()=>e.children)),s=t.children((()=>e.children));let l,c,m=!1;const[d,u]=t.createSignal(!1),[f,v]=t.createSignal(1e4),p=o(),g=()=>"left"===r.direction||"right"===r.direction,h=()=>{const e=g()?l.scrollWidth:l.scrollHeight,n=g()?l.clientWidth:l.clientHeight,t=d()?2:1,a=(e-(d()?r.gap:0))/t>n,o=!m;m=!1;const i=e/r.speed*1e3;v(Number.isFinite(i)?i:1e4),"auto"===r.mode&&a!==d()&&o&&(u(a),m=!0)},L=new MutationObserver(h);return t.onMount((()=>{const e=Date.now()+3e3,n=(null==l?void 0:l.parentElement)??l,t=()=>{Date.now()>e||requestAnimationFrame((()=>{0===l.clientWidth?t():(h(),m=!1)}))};t(),L.observe(n,{characterData:!0,childList:!0,subtree:!0,attributes:!0})})),t.createEffect(t.on([()=>r.speed,()=>r.direction],(()=>{h()}))),t.createEffect((()=>{"scroll"===r.mode&&u(!0)})),t.onCleanup((()=>{L.disconnect()})),n.createComponent(n.Dynamic,n.mergeProps(a,{ref(e){"function"==typeof l?l(e):l=e},get component(){return r.component},get style(){return(()=>{const e=(null==c?void 0:c.clientHeight)?`${c.clientHeight}px`:"auto";if("string"==typeof a.style){const n=g()?"":`height: ${e};`;return`${a.style}; overflow: hidden; --duration: ${f()}ms;${n}`}return{...a.style,overflow:"hidden",height:g()?"":`${e}`,"--duration":`${f()}ms`}})()},get class(){return((...e)=>e.filter((e=>!!e)).join(" "))(p,r.direction,a.class)},get children(){return[n.createComponent(n.Dynamic,{get component(){return r.component},ref(e){"function"==typeof c?c(e):c=e},get class(){return""+(d()?"marquee ignore":"")},get style(){return`padding-right: ${d()?r.gap:0}px`},get children(){return i()}}),n.createComponent(t.Show,{get when(){return d()},get children(){return n.createComponent(n.Dynamic,{get component(){return r.component},class:"marquee",get style(){return`padding-right: ${r.gap}px`},get children(){return s()}})}})]}}))},e.Transition=e=>{const[r,a,o]=t.splitProps(t.mergeProps({appear:!1,mode:"in-out"},e),["onBeforeEnter","onEnter","onAfterEnter","onBeforeLeave","onLeave","onAfterLeave"],["enterFromClass","enterActiveClass","enterToClass","leaveFromClass","leaveActiveClass","leaveToClass"]),s=t.children((()=>o.children)),l=t.children((()=>o.children)),c=()=>s.toArray().at(0),m=()=>l.toArray().at(0),[d,u]=t.createSignal(!1),[f,v]=t.createSignal(m()),p=()=>a.enterFromClass??`${o.name}-enter-from`,g=()=>a.enterActiveClass??`${o.name}-enter-active`,h=()=>a.enterToClass??`${o.name}-enter-to`,L=()=>a.leaveFromClass??`${o.name}-leave-from`,y=()=>a.leaveActiveClass??`${o.name}-leave-active`,E=()=>a.leaveToClass??`${o.name}-leave-to`,w=async(e,n=(()=>{}))=>{(e=>{var n;e.classList.add(p()),e.classList.add(g()),null==(n=r.onBeforeEnter)||n.call(r,e)})(e),await i();const t=async()=>{e.removeEventListener("animationend",t),e.removeEventListener("transitionend",t),e.removeEventListener("animationcancel",n),e.removeEventListener("transitioncancel",n);const a=(e=>{var n;return null==(n=r.onAfterEnter)||n.call(r,e),()=>{e.classList.remove(h()),e.classList.remove(g())}})(e);a(),n()};(e=>{var n;e.classList.remove(p()),e.classList.add(h()),null==(n=r.onEnter)||n.call(r,e)})(e),e.addEventListener("animationend",t),e.addEventListener("transitionend",t),e.addEventListener("animationcancel",n),e.addEventListener("transitioncancel",n)},$=async(e,n=(()=>{}))=>{(e=>{var n;e&&(e.classList.add(L()),e.classList.add(y()),null==(n=r.onBeforeLeave)||n.call(r,e))})(e),await i();const t=async()=>{e.removeEventListener("animationend",t),e.removeEventListener("transitionend",t),e.removeEventListener("animationcancel",n),e.removeEventListener("transitioncancel",n);const a=(e=>{var n;return e?(null==(n=r.onAfterLeave)||n.call(r,e),()=>{e.classList.remove(E()),e.classList.remove(y())}):()=>{}})(e);a(),n()};(e=>{var n;e&&(e.classList.remove(L()),e.classList.add(E()),null==(n=r.onLeave)||n.call(r,e))})(e),e.addEventListener("animationend",t),e.addEventListener("transitionend",t),e.removeEventListener("animationcancel",n),e.removeEventListener("transitioncancel",n)};let q=!1;return t.createEffect(t.on(c,(async()=>{if(!q&&!o.appear)return void(q=!0);const e=c(),n=f(),r=()=>{t.startTransition((()=>{v(m()),u(!1)}))};if("in-out"===o.mode)u(!0),e instanceof HTMLElement&&w(e,r),n instanceof HTMLElement&&$(n,r);else{u(!0);const e=()=>{v(m());const e=f();e instanceof HTMLElement&&w(e,r)};n instanceof HTMLElement?$(n,e):e()}}))),[n.createComponent(t.Show,{get when(){return n.memo((()=>!!d()))()&&f()},get children(){return f()}}),n.createComponent(t.Show,{get when(){return"in-out"===o.mode||!d()},get children(){return c()}})]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})})); |
{ | ||
"name": "@suyongs/solid-utility", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Utilities for SolidJS", | ||
@@ -24,3 +24,4 @@ "main": "dist/index.umd.js", | ||
"example:marquee": "cd examples/marquee && npm run dev", | ||
"release": "release-it" | ||
"example:transition": "cd examples/transition && npm run dev", | ||
"release": "dotenv release-it" | ||
}, | ||
@@ -32,2 +33,3 @@ "keywords": [], | ||
"@types/node": "^20.4.2", | ||
"dotenv-cli": "^7.2.1", | ||
"release-it": "^16.1.2", | ||
@@ -34,0 +36,0 @@ "rimraf": "^5.0.1", |
34379
9
463
9