pickit-color 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/colorpicker.css +59 -5
- package/dist/colorpicker.js +121 -24
- package/dist/colorpicker.min.css +1 -1
- package/dist/colorpicker.min.js +2 -2
- package/dist/esm/index.js +114 -18
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/index.d.ts +5 -0
- package/package.json +5 -3
- package/src/colorpicker.styl +41 -5
- package/src/index.ts +139 -22
package/src/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export interface ColorPickerOptions {
|
|
|
17
17
|
inline?: boolean;
|
|
18
18
|
compact?: boolean;
|
|
19
19
|
inputPreview?: boolean;
|
|
20
|
+
previewTarget?: string;
|
|
21
|
+
previewProperty?: string;
|
|
20
22
|
onChange?: (color: string) => void;
|
|
21
23
|
onOpen?: () => void;
|
|
22
24
|
onClose?: () => void;
|
|
@@ -103,6 +105,8 @@ export class ColorPicker {
|
|
|
103
105
|
inline: options.inline ?? false,
|
|
104
106
|
compact: options.compact ?? false,
|
|
105
107
|
inputPreview: options.inputPreview ?? false,
|
|
108
|
+
previewTarget: options.previewTarget || "",
|
|
109
|
+
previewProperty: options.previewProperty || "background-color",
|
|
106
110
|
onChange: options.onChange || (() => {}),
|
|
107
111
|
onOpen: options.onOpen || (() => {}),
|
|
108
112
|
onClose: options.onClose || (() => {}),
|
|
@@ -147,9 +151,11 @@ export class ColorPicker {
|
|
|
147
151
|
// Update display
|
|
148
152
|
this.updateColorDisplay();
|
|
149
153
|
|
|
150
|
-
// Open if inline
|
|
151
|
-
if (this.options.inline) {
|
|
152
|
-
this.
|
|
154
|
+
// Open if inline (without scrolling)
|
|
155
|
+
if (this.options.inline && this.container) {
|
|
156
|
+
this.isOpen = true;
|
|
157
|
+
this.container.style.display = "block";
|
|
158
|
+
this.options.onOpen();
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
|
|
@@ -518,6 +524,9 @@ export class ColorPicker {
|
|
|
518
524
|
this.updateColorDisplay();
|
|
519
525
|
this.announceColorChange();
|
|
520
526
|
});
|
|
527
|
+
this.hueSlider.addEventListener("touchstart", (e) => {
|
|
528
|
+
this.handleSliderTouch(e, this.hueSlider!, 'h', 0, 360);
|
|
529
|
+
});
|
|
521
530
|
}
|
|
522
531
|
|
|
523
532
|
// Saturation slider (sliderMode only)
|
|
@@ -527,6 +536,9 @@ export class ColorPicker {
|
|
|
527
536
|
this.updateColorDisplay();
|
|
528
537
|
this.announceColorChange();
|
|
529
538
|
});
|
|
539
|
+
this.saturationSlider.addEventListener("touchstart", (e) => {
|
|
540
|
+
this.handleSliderTouch(e, this.saturationSlider!, 's', 0, 100);
|
|
541
|
+
});
|
|
530
542
|
}
|
|
531
543
|
|
|
532
544
|
// Lightness slider (sliderMode only)
|
|
@@ -536,6 +548,9 @@ export class ColorPicker {
|
|
|
536
548
|
this.updateColorDisplay();
|
|
537
549
|
this.announceColorChange();
|
|
538
550
|
});
|
|
551
|
+
this.lightnessSlider.addEventListener("touchstart", (e) => {
|
|
552
|
+
this.handleSliderTouch(e, this.lightnessSlider!, 'l', 0, 100);
|
|
553
|
+
});
|
|
539
554
|
}
|
|
540
555
|
|
|
541
556
|
// Alpha slider
|
|
@@ -546,6 +561,9 @@ export class ColorPicker {
|
|
|
546
561
|
this.updateColorDisplay();
|
|
547
562
|
this.announceColorChange();
|
|
548
563
|
});
|
|
564
|
+
this.alphaSlider.addEventListener("touchstart", (e) => {
|
|
565
|
+
this.handleSliderTouch(e, this.alphaSlider!, 'a', 0, 100, true);
|
|
566
|
+
});
|
|
549
567
|
}
|
|
550
568
|
|
|
551
569
|
// Saturation box
|
|
@@ -553,6 +571,9 @@ export class ColorPicker {
|
|
|
553
571
|
this.colorBox.addEventListener("mousedown", (e) =>
|
|
554
572
|
this.onSaturationMouseDown(e)
|
|
555
573
|
);
|
|
574
|
+
this.colorBox.addEventListener("touchstart", (e) =>
|
|
575
|
+
this.onSaturationTouchStart(e)
|
|
576
|
+
);
|
|
556
577
|
this.colorBox.addEventListener("keydown", (e) =>
|
|
557
578
|
this.onSaturationKeyDown(e)
|
|
558
579
|
);
|
|
@@ -706,6 +727,83 @@ export class ColorPicker {
|
|
|
706
727
|
document.addEventListener("mouseup", onMouseUp);
|
|
707
728
|
}
|
|
708
729
|
|
|
730
|
+
private onSaturationTouchStart(e: TouchEvent): void {
|
|
731
|
+
e.preventDefault();
|
|
732
|
+
const touch = e.touches[0];
|
|
733
|
+
this.updateSaturationFromTouch(touch);
|
|
734
|
+
|
|
735
|
+
const onTouchMove = (e: TouchEvent) => {
|
|
736
|
+
e.preventDefault();
|
|
737
|
+
const touch = e.touches[0];
|
|
738
|
+
this.updateSaturationFromTouch(touch);
|
|
739
|
+
};
|
|
740
|
+
|
|
741
|
+
const onTouchEnd = () => {
|
|
742
|
+
document.removeEventListener("touchmove", onTouchMove);
|
|
743
|
+
document.removeEventListener("touchend", onTouchEnd);
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
document.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
747
|
+
document.addEventListener("touchend", onTouchEnd);
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
private updateSaturationFromTouch(touch: Touch): void {
|
|
751
|
+
if (!this.colorBox) return;
|
|
752
|
+
|
|
753
|
+
const rect = this.colorBox.getBoundingClientRect();
|
|
754
|
+
const x = Math.max(0, Math.min(touch.clientX - rect.left, rect.width));
|
|
755
|
+
const y = Math.max(0, Math.min(touch.clientY - rect.top, rect.height));
|
|
756
|
+
|
|
757
|
+
this.currentColor.s = (x / rect.width) * 100;
|
|
758
|
+
this.currentColor.l = 100 - (y / rect.height) * 100;
|
|
759
|
+
|
|
760
|
+
this.updateColorDisplay();
|
|
761
|
+
this.announceColorChange();
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
private handleSliderTouch(
|
|
765
|
+
e: TouchEvent,
|
|
766
|
+
slider: HTMLInputElement,
|
|
767
|
+
property: 'h' | 's' | 'l' | 'a',
|
|
768
|
+
min: number,
|
|
769
|
+
max: number,
|
|
770
|
+
isAlpha: boolean = false
|
|
771
|
+
): void {
|
|
772
|
+
const updateFromTouch = (touch: Touch) => {
|
|
773
|
+
const rect = slider.getBoundingClientRect();
|
|
774
|
+
const x = Math.max(0, Math.min(touch.clientX - rect.left, rect.width));
|
|
775
|
+
const ratio = x / rect.width;
|
|
776
|
+
const value = min + ratio * (max - min);
|
|
777
|
+
|
|
778
|
+
if (isAlpha) {
|
|
779
|
+
this.currentColor[property] = value / 100;
|
|
780
|
+
} else {
|
|
781
|
+
this.currentColor[property] = Math.round(value);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
slider.value = String(Math.round(value));
|
|
785
|
+
this.updateColorDisplay();
|
|
786
|
+
this.announceColorChange();
|
|
787
|
+
};
|
|
788
|
+
|
|
789
|
+
const touch = e.touches[0];
|
|
790
|
+
updateFromTouch(touch);
|
|
791
|
+
|
|
792
|
+
const onTouchMove = (e: TouchEvent) => {
|
|
793
|
+
e.preventDefault();
|
|
794
|
+
const touch = e.touches[0];
|
|
795
|
+
updateFromTouch(touch);
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
const onTouchEnd = () => {
|
|
799
|
+
document.removeEventListener("touchmove", onTouchMove);
|
|
800
|
+
document.removeEventListener("touchend", onTouchEnd);
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
document.addEventListener("touchmove", onTouchMove, { passive: false });
|
|
804
|
+
document.addEventListener("touchend", onTouchEnd);
|
|
805
|
+
}
|
|
806
|
+
|
|
709
807
|
private updateSaturationFromMouse(e: MouseEvent): void {
|
|
710
808
|
if (!this.colorBox) return;
|
|
711
809
|
|
|
@@ -804,6 +902,15 @@ export class ColorPicker {
|
|
|
804
902
|
this.input.value = this.formatColor(this.currentColor);
|
|
805
903
|
this.options.onChange(this.input.value);
|
|
806
904
|
|
|
905
|
+
// Update preview target if configured
|
|
906
|
+
if (this.options.previewTarget) {
|
|
907
|
+
const target = document.querySelector(this.options.previewTarget) as HTMLElement;
|
|
908
|
+
if (target) {
|
|
909
|
+
const property = this.options.previewProperty || 'background-color';
|
|
910
|
+
target.style.setProperty(property, this.input.value);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
|
|
807
914
|
// Update compact button preview
|
|
808
915
|
if (this.compactButton) {
|
|
809
916
|
const preview = this.compactButton.querySelector('.colorpicker-compact-preview') as HTMLElement;
|
|
@@ -1038,25 +1145,27 @@ export class ColorPicker {
|
|
|
1038
1145
|
|
|
1039
1146
|
this.options.onOpen();
|
|
1040
1147
|
|
|
1041
|
-
//
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
focusTarget
|
|
1058
|
-
|
|
1059
|
-
|
|
1148
|
+
// Auto-focus only for popup mode, not inline
|
|
1149
|
+
if (!this.options.inline) {
|
|
1150
|
+
setTimeout(() => {
|
|
1151
|
+
let focusTarget: HTMLElement | null = null;
|
|
1152
|
+
|
|
1153
|
+
if (this.options.presetsOnly) {
|
|
1154
|
+
// In presets-only mode, focus first preset
|
|
1155
|
+
focusTarget = this.container?.querySelector('.colorpicker-preset') as HTMLElement;
|
|
1156
|
+
} else if (this.options.sliderMode) {
|
|
1157
|
+
// In slider mode, focus first slider (hue)
|
|
1158
|
+
focusTarget = this.hueSlider;
|
|
1159
|
+
} else {
|
|
1160
|
+
// In standard mode, focus saturation box
|
|
1161
|
+
focusTarget = this.colorBox;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
if (focusTarget) {
|
|
1165
|
+
focusTarget.focus();
|
|
1166
|
+
}
|
|
1167
|
+
}, 0);
|
|
1168
|
+
}
|
|
1060
1169
|
}
|
|
1061
1170
|
|
|
1062
1171
|
public close(): void {
|
|
@@ -1209,6 +1318,14 @@ export function initColorPickers(root: Document | HTMLElement = document): Color
|
|
|
1209
1318
|
case 'inputPreview':
|
|
1210
1319
|
options.inputPreview = value === 'true' || value === '1';
|
|
1211
1320
|
break;
|
|
1321
|
+
case 'target':
|
|
1322
|
+
case 'previewTarget':
|
|
1323
|
+
options.previewTarget = value;
|
|
1324
|
+
break;
|
|
1325
|
+
case 'property':
|
|
1326
|
+
case 'previewProperty':
|
|
1327
|
+
options.previewProperty = value;
|
|
1328
|
+
break;
|
|
1212
1329
|
}
|
|
1213
1330
|
});
|
|
1214
1331
|
}
|