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/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.open();
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
- // Focus first interactive element based on mode
1042
- setTimeout(() => {
1043
- let focusTarget: HTMLElement | null = null;
1044
-
1045
- if (this.options.presetsOnly) {
1046
- // In presets-only mode, focus first preset
1047
- focusTarget = this.container?.querySelector('.colorpicker-preset') as HTMLElement;
1048
- } else if (this.options.sliderMode) {
1049
- // In slider mode, focus first slider (hue)
1050
- focusTarget = this.hueSlider;
1051
- } else {
1052
- // In standard mode, focus saturation box
1053
- focusTarget = this.colorBox;
1054
- }
1055
-
1056
- if (focusTarget) {
1057
- focusTarget.focus();
1058
- }
1059
- }, 0);
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
  }