alwan
Version:
A simple, lightweight, customizable, touch friendly color picker, written in vanilla javascript with zero dependencies.
3 lines (2 loc) • 10.6 kB
JavaScript
const t={id:"",classname:"",theme:"light",parent:"",toggle:!0,popover:!0,position:"bottom-start",margin:4,preset:!0,color:"#000",default:"#000",target:"",disabled:!1,format:"rgb",singleInput:!1,inputs:!0,opacity:!0,preview:!0,copy:!0,swatches:[],toggleSwatches:!1,closeOnScroll:!1,i18n:{picker:"Color picker",buttons:{copy:"Copy color to clipboard",changeFormat:"Change color format",swatch:"Color swatch: %label%",toggleSwatches:"Toggle Swatches"},sliders:{hue:"Change hue",alpha:"Change opacity"}}},e=document,s=e.documentElement,r="#000000",o="button",a="open",n="close",l="color",i="click",h="pointerdown",c="pointermove",p="pointerup",g="scroll",u="keydown",d="input",_="change",w="rgb",b="hsl",v={capture:!0},f=["hex",w,b],y=t=>"string"==typeof t,m=t=>t instanceof Element,$=t=>Number.isFinite(y(t)&&""!==t.trim()?+t:t),{keys:x,assign:A,setPrototypeOf:S,prototype:k}=Object,{isArray:C}=Array,H=t=>null!=t&&"object"==typeof t&&!C(t)&&!m(t),O=(t,e)=>x(t).forEach((s=>e(s,t[s]))),V=(t,e)=>(O(e,((e,s)=>{A(t,{[e]:H(s)?V(t[e]||{},s):s})})),t),L=()=>e.body,M=(t,e=s)=>y(t)&&t.trim()?[...e.querySelectorAll(t)]:m(t)?[t]:[],z=t=>M(`${d},${o},[tabindex]`,t),B=(t,s,r,o={},a)=>{const n=e.createElement(t);return s&&(n.className=s.trim()),r&&(y(r)?n.innerHTML=r:n.append(...(C(r)?r:[r]).filter((t=>!!t)))),O(y(a)?{...o,"aria-label":a}:o,((t,e)=>n.setAttribute(t,e+""))),n},E=(t,e,s)=>B("div",e,t,{},s),I=(t,e)=>(t&&t!==e&&t.replaceWith(e),e),j=(t="",e="",s,r=t)=>B(o,"alwan__button "+e,s,{type:o,title:r},t),D=(t,e,s,r=1)=>B(d,"alwan__slider alwan__"+e,"",{type:"range",max:s,step:r},t),F=(t,e)=>t.style.setProperty("--color",e),N=(t,e,s)=>t.classList.toggle("alwan--"+e,s),P=(t,e,s)=>{t.style.transform=`translate(${e}px,${s}px)`},R=t=>{const{x:e,y:s,width:r,height:o}=t.getBoundingClientRect();return[e,s,r,o,r+e,o+s]},T=t=>E(t,"alwan__container"),Z=(t,e)=>t.style.display=e?"none":"",K=(t,e,s,r)=>t.addEventListener(e,s,r),U=(t,e,s)=>t.removeEventListener(e,s),q=(t,e=w)=>e?e+(e===w?`(${t.r}, ${t.g}, ${t.b}`:`(${t.h}, ${t.s}%, ${t.l}%`)+(t.a<1?`, ${t.a})`:")"):r,{min:G,max:J,abs:Q,round:W,PI:X}=Math,Y=(t,e=100,s=0)=>t>e?e:t<s?s:t,tt=t=>W((t%=360)<0?t+360:t),et=t=>parseInt(t,16),st=t=>{let e,s,{config:r,s:o}=t,a=!1;const n=()=>{const t={};a||(o.t(),a=!0),O(e,((e,s)=>t[e]=s.value)),o.o(t[s]||q(t,s),!0)},l=()=>{e={};const t="hex"===s||r.singleInput?[s]:[...s+(r.opacity?"a":"")];return E(t.map((t=>B("label","",[e[t]=B(d,"alwan__input",[],{type:"text",value:o.i[t]}),B("span","",t)]))),"alwan__inputs")};return{p({inputs:e,format:r,i18n:h}){let c,p,g,w,b=f;return!0!==e&&(e=e||{},b=b.filter((t=>e[t]))),w=b.length,b=w?b:f,s=b[J(b.indexOf(r),0)],o.u(s),w?(w>1&&(g=j(h.buttons.changeFormat,"",'<svg width="15" height="15" viewBox="0 0 20 20" aria-role="none"><path d="M10 1L5 8h10l-5-7zm0 18l5-7H5l5 7z"></path></svg>'),K(g,i,(()=>{s=b[(b.indexOf(s)+1)%w],o.u(s),c=I(c,l())}))),c=l(),p=E(c),K(p,d,n),K(p,_,(()=>{o._(),a=!1})),K(p,"focusin",(t=>t.target.select())),K(p,u,(e=>"Enter"===e.key&&t.c.v(!1))),T([p,g])):null},m(t){a||O(e||{},((e,s)=>s.value=t[e]+""))}}},rt={ArrowLeft:-1,ArrowRight:1},ot={ArrowUp:-1,ArrowDown:1},at=({s:t})=>{let s,r,o,a,n;const l={s:0,l:0},i=(e,s)=>{let i,h,[,,c,p]=n;o=e=Y(e,c),a=s=Y(s,p),P(r,e,s),i=1-s/p,h=i*(1-e/(2*c)),l.s=1===h||0===h?0:(i-h)/G(h,1-h)*100,l.l=100*h,t.$(l)},g=({x:t,y:e,buttons:s})=>{s?i(t-n[0],e-n[1]):d()},d=()=>{t._(),U(e,c,g),U(e,p,d)},_=r=>{s.setPointerCapture(r.pointerId),t.t(),n=R(s),i(r.x-n[0],r.y-n[1]),K(e,c,g),K(e,p,d)},w=e=>{const r=e.key,l=rt[r]||0,h=ot[r]||0;(l||h)&&(e.preventDefault(),n=R(s),t.t(),i(o+l*n[2]/100,a+h*n[3]/100),t._())};return{p:({i18n:t,disabled:e})=>(r=E("","alwan__cursor"),s=E(r,"alwan__selector",t.picker||t.palette),e||(s.tabIndex=0,K(s,h,_),K(s,u,w)),s),A(t,e){t=(e/=100)+t/100*G(e,1-e),n=R(s),o=(t?2*(1-e/t):0)*n[2],a=(1-t)*n[3],P(r,o,a)}}},nt=({s:t,e:e})=>{let s,r,o;return{p:({opacity:a,i18n:{sliders:n}})=>(s=D(n.hue,"hue",360),r=a?D(n.alpha,"alpha",1,.01):null,o=E([s,r]),K(o,_,(()=>e.S(_))),K(o,d,(({target:e})=>t.$({[e===s?"h":"a"]:e.value}))),o),m(t,e){s.value=t+"",r&&(r.value=e+"")}}},lt=t=>(t<16?"0":"")+t.toString(16),it=(t,e,s)=>(t%=12,W(255*(s-e*G(s,1-s)*J(-1,G(t-3,9-t,1))))),ht=B("canvas").getContext("2d"),ct={turn:360,rad:180/X,grad:.9},pt=/a?\(\s*([+-]?\d*\.?\d+)(\w*)?\s*[\s,]\s*([+-]?\d*\.?\d+)%?\s*,?\s*([+-]?\d*\.?\d+)%?(?:\s*[\/,]\s*([+-]?\d*\.?\d+)(%)?)?\s*\)?$/,gt=t=>y(t)?t:q(t,(t=>H(t)&&[b,w].find((e=>[...e].every((e=>$(t[e])))))||"")(t)),ut=t=>(ht.fillStyle=r,ht.fillStyle=t,ht.fillStyle),dt=(t,e)=>{let s,r,o=gt(t).trim();if(/^hsl/.test(o)){const[t,e,s,a,n,l="1",i]=pt.exec(o)||[];t&&(r={h:tt(+e*(ct[s]||1)),s:Y(+a),l:Y(+n),a:Y(+l/(i?100:1),1)})}if(!r){if(/^[\da-f]+$/i.test(o)&&(o="#"+o),o=ut(o),"#"===o[0])s={r:et(o[1]+o[2]),g:et(o[3]+o[4]),b:et(o[5]+o[6]),a:1};else{const[t,e,r,a]=o.match(/[\d\.]+/g).map(Number);s={r:t,g:e,b:r,a:a}}r=(({r:t,g:e,b:s,a:r})=>{const o=J(t/=255,e/=255,s/=255),a=G(t,e,s),n=o-a,l=(o+a)/2;return{h:tt(60*(0===n?0:o===t?(e-s)/n%6:o===e?(s-t)/n+2:o===s?(t-e)/n+4:0)),s:n?n/(1-Q(2*l-1))*100:0,l:100*l,a:r}})(s)}return r.a=e?W(100*r.a)/100:1,s&&(s.a=r.a),[r,s]},_t=t=>{let e=!1;const s=(e,s)=>{let o,a,n,l;var h;return H(h=e)&&"color"in h?({color:a,label:l}=e):a=e,n=gt(a),n=ut(n)===r?r:n,l=y(l)?l:n,o=j(s.replace("%label%",l),"alwan__swatch","",l),F(o,n),K(o,i,(()=>t.s.o(n,!0,!0))),o};return{p({swatches:r,toggleSwatches:o,i18n:{buttons:a}}){let n,l,h;return C(r)&&r.length?(n=E(r.map((t=>s(t,a.swatch))),"alwan__swatches"),o?(h=(s=!e)=>{e=s,N(n,"collapse",e),t.c.k()},l=j(a.toggleSwatches,"alwan__toggle-button",'<svg width="20" height="20" viewBox="0 0 24 24" aria-role="none"><path d="M6.984 14.016l5.016-5.016 5.016 5.016h-10.031z"></path></svg>'),K(l,i,(()=>h())),h(e),E([n,l])):n):n}}},wt=t=>({p({preview:e,copy:s,i18n:r}){let o,a,n,l,h;return s&&(o=j(r.buttons.copy,"alwan__cp",'<svg width="18" height="18" viewBox="0 0 24 24" aria-role="none"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg width="18" height="18" viewBox="0 0 24 24" aria-role="none"><path d="M9,20.42L2.79,14.21L5.62,11.38L9,14.77L18.88,4.88L21.71,7.71L9,20.42Z"></path></svg>'),[n,l]=o.children,a=t=>{Z(n,t),Z(l,!t)},a(!1),h=navigator.clipboard,h&&(K(o,i,(()=>h.writeText(t.s.C()).then((()=>a(!0))))),K(o,"blur",(()=>a())),K(o,"mouseleave",(()=>o.blur())))),e?E(o,"alwan__preview"):o}}),bt=(t,e)=>t.map((t=>C(t)?T(bt(t,e)):t.p(e))),vt={top:[1,5,4,0],bottom:[5,1,4,0],right:[4,0,1,5],left:[0,4,1,5]},ft={start:[0,1,2],center:[1,0,2],end:[2,1,0]},yt=(t,r)=>{let o,l,c=E(),p=!1,d=null;const{config:_,s:w}=t,b=((t,e)=>{const s=j(),r=s.className+" alwan__ref ";let o;return t&&t.id&&(s.id=t.id),{H:a=>(o=I(o||t,a.preset||!t?s:t),o===s&&(o.className=(r+a.classname).trim(),o.parentNode||L().append(o)),K(o,i,e),o),O(){t?(U(t,i,e),I(o,t)):o.remove()}}})(r,(()=>t.toggle())),f=E(c,"alwan"),[m,x,A,S,k]=(t=>[at,wt,nt,st,_t].map((e=>e(t))))(t);return w.V((t=>{F(o,t.rgb),c.style.cssText=`--rgb:${t.r},${t.g},${t.b};--a:${t.a};--h:${t.h}`,S.m(t)}),(({a:t,h:e,s:s,l:r})=>{A.m(e,t),m.A(s,r)})),{L(t){const r=this,{id:a,color:n=w.i.hsl}=t,{theme:i,parent:C,toggle:H,popover:O,target:B,disabled:j}=V(_,t);o=b.H(_);let D=M(C)[0],F=M(B)[0]||o;a&&(f.id=a),N(f,"dark","dark"===i),c=I(c,E(bt([m,[x,A],S,k],_))),Z(o,!O&&!H),d&&(d.M(),d=null),O?(D=D||H&&L(),l=E(f,"alwan__popover-container"),d=((t,r,o,a,{margin:n,position:l,closeOnScroll:i,toggle:c,disabled:p},{v:d,B:_})=>{let w;n=$(n)?+n:0;let b=_();const[f,m]=y(l)?l.split("-"):[],x=r.style,A=t.getRootNode(),S=z(r),k=S[0],C=S.pop(),H=()=>{const e=[s.clientWidth,s.clientHeight],a=R(t),l=R(r),i=R(o),h=[-1,-1];x.height="",!b||!w||a[4]<0||a[5]<0||a[0]>e[0]||a[1]>e[1]||((vt[f]||vt.bottom).some((t=>{let s=t%2,r=a[t]+(t<=1?-l[s+2]-n:n);return!(r<0||r+l[s+2]+n>e[s])&&(h[s]=r,s=+!s,(ft[m]||ft.center).some((t=>(r=0===t?a[s]:a[s+4]-(2===t?l[s+2]:(l[s+2]+a[s+2])/2),!(r<0||r+l[s+2]>e[s]||(h[s]=r,0))))))})),P(r,...h.map(((t,s)=>(s&&-1===t&&l[3]>e[s]&&(x.height=e[s]-6+"px",l[3]=e[s]-3),W((t>=0?t:(e[s]-l[s+2])/2)-i[s]))))))};c&&K(r,u,(t=>{let e,{key:s,target:r,shiftKey:o}=t;"Escape"===s?d(!1):"Tab"===s&&(r===k&&o?e=C:r!==C||o||(e=k),e&&(e.focus(),t.preventDefault()))}));const O=[r,a,...a.labels||[]],V=t=>{const e=t.composedPath();b&&!O.some((t=>e.includes(t)))&&d(!1)},L=new IntersectionObserver((([t])=>{w=t.isIntersecting,d(!p&&w&&(!c||b),!0)})),M=({target:e})=>{(A instanceof ShadowRoot&&e.contains(A.host)||e.contains(t))&&(H(),i&&d(!1))},B=t=>{t(window,"resize",H),t(e,g,M,v),t(A,g,M,v),t(e,h,V)};return L.observe(t),B(K),{I:()=>w,k(t,e){b=t,w&&(H(),c&&e!==t&&(t?k:a).focus())},M(){x.cssText="",L.unobserve(t),B(U),o.remove()}}})(F,f,l,o,_,r)):(l=f,r.v(!H||!j&&p,!0)),D?D.append(l):F.after(l),j&&[o,...z(f)].forEach((t=>{t.disabled=!0})),w.o(n)},v(e=!p,s=!1){(e!==p&&(!d||d.I())&&!_.disabled&&_.toggle||s)&&(N(f,a,e),d&&d.k(e,p),p=e,t.e.S(p?a:n))},B:()=>p,k(){d&&d.k(p,p)},M(){f.remove(),d&&d.M(),b.O()}}},mt=t=>{const e={h:0,s:0,l:0,r:0,g:0,b:0,a:1,rgb:"",hsl:"",hex:""},s=t.config,r=t.e.S;let o,a,n,i;return{i:e,C:()=>e[n],V(t,e){o=t,a=e},u(t){n=s.format=t},$(t,s,a=!0,n){const i=e.hex;A(e,t),A(e,s||(({h:t,s:e,l:s,a:r})=>({r:it(t/=30,e/=100,s/=100),g:it(t+8,e,s),b:it(t+4,e,s),a:r}))(e)),e.s=W(e.s),e.l=W(e.l),e.rgb=q(e),e.hsl=q(e,b),e.hex=(({r:t,g:e,b:s,a:r})=>"#"+lt(t)+lt(e)+lt(s)+(r<1?lt(W(255*r)):""))(e),o(e),i!==e.hex&&(a&&r(l,e),n&&r(_,e))},o(t,r=!1,o){this.$(...dt(t,s.opacity),r,o),a(e)},t(){i=e[n]},_(){i!==e[n]&&r(_,e)}}};class $t{static version(){return"2.3.1"}static setDefaults(e){V(t,e)}constructor(e,s){this.config=V({},t),this.e=(t=>{const e={[a]:[],[n]:[],[_]:[],[l]:[]};return{S(s,r=t.s.i){(e[s]||[]).forEach((e=>e(A({type:s,source:t},r))))},j(t,s){s&&!(e[t]||[]).includes(s)&&e[t].push(s)},D(t,s){t?e[t]&&(e[t]=s?e[t].filter((t=>t!==s)):[]):O(e,(t=>{e[t]=[]}))}}})(this),this.s=mt(this),this.c=yt(this,M(e)[0]),this.c.L(s||{})}setOptions(t){t&&this.c.L(t)}setColor(t){return this.s.o(t),this}getColor(){return{...this.s.i}}isOpen(){return this.c.B()}open(){this.c.v(!0)}close(){this.c.v(!1)}toggle(){this.c.v()}on(t,e){this.e.j(t,e)}off(t,e){this.e.D(t,e)}addSwatches(...t){this.c.L({swatches:this.config.swatches.concat(t)})}removeSwatches(...t){this.c.L({swatches:this.config.swatches.filter(((e,s)=>!t.some((t=>$(t)?+t===s:t===e))))})}enable(){this.c.L({disabled:!1})}disable(){this.c.L({disabled:!0})}reset(){this.s.o(this.config.default)}reposition(){this.c.k()}trigger(t){this.e.S(t)}destroy(){this.c.M(),O(this,(t=>{this[t]=null})),S(this,k)}}export{$t as default};
//# sourceMappingURL=alwan.min.js.map