alwan
Version:
A simple, lightweight, customizable, touch friendly color picker, written in vanilla javascript with zero dependencies.
3 lines (2 loc) • 11.2 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Alwan=e()}(this,(function(){"use strict";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",toggleSwatches:"Toggle Swatches"},sliders:{hue:"Change hue",alpha:"Change opacity"}}},e=document,s=e.documentElement,n="button",r="open",o="close",a="color",i="click",l="pointerdown",h="pointermove",c="pointerup",p="scroll",u="keydown",g="input",d="change",_="rgb",w="hsl",b={capture:!0},f=["hex",_,w],y=t=>"string"==typeof t,m=t=>t instanceof Element,v=t=>Number.isFinite(y(t)&&""!==t.trim()?+t:t),$=t=>[w,_].find((e=>[...e].every((e=>v(t[e]))))),{keys:x,assign:k,setPrototypeOf:A,prototype:C}=Object,{isArray:S}=Array,H=t=>null!=t&&"object"==typeof t&&!S(t)&&!m(t),O=(t,e)=>x(t).forEach((s=>e(s,t[s]))),V=(t,e)=>(O(e,((e,s)=>{k(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]:[],T=t=>M(`${g},${n},[tabindex]`,t),z=(t,s,n,r={},o)=>{const a=e.createElement(t);return s&&(a.className=s.trim()),n&&(y(n)?a.innerHTML=n:a.append(...(S(n)?n:[n]).filter((t=>!!t)))),O(o?{...r,"aria-label":o}:r,((t,e)=>{(v(e)||e)&&a.setAttribute(t,e+"")})),a},B=(t,e,s)=>z("div",e,t,{},s),E=(t,e)=>(t&&t!==e&&t.replaceWith(e),e),I=(t="",e="",s,r=t)=>z(n,"alwan__button "+e,s,{type:n,title:r},t),j=(t,e,s,n=1)=>z(g,"alwan__slider alwan__"+e,"",{type:"range",max:s,step:n},t),F=(t,e)=>t.style.setProperty("--color",e),D=(t,e,s)=>t.classList.toggle("alwan--"+e,s),N=(t,e,s)=>{t.style.transform=`translate(${e}px,${s}px)`},P=(t,e)=>{let{x:s,y:n,width:r,height:o}=t.getBoundingClientRect();return e&&(s+=t.clientLeft-t.scrollLeft,n+=t.clientTop-t.scrollTop),[s,n,r,o,r+s,o+n]},R=t=>B(t,"alwan__container"),Z=(t,e)=>t.style.display=e?"none":"",K=[":popover-open",":modal"],U=(t,s)=>!(t=t&&t.parentNode)||t===e||(t=>m(t)&&K.some((e=>{try{return t.matches(e)}catch(t){return!1}})))(t)?[0,0]:(t===s&&(t=s.host),m(t)&&(({transform:t,perspective:e,filter:s,containerType:n,backdropFilter:r,willChange:o,contain:a})=>"none"!==t||"none"!==e||"normal"!==n||"none"!==r||"none"!==s||o&&/\b(transform|perspective|filter)\b/.test(o)||a&&/\b(paint|layout|strict|content)\b/.test(a))(getComputedStyle(t))?P(t,!0):U(t,s)),q=(t,e,s,n)=>t.addEventListener(e,s,n),G=(t,e,s)=>t.removeEventListener(e,s),J=(t,e=_)=>e+(e===_?`(${t.r}, ${t.g}, ${t.b}`:`(${t.h}, ${t.s}%, ${t.l}%`)+(t.a<1?`, ${t.a})`:")"),{min:Q,max:W,abs:X,round:Y,PI:tt}=Math,et=(t,e=100,s=0)=>t>e?e:t<s?s:t,st=t=>Y((t%=360)<0?t+360:t),nt=t=>parseInt(t,16),rt=t=>{let e,s,{config:n,s:r}=t,o=!1;const a=()=>{const t={};o||(r.t(),o=!0),O(e,((e,s)=>t[e]=s.value)),r.o(t[s]||J(t,s),!0)},l=()=>{e={};const t="hex"===s||n.singleInput?[s]:[...s+(n.opacity?"a":"")];return B(t.map((t=>z("label","",[e[t]=z(g,"alwan__input",[],{type:"text",value:r.i[t]}),z("span","",t)]))),"alwan__inputs")};return{p({inputs:e,format:n,i18n:h}){let c,p,_,w,b=f;return!0!==e&&(e=e||{},b=b.filter((t=>e[t]))),w=b.length,b=w?b:f,s=b[W(b.indexOf(n),0)],r.u(s),w?(w>1&&(_=I(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>'),q(_,i,(()=>{s=b[(b.indexOf(s)+1)%w],r.u(s),c=E(c,l())}))),c=l(),p=B(c),q(p,g,a),q(p,d,(()=>{r._(),o=!1})),q(p,"focusin",(t=>t.target.select())),q(p,u,(e=>"Enter"===e.key&&t.c.m(!1))),R([p,_])):null},v(t){o||O(e||{},((e,s)=>s.value=t[e]+""))}}},ot={ArrowLeft:-1,ArrowRight:1},at={ArrowUp:-1,ArrowDown:1},it=({s:t})=>{let s,n,r,o,a;const i={s:0,l:0},p=(e,s)=>{let l,h,[,,c,p]=a;r=e=et(e,c),o=s=et(s,p),N(n,e,s),l=1-s/p,h=l*(1-e/(2*c)),i.s=1===h||0===h?0:(l-h)/Q(h,1-h)*100,i.l=100*h,t.$(i)},g=({x:t,y:e,buttons:s})=>{s?p(t-a[0],e-a[1]):d()},d=()=>{t._(),G(e,h,g),G(e,c,d)},_=n=>{s.setPointerCapture(n.pointerId),t.t(),a=P(s),p(n.x-a[0],n.y-a[1]),q(e,h,g),q(e,c,d)},w=e=>{const n=e.key,i=ot[n]||0,l=at[n]||0;(i||l)&&(e.preventDefault(),a=P(s),t.t(),p(r+i*a[2]/100,o+l*a[3]/100),t._())};return{p:({i18n:t,disabled:e})=>(n=B("","alwan__cursor"),s=B(n,"alwan__selector",t.picker||t.palette),e||(s.tabIndex=0,q(s,l,_),q(s,u,w)),s),k(t,e){t=(e/=100)+t/100*Q(e,1-e),a=P(s),r=(t?2*(1-e/t):0)*a[2],o=(1-t)*a[3],N(n,r,o)}}},lt=({s:t,e:e})=>{let s,n,r;return{p:({opacity:o,i18n:{sliders:a}})=>(s=j(a.hue,"hue",360),n=o?j(a.alpha,"alpha",1,.01):null,r=B([s,n]),q(r,d,(()=>e.A(d))),q(r,g,(({target:e})=>t.$({[e===s?"h":"a"]:e.value}))),r),v(t,e){s.value=t+"",n&&(n.value=e+"")}}},ht=t=>{let e=!1;return{p({swatches:s,toggleSwatches:n,i18n:{buttons:r}}){let o,a,l;return S(s)&&s.length?(o=B(s.map((e=>{const s=y(e)?e:J(e,$(e)),n=I(r.swatch,"alwan__swatch","",s);return F(n,s),q(n,i,(()=>t.s.o(s,!0,!0))),n})),"alwan__swatches"),n?(l=(s=!e)=>{e=s,D(o,"collapse",e),t.c.C()},a=I(r.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>'),q(a,i,(()=>l())),l(e),B([o,a])):o):o}}},ct=t=>({p({preview:e,copy:s,i18n:n}){let r,o,a,l,h;return s&&(r=I(n.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>'),[a,l]=r.children,o=t=>{Z(a,t),Z(l,!t)},o(!1),h=navigator.clipboard,h&&(q(r,i,(()=>h.writeText(t.s.S()).then((()=>o(!0))))),q(r,"blur",(()=>o())),q(r,"mouseleave",(()=>r.blur())))),e?B(r,"alwan__preview"):r}}),pt=(t,e)=>t.map((t=>S(t)?R(pt(t,e)):t.p(e))),ut={top:[1,5,4,0],bottom:[5,1,4,0],right:[4,0,1,5],left:[0,4,1,5]},gt={start:[0,1,2],center:[1,0,2],end:[2,1,0]},dt=(t,n)=>{let a,h=B(),c=!1,g=null;const{config:d,s:_}=t,w=((t,e)=>{const s=I(),n=s.className+" alwan__ref ";let r;return t&&t.id&&(s.id=t.id),{H:o=>(r=E(r||t,o.preset||!t?s:t),r===s&&(r.className=(n+o.classname).trim(),r.parentNode||L().append(r)),q(r,i,e),r),O(){t?(G(t,i,e),E(r,t)):r.remove()}}})(n,(()=>t.toggle())),f=B(h,"alwan"),[m,$,x,k,A]=(t=>[it,ct,lt,rt,ht].map((e=>e(t))))(t);return _.V((t=>{F(a,t.rgb),h.style.cssText=`--rgb:${t.r},${t.g},${t.b};--a:${t.a};--h:${t.h}`,k.v(t)}),(({a:t,h:e,s:s,l:n})=>{x.v(e,t),m.k(s,n)})),{L(t){const n=this,{id:r,color:o=_.i.hsl}=t,{theme:i,parent:C,toggle:S,popover:H,target:O,disabled:z}=V(d,t);a=w.H(d);let I=M(C)[0],j=M(O)[0]||a;r&&(f.id=r),D(f,"dark","dark"===i),D(f,"block",!H),h=E(h,B(pt([m,[$,x],k,A],d))),Z(a,!H&&!S),g&&(g.M(),g=null),H?(I=I||S&&L(),g=((t,n,r,{margin:o,position:a,closeOnScroll:i,toggle:h,disabled:c},{m:g,T:d})=>{let _;o=v(o)?+o:0;let w=d(),f=t.getRootNode();const[m,$]=y(a)?a.split("-"):[],x=n.style,k=f instanceof ShadowRoot?f:null,A=T(n),C=A[0],S=A.pop(),H=()=>{const e=[s.clientWidth,s.clientHeight],r=P(t),a=P(n),i=U(n,k),l=[-1,-1];x.height="",!w||!_||r[4]<0||r[5]<0||r[0]>e[0]||r[1]>e[1]||((ut[m]||ut.bottom).some((t=>{let s=t%2,n=r[t]+(t<=1?-a[s+2]-o:o);return!(n<0||n+a[s+2]+o>e[s])&&(l[s]=n,s=+!s,(gt[$]||gt.center).some((t=>(n=0===t?r[s]:r[s+4]-(2===t?a[s+2]:(a[s+2]+r[s+2])/2),!(n<0||n+a[s+2]>e[s]||(l[s]=n,0))))))})),N(n,...l.map(((t,s)=>(s&&-1===t&&a[3]>e[s]&&(x.height=e[s]-6+"px",a[3]=e[s]-3),Y((t>=0?t:(e[s]-a[s+2])/2)-i[s]))))))};h&&q(n,u,(t=>{let e,{key:s,target:n,shiftKey:r}=t;"Escape"===s?g(!1):"Tab"===s&&(n===C&&r?e=S:n!==S||r||(e=C),e&&(e.focus(),t.preventDefault()))}));const O=[n,r,...r.labels||[]],V=t=>{const e=t.composedPath();w&&!O.some((t=>e.includes(t)))&&g(!1)},L=new IntersectionObserver((([t])=>{_=t.isIntersecting,g(!c&&_&&(!h||w),!0)})),M=({target:e})=>{(k&&e.contains(k.host)||e.contains(t))&&(H(),i&&g(!1))},z=t=>{t(window,"resize",H),t(e,p,M,b),t(e,l,V),k&&t(k,p,M,b)};return L.observe(t),z(q),{B:()=>_,C(t,e){w=t,_&&(H(),h&&e!==t&&(t?C:r).focus())},M(){x.cssText="",L.unobserve(t),z(G)}}})(j,f,a,d,n)):n.m(!S||!z&&c,!0),I?I.append(f):j.after(f),z&&[a,...T(f)].forEach((t=>{t.disabled=!0})),_.o(o)},m(e=!c,s=!1){(e!==c&&(!g||g.B())&&!d.disabled&&d.toggle||s)&&(D(f,r,e),g&&g.C(e,c),c=e,t.e.A(c?r:o))},T:()=>c,C(){g&&g.C(c,c)},M(){f.remove(),g&&g.M(),w.O()}}},_t=t=>(t<16?"0":"")+t.toString(16),wt=(t,e,s)=>(t%=12,Y(255*(s-e*Q(s,1-s)*W(-1,Q(t-3,9-t,1))))),bt=z("canvas").getContext("2d"),ft={turn:360,rad:180/tt,grad:.9},yt=/a?\(\s*([+-]?\d*\.?\d+)(\w*)?\s*[\s,]\s*([+-]?\d*\.?\d+)%?\s*,?\s*([+-]?\d*\.?\d+)%?(?:\s*[\/,]\s*([+-]?\d*\.?\d+)(%)?)?\s*\)?$/,mt=(t,e)=>{let s,n,r,o="";if(y(t)?o=t.trim():H(t)&&(r=$(t),r&&(o=J(t,r))),/^hsl/.test(o)){const[t,e,s,r,a,i="1",l]=yt.exec(o)||[];t&&(n={h:st(+e*(ft[s]||1)),s:et(+r),l:et(+a),a:et(+i/(l?100:1),1)})}if(!n){if(/^[\da-f]+$/i.test(o)&&(o="#"+o),bt.fillStyle="#000",bt.fillStyle=o,o=bt.fillStyle,"#"===o[0])s={r:nt(o[1]+o[2]),g:nt(o[3]+o[4]),b:nt(o[5]+o[6]),a:1};else{const[t,e,n,r]=o.match(/[\d\.]+/g).map(Number);s={r:t,g:e,b:n,a:r}}n=(({r:t,g:e,b:s,a:n})=>{const r=W(t/=255,e/=255,s/=255),o=Q(t,e,s),a=r-o,i=(r+o)/2;return{h:st(60*(0===a?0:r===t?(e-s)/a%6:r===e?(s-t)/a+2:r===s?(t-e)/a+4:0)),s:a?a/(1-X(2*i-1))*100:0,l:100*i,a:n}})(s)}return n.a=e?Y(100*n.a)/100:1,s&&(s.a=n.a),[n,s]},vt=t=>{const e={h:0,s:0,l:0,r:0,g:0,b:0,a:1,rgb:"",hsl:"",hex:""},s=t.config,n=t.e.A;let r,o,i,l;return{i:e,S:()=>e[i],V(t,e){r=t,o=e},u(t){i=s.format=t},$(t,s,o=!0,i){const l=e.hex;k(e,t),k(e,s||(({h:t,s:e,l:s,a:n})=>({r:wt(t/=30,e/=100,s/=100),g:wt(t+8,e,s),b:wt(t+4,e,s),a:n}))(e)),e.s=Y(e.s),e.l=Y(e.l),e.rgb=J(e),e.hsl=J(e,w),e.hex=(({r:t,g:e,b:s,a:n})=>"#"+_t(t)+_t(e)+_t(s)+(n<1?_t(Y(255*n)):""))(e),r(e),l!==e.hex&&(o&&n(a,e),i&&n(d,e))},o(t,n=!1,r){this.$(...mt(t,s.opacity),n,r),o(e)},t(){l=e[i]},_(){l!==e[i]&&n(d,e)}}};return class{static version(){return"2.2.0"}static setDefaults(e){V(t,e)}constructor(e,s){this.config=V({},t),this.e=(t=>{const e={[r]:[],[o]:[],[d]:[],[a]:[]};return{A(s,n=t.s.i){(e[s]||[]).forEach((e=>e(k({type:s,source:t},n))))},I(t,s){s&&!(e[t]||[]).includes(s)&&e[t].push(s)},j(t,s){t?e[t]&&(e[t]=s?e[t].filter((t=>t!==s)):[]):O(e,(t=>{e[t]=[]}))}}})(this),this.s=vt(this),this.c=dt(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.T()}open(){this.c.m(!0)}close(){this.c.m(!1)}toggle(){this.c.m()}on(t,e){this.e.I(t,e)}off(t,e){this.e.j(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=>v(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.C()}trigger(t){this.e.A(t)}destroy(){this.c.M(),O(this,(t=>{this[t]=null})),A(this,C)}}}));
//# sourceMappingURL=alwan.min.js.map