kempo-ui 0.0.33 → 0.0.35
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.
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";export default class ColorPicker extends ShadowComponent{static formAssociated=!0;static properties={name:{type:String,reflect:!0,attribute:"name"},format:{type:String,reflect:!0,attribute:"format"},value:{type:String,reflect:!0,attribute:"value"},red:{type:Number},green:{type:Number},blue:{type:Number},alpha:{type:Number}};constructor(){super(),this.internals=this.attachInternals(),this.format="hex",this.red=0,this.green=0,this.blue=0,this.alpha=1}connectedCallback(){super.connectedCallback(),this.originalHadFormat=this.hasAttribute("format"),this.originalValue=this.getAttribute("value")}firstUpdated(t){if(super.firstUpdated(t),this.originalValue&&!this.originalHadFormat)for(const[t,a]of Object.entries(this.constructor.formats))if(a.detect(this.originalValue)){this.format=t;break}}updated(t){super.updated(t),t.has("format")&&this.requestUpdate(),(t.has("red")||t.has("green")||t.has("blue")||t.has("alpha")||t.has("format"))&&this.updateFormValue()}get value(){if(void 0===this.red||void 0===this.green||void 0===this.blue){const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(0,0,0,1):"#000000"}const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(this.red,this.green,this.blue,this.alpha||1):"#000000"}set value(t){if(t&&"string"==typeof t){for(const[a,s]of Object.entries(this.constructor.formats))if(s.detect(t)){const a=s.parse(t);if(a)return this.red=a.r,this.green=a.g,this.blue=a.b,a.hasAlpha&&(this.alpha=a.a),void this.updateFormValue()}this.red=0,this.green=0,this.blue=0,this.alpha=1,this.updateFormValue()}}updateFormValue(){const t=this.value;this.internals.setFormValue(t)}onColorInputChange(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1)}onTextInputChange(t){this.value=t.target.value}render(){return html`
|
|
1
|
+
import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";export default class ColorPicker extends ShadowComponent{static formAssociated=!0;static properties={name:{type:String,reflect:!0,attribute:"name"},format:{type:String,reflect:!0,attribute:"format"},value:{type:String,reflect:!0,attribute:"value"},red:{type:Number},green:{type:Number},blue:{type:Number},alpha:{type:Number}};constructor(){super(),this.internals=this.attachInternals(),this.format="hex",this.red=0,this.green=0,this.blue=0,this.alpha=1}connectedCallback(){super.connectedCallback(),this.originalHadFormat=this.hasAttribute("format"),this.originalValue=this.getAttribute("value")}firstUpdated(t){if(super.firstUpdated(t),this.originalValue&&!this.originalHadFormat)for(const[t,a]of Object.entries(this.constructor.formats))if(a.detect(this.originalValue)){this.format=t;break}}updated(t){super.updated(t),t.has("format")&&this.requestUpdate(),(t.has("red")||t.has("green")||t.has("blue")||t.has("alpha")||t.has("format"))&&(this.updateFormValue(),this.syncInputs(t.has("format")))}syncInputs(t=!1){const a=this.shadowRoot?.querySelector("#text"),s=this.shadowRoot?.querySelector("#color"),r=this.shadowRoot?.querySelector("#format"),e=this.shadowRoot?.activeElement;a&&(t||e!==a)&&(a.value=this.value),s&&e!==s&&(s.value=this.constructor.formats.hex.toString(this.red||0,this.green||0,this.blue||0,1)),r&&e!==r&&(r.value=this.format)}get value(){if(void 0===this.red||void 0===this.green||void 0===this.blue){const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(0,0,0,1):"#000000"}const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(this.red,this.green,this.blue,this.alpha||1):"#000000"}set value(t){if(t&&"string"==typeof t){for(const[a,s]of Object.entries(this.constructor.formats))if(s.detect(t)){const a=s.parse(t);if(a)return this.red=a.r,this.green=a.g,this.blue=a.b,a.hasAlpha&&(this.alpha=a.a),void this.updateFormValue()}this.red=0,this.green=0,this.blue=0,this.alpha=1,this.updateFormValue()}}updateFormValue(){const t=this.value;this.internals.setFormValue(t)}onColorInputChange(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1),this.forwardEvent(t)}onTextInputChange(t){this.value=t.target.value,this.forwardEvent(t)}onTextInput(t){this.value=t.target.value,this.forwardEvent(t)}onColorInput(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1),this.forwardEvent(t)}onFormatChange(t){this.format=t.target.value,this.forwardEvent(t)}onFormatInput(t){this.format=t.target.value,this.forwardEvent(t)}forwardEvent=t=>{this.dispatchEvent(new t.constructor(t.type,t))};render(){return html`
|
|
2
2
|
<div id="container">
|
|
3
3
|
<select
|
|
4
4
|
id="format"
|
|
5
5
|
value="${this.format}"
|
|
6
|
-
@change=${
|
|
6
|
+
@change=${this.onFormatChange}
|
|
7
|
+
@input=${this.onFormatInput}
|
|
8
|
+
@focus=${this.forwardEvent}
|
|
9
|
+
@blur=${this.forwardEvent}
|
|
7
10
|
>${this.constructor.formats?Object.keys(this.constructor.formats).map(t=>html`<option value="${t}" ?selected=${this.format===t}>${t.toUpperCase()}</option>`):null}</select>
|
|
8
11
|
<input
|
|
9
12
|
id="text"
|
|
10
13
|
type="text"
|
|
11
14
|
value="${this.value}"
|
|
12
15
|
@change=${this.onTextInputChange}
|
|
16
|
+
@input=${this.onTextInput}
|
|
17
|
+
@focus=${this.forwardEvent}
|
|
18
|
+
@blur=${this.forwardEvent}
|
|
13
19
|
/>
|
|
14
20
|
<div id="color-wrapper">
|
|
15
21
|
<input
|
|
@@ -17,6 +23,9 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
17
23
|
type="color"
|
|
18
24
|
value="${this.constructor.formats.hex.toString(this.red||0,this.green||0,this.blue||0,1)}"
|
|
19
25
|
@change=${this.onColorInputChange}
|
|
26
|
+
@input=${this.onColorInput}
|
|
27
|
+
@focus=${this.forwardEvent}
|
|
28
|
+
@blur=${this.forwardEvent}
|
|
20
29
|
/>
|
|
21
30
|
</div>
|
|
22
31
|
</div>
|
|
@@ -42,4 +51,4 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
42
51
|
aspect-ratio: 1;
|
|
43
52
|
height: 100%;
|
|
44
53
|
}
|
|
45
|
-
`;static formats={hex:{detect:t=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/.test(t),parse:t=>{let a,s,e
|
|
54
|
+
`;static formats={hex:{detect:t=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/.test(t),parse:t=>{let a,s,r,e=t.slice(1),o=e.length,h=1,n=!1;return 3===o||4===o?(a=parseInt(e[0]+e[0],16),s=parseInt(e[1]+e[1],16),r=parseInt(e[2]+e[2],16),4===o&&(h=parseInt(e[3]+e[3],16)/255,n=!0)):6!==o&&8!==o||(a=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),r=parseInt(e.slice(4,6),16),8===o&&(h=parseInt(e.slice(6,8),16)/255,n=!0)),{r:a,g:s,b:r,a:h,hasAlpha:n}},toString:(t,a,s,r)=>{let e=((t=Math.round(t))<<16|(a=Math.round(a))<<8|(s=Math.round(s))).toString(16).padStart(6,"0");if(r<1){e+=Math.round(255*r).toString(16).padStart(2,"0")}return"#"+e}},rgb:{detect:t=>/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*(?:0?\.\d+|1(?:\.0*)?|\d+(?:\.\d*)?))?\s*\)$/.test(t),parse:t=>{const a=t.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)$/);if(!a)return null;return{r:parseInt(a[1],10),g:parseInt(a[2],10),b:parseInt(a[3],10),a:a[4]?parseFloat(a[4]):1,hasAlpha:!!a[4]}},toString:(t,a,s,r)=>(t=Math.round(t),a=Math.round(a),s=Math.round(s),r<1?`rgba(${t}, ${a}, ${s}, ${r})`:`rgb(${t}, ${a}, ${s})`)},hsl:{detect:t=>/^hsla?\(\s*\d+(?:\.\d+)?\s*,\s*\d+(?:\.\d+)?%\s*,\s*\d+(?:\.\d+)?%\s*(?:,\s*(?:0?\.\d+|1(?:\.0*)?|\d+(?:\.\d*)?))?\s*\)$/.test(t),parse:t=>{const a=t.match(/^hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*(?:,\s*([\d.]+))?\s*\)$/);if(!a)return null;let s=parseFloat(a[1])/360,r=parseFloat(a[2])/100,e=parseFloat(a[3])/100,o=a[4]?parseFloat(a[4]):1;const h=!!a[4];let n,i,d;if(0===r)n=i=d=e;else{const t=(t,a,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(a-t)*s:s<.5?a:s<2/3?t+(a-t)*(2/3-s)*6:t),a=e<.5?e*(1+r):e+r-e*r,o=2*e-a;n=t(o,a,s+1/3),i=t(o,a,s),d=t(o,a,s-1/3)}return{r:Math.round(255*n),g:Math.round(255*i),b:Math.round(255*d),a:o,hasAlpha:h}},toString:(t,a,s,r)=>{t/=255,a/=255,s/=255;const e=Math.max(t,a,s),o=Math.min(t,a,s);let h,n,i=(e+o)/2;if(e===o)h=n=0;else{const r=e-o;switch(n=i>.5?r/(2-e-o):r/(e+o),e){case t:h=(a-s)/r+(a<s?6:0);break;case a:h=(s-t)/r+2;break;case s:h=(t-a)/r+4}h/=6}return h=Math.round(360*h),n=Math.round(100*n),i=Math.round(100*i),r<1?`hsla(${h}, ${n}%, ${i}%, ${r})`:`hsl(${h}, ${n}%, ${i}%)`}},hwb:{detect:t=>/^hwb\(\s*(\d+(?:\.\d+)?)(?:deg)?\s+(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)%\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^hwb\(\s*(\d+(?:\.\d+)?)(?:deg)?\s+(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)%\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s,r,e,o=parseFloat(a[1]),h=parseFloat(a[2])/100,n=parseFloat(a[3])/100,i=a[4]?parseFloat(a[4]):1,d=1-h-n;if(d>0){let t=o/360,a=1-Math.abs(6*t%2-1),n=h+d*(1-a),i=h+d*a;t<1/6?(s=h+d,r=i,e=h):t<2/6?(s=n,r=h+d,e=h):t<.5?(s=h,r=h+d,e=i):t<4/6?(s=h,r=n,e=h+d):t<5/6?(s=i,r=h,e=h+d):(s=h+d,r=h,e=n)}else s=r=e=h;const l=!!a[4];return{r:Math.round(255*s),g:Math.round(255*r),b:Math.round(255*e),a:i,hasAlpha:l}},toString:(t,a,s,r)=>{t/=255,a/=255,s/=255;const e=Math.max(t,a,s),o=Math.min(t,a,s),h=e-o;let n=0;if(0!==h){switch(e){case t:n=(a-s)/h%6;break;case a:n=(s-t)/h+2;break;case s:n=(t-a)/h+4}n=Math.round(60*n),n<0&&(n+=360)}const i=Math.round(100*o),d=Math.round(100*(1-e));return r<1?`hwb(${n} ${i}% ${d}% / ${r})`:`hwb(${n} ${i}% ${d}%)`}},lab:{detect:t=>/^lab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^lab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=(100*s+16)/116,n=h+r/500,i=h-e/200,d=.95047*(n>.206893034?n*n*n:(n-16/116)/7.787),l=1*(h>.206893034?h*h*h:(h-16/116)/7.787),u=1.08883*(i>.206893034?i*i*i:(i-16/116)/7.787),p=3.2404542*d-1.5371385*l-.4985314*u,c=-.969266*d+1.8760108*l+.041556*u,M=.0556434*d-.2040259*l+1.0572252*u,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055,$=M<=.0031308?12.92*M:1.055*Math.pow(M,1/2.4)-.055;const g=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,m))),g:Math.round(255*Math.max(0,Math.min(1,f))),b:Math.round(255*Math.max(0,Math.min(1,$))),a:o,hasAlpha:g}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=(.4124564*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.3575761*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.1804375*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)))/.95047,o=(.2126729*t+.7151522*a+.072175*s)/1,h=(.0193339*t+.119192*a+.9503041*s)/1.08883,n=e>.008856?Math.pow(e,1/3):7.787*e+16/116,i=o>.008856?Math.pow(o,1/3):7.787*o+16/116,d=h>.008856?Math.pow(h,1/3):7.787*h+16/116,l=Math.round(100*(116*i-16))/100,u=Math.round(500*(n-i)*100)/100,p=Math.round(200*(i-d)*100)/100;return r<1?`lab(${l}% ${u} ${p} / ${r})`:`lab(${l}% ${u} ${p})`}},lch:{detect:t=>/^lch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^lch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1]),r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=(100*(s/100)+16)/116,n=h+r*Math.cos(e*Math.PI/180)/500,i=h-r*Math.sin(e*Math.PI/180)/200,d=.95047*(n>.206893034?n*n*n:(n-16/116)/7.787),l=1*(h>.206893034?h*h*h:(h-16/116)/7.787),u=1.08883*(i>.206893034?i*i*i:(i-16/116)/7.787),p=3.2404542*d-1.5371385*l-.4985314*u,c=-.969266*d+1.8760108*l+.041556*u,M=.0556434*d-.2040259*l+1.0572252*u,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055,$=M<=.0031308?12.92*M:1.055*Math.pow(M,1/2.4)-.055;const g=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,m))),g:Math.round(255*Math.max(0,Math.min(1,f))),b:Math.round(255*Math.max(0,Math.min(1,$))),a:o,hasAlpha:g}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=(.4124564*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.3575761*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.1804375*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)))/.95047,o=(.2126729*t+.7151522*a+.072175*s)/1,h=(.0193339*t+.119192*a+.9503041*s)/1.08883,n=e>.008856?Math.pow(e,1/3):7.787*e+16/116,i=o>.008856?Math.pow(o,1/3):7.787*o+16/116,d=(116*i-16)/100,l=500*(n-i),u=200*(i-(h>.008856?Math.pow(h,1/3):7.787*h+16/116)),p=Math.sqrt(l*l+u*u);let c=180*Math.atan2(u,l)/Math.PI;c<0&&(c+=360);const M=Math.round(100*d*100)/100,m=Math.round(100*p)/100,f=Math.round(100*c)/100;return r<1?`lch(${M}% ${m} ${f} / ${r})`:`lch(${M}% ${m} ${f})`}},oklab:{detect:t=>/^oklab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^oklab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=s+.3963377774*r+.2158037573*e,n=s-.1055613458*r-.0638541728*e,i=s-.0894841775*r-1.291485548*e,d=4.0767416621*h-3.3077115913*n+.2309699292*i,l=-1.2684380046*h+2.6097574011*n-.3413193965*i,u=-.0041960863*h-.7034186147*n+1.707614701*i,p=d<=.0031308?12.92*d:1.055*Math.pow(d,1/2.4)-.055,c=l<=.0031308?12.92*l:1.055*Math.pow(l,1/2.4)-.055,M=u<=.0031308?12.92*u:1.055*Math.pow(u,1/2.4)-.055;const m=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,p))),g:Math.round(255*Math.max(0,Math.min(1,c))),b:Math.round(255*Math.max(0,Math.min(1,M))),a:o,hasAlpha:m}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=.4122214708*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.5363325363*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.0514459929*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)),o=.2119034982*t+.6806995451*a+.1073969566*s,h=.0883024619*t+.2817188376*a+.6299787005*s,n=Math.pow(e,1/3),i=Math.pow(o,1/3),d=Math.pow(h,1/3),l=.2104542553*n+.793617785*i-.0040720468*d,u=1.9779984951*n-2.428592205*i+.4505937099*d,p=.0259040371*n+.7827717662*i-.808675766*d,c=Math.round(100*l*100)/100,M=Math.round(100*u)/100,m=Math.round(100*p)/100;return r<1?`oklab(${c}% ${M} ${m} / ${r})`:`oklab(${c}% ${M} ${m})`}},oklch:{detect:t=>/^oklch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^oklch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=r*Math.cos(e*Math.PI/180),n=r*Math.sin(e*Math.PI/180),i=s+.3963377774*h+.2158037573*n,d=s-.1055613458*h-.0638541728*n,l=s-.0894841775*h-1.291485548*n,u=4.0767416621*i-3.3077115913*d+.2309699292*l,p=-1.2684380046*i+2.6097574011*d-.3413193965*l,c=-.0041960863*i-.7034186147*d+1.707614701*l,M=u<=.0031308?12.92*u:1.055*Math.pow(u,1/2.4)-.055,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055;const $=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,M))),g:Math.round(255*Math.max(0,Math.min(1,m))),b:Math.round(255*Math.max(0,Math.min(1,f))),a:o,hasAlpha:$}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=.4122214708*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.5363325363*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.0514459929*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)),o=.2119034982*t+.6806995451*a+.1073969566*s,h=.0883024619*t+.2817188376*a+.6299787005*s,n=Math.pow(e,1/3),i=Math.pow(o,1/3),d=Math.pow(h,1/3),l=.2104542553*n+.793617785*i-.0040720468*d,u=1.9779984951*n-2.428592205*i+.4505937099*d,p=.0259040371*n+.7827717662*i-.808675766*d,c=Math.sqrt(u*u+p*p);let M=180*Math.atan2(p,u)/Math.PI;M<0&&(M+=360);const m=Math.round(100*l*100)/100,f=Math.round(100*c)/100,$=Math.round(100*M)/100;return r<1?`oklch(${m}% ${f} ${$} / ${r})`:`oklch(${m}% ${f} ${$})`}}}}window.customElements.define("k-color-picker",ColorPicker);
|
|
@@ -30,12 +30,14 @@
|
|
|
30
30
|
<a href="#formatSelection">Format Selection</a><br />
|
|
31
31
|
<a href="#formUsage">Form Integration</a><br />
|
|
32
32
|
<a href="#javascriptUsage">JavaScript Usage</a><br />
|
|
33
|
+
<a href="#eventHandling">Event Handling</a><br />
|
|
33
34
|
|
|
34
35
|
<h6 class="mt"><a href="#jsRef" class="no-link">JavaScript Reference</a></h6>
|
|
35
36
|
<a href="#constructor">Constructor</a><br />
|
|
36
37
|
<a href="#requirements">Requirements</a><br />
|
|
37
38
|
<a href="#properties">Properties</a><br />
|
|
38
39
|
<a href="#methods">Methods</a><br />
|
|
40
|
+
<a href="#events">Events</a><br />
|
|
39
41
|
<a href="#staticMembers">Static Members</a><br />
|
|
40
42
|
</div>
|
|
41
43
|
</k-accordion-panel>
|
|
@@ -336,6 +338,161 @@
|
|
|
336
338
|
</div>
|
|
337
339
|
</div>
|
|
338
340
|
|
|
341
|
+
<h2 id="eventHandling"><a href="#eventHandling" class="no-link">Event Handling</a></h2>
|
|
342
|
+
<p>The ColorPicker component forwards DOM events from its internal form elements (select, text input, and color
|
|
343
|
+
input), allowing you to listen for user interactions. The following events are forwarded: <code>change</code>,
|
|
344
|
+
<code>input</code>, <code>focus</code>, and <code>blur</code>.</p>
|
|
345
|
+
|
|
346
|
+
<h3>Change Event</h3>
|
|
347
|
+
<p>Fired when the user commits a color change through any of the internal inputs.</p>
|
|
348
|
+
<div class="row -mx">
|
|
349
|
+
<div class="col m-span-12 px">
|
|
350
|
+
<k-card label="HTML">
|
|
351
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-color-picker</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"changeEventPicker"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"#3498db"</span>></span><span class="hljs-tag"></<span class="hljs-name">k-color-picker</span>></span>
|
|
352
|
+
<span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"changeOutput"</span>></span>Change the color to see the event<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
|
|
353
|
+
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript">
|
|
354
|
+
<span class="hljs-keyword">const</span> picker = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'changeEventPicker'</span>);
|
|
355
|
+
picker.addEventListener(<span class="hljs-string">'change'</span>, (e) => {
|
|
356
|
+
<span class="hljs-keyword">const</span> output = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'changeOutput'</span>);
|
|
357
|
+
output.textContent = <span class="hljs-string">`Changed to: <span class="hljs-subst">${picker.value}</span>`</span>;
|
|
358
|
+
});
|
|
359
|
+
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
360
|
+
</k-card>
|
|
361
|
+
</div>
|
|
362
|
+
<div class="col m-span-12 px">
|
|
363
|
+
<k-card label="Output">
|
|
364
|
+
<k-color-picker id="changeEventPicker" value="#3498db" class="mb"></k-color-picker>
|
|
365
|
+
<p id="changeOutput">Change the color to see the event</p>
|
|
366
|
+
<script>
|
|
367
|
+
const changeEventPicker = document.getElementById('changeEventPicker');
|
|
368
|
+
changeEventPicker.addEventListener('change', (e) => {
|
|
369
|
+
const output = document.getElementById('changeOutput');
|
|
370
|
+
output.textContent = `Changed to: ${changeEventPicker.value}`;
|
|
371
|
+
});
|
|
372
|
+
</script>
|
|
373
|
+
</k-card>
|
|
374
|
+
</div>
|
|
375
|
+
</div>
|
|
376
|
+
|
|
377
|
+
<h3>Input Event</h3>
|
|
378
|
+
<p>Fired as the user types or modifies the color value, providing real-time updates.</p>
|
|
379
|
+
<div class="row -mx">
|
|
380
|
+
<div class="col m-span-12 px">
|
|
381
|
+
<k-card label="HTML">
|
|
382
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-color-picker</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"inputEventPicker"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"#e74c3c"</span>></span><span class="hljs-tag"></<span class="hljs-name">k-color-picker</span>></span>
|
|
383
|
+
<span class="hljs-tag"><<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"colorPreview"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"width:100%; height:50px; background:#e74c3c; border-radius:4px;"</span>></span><span class="hljs-tag"></<span class="hljs-name">div</span>></span>
|
|
384
|
+
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript">
|
|
385
|
+
<span class="hljs-keyword">const</span> picker = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'inputEventPicker'</span>);
|
|
386
|
+
<span class="hljs-keyword">const</span> preview = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'colorPreview'</span>);
|
|
387
|
+
picker.addEventListener(<span class="hljs-string">'input'</span>, (e) => {
|
|
388
|
+
preview.style.backgroundColor = picker.value;
|
|
389
|
+
});
|
|
390
|
+
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
391
|
+
</k-card>
|
|
392
|
+
</div>
|
|
393
|
+
<div class="col m-span-12 px">
|
|
394
|
+
<k-card label="Output">
|
|
395
|
+
<k-color-picker id="inputEventPicker" value="#e74c3c" class="mb"></k-color-picker>
|
|
396
|
+
<div id="colorPreview" style="width:100%; height:50px; background:#e74c3c; border-radius:4px;"></div>
|
|
397
|
+
<script>
|
|
398
|
+
const inputEventPicker = document.getElementById('inputEventPicker');
|
|
399
|
+
const colorPreview = document.getElementById('colorPreview');
|
|
400
|
+
inputEventPicker.addEventListener('input', (e) => {
|
|
401
|
+
colorPreview.style.backgroundColor = inputEventPicker.value;
|
|
402
|
+
});
|
|
403
|
+
</script>
|
|
404
|
+
</k-card>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
|
|
408
|
+
<h3>Focus and Blur Events</h3>
|
|
409
|
+
<p>Track when the user focuses on or leaves any of the color picker's input elements.</p>
|
|
410
|
+
<div class="row -mx">
|
|
411
|
+
<div class="col m-span-12 px">
|
|
412
|
+
<k-card label="HTML">
|
|
413
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-color-picker</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"focusEventPicker"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"#2ecc71"</span>></span><span class="hljs-tag"></<span class="hljs-name">k-color-picker</span>></span>
|
|
414
|
+
<span class="hljs-tag"><<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"focusOutput"</span>></span>Click on the color picker to see focus/blur events<span class="hljs-tag"></<span class="hljs-name">p</span>></span>
|
|
415
|
+
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript">
|
|
416
|
+
<span class="hljs-keyword">const</span> picker = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'focusEventPicker'</span>);
|
|
417
|
+
<span class="hljs-keyword">const</span> output = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'focusOutput'</span>);
|
|
418
|
+
picker.addEventListener(<span class="hljs-string">'focus'</span>, (e) => {
|
|
419
|
+
output.textContent = <span class="hljs-string">'Color picker focused'</span>;
|
|
420
|
+
output.style.color = <span class="hljs-string">'#2ecc71'</span>;
|
|
421
|
+
});
|
|
422
|
+
picker.addEventListener(<span class="hljs-string">'blur'</span>, (e) => {
|
|
423
|
+
output.textContent = <span class="hljs-string">'Color picker blurred'</span>;
|
|
424
|
+
output.style.color = <span class="hljs-string">'#95a5a6'</span>;
|
|
425
|
+
});
|
|
426
|
+
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
427
|
+
</k-card>
|
|
428
|
+
</div>
|
|
429
|
+
<div class="col m-span-12 px">
|
|
430
|
+
<k-card label="Output">
|
|
431
|
+
<k-color-picker id="focusEventPicker" value="#2ecc71" class="mb"></k-color-picker>
|
|
432
|
+
<p id="focusOutput">Click on the color picker to see focus/blur events</p>
|
|
433
|
+
<script>
|
|
434
|
+
const focusEventPicker = document.getElementById('focusEventPicker');
|
|
435
|
+
const focusOutput = document.getElementById('focusOutput');
|
|
436
|
+
focusEventPicker.addEventListener('focus', (e) => {
|
|
437
|
+
focusOutput.textContent = 'Color picker focused';
|
|
438
|
+
focusOutput.style.color = '#2ecc71';
|
|
439
|
+
});
|
|
440
|
+
focusEventPicker.addEventListener('blur', (e) => {
|
|
441
|
+
focusOutput.textContent = 'Color picker blurred';
|
|
442
|
+
focusOutput.style.color = '#95a5a6';
|
|
443
|
+
});
|
|
444
|
+
</script>
|
|
445
|
+
</k-card>
|
|
446
|
+
</div>
|
|
447
|
+
</div>
|
|
448
|
+
|
|
449
|
+
<h3>Multiple Events Example</h3>
|
|
450
|
+
<p>Combining multiple event listeners to create an interactive color picking experience with event logging.</p>
|
|
451
|
+
<div class="row -mx">
|
|
452
|
+
<div class="col m-span-12 px">
|
|
453
|
+
<k-card label="HTML">
|
|
454
|
+
<pre><code class="hljs xml"><span class="hljs-tag"><<span class="hljs-name">k-color-picker</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"multiEventPicker"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"#9b59b6"</span>></span><span class="hljs-tag"></<span class="hljs-name">k-color-picker</span>></span>
|
|
455
|
+
<span class="hljs-tag"><<span class="hljs-name">pre</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"eventLog"</span>></span><span class="hljs-tag"></<span class="hljs-name">pre</span>></span>
|
|
456
|
+
<span class="hljs-tag"><<span class="hljs-name">script</span>></span><span class="javascript">
|
|
457
|
+
<span class="hljs-keyword">const</span> picker = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'multiEventPicker'</span>);
|
|
458
|
+
<span class="hljs-keyword">const</span> log = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'eventLog'</span>);
|
|
459
|
+
<span class="hljs-keyword">const</span> logEvent = <span class="hljs-function">(<span class="hljs-params">type, value</span>) =></span> {
|
|
460
|
+
<span class="hljs-keyword">const</span> time = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>().toLocaleTimeString();
|
|
461
|
+
<span class="hljs-keyword">const</span> entry = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>);
|
|
462
|
+
entry.textContent = <span class="hljs-string">`<span class="hljs-subst">${time}</span> - <span class="hljs-subst">${type}</span>: <span class="hljs-subst">${value}</span>`</span>;
|
|
463
|
+
log.insertBefore(entry, log.firstChild);
|
|
464
|
+
<span class="hljs-keyword">if</span> (log.children.length > <span class="hljs-number">10</span>) log.lastChild.remove();
|
|
465
|
+
};
|
|
466
|
+
picker.addEventListener(<span class="hljs-string">'change'</span>, () => logEvent(<span class="hljs-string">'change'</span>, picker.value));
|
|
467
|
+
picker.addEventListener(<span class="hljs-string">'input'</span>, () => logEvent(<span class="hljs-string">'input'</span>, picker.value));
|
|
468
|
+
picker.addEventListener(<span class="hljs-string">'focus'</span>, () => logEvent(<span class="hljs-string">'focus'</span>, <span class="hljs-string">'focused'</span>));
|
|
469
|
+
picker.addEventListener(<span class="hljs-string">'blur'</span>, () => logEvent(<span class="hljs-string">'blur'</span>, <span class="hljs-string">'blurred'</span>));
|
|
470
|
+
</span><span class="hljs-tag"></<span class="hljs-name">script</span>></span></code></pre>
|
|
471
|
+
</k-card>
|
|
472
|
+
</div>
|
|
473
|
+
<div class="col m-span-12 px">
|
|
474
|
+
<k-card label="Output">
|
|
475
|
+
<k-color-picker id="multiEventPicker" value="#9b59b6" class="mb"></k-color-picker>
|
|
476
|
+
<pre id="eventLog"></pre>
|
|
477
|
+
<script>
|
|
478
|
+
const multiEventPicker = document.getElementById('multiEventPicker');
|
|
479
|
+
const eventLog = document.getElementById('eventLog');
|
|
480
|
+
const logEvent = (type, value) => {
|
|
481
|
+
const time = new Date().toLocaleTimeString();
|
|
482
|
+
const entry = document.createElement('div');
|
|
483
|
+
entry.textContent = `${time} - ${type}: ${value}`;
|
|
484
|
+
eventLog.insertBefore(entry, eventLog.firstChild);
|
|
485
|
+
if (eventLog.children.length > 10) eventLog.lastChild.remove();
|
|
486
|
+
};
|
|
487
|
+
multiEventPicker.addEventListener('change', () => logEvent('change', multiEventPicker.value));
|
|
488
|
+
multiEventPicker.addEventListener('input', () => logEvent('input', multiEventPicker.value));
|
|
489
|
+
multiEventPicker.addEventListener('focus', () => logEvent('focus', 'focused'));
|
|
490
|
+
multiEventPicker.addEventListener('blur', () => logEvent('blur', 'blurred'));
|
|
491
|
+
</script>
|
|
492
|
+
</k-card>
|
|
493
|
+
</div>
|
|
494
|
+
</div>
|
|
495
|
+
|
|
339
496
|
<h2 id="jsRef"><a href="jsRef" class="no-link">JavaScript Reference</a></h2>
|
|
340
497
|
|
|
341
498
|
<h3 id="constructor"><a href="#constructor" class="no-link">Constructor</a></h3>
|
|
@@ -381,6 +538,23 @@
|
|
|
381
538
|
<h5><code>toHexColor(red, green, blue)<i>: string</i></code></h5>
|
|
382
539
|
<p>Converts RGB values to a hex color string for the native color input.</p>
|
|
383
540
|
|
|
541
|
+
<h3 id="events"><a href="#events" class="no-link">Events</a></h3>
|
|
542
|
+
<h5><code>change</code></h5>
|
|
543
|
+
<p>Fired when the user commits a color change through any of the internal inputs (select, text input, or color
|
|
544
|
+
input). This event is forwarded from the native DOM elements.</p>
|
|
545
|
+
|
|
546
|
+
<h5><code>input</code></h5>
|
|
547
|
+
<p>Fired when the user types or modifies values in the text input or interacts with the format selector. This event
|
|
548
|
+
is forwarded from the native DOM elements and provides real-time updates.</p>
|
|
549
|
+
|
|
550
|
+
<h5><code>focus</code></h5>
|
|
551
|
+
<p>Fired when any of the internal form elements (select, text input, or color input) receives focus. This event is
|
|
552
|
+
forwarded from the native DOM elements.</p>
|
|
553
|
+
|
|
554
|
+
<h5><code>blur</code></h5>
|
|
555
|
+
<p>Fired when any of the internal form elements (select, text input, or color input) loses focus. This event is
|
|
556
|
+
forwarded from the native DOM elements.</p>
|
|
557
|
+
|
|
384
558
|
<h3 id="staticMembers"><a href="#staticMembers" class="no-link">Static Members</a></h3>
|
|
385
559
|
<h5><code>namedColors<i>: object</i></code></h5>
|
|
386
560
|
<p>An object containing 147 named CSS colors mapped to their hex values.</p>
|
|
@@ -1,15 +1,21 @@
|
|
|
1
|
-
import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";export default class ColorPicker extends ShadowComponent{static formAssociated=!0;static properties={name:{type:String,reflect:!0,attribute:"name"},format:{type:String,reflect:!0,attribute:"format"},value:{type:String,reflect:!0,attribute:"value"},red:{type:Number},green:{type:Number},blue:{type:Number},alpha:{type:Number}};constructor(){super(),this.internals=this.attachInternals(),this.format="hex",this.red=0,this.green=0,this.blue=0,this.alpha=1}connectedCallback(){super.connectedCallback(),this.originalHadFormat=this.hasAttribute("format"),this.originalValue=this.getAttribute("value")}firstUpdated(t){if(super.firstUpdated(t),this.originalValue&&!this.originalHadFormat)for(const[t,a]of Object.entries(this.constructor.formats))if(a.detect(this.originalValue)){this.format=t;break}}updated(t){super.updated(t),t.has("format")&&this.requestUpdate(),(t.has("red")||t.has("green")||t.has("blue")||t.has("alpha")||t.has("format"))&&this.updateFormValue()}get value(){if(void 0===this.red||void 0===this.green||void 0===this.blue){const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(0,0,0,1):"#000000"}const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(this.red,this.green,this.blue,this.alpha||1):"#000000"}set value(t){if(t&&"string"==typeof t){for(const[a,s]of Object.entries(this.constructor.formats))if(s.detect(t)){const a=s.parse(t);if(a)return this.red=a.r,this.green=a.g,this.blue=a.b,a.hasAlpha&&(this.alpha=a.a),void this.updateFormValue()}this.red=0,this.green=0,this.blue=0,this.alpha=1,this.updateFormValue()}}updateFormValue(){const t=this.value;this.internals.setFormValue(t)}onColorInputChange(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1)}onTextInputChange(t){this.value=t.target.value}render(){return html`
|
|
1
|
+
import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-all.min.js";export default class ColorPicker extends ShadowComponent{static formAssociated=!0;static properties={name:{type:String,reflect:!0,attribute:"name"},format:{type:String,reflect:!0,attribute:"format"},value:{type:String,reflect:!0,attribute:"value"},red:{type:Number},green:{type:Number},blue:{type:Number},alpha:{type:Number}};constructor(){super(),this.internals=this.attachInternals(),this.format="hex",this.red=0,this.green=0,this.blue=0,this.alpha=1}connectedCallback(){super.connectedCallback(),this.originalHadFormat=this.hasAttribute("format"),this.originalValue=this.getAttribute("value")}firstUpdated(t){if(super.firstUpdated(t),this.originalValue&&!this.originalHadFormat)for(const[t,a]of Object.entries(this.constructor.formats))if(a.detect(this.originalValue)){this.format=t;break}}updated(t){super.updated(t),t.has("format")&&this.requestUpdate(),(t.has("red")||t.has("green")||t.has("blue")||t.has("alpha")||t.has("format"))&&(this.updateFormValue(),this.syncInputs(t.has("format")))}syncInputs(t=!1){const a=this.shadowRoot?.querySelector("#text"),s=this.shadowRoot?.querySelector("#color"),r=this.shadowRoot?.querySelector("#format"),e=this.shadowRoot?.activeElement;a&&(t||e!==a)&&(a.value=this.value),s&&e!==s&&(s.value=this.constructor.formats.hex.toString(this.red||0,this.green||0,this.blue||0,1)),r&&e!==r&&(r.value=this.format)}get value(){if(void 0===this.red||void 0===this.green||void 0===this.blue){const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(0,0,0,1):"#000000"}const t=this.constructor.formats[this.format];return t&&t.toString?t.toString(this.red,this.green,this.blue,this.alpha||1):"#000000"}set value(t){if(t&&"string"==typeof t){for(const[a,s]of Object.entries(this.constructor.formats))if(s.detect(t)){const a=s.parse(t);if(a)return this.red=a.r,this.green=a.g,this.blue=a.b,a.hasAlpha&&(this.alpha=a.a),void this.updateFormValue()}this.red=0,this.green=0,this.blue=0,this.alpha=1,this.updateFormValue()}}updateFormValue(){const t=this.value;this.internals.setFormValue(t)}onColorInputChange(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1),this.forwardEvent(t)}onTextInputChange(t){this.value=t.target.value,this.forwardEvent(t)}onTextInput(t){this.value=t.target.value,this.forwardEvent(t)}onColorInput(t){const a=this.constructor.formats.hex.parse(t.target.value);a&&(this.red=a.r,this.green=a.g,this.blue=a.b,this.alpha=1),this.forwardEvent(t)}onFormatChange(t){this.format=t.target.value,this.forwardEvent(t)}onFormatInput(t){this.format=t.target.value,this.forwardEvent(t)}forwardEvent=t=>{this.dispatchEvent(new t.constructor(t.type,t))};render(){return html`
|
|
2
2
|
<div id="container">
|
|
3
3
|
<select
|
|
4
4
|
id="format"
|
|
5
5
|
value="${this.format}"
|
|
6
|
-
@change=${
|
|
6
|
+
@change=${this.onFormatChange}
|
|
7
|
+
@input=${this.onFormatInput}
|
|
8
|
+
@focus=${this.forwardEvent}
|
|
9
|
+
@blur=${this.forwardEvent}
|
|
7
10
|
>${this.constructor.formats?Object.keys(this.constructor.formats).map(t=>html`<option value="${t}" ?selected=${this.format===t}>${t.toUpperCase()}</option>`):null}</select>
|
|
8
11
|
<input
|
|
9
12
|
id="text"
|
|
10
13
|
type="text"
|
|
11
14
|
value="${this.value}"
|
|
12
15
|
@change=${this.onTextInputChange}
|
|
16
|
+
@input=${this.onTextInput}
|
|
17
|
+
@focus=${this.forwardEvent}
|
|
18
|
+
@blur=${this.forwardEvent}
|
|
13
19
|
/>
|
|
14
20
|
<div id="color-wrapper">
|
|
15
21
|
<input
|
|
@@ -17,6 +23,9 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
17
23
|
type="color"
|
|
18
24
|
value="${this.constructor.formats.hex.toString(this.red||0,this.green||0,this.blue||0,1)}"
|
|
19
25
|
@change=${this.onColorInputChange}
|
|
26
|
+
@input=${this.onColorInput}
|
|
27
|
+
@focus=${this.forwardEvent}
|
|
28
|
+
@blur=${this.forwardEvent}
|
|
20
29
|
/>
|
|
21
30
|
</div>
|
|
22
31
|
</div>
|
|
@@ -42,4 +51,4 @@ import ShadowComponent from"./ShadowComponent.js";import{html,css}from"../lit-al
|
|
|
42
51
|
aspect-ratio: 1;
|
|
43
52
|
height: 100%;
|
|
44
53
|
}
|
|
45
|
-
`;static formats={hex:{detect:t=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/.test(t),parse:t=>{let a,s,e
|
|
54
|
+
`;static formats={hex:{detect:t=>/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}|[A-Fa-f0-9]{8}|[A-Fa-f0-9]{4})$/.test(t),parse:t=>{let a,s,r,e=t.slice(1),o=e.length,h=1,n=!1;return 3===o||4===o?(a=parseInt(e[0]+e[0],16),s=parseInt(e[1]+e[1],16),r=parseInt(e[2]+e[2],16),4===o&&(h=parseInt(e[3]+e[3],16)/255,n=!0)):6!==o&&8!==o||(a=parseInt(e.slice(0,2),16),s=parseInt(e.slice(2,4),16),r=parseInt(e.slice(4,6),16),8===o&&(h=parseInt(e.slice(6,8),16)/255,n=!0)),{r:a,g:s,b:r,a:h,hasAlpha:n}},toString:(t,a,s,r)=>{let e=((t=Math.round(t))<<16|(a=Math.round(a))<<8|(s=Math.round(s))).toString(16).padStart(6,"0");if(r<1){e+=Math.round(255*r).toString(16).padStart(2,"0")}return"#"+e}},rgb:{detect:t=>/^rgba?\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*(?:,\s*(?:0?\.\d+|1(?:\.0*)?|\d+(?:\.\d*)?))?\s*\)$/.test(t),parse:t=>{const a=t.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)$/);if(!a)return null;return{r:parseInt(a[1],10),g:parseInt(a[2],10),b:parseInt(a[3],10),a:a[4]?parseFloat(a[4]):1,hasAlpha:!!a[4]}},toString:(t,a,s,r)=>(t=Math.round(t),a=Math.round(a),s=Math.round(s),r<1?`rgba(${t}, ${a}, ${s}, ${r})`:`rgb(${t}, ${a}, ${s})`)},hsl:{detect:t=>/^hsla?\(\s*\d+(?:\.\d+)?\s*,\s*\d+(?:\.\d+)?%\s*,\s*\d+(?:\.\d+)?%\s*(?:,\s*(?:0?\.\d+|1(?:\.0*)?|\d+(?:\.\d*)?))?\s*\)$/.test(t),parse:t=>{const a=t.match(/^hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)%\s*,\s*(\d+(?:\.\d+)?)%\s*(?:,\s*([\d.]+))?\s*\)$/);if(!a)return null;let s=parseFloat(a[1])/360,r=parseFloat(a[2])/100,e=parseFloat(a[3])/100,o=a[4]?parseFloat(a[4]):1;const h=!!a[4];let n,i,d;if(0===r)n=i=d=e;else{const t=(t,a,s)=>(s<0&&(s+=1),s>1&&(s-=1),s<1/6?t+6*(a-t)*s:s<.5?a:s<2/3?t+(a-t)*(2/3-s)*6:t),a=e<.5?e*(1+r):e+r-e*r,o=2*e-a;n=t(o,a,s+1/3),i=t(o,a,s),d=t(o,a,s-1/3)}return{r:Math.round(255*n),g:Math.round(255*i),b:Math.round(255*d),a:o,hasAlpha:h}},toString:(t,a,s,r)=>{t/=255,a/=255,s/=255;const e=Math.max(t,a,s),o=Math.min(t,a,s);let h,n,i=(e+o)/2;if(e===o)h=n=0;else{const r=e-o;switch(n=i>.5?r/(2-e-o):r/(e+o),e){case t:h=(a-s)/r+(a<s?6:0);break;case a:h=(s-t)/r+2;break;case s:h=(t-a)/r+4}h/=6}return h=Math.round(360*h),n=Math.round(100*n),i=Math.round(100*i),r<1?`hsla(${h}, ${n}%, ${i}%, ${r})`:`hsl(${h}, ${n}%, ${i}%)`}},hwb:{detect:t=>/^hwb\(\s*(\d+(?:\.\d+)?)(?:deg)?\s+(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)%\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^hwb\(\s*(\d+(?:\.\d+)?)(?:deg)?\s+(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)%\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s,r,e,o=parseFloat(a[1]),h=parseFloat(a[2])/100,n=parseFloat(a[3])/100,i=a[4]?parseFloat(a[4]):1,d=1-h-n;if(d>0){let t=o/360,a=1-Math.abs(6*t%2-1),n=h+d*(1-a),i=h+d*a;t<1/6?(s=h+d,r=i,e=h):t<2/6?(s=n,r=h+d,e=h):t<.5?(s=h,r=h+d,e=i):t<4/6?(s=h,r=n,e=h+d):t<5/6?(s=i,r=h,e=h+d):(s=h+d,r=h,e=n)}else s=r=e=h;const l=!!a[4];return{r:Math.round(255*s),g:Math.round(255*r),b:Math.round(255*e),a:i,hasAlpha:l}},toString:(t,a,s,r)=>{t/=255,a/=255,s/=255;const e=Math.max(t,a,s),o=Math.min(t,a,s),h=e-o;let n=0;if(0!==h){switch(e){case t:n=(a-s)/h%6;break;case a:n=(s-t)/h+2;break;case s:n=(t-a)/h+4}n=Math.round(60*n),n<0&&(n+=360)}const i=Math.round(100*o),d=Math.round(100*(1-e));return r<1?`hwb(${n} ${i}% ${d}% / ${r})`:`hwb(${n} ${i}% ${d}%)`}},lab:{detect:t=>/^lab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^lab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=(100*s+16)/116,n=h+r/500,i=h-e/200,d=.95047*(n>.206893034?n*n*n:(n-16/116)/7.787),l=1*(h>.206893034?h*h*h:(h-16/116)/7.787),u=1.08883*(i>.206893034?i*i*i:(i-16/116)/7.787),p=3.2404542*d-1.5371385*l-.4985314*u,c=-.969266*d+1.8760108*l+.041556*u,M=.0556434*d-.2040259*l+1.0572252*u,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055,$=M<=.0031308?12.92*M:1.055*Math.pow(M,1/2.4)-.055;const g=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,m))),g:Math.round(255*Math.max(0,Math.min(1,f))),b:Math.round(255*Math.max(0,Math.min(1,$))),a:o,hasAlpha:g}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=(.4124564*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.3575761*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.1804375*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)))/.95047,o=(.2126729*t+.7151522*a+.072175*s)/1,h=(.0193339*t+.119192*a+.9503041*s)/1.08883,n=e>.008856?Math.pow(e,1/3):7.787*e+16/116,i=o>.008856?Math.pow(o,1/3):7.787*o+16/116,d=h>.008856?Math.pow(h,1/3):7.787*h+16/116,l=Math.round(100*(116*i-16))/100,u=Math.round(500*(n-i)*100)/100,p=Math.round(200*(i-d)*100)/100;return r<1?`lab(${l}% ${u} ${p} / ${r})`:`lab(${l}% ${u} ${p})`}},lch:{detect:t=>/^lch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^lch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1]),r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=(100*(s/100)+16)/116,n=h+r*Math.cos(e*Math.PI/180)/500,i=h-r*Math.sin(e*Math.PI/180)/200,d=.95047*(n>.206893034?n*n*n:(n-16/116)/7.787),l=1*(h>.206893034?h*h*h:(h-16/116)/7.787),u=1.08883*(i>.206893034?i*i*i:(i-16/116)/7.787),p=3.2404542*d-1.5371385*l-.4985314*u,c=-.969266*d+1.8760108*l+.041556*u,M=.0556434*d-.2040259*l+1.0572252*u,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055,$=M<=.0031308?12.92*M:1.055*Math.pow(M,1/2.4)-.055;const g=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,m))),g:Math.round(255*Math.max(0,Math.min(1,f))),b:Math.round(255*Math.max(0,Math.min(1,$))),a:o,hasAlpha:g}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=(.4124564*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.3575761*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.1804375*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)))/.95047,o=(.2126729*t+.7151522*a+.072175*s)/1,h=(.0193339*t+.119192*a+.9503041*s)/1.08883,n=e>.008856?Math.pow(e,1/3):7.787*e+16/116,i=o>.008856?Math.pow(o,1/3):7.787*o+16/116,d=(116*i-16)/100,l=500*(n-i),u=200*(i-(h>.008856?Math.pow(h,1/3):7.787*h+16/116)),p=Math.sqrt(l*l+u*u);let c=180*Math.atan2(u,l)/Math.PI;c<0&&(c+=360);const M=Math.round(100*d*100)/100,m=Math.round(100*p)/100,f=Math.round(100*c)/100;return r<1?`lch(${M}% ${m} ${f} / ${r})`:`lch(${M}% ${m} ${f})`}},oklab:{detect:t=>/^oklab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^oklab\(\s*(\d+(?:\.\d+)?)%\s+(-?\d+(?:\.\d+)?)\s+(-?\d+(?:\.\d+)?)\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=s+.3963377774*r+.2158037573*e,n=s-.1055613458*r-.0638541728*e,i=s-.0894841775*r-1.291485548*e,d=4.0767416621*h-3.3077115913*n+.2309699292*i,l=-1.2684380046*h+2.6097574011*n-.3413193965*i,u=-.0041960863*h-.7034186147*n+1.707614701*i,p=d<=.0031308?12.92*d:1.055*Math.pow(d,1/2.4)-.055,c=l<=.0031308?12.92*l:1.055*Math.pow(l,1/2.4)-.055,M=u<=.0031308?12.92*u:1.055*Math.pow(u,1/2.4)-.055;const m=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,p))),g:Math.round(255*Math.max(0,Math.min(1,c))),b:Math.round(255*Math.max(0,Math.min(1,M))),a:o,hasAlpha:m}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=.4122214708*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.5363325363*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.0514459929*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)),o=.2119034982*t+.6806995451*a+.1073969566*s,h=.0883024619*t+.2817188376*a+.6299787005*s,n=Math.pow(e,1/3),i=Math.pow(o,1/3),d=Math.pow(h,1/3),l=.2104542553*n+.793617785*i-.0040720468*d,u=1.9779984951*n-2.428592205*i+.4505937099*d,p=.0259040371*n+.7827717662*i-.808675766*d,c=Math.round(100*l*100)/100,M=Math.round(100*u)/100,m=Math.round(100*p)/100;return r<1?`oklab(${c}% ${M} ${m} / ${r})`:`oklab(${c}% ${M} ${m})`}},oklch:{detect:t=>/^oklch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i.test(t),parse:t=>{const a=t.match(/^oklch\(\s*(\d+(?:\.\d+)?)%\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)(?:deg)?\s*(?:\/\s*([\d.]+))?\s*\)$/i);if(!a)return null;let s=parseFloat(a[1])/100,r=parseFloat(a[2]),e=parseFloat(a[3]),o=a[4]?parseFloat(a[4]):1,h=r*Math.cos(e*Math.PI/180),n=r*Math.sin(e*Math.PI/180),i=s+.3963377774*h+.2158037573*n,d=s-.1055613458*h-.0638541728*n,l=s-.0894841775*h-1.291485548*n,u=4.0767416621*i-3.3077115913*d+.2309699292*l,p=-1.2684380046*i+2.6097574011*d-.3413193965*l,c=-.0041960863*i-.7034186147*d+1.707614701*l,M=u<=.0031308?12.92*u:1.055*Math.pow(u,1/2.4)-.055,m=p<=.0031308?12.92*p:1.055*Math.pow(p,1/2.4)-.055,f=c<=.0031308?12.92*c:1.055*Math.pow(c,1/2.4)-.055;const $=!!a[4];return{r:Math.round(255*Math.max(0,Math.min(1,M))),g:Math.round(255*Math.max(0,Math.min(1,m))),b:Math.round(255*Math.max(0,Math.min(1,f))),a:o,hasAlpha:$}},toString:(t,a,s,r)=>{a/=255,s/=255;const e=.4122214708*(t=(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4))+.5363325363*(a=a<=.04045?a/12.92:Math.pow((a+.055)/1.055,2.4))+.0514459929*(s=s<=.04045?s/12.92:Math.pow((s+.055)/1.055,2.4)),o=.2119034982*t+.6806995451*a+.1073969566*s,h=.0883024619*t+.2817188376*a+.6299787005*s,n=Math.pow(e,1/3),i=Math.pow(o,1/3),d=Math.pow(h,1/3),l=.2104542553*n+.793617785*i-.0040720468*d,u=1.9779984951*n-2.428592205*i+.4505937099*d,p=.0259040371*n+.7827717662*i-.808675766*d,c=Math.sqrt(u*u+p*p);let M=180*Math.atan2(p,u)/Math.PI;M<0&&(M+=360);const m=Math.round(100*l*100)/100,f=Math.round(100*c)/100,$=Math.round(100*M)/100;return r<1?`oklch(${m}% ${f} ${$} / ${r})`:`oklch(${m}% ${f} ${$})`}}}}window.customElements.define("k-color-picker",ColorPicker);
|
package/package.json
CHANGED
|
@@ -75,6 +75,29 @@ export default class ColorPicker extends ShadowComponent {
|
|
|
75
75
|
|
|
76
76
|
if(changedProperties.has('red') || changedProperties.has('green') || changedProperties.has('blue') || changedProperties.has('alpha') || changedProperties.has('format')){
|
|
77
77
|
this.updateFormValue();
|
|
78
|
+
this.syncInputs(changedProperties.has('format'));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
syncInputs(formatChanged = false){
|
|
83
|
+
const textInput = this.shadowRoot?.querySelector('#text');
|
|
84
|
+
const colorInput = this.shadowRoot?.querySelector('#color');
|
|
85
|
+
const formatSelect = this.shadowRoot?.querySelector('#format');
|
|
86
|
+
const activeElement = this.shadowRoot?.activeElement;
|
|
87
|
+
|
|
88
|
+
// Always update text input if format changed, otherwise only if not focused
|
|
89
|
+
if(textInput && (formatChanged || activeElement !== textInput)){
|
|
90
|
+
textInput.value = this.value;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Update color input if it's not focused
|
|
94
|
+
if(colorInput && activeElement !== colorInput){
|
|
95
|
+
colorInput.value = this.constructor.formats.hex.toString(this.red || 0, this.green || 0, this.blue || 0, 1);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Update format select if it's not focused
|
|
99
|
+
if(formatSelect && activeElement !== formatSelect){
|
|
100
|
+
formatSelect.value = this.format;
|
|
78
101
|
}
|
|
79
102
|
}
|
|
80
103
|
|
|
@@ -137,11 +160,42 @@ export default class ColorPicker extends ShadowComponent {
|
|
|
137
160
|
this.blue = parsed.b;
|
|
138
161
|
this.alpha = 1;
|
|
139
162
|
}
|
|
163
|
+
this.forwardEvent(event);
|
|
140
164
|
}
|
|
141
165
|
onTextInputChange(event){
|
|
142
166
|
this.value = event.target.value;
|
|
167
|
+
this.forwardEvent(event);
|
|
168
|
+
}
|
|
169
|
+
onTextInput(event){
|
|
170
|
+
this.value = event.target.value;
|
|
171
|
+
this.forwardEvent(event);
|
|
172
|
+
}
|
|
173
|
+
onColorInput(event){
|
|
174
|
+
const parsed = this.constructor.formats.hex.parse(event.target.value);
|
|
175
|
+
if (parsed) {
|
|
176
|
+
this.red = parsed.r;
|
|
177
|
+
this.green = parsed.g;
|
|
178
|
+
this.blue = parsed.b;
|
|
179
|
+
this.alpha = 1;
|
|
180
|
+
}
|
|
181
|
+
this.forwardEvent(event);
|
|
182
|
+
}
|
|
183
|
+
onFormatChange(event){
|
|
184
|
+
this.format = event.target.value;
|
|
185
|
+
this.forwardEvent(event);
|
|
186
|
+
}
|
|
187
|
+
onFormatInput(event){
|
|
188
|
+
this.format = event.target.value;
|
|
189
|
+
this.forwardEvent(event);
|
|
143
190
|
}
|
|
144
191
|
|
|
192
|
+
/*
|
|
193
|
+
Event Forwarding
|
|
194
|
+
*/
|
|
195
|
+
forwardEvent = (event) => {
|
|
196
|
+
this.dispatchEvent(new event.constructor(event.type, event));
|
|
197
|
+
};
|
|
198
|
+
|
|
145
199
|
/* Rendering */
|
|
146
200
|
render(){
|
|
147
201
|
return html`
|
|
@@ -149,7 +203,10 @@ export default class ColorPicker extends ShadowComponent {
|
|
|
149
203
|
<select
|
|
150
204
|
id="format"
|
|
151
205
|
value="${this.format}"
|
|
152
|
-
@change=${
|
|
206
|
+
@change=${this.onFormatChange}
|
|
207
|
+
@input=${this.onFormatInput}
|
|
208
|
+
@focus=${this.forwardEvent}
|
|
209
|
+
@blur=${this.forwardEvent}
|
|
153
210
|
>${
|
|
154
211
|
this.constructor.formats ? Object.keys(this.constructor.formats).map(formatName => html`<option value="${formatName}" ?selected=${this.format === formatName}>${formatName.toUpperCase()}</option>`) : null
|
|
155
212
|
}</select>
|
|
@@ -158,6 +215,9 @@ export default class ColorPicker extends ShadowComponent {
|
|
|
158
215
|
type="text"
|
|
159
216
|
value="${this.value}"
|
|
160
217
|
@change=${this.onTextInputChange}
|
|
218
|
+
@input=${this.onTextInput}
|
|
219
|
+
@focus=${this.forwardEvent}
|
|
220
|
+
@blur=${this.forwardEvent}
|
|
161
221
|
/>
|
|
162
222
|
<div id="color-wrapper">
|
|
163
223
|
<input
|
|
@@ -165,6 +225,9 @@ export default class ColorPicker extends ShadowComponent {
|
|
|
165
225
|
type="color"
|
|
166
226
|
value="${this.constructor.formats.hex.toString(this.red || 0, this.green || 0, this.blue || 0, 1)}"
|
|
167
227
|
@change=${this.onColorInputChange}
|
|
228
|
+
@input=${this.onColorInput}
|
|
229
|
+
@focus=${this.forwardEvent}
|
|
230
|
+
@blur=${this.forwardEvent}
|
|
168
231
|
/>
|
|
169
232
|
</div>
|
|
170
233
|
</div>
|
package/color-picker-fixed.png
DELETED
|
Binary file
|