@ben-million/tweaker 0.7.1 → 0.8.1
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/dist/index.d.ts.map +1 -1
- package/dist/index.js +211 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/tweaker.tsx","../src/gray-scales.ts"],"mappings":";;;UAEiB,SAAA;EACf,KAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/types.ts","../src/tweaker.tsx","../src/gray-scales.ts"],"mappings":";;;UAEiB,SAAA;EACf,KAAA;EACA,MAAA,EAAQ,MAAA;AAAA;AAAA,UA0BO,YAAA;EACf,MAAA,GAAS,MAAA,SAAe,SAAA;EACxB,WAAA;AAAA;;;cCRW,OAAA;EAAW,MAAA;EAAA;AAAA,GAAmD,YAAA,KAAY,kBAAA,CAAA,GAAA,CAAA,OAAA;;;cCtB1E,WAAA,EAAa,MAAA,SAAe,SAAA"}
|
package/dist/index.js
CHANGED
|
@@ -146,6 +146,7 @@ const MOUSE_PADDING_SENSITIVITY = .2;
|
|
|
146
146
|
const MINIMAP_WIDTH_PX = 160;
|
|
147
147
|
const MINIMAP_HEIGHT_PX = 100;
|
|
148
148
|
const THUMB_SIZE_PX = 10;
|
|
149
|
+
const NEARBY_SAMPLE_OFFSET_PX = 20;
|
|
149
150
|
|
|
150
151
|
//#endregion
|
|
151
152
|
//#region src/utils/color.ts
|
|
@@ -262,6 +263,8 @@ const applyModification = (modification, scales, scaleKey) => {
|
|
|
262
263
|
modification.element.style.paddingBottom = `${Math.max(0, paddingY)}px`;
|
|
263
264
|
modification.element.style.marginTop = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginTop;
|
|
264
265
|
modification.element.style.marginBottom = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginBottom;
|
|
266
|
+
if (modification.translateX !== 0 || modification.translateY !== 0) modification.element.style.transform = `translate(${modification.translateX}px, ${modification.translateY}px)`;
|
|
267
|
+
else modification.element.style.transform = modification.originalInlineTransform;
|
|
265
268
|
};
|
|
266
269
|
const restoreModification = (modification) => {
|
|
267
270
|
modification.element.style.backgroundColor = modification.originalInlineBg;
|
|
@@ -272,19 +275,43 @@ const restoreModification = (modification) => {
|
|
|
272
275
|
modification.element.style.paddingBottom = modification.originalInlinePaddingBottom;
|
|
273
276
|
modification.element.style.marginTop = modification.originalInlineMarginTop;
|
|
274
277
|
modification.element.style.marginBottom = modification.originalInlineMarginBottom;
|
|
278
|
+
modification.element.style.transform = modification.originalInlineTransform;
|
|
275
279
|
};
|
|
276
280
|
const roundToStep = (value) => parseFloat((Math.round(value * 10) / 10).toFixed(1));
|
|
277
281
|
const roundToHalf = (value) => Math.round(value * 2) / 2;
|
|
278
282
|
|
|
279
283
|
//#endregion
|
|
280
284
|
//#region src/utils/prompt.ts
|
|
281
|
-
const
|
|
285
|
+
const getLayoutContext = (element) => {
|
|
286
|
+
const parent = element.parentElement;
|
|
287
|
+
if (!parent) return "no parent";
|
|
288
|
+
const style = getComputedStyle(parent);
|
|
289
|
+
const display = style.display;
|
|
290
|
+
const parts = [display];
|
|
291
|
+
if (display === "flex" || display === "inline-flex") {
|
|
292
|
+
parts.push(style.flexDirection);
|
|
293
|
+
if (style.gap && style.gap !== "normal" && style.gap !== "0px") parts.push(`gap: ${style.gap}`);
|
|
294
|
+
}
|
|
295
|
+
if (display === "grid" || display === "inline-grid") {
|
|
296
|
+
if (style.gap && style.gap !== "normal" && style.gap !== "0px") parts.push(`gap: ${style.gap}`);
|
|
297
|
+
}
|
|
298
|
+
return parts.join(", ");
|
|
299
|
+
};
|
|
300
|
+
const describeElement = (info) => {
|
|
301
|
+
const nameParts = [];
|
|
302
|
+
if (info.componentName) nameParts.push(`<${info.componentName}>`);
|
|
303
|
+
nameParts.push(info.selector);
|
|
304
|
+
if (info.textPreview) nameParts.push(`("${info.textPreview}")`);
|
|
305
|
+
return nameParts.join(" ");
|
|
306
|
+
};
|
|
307
|
+
const generatePrompt = (modifications, scales, scaleKey, nearbyElements) => {
|
|
282
308
|
if (modifications.length === 0) return "";
|
|
283
309
|
const scaleName = scales[scaleKey]?.label || scaleKey;
|
|
284
310
|
const colorLines = [];
|
|
285
311
|
const sizeLines = [];
|
|
286
312
|
const paddingLines = [];
|
|
287
|
-
|
|
313
|
+
const positionLines = [];
|
|
314
|
+
modifications.forEach((modification, index) => {
|
|
288
315
|
const nameParts = [modification.selector];
|
|
289
316
|
if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);
|
|
290
317
|
if (modification.textPreview) nameParts.push(`("${modification.textPreview}")`);
|
|
@@ -298,6 +325,19 @@ const generatePrompt = (modifications, scales, scaleKey) => {
|
|
|
298
325
|
if (modification.sourceFile) sizeLines.push(` Source: ${modification.sourceFile}`);
|
|
299
326
|
paddingLines.push(`- vertical padding of ${description} → ${Math.round(modification.paddingY)}px`);
|
|
300
327
|
if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);
|
|
328
|
+
if (modification.translateX !== 0 || modification.translateY !== 0) {
|
|
329
|
+
positionLines.push(`- move ${description}`);
|
|
330
|
+
positionLines.push(` Parent layout: ${getLayoutContext(modification.element)}`);
|
|
331
|
+
if (modification.sourceFile) positionLines.push(` Source: ${modification.sourceFile}`);
|
|
332
|
+
const nearby = nearbyElements?.get(index);
|
|
333
|
+
if (nearby && nearby.length > 0) {
|
|
334
|
+
positionLines.push(" Place it near these elements at the target position:");
|
|
335
|
+
for (const element of nearby) {
|
|
336
|
+
positionLines.push(` - ${element.label}: ${describeElement(element)}`);
|
|
337
|
+
if (element.sourceFile) positionLines.push(` Source: ${element.sourceFile}`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
301
341
|
});
|
|
302
342
|
const sections = [];
|
|
303
343
|
if (colorLines.length > 0) sections.push("Change the following colors using the design system's gray scale:", "", ...colorLines);
|
|
@@ -309,9 +349,85 @@ const generatePrompt = (modifications, scales, scaleKey) => {
|
|
|
309
349
|
if (sections.length > 0) sections.push("");
|
|
310
350
|
sections.push("Change the following padding:", "", ...paddingLines);
|
|
311
351
|
}
|
|
352
|
+
if (positionLines.length > 0) {
|
|
353
|
+
if (sections.length > 0) sections.push("");
|
|
354
|
+
sections.push("Reposition the following elements (use canonical CSS like margin, padding, gap, or flexbox order — do NOT use CSS transforms):", "", ...positionLines);
|
|
355
|
+
}
|
|
312
356
|
return sections.join("\n");
|
|
313
357
|
};
|
|
314
358
|
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region src/utils/nearby.ts
|
|
361
|
+
const getReactGrabModule = () => {
|
|
362
|
+
const module = window.__REACT_GRAB_MODULE__;
|
|
363
|
+
if (module && typeof module.getStack === "function") return module;
|
|
364
|
+
return null;
|
|
365
|
+
};
|
|
366
|
+
const getSourceFromStack = async (element, reactGrab) => {
|
|
367
|
+
try {
|
|
368
|
+
const stack = await reactGrab.getStack(element);
|
|
369
|
+
if (stack) {
|
|
370
|
+
for (const frame of stack) if (frame.fileName && !frame.fileName.includes("node_modules")) return {
|
|
371
|
+
sourceFile: frame.fileName,
|
|
372
|
+
componentName: frame.functionName && /^[A-Z]/.test(frame.functionName) ? frame.functionName : null
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
} catch {}
|
|
376
|
+
return {
|
|
377
|
+
componentName: null,
|
|
378
|
+
sourceFile: null
|
|
379
|
+
};
|
|
380
|
+
};
|
|
381
|
+
const findNearbyElements = async (draggedElement) => {
|
|
382
|
+
const rect = draggedElement.getBoundingClientRect();
|
|
383
|
+
const centerX = rect.left + rect.width / 2;
|
|
384
|
+
const samplePoints = [
|
|
385
|
+
{
|
|
386
|
+
y: rect.top - NEARBY_SAMPLE_OFFSET_PX,
|
|
387
|
+
label: "above"
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
y: rect.top + rect.height / 2,
|
|
391
|
+
label: "at"
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
y: rect.bottom + NEARBY_SAMPLE_OFFSET_PX,
|
|
395
|
+
label: "below"
|
|
396
|
+
}
|
|
397
|
+
];
|
|
398
|
+
const reactGrab = getReactGrabModule();
|
|
399
|
+
const seen = /* @__PURE__ */ new Set();
|
|
400
|
+
seen.add(draggedElement);
|
|
401
|
+
const results = [];
|
|
402
|
+
for (const point of samplePoints) {
|
|
403
|
+
const elements = document.elementsFromPoint(centerX, point.y);
|
|
404
|
+
for (const element of elements) {
|
|
405
|
+
if (!(element instanceof HTMLElement)) continue;
|
|
406
|
+
if (seen.has(element)) continue;
|
|
407
|
+
if (element.contains(draggedElement) || draggedElement.contains(element)) continue;
|
|
408
|
+
if (element.closest("[data-tweaker]")) continue;
|
|
409
|
+
if (element.tagName === "HTML" || element.tagName === "BODY") continue;
|
|
410
|
+
seen.add(element);
|
|
411
|
+
let componentName = null;
|
|
412
|
+
let sourceFile = null;
|
|
413
|
+
if (reactGrab) {
|
|
414
|
+
const source = await getSourceFromStack(element, reactGrab);
|
|
415
|
+
componentName = source.componentName;
|
|
416
|
+
sourceFile = source.sourceFile;
|
|
417
|
+
}
|
|
418
|
+
results.push({
|
|
419
|
+
label: point.label,
|
|
420
|
+
selector: getSelector(element),
|
|
421
|
+
textPreview: getTextPreview(element),
|
|
422
|
+
componentName,
|
|
423
|
+
sourceFile
|
|
424
|
+
});
|
|
425
|
+
break;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return results;
|
|
429
|
+
};
|
|
430
|
+
|
|
315
431
|
//#endregion
|
|
316
432
|
//#region src/tweaker.tsx
|
|
317
433
|
const requestLock = () => {
|
|
@@ -327,6 +443,7 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
327
443
|
const [inputValue, setInputValue] = useState("");
|
|
328
444
|
const [shiftHeld, setShiftHeld] = useState(false);
|
|
329
445
|
const [spaceHeld, setSpaceHeld] = useState(false);
|
|
446
|
+
const [controlHeld, setControlHeld] = useState(false);
|
|
330
447
|
const typingBuffer = useRef("");
|
|
331
448
|
const typingTimeout = useRef(void 0);
|
|
332
449
|
const activeMod = activeIndex >= 0 ? modifications[activeIndex] : null;
|
|
@@ -359,10 +476,12 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
359
476
|
const handleKeyDown = (event) => {
|
|
360
477
|
setShiftHeld(event.shiftKey);
|
|
361
478
|
if (event.key === " ") setSpaceHeld(true);
|
|
479
|
+
if (event.key === "Control") setControlHeld(true);
|
|
362
480
|
};
|
|
363
481
|
const handleKeyUp = (event) => {
|
|
364
482
|
setShiftHeld(event.shiftKey);
|
|
365
483
|
if (event.key === " ") setSpaceHeld(false);
|
|
484
|
+
if (event.key === "Control") setControlHeld(false);
|
|
366
485
|
};
|
|
367
486
|
document.addEventListener("keydown", handleKeyDown);
|
|
368
487
|
document.addEventListener("keyup", handleKeyUp);
|
|
@@ -377,11 +496,15 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
377
496
|
if (!document.pointerLockElement) return;
|
|
378
497
|
const index = activeIndexRef.current;
|
|
379
498
|
if (index < 0) return;
|
|
380
|
-
const isPadding = event.shiftKey;
|
|
381
499
|
setModifications((previous) => {
|
|
382
500
|
const updated = [...previous];
|
|
383
501
|
const current = updated[index];
|
|
384
|
-
if (
|
|
502
|
+
if (event.ctrlKey) updated[index] = {
|
|
503
|
+
...current,
|
|
504
|
+
translateX: current.translateX + event.movementX,
|
|
505
|
+
translateY: current.translateY + event.movementY
|
|
506
|
+
};
|
|
507
|
+
else if (event.shiftKey) {
|
|
385
508
|
const newPaddingY = Math.max(PADDING_MIN_PX, Math.min(PADDING_MAX_PX, current.paddingY - event.movementY * MOUSE_PADDING_SENSITIVITY));
|
|
386
509
|
updated[index] = {
|
|
387
510
|
...current,
|
|
@@ -408,13 +531,25 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
408
531
|
releaseLock();
|
|
409
532
|
};
|
|
410
533
|
}, [hasModifications, picking]);
|
|
534
|
+
const gatherNearbyElements = async (modifications) => {
|
|
535
|
+
const nearbyMap = /* @__PURE__ */ new Map();
|
|
536
|
+
for (let index = 0; index < modifications.length; index++) {
|
|
537
|
+
const modification = modifications[index];
|
|
538
|
+
if (modification.translateX !== 0 || modification.translateY !== 0) {
|
|
539
|
+
const nearby = await findNearbyElements(modification.element);
|
|
540
|
+
nearbyMap.set(index, nearby);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
return nearbyMap;
|
|
544
|
+
};
|
|
411
545
|
useEffect(() => {
|
|
412
546
|
if (!hasModifications) return;
|
|
413
|
-
const handleKeyDown = (event) => {
|
|
547
|
+
const handleKeyDown = async (event) => {
|
|
414
548
|
if (event.key === "Escape") {
|
|
415
549
|
event.preventDefault();
|
|
416
550
|
releaseLock();
|
|
417
|
-
const
|
|
551
|
+
const nearbyMap = await gatherNearbyElements(modificationsRef.current);
|
|
552
|
+
const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, nearbyMap);
|
|
418
553
|
navigator.clipboard.writeText(prompt);
|
|
419
554
|
modificationsRef.current.forEach(restoreModification);
|
|
420
555
|
setModifications([]);
|
|
@@ -424,7 +559,8 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
424
559
|
if (event.key === "Enter") {
|
|
425
560
|
event.preventDefault();
|
|
426
561
|
releaseLock();
|
|
427
|
-
const
|
|
562
|
+
const nearbyMap = await gatherNearbyElements(modificationsRef.current);
|
|
563
|
+
const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, nearbyMap);
|
|
428
564
|
navigator.clipboard.writeText(prompt);
|
|
429
565
|
setPicking(true);
|
|
430
566
|
}
|
|
@@ -550,7 +686,7 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
550
686
|
target.style.outlineOffset = "";
|
|
551
687
|
if (hoveredElement === target) hoveredElement = null;
|
|
552
688
|
};
|
|
553
|
-
const handleClick = (event) => {
|
|
689
|
+
const handleClick = async (event) => {
|
|
554
690
|
event.preventDefault();
|
|
555
691
|
event.stopPropagation();
|
|
556
692
|
const target = event.target;
|
|
@@ -566,11 +702,26 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
566
702
|
const position = findClosestPosition(scales, activeScale, defaultProperty === "bg" ? rgbToOklch(bgRed, bgGreen, bgBlue) : defaultProperty === "border" ? rgbToOklch(borderRed, borderGreen, borderBlue) : rgbToOklch(textRed, textGreen, textBlue));
|
|
567
703
|
const currentSize = parseFloat(computed.fontSize) || 16;
|
|
568
704
|
const currentPaddingY = parseFloat(computed.paddingTop) || 0;
|
|
705
|
+
let componentName = null;
|
|
706
|
+
let sourceFile = null;
|
|
707
|
+
try {
|
|
708
|
+
const reactGrab = window.__REACT_GRAB_MODULE__;
|
|
709
|
+
if (reactGrab?.getStack) {
|
|
710
|
+
const stack = await reactGrab.getStack(target);
|
|
711
|
+
if (stack) {
|
|
712
|
+
for (const frame of stack) if (frame.fileName && !frame.fileName.includes("node_modules")) {
|
|
713
|
+
sourceFile = frame.fileName;
|
|
714
|
+
if (frame.functionName && /^[A-Z]/.test(frame.functionName)) componentName = frame.functionName;
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
} catch {}
|
|
569
720
|
const newModification = {
|
|
570
721
|
element: target,
|
|
571
722
|
selector: getSelector(target),
|
|
572
|
-
componentName
|
|
573
|
-
sourceFile
|
|
723
|
+
componentName,
|
|
724
|
+
sourceFile,
|
|
574
725
|
textPreview: getTextPreview(target),
|
|
575
726
|
originalInlineBg: target.style.backgroundColor,
|
|
576
727
|
originalInlineColor: target.style.color,
|
|
@@ -580,10 +731,13 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
580
731
|
originalInlinePaddingBottom: target.style.paddingBottom,
|
|
581
732
|
originalInlineMarginTop: target.style.marginTop,
|
|
582
733
|
originalInlineMarginBottom: target.style.marginBottom,
|
|
734
|
+
originalInlineTransform: target.style.transform,
|
|
583
735
|
property: defaultProperty,
|
|
584
736
|
position,
|
|
585
737
|
fontSize: currentSize,
|
|
586
|
-
paddingY: currentPaddingY
|
|
738
|
+
paddingY: currentPaddingY,
|
|
739
|
+
translateX: 0,
|
|
740
|
+
translateY: 0
|
|
587
741
|
};
|
|
588
742
|
setModifications((previous) => [...previous, newModification]);
|
|
589
743
|
setActiveIndex(modifications.length);
|
|
@@ -611,6 +765,7 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
611
765
|
const fillColor = activeMod ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position)) : scales[activeScale]?.shades["500"] ?? "rgba(255,255,255,0.3)";
|
|
612
766
|
const propertyLabel = activeMod?.property === "text" ? "F" : activeMod?.property === "border" ? "D" : "B";
|
|
613
767
|
const isPaddingMode = shiftHeld && hasModifications && !picking;
|
|
768
|
+
const isDragMode = controlHeld && hasModifications && !picking;
|
|
614
769
|
const guideRect = activeMod && !picking && !spaceHeld ? activeMod.element.getBoundingClientRect() : null;
|
|
615
770
|
const thumbX = activeMod ? isPaddingMode ? (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) / 2 : (activeMod.fontSize - FONT_SIZE_MIN_PX) / (FONT_SIZE_MAX_PX - FONT_SIZE_MIN_PX) * (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) : 0;
|
|
616
771
|
const thumbY = activeMod ? isPaddingMode ? (1 - (activeMod.paddingY - PADDING_MIN_PX) / (PADDING_MAX_PX - PADDING_MIN_PX)) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX) : (1 - activeMod.position / SLIDER_MAX) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX) : MINIMAP_HEIGHT_PX - THUMB_SIZE_PX;
|
|
@@ -655,21 +810,36 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
655
810
|
gap: 4,
|
|
656
811
|
pointerEvents: "none"
|
|
657
812
|
},
|
|
658
|
-
children: [
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
813
|
+
children: [
|
|
814
|
+
/* @__PURE__ */ jsxs("span", {
|
|
815
|
+
style: guidelineLabelStyle,
|
|
816
|
+
children: [
|
|
817
|
+
"↕ ",
|
|
818
|
+
activeMod.paddingY,
|
|
819
|
+
"px"
|
|
820
|
+
]
|
|
821
|
+
}),
|
|
822
|
+
/* @__PURE__ */ jsxs("span", {
|
|
823
|
+
style: {
|
|
824
|
+
...guidelineLabelStyle,
|
|
825
|
+
color: "rgba(59, 130, 246, 0.8)",
|
|
826
|
+
background: "rgba(59, 130, 246, 0.06)"
|
|
827
|
+
},
|
|
828
|
+
children: [activeMod.fontSize, "px"]
|
|
829
|
+
}),
|
|
830
|
+
(activeMod.translateX !== 0 || activeMod.translateY !== 0) && /* @__PURE__ */ jsxs("span", {
|
|
831
|
+
style: {
|
|
832
|
+
...guidelineLabelStyle,
|
|
833
|
+
color: "rgba(168, 85, 247, 0.9)",
|
|
834
|
+
background: "rgba(168, 85, 247, 0.08)"
|
|
835
|
+
},
|
|
836
|
+
children: [
|
|
837
|
+
Math.round(activeMod.translateX),
|
|
838
|
+
", ",
|
|
839
|
+
Math.round(activeMod.translateY)
|
|
840
|
+
]
|
|
841
|
+
})
|
|
842
|
+
]
|
|
673
843
|
})
|
|
674
844
|
]
|
|
675
845
|
}), /* @__PURE__ */ jsx(AnimatePresence, { children: (hasModifications || picking) && /* @__PURE__ */ jsxs(motion.div, {
|
|
@@ -708,18 +878,25 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
708
878
|
style: minimapModeStyle,
|
|
709
879
|
children: /* @__PURE__ */ jsx("span", {
|
|
710
880
|
style: minimapLabelStyle,
|
|
711
|
-
children: isPaddingMode ? "⇧ Padding" : "Style"
|
|
881
|
+
children: isDragMode ? "⌃ Move" : isPaddingMode ? "⇧ Padding" : "Style"
|
|
712
882
|
})
|
|
713
883
|
}),
|
|
714
884
|
/* @__PURE__ */ jsxs("div", {
|
|
715
885
|
style: minimapValuesStyle,
|
|
716
|
-
children: [
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
886
|
+
children: [
|
|
887
|
+
/* @__PURE__ */ jsx("span", {
|
|
888
|
+
style: minimapLabelStyle,
|
|
889
|
+
children: picking ? "Picking…" : isDragMode ? `x: ${activeMod?.translateX ?? 0}` : isPaddingMode ? `↕ ${activeMod?.paddingY ?? 0}px` : `${propertyLabel} ${inputValue || "0"}`
|
|
890
|
+
}),
|
|
891
|
+
!picking && activeMod && isDragMode && /* @__PURE__ */ jsx("span", {
|
|
892
|
+
style: minimapLabelStyle,
|
|
893
|
+
children: `y: ${activeMod.translateY}`
|
|
894
|
+
}),
|
|
895
|
+
!picking && activeMod && !isPaddingMode && !isDragMode && /* @__PURE__ */ jsx("span", {
|
|
896
|
+
style: minimapLabelStyle,
|
|
897
|
+
children: `${activeMod.fontSize}px`
|
|
898
|
+
})
|
|
899
|
+
]
|
|
723
900
|
})
|
|
724
901
|
]
|
|
725
902
|
}, "minimap") })] });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/gray-scales.ts","../src/constants.ts","../src/utils/color.ts","../src/utils/dom.ts","../src/utils/modification.ts","../src/utils/prompt.ts","../src/tweaker.tsx"],"sourcesContent":["import type { GrayScale } from \"./types\";\n\nexport const GRAY_SCALES: Record<string, GrayScale> = {\n neutral: {\n label: \"Neutral\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.97 0 0)\",\n \"200\": \"oklch(0.922 0 0)\",\n \"300\": \"oklch(0.87 0 0)\",\n \"400\": \"oklch(0.708 0 0)\",\n \"500\": \"oklch(0.556 0 0)\",\n \"600\": \"oklch(0.439 0 0)\",\n \"700\": \"oklch(0.371 0 0)\",\n \"800\": \"oklch(0.269 0 0)\",\n \"900\": \"oklch(0.205 0 0)\",\n \"950\": \"oklch(0.145 0 0)\",\n },\n },\n slate: {\n label: \"Slate\",\n shades: {\n \"50\": \"oklch(0.984 0.003 247.858)\",\n \"100\": \"oklch(0.968 0.007 247.896)\",\n \"200\": \"oklch(0.929 0.013 255.508)\",\n \"300\": \"oklch(0.869 0.022 252.894)\",\n \"400\": \"oklch(0.704 0.04 256.788)\",\n \"500\": \"oklch(0.554 0.046 257.417)\",\n \"600\": \"oklch(0.446 0.043 257.281)\",\n \"700\": \"oklch(0.372 0.044 257.287)\",\n \"800\": \"oklch(0.279 0.041 260.031)\",\n \"900\": \"oklch(0.208 0.042 265.755)\",\n \"950\": \"oklch(0.129 0.042 264.695)\",\n },\n },\n gray: {\n label: \"Gray\",\n shades: {\n \"50\": \"oklch(0.985 0.002 247.839)\",\n \"100\": \"oklch(0.967 0.003 264.542)\",\n \"200\": \"oklch(0.928 0.006 264.531)\",\n \"300\": \"oklch(0.872 0.01 258.338)\",\n \"400\": \"oklch(0.707 0.022 261.325)\",\n \"500\": \"oklch(0.551 0.027 264.364)\",\n \"600\": \"oklch(0.446 0.03 256.802)\",\n \"700\": \"oklch(0.373 0.034 259.733)\",\n \"800\": \"oklch(0.278 0.033 256.848)\",\n \"900\": \"oklch(0.21 0.034 264.665)\",\n \"950\": \"oklch(0.13 0.028 261.692)\",\n },\n },\n zinc: {\n label: \"Zinc\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.967 0.001 286.375)\",\n \"200\": \"oklch(0.92 0.004 286.32)\",\n \"300\": \"oklch(0.871 0.006 286.286)\",\n \"400\": \"oklch(0.705 0.015 286.067)\",\n \"500\": \"oklch(0.552 0.016 285.938)\",\n \"600\": \"oklch(0.442 0.017 285.786)\",\n \"700\": \"oklch(0.37 0.013 285.805)\",\n \"800\": \"oklch(0.274 0.006 286.033)\",\n \"900\": \"oklch(0.21 0.006 285.885)\",\n \"950\": \"oklch(0.141 0.005 285.823)\",\n },\n },\n stone: {\n label: \"Stone\",\n shades: {\n \"50\": \"oklch(0.985 0.001 106.423)\",\n \"100\": \"oklch(0.97 0.001 106.424)\",\n \"200\": \"oklch(0.923 0.003 48.717)\",\n \"300\": \"oklch(0.869 0.005 56.366)\",\n \"400\": \"oklch(0.709 0.01 56.259)\",\n \"500\": \"oklch(0.553 0.013 58.071)\",\n \"600\": \"oklch(0.444 0.011 73.639)\",\n \"700\": \"oklch(0.374 0.01 67.558)\",\n \"800\": \"oklch(0.268 0.007 34.298)\",\n \"900\": \"oklch(0.216 0.006 56.043)\",\n \"950\": \"oklch(0.147 0.004 49.25)\",\n },\n },\n mauve: {\n label: \"Mauve\",\n shades: {\n \"50\": \"oklch(0.985 0.003 310)\",\n \"100\": \"oklch(0.968 0.006 310)\",\n \"200\": \"oklch(0.925 0.011 310)\",\n \"300\": \"oklch(0.87 0.017 310)\",\n \"400\": \"oklch(0.708 0.03 310)\",\n \"500\": \"oklch(0.556 0.03 310)\",\n \"600\": \"oklch(0.44 0.028 310)\",\n \"700\": \"oklch(0.372 0.025 310)\",\n \"800\": \"oklch(0.27 0.02 310)\",\n \"900\": \"oklch(0.208 0.018 310)\",\n \"950\": \"oklch(0.145 0.014 310)\",\n },\n },\n olive: {\n label: \"Olive\",\n shades: {\n \"50\": \"oklch(0.985 0.003 130)\",\n \"100\": \"oklch(0.968 0.006 130)\",\n \"200\": \"oklch(0.925 0.011 130)\",\n \"300\": \"oklch(0.87 0.017 130)\",\n \"400\": \"oklch(0.708 0.028 130)\",\n \"500\": \"oklch(0.556 0.028 130)\",\n \"600\": \"oklch(0.44 0.024 130)\",\n \"700\": \"oklch(0.372 0.02 130)\",\n \"800\": \"oklch(0.27 0.016 130)\",\n \"900\": \"oklch(0.208 0.014 130)\",\n \"950\": \"oklch(0.145 0.01 130)\",\n },\n },\n};\n","export const SLIDER_MAX = 10;\nexport const TEXT_PREVIEW_MAX_LENGTH = 30;\nexport const TYPING_RESET_DELAY_MS = 1500;\nexport const SHADE_KEYS = [\"50\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"950\"];\nexport const FONT_SIZE_MIN_PX = 1;\nexport const FONT_SIZE_MAX_PX = 200;\nexport const PADDING_MIN_PX = -200;\nexport const PADDING_MAX_PX = 200;\nexport const MOUSE_COLOR_SENSITIVITY = 0.02;\nexport const MOUSE_SIZE_SENSITIVITY = 0.1;\nexport const MOUSE_PADDING_SENSITIVITY = 0.2;\nexport const MINIMAP_WIDTH_PX = 160;\nexport const MINIMAP_HEIGHT_PX = 100;\nexport const THUMB_SIZE_PX = 10;\n","import type { OKLCH } from \"../types\";\nimport { SHADE_KEYS, SLIDER_MAX } from \"../constants\";\nimport type { GrayScale } from \"../types\";\n\nexport const parseOklch = (oklchStr: string): OKLCH => {\n const match = oklchStr.match(/oklch\\(([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\)/);\n if (!match) return [0, 0, 0];\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n};\n\nexport const lerpOklch = (colorA: OKLCH, colorB: OKLCH, interpolation: number): OKLCH => [\n colorA[0] + (colorB[0] - colorA[0]) * interpolation,\n colorA[1] + (colorB[1] - colorA[1]) * interpolation,\n colorA[2] + (colorB[2] - colorA[2]) * interpolation,\n];\n\nexport const formatOklch = (oklch: OKLCH): string =>\n `oklch(${oklch[0].toFixed(3)} ${oklch[1].toFixed(3)} ${oklch[2].toFixed(1)})`;\n\nexport const oklchToCssString = (oklch: OKLCH): string =>\n `oklch(${oklch[0]} ${oklch[1]} ${oklch[2]})`;\n\nexport const getColorAtPosition = (scales: Record<string, GrayScale>, scaleKey: string, position: number): OKLCH => {\n const scale = scales[scaleKey];\n if (!scale) return [0.5, 0, 0];\n\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.min(Math.floor(segment), SHADE_KEYS.length - 2);\n const interpolation = segment - index;\n\n const lower = parseOklch(scale.shades[SHADE_KEYS[index]]);\n const upper = parseOklch(scale.shades[SHADE_KEYS[index + 1]]);\n\n return lerpOklch(lower, upper, interpolation);\n};\n\nexport const getClosestShadeLabel = (position: number): string => {\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.round(segment);\n return SHADE_KEYS[Math.min(index, SHADE_KEYS.length - 1)];\n};\n\nexport const parseRgb = (color: string): [number, number, number, number] => {\n const match = color.match(\n /rgba?\\(\\s*([\\d.]+),\\s*([\\d.]+),\\s*([\\d.]+)(?:,\\s*([\\d.]+))?\\s*\\)/\n );\n if (!match) return [0, 0, 0, 0];\n return [\n Number(match[1]),\n Number(match[2]),\n Number(match[3]),\n match[4] !== undefined ? Number(match[4]) : 1,\n ];\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): OKLCH => {\n const linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n const linearRed = linearize(red);\n const linearGreen = linearize(green);\n const linearBlue = linearize(blue);\n\n const lmsL = Math.cbrt(0.4122214708 * linearRed + 0.5363325363 * linearGreen + 0.0514459929 * linearBlue);\n const lmsM = Math.cbrt(0.2119034982 * linearRed + 0.6806995451 * linearGreen + 0.1073969566 * linearBlue);\n const lmsS = Math.cbrt(0.0883024619 * linearRed + 0.2817188376 * linearGreen + 0.6299787005 * linearBlue);\n\n const lightness = 0.2104542553 * lmsL + 0.793617785 * lmsM - 0.0040720468 * lmsS;\n const labA = 1.9779984951 * lmsL - 2.428592205 * lmsM + 0.4505937099 * lmsS;\n const labB = 0.0259040371 * lmsL + 0.7827717662 * lmsM - 0.808675766 * lmsS;\n\n const chroma = Math.sqrt(labA * labA + labB * labB);\n const hue = Math.atan2(labB, labA) * (180 / Math.PI);\n\n return [lightness, chroma, hue < 0 ? hue + 360 : hue];\n};\n\nexport const findClosestPosition = (scales: Record<string, GrayScale>, scaleKey: string, targetOklch: OKLCH): number => {\n let bestPosition = 0;\n let bestDistance = Infinity;\n\n for (let position = 0; position <= SLIDER_MAX; position++) {\n const color = getColorAtPosition(scales, scaleKey, position);\n const distance =\n (color[0] - targetOklch[0]) ** 2 +\n (color[1] - targetOklch[1]) ** 2 +\n ((color[2] - targetOklch[2]) / 360) ** 2;\n if (distance < bestDistance) {\n bestDistance = distance;\n bestPosition = position;\n }\n }\n\n return bestPosition;\n};\n","import { TEXT_PREVIEW_MAX_LENGTH } from \"../constants\";\n\nexport const getSelector = (element: HTMLElement): string => {\n const tag = element.tagName.toLowerCase();\n const classes = Array.from(element.classList)\n .filter((className) => !className.startsWith(\"__\"))\n .slice(0, 2)\n .join(\".\");\n return classes ? `${tag}.${classes}` : tag;\n};\n\nexport const getTextPreview = (element: HTMLElement): string => {\n const text = element.textContent?.trim() || \"\";\n return text.length > TEXT_PREVIEW_MAX_LENGTH\n ? `${text.slice(0, TEXT_PREVIEW_MAX_LENGTH)}…`\n : text;\n};\n","import type { GrayScale, Modification } from \"../types\";\nimport { getColorAtPosition, oklchToCssString } from \"./color\";\n\nexport const applyModification = (\n modification: Modification,\n scales: Record<string, GrayScale>,\n scaleKey: string,\n) => {\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const colorValue = oklchToCssString(oklch);\n if (modification.property === \"bg\") {\n modification.element.style.backgroundColor = colorValue;\n } else if (modification.property === \"text\") {\n modification.element.style.color = colorValue;\n } else {\n modification.element.style.borderColor = colorValue;\n }\n modification.element.style.fontSize = `${modification.fontSize}px`;\n\n const paddingY = Math.round(modification.paddingY);\n\n modification.element.style.paddingTop = `${Math.max(0, paddingY)}px`;\n modification.element.style.paddingBottom = `${Math.max(0, paddingY)}px`;\n\n modification.element.style.marginTop = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginTop;\n modification.element.style.marginBottom = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginBottom;\n};\n\nexport const restoreModification = (modification: Modification) => {\n modification.element.style.backgroundColor = modification.originalInlineBg;\n modification.element.style.color = modification.originalInlineColor;\n modification.element.style.borderColor = modification.originalInlineBorderColor;\n modification.element.style.fontSize = modification.originalInlineFontSize;\n modification.element.style.paddingTop = modification.originalInlinePaddingTop;\n modification.element.style.paddingBottom = modification.originalInlinePaddingBottom;\n modification.element.style.marginTop = modification.originalInlineMarginTop;\n modification.element.style.marginBottom = modification.originalInlineMarginBottom;\n};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\n\nexport const roundToHalf = (value: number): number =>\n Math.round(value * 2) / 2;\n","import type { GrayScale, Modification } from \"../types\";\nimport { formatOklch, getColorAtPosition, getClosestShadeLabel } from \"./color\";\n\nexport const generatePrompt = (\n modifications: Modification[],\n scales: Record<string, GrayScale>,\n scaleKey: string,\n): string => {\n if (modifications.length === 0) return \"\";\n\n const scaleName = scales[scaleKey]?.label || scaleKey;\n const colorLines: string[] = [];\n const sizeLines: string[] = [];\n const paddingLines: string[] = [];\n\n modifications.forEach((modification) => {\n const nameParts = [modification.selector];\n if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);\n if (modification.textPreview) nameParts.push(`(\"${modification.textPreview}\")`);\n const description = nameParts.join(\" \");\n\n const shade = getClosestShadeLabel(modification.position);\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const property =\n modification.property === \"bg\"\n ? \"background color\"\n : modification.property === \"text\"\n ? \"text color\"\n : \"border color\";\n colorLines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);\n if (modification.sourceFile) colorLines.push(` Source: ${modification.sourceFile}`);\n\n sizeLines.push(`- font-size of ${description} → ${modification.fontSize}px`);\n if (modification.sourceFile) sizeLines.push(` Source: ${modification.sourceFile}`);\n\n paddingLines.push(`- vertical padding of ${description} → ${Math.round(modification.paddingY)}px`);\n if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);\n });\n\n const sections: string[] = [];\n\n if (colorLines.length > 0) {\n sections.push(\n \"Change the following colors using the design system's gray scale:\",\n \"\",\n ...colorLines,\n );\n }\n\n if (sizeLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following font sizes:\", \"\", ...sizeLines);\n }\n\n if (paddingLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following padding:\", \"\", ...paddingLines);\n }\n\n return sections.join(\"\\n\");\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, TYPING_RESET_DELAY_MS, FONT_SIZE_MIN_PX, FONT_SIZE_MAX_PX, PADDING_MIN_PX, PADDING_MAX_PX, MOUSE_COLOR_SENSITIVITY, MOUSE_SIZE_SENSITIVITY, MOUSE_PADDING_SENSITIVITY, MINIMAP_WIDTH_PX, MINIMAP_HEIGHT_PX, THUMB_SIZE_PX } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep, roundToHalf } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\n\nconst requestLock = () => {\n if (!document.pointerLockElement) {\n document.body.requestPointerLock();\n }\n};\n\nconst releaseLock = () => {\n if (document.pointerLockElement) {\n document.exitPointerLock();\n }\n};\n\nexport const Tweaker = ({ scales = GRAY_SCALES, activeScale = \"neutral\" }: TweakerProps) => {\n const [picking, setPicking] = useState(false);\n const [modifications, setModifications] = useState<Modification[]>([]);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [inputValue, setInputValue] = useState(\"\");\n const [shiftHeld, setShiftHeld] = useState(false);\n const [spaceHeld, setSpaceHeld] = useState(false);\n const typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const activeMod = activeIndex >= 0 ? modifications[activeIndex] : null;\n const hasModifications = modifications.length > 0;\n\n const activeIndexRef = useRef(activeIndex);\n const activeScaleRef = useRef(activeScale);\n const modificationsRef = useRef(modifications);\n const scalesRef = useRef(scales);\n activeIndexRef.current = activeIndex;\n activeScaleRef.current = activeScale;\n modificationsRef.current = modifications;\n scalesRef.current = scales;\n\n const updateActivePosition = useCallback(\n (newPosition: number) => {\n if (activeIndex < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n updated[activeIndex] = { ...updated[activeIndex], position: newPosition };\n applyModification(updated[activeIndex], scales, activeScale);\n return updated;\n });\n },\n [activeIndex, activeScale, scales],\n );\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(true);\n };\n const handleKeyUp = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(false);\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"keyup\", handleKeyUp);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"keyup\", handleKeyUp);\n };\n }, []);\n\n useEffect(() => {\n if (!hasModifications || picking) return;\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!document.pointerLockElement) return;\n const index = activeIndexRef.current;\n if (index < 0) return;\n\n const isPadding = event.shiftKey;\n\n setModifications((previous) => {\n const updated = [...previous];\n const current = updated[index];\n\n if (isPadding) {\n const newPaddingY = Math.max(PADDING_MIN_PX, Math.min(PADDING_MAX_PX, current.paddingY - event.movementY * MOUSE_PADDING_SENSITIVITY));\n updated[index] = { ...current, paddingY: Math.round(newPaddingY) };\n } else {\n const newPosition = Math.max(0, Math.min(SLIDER_MAX, current.position - event.movementY * MOUSE_COLOR_SENSITIVITY));\n const newSize = Math.max(FONT_SIZE_MIN_PX, Math.min(FONT_SIZE_MAX_PX, current.fontSize + event.movementX * MOUSE_SIZE_SENSITIVITY));\n updated[index] = { ...current, position: roundToStep(newPosition), fontSize: roundToHalf(newSize) };\n }\n\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n setInputValue(String(updated[index].position));\n return updated;\n });\n };\n\n requestLock();\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n releaseLock();\n };\n }, [hasModifications, picking]);\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n releaseLock();\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current);\n navigator.clipboard.writeText(prompt);\n modificationsRef.current.forEach(restoreModification);\n setModifications([]);\n setActiveIndex(-1);\n setInputValue(\"\");\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n releaseLock();\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current);\n navigator.clipboard.writeText(prompt);\n setPicking(true);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n if (!activeMod || picking) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"Escape\") return;\n\n if ((event.key >= \"0\" && event.key <= \"9\") || event.key === \".\") {\n event.preventDefault();\n const next = typingBuffer.current + event.key;\n\n if (event.key === \".\" && typingBuffer.current.includes(\".\")) return;\n\n const hasDecimal = typingBuffer.current.includes(\".\");\n if (hasDecimal && event.key !== \".\" && typingBuffer.current.split(\".\")[1]?.length >= 1) {\n return;\n }\n\n const parsed = parseFloat(next);\n if (!isNaN(parsed) && parsed > SLIDER_MAX) {\n typingBuffer.current = event.key === \".\" ? \".\" : event.key;\n } else {\n typingBuffer.current = next;\n }\n\n const value = parseFloat(typingBuffer.current);\n if (!isNaN(value)) {\n const clamped = Math.min(SLIDER_MAX, value);\n updateActivePosition(clamped);\n setInputValue(typingBuffer.current);\n }\n\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n\n if (event.key === \"Backspace\") {\n event.preventDefault();\n typingBuffer.current = typingBuffer.current.slice(0, -1);\n if (typingBuffer.current && typingBuffer.current !== \".\") {\n const value = Math.min(SLIDER_MAX, parseFloat(typingBuffer.current));\n updateActivePosition(value);\n setInputValue(typingBuffer.current);\n }\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n clearTimeout(typingTimeout.current);\n };\n }, [activeMod, picking, activeIndex, updateActivePosition]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"t\") {\n event.preventDefault();\n setPicking(true);\n }\n if (hasModifications && (event.key === \"b\" || event.key === \"f\" || event.key === \"d\")) {\n event.preventDefault();\n const property: \"bg\" | \"text\" | \"border\" =\n event.key === \"b\" ? \"bg\" : event.key === \"f\" ? \"text\" : \"border\";\n const index = activeIndexRef.current;\n if (index < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n restoreModification(updated[index]);\n updated[index] = { ...updated[index], property };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n }\n };\n\n const handleMiddleClick = (event: MouseEvent) => {\n if (event.button !== 1) return;\n event.preventDefault();\n setPicking(true);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMiddleClick, true);\n document.addEventListener(\"auxclick\", handleMiddleClick, true);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMiddleClick, true);\n document.removeEventListener(\"auxclick\", handleMiddleClick, true);\n };\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n releaseLock();\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, activeMod?.fontSize, activeMod?.paddingY, activeScale, scales]);\n\n useEffect(() => {\n if (!picking) return;\n\n let hoveredElement: HTMLElement | null = null;\n\n const handleMouseOver = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n hoveredElement = target;\n target.style.outline = \"2px solid #3b82f6\";\n target.style.outlineOffset = \"2px\";\n };\n\n const handleMouseOut = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n if (hoveredElement === target) hoveredElement = null;\n };\n\n const handleClick = (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n\n const computed = getComputedStyle(target);\n const [bgRed, bgGreen, bgBlue, bgAlpha] = parseRgb(computed.backgroundColor);\n const [textRed, textGreen, textBlue] = parseRgb(computed.color);\n const [borderRed, borderGreen, borderBlue, borderAlpha] = parseRgb(computed.borderColor);\n const hasBorder = borderAlpha > 0 && parseFloat(computed.borderWidth) > 0;\n\n const hasBackground = bgAlpha > 0;\n const defaultProperty: \"bg\" | \"text\" | \"border\" = hasBackground ? \"bg\" : hasBorder ? \"border\" : \"text\";\n const targetOklch =\n defaultProperty === \"bg\"\n ? rgbToOklch(bgRed, bgGreen, bgBlue)\n : defaultProperty === \"border\"\n ? rgbToOklch(borderRed, borderGreen, borderBlue)\n : rgbToOklch(textRed, textGreen, textBlue);\n\n const position = findClosestPosition(scales, activeScale, targetOklch);\n const currentSize = parseFloat(computed.fontSize) || 16;\n const currentPaddingY = parseFloat(computed.paddingTop) || 0;\n\n const newModification: Modification = {\n element: target,\n selector: getSelector(target),\n componentName: null,\n sourceFile: null,\n textPreview: getTextPreview(target),\n originalInlineBg: target.style.backgroundColor,\n originalInlineColor: target.style.color,\n originalInlineBorderColor: target.style.borderColor,\n originalInlineFontSize: target.style.fontSize,\n originalInlinePaddingTop: target.style.paddingTop,\n originalInlinePaddingBottom: target.style.paddingBottom,\n originalInlineMarginTop: target.style.marginTop,\n originalInlineMarginBottom: target.style.marginBottom,\n property: defaultProperty,\n position,\n fontSize: currentSize,\n paddingY: currentPaddingY,\n };\n\n setModifications((previous) => [...previous, newModification]);\n setActiveIndex(modifications.length);\n setInputValue(String(position));\n setPicking(false);\n };\n\n document.addEventListener(\"mouseover\", handleMouseOver, true);\n document.addEventListener(\"mouseout\", handleMouseOut, true);\n document.addEventListener(\"click\", handleClick, true);\n\n return () => {\n document.removeEventListener(\"mouseover\", handleMouseOver, true);\n document.removeEventListener(\"mouseout\", handleMouseOut, true);\n document.removeEventListener(\"click\", handleClick, true);\n if (hoveredElement) {\n hoveredElement.style.outline = \"\";\n hoveredElement.style.outlineOffset = \"\";\n }\n };\n }, [picking, activeScale, scales, modifications.length]);\n\n const fillColor = activeMod\n ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position))\n : scales[activeScale]?.shades[\"500\"] ?? \"rgba(255,255,255,0.3)\";\n\n const propertyLabel =\n activeMod?.property === \"text\" ? \"F\" : activeMod?.property === \"border\" ? \"D\" : \"B\";\n\n const isPaddingMode = shiftHeld && hasModifications && !picking;\n\n const guideRect = activeMod && !picking && !spaceHeld ? activeMod.element.getBoundingClientRect() : null;\n\n const thumbX = activeMod\n ? isPaddingMode\n ? (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) / 2\n : ((activeMod.fontSize - FONT_SIZE_MIN_PX) / (FONT_SIZE_MAX_PX - FONT_SIZE_MIN_PX)) * (MINIMAP_WIDTH_PX - THUMB_SIZE_PX)\n : 0;\n const thumbY = activeMod\n ? isPaddingMode\n ? (1 - (activeMod.paddingY - PADDING_MIN_PX) / (PADDING_MAX_PX - PADDING_MIN_PX)) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : (1 - activeMod.position / SLIDER_MAX) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : MINIMAP_HEIGHT_PX - THUMB_SIZE_PX;\n\n return (\n <>\n {guideRect && activeMod && (\n <div data-tweaker style={guidelinesContainerStyle}>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: guideRect.height,\n boxSizing: \"border-box\",\n border: \"1px solid rgba(59, 130, 246, 0.5)\",\n borderRadius: 1,\n }}\n />\n {activeMod.paddingY > 0 && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderBottom: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.bottom - Math.min(activeMod.paddingY, guideRect.height / 2),\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderTop: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n </>\n )}\n <div\n style={{\n position: \"absolute\",\n left: guideRect.right + 8,\n top: guideRect.top,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n pointerEvents: \"none\",\n }}\n >\n <span style={guidelineLabelStyle}>\n ↕ {activeMod.paddingY}px\n </span>\n <span style={{ ...guidelineLabelStyle, color: \"rgba(59, 130, 246, 0.8)\", background: \"rgba(59, 130, 246, 0.06)\" }}>\n {activeMod.fontSize}px\n </span>\n </div>\n </div>\n )}\n <AnimatePresence>\n {(hasModifications || picking) && (\n <motion.div\n key=\"minimap\"\n data-tweaker\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.2 }}\n style={minimapContainerStyle}\n >\n <div style={minimapFieldStyle}>\n <div\n style={{\n position: \"absolute\",\n left: thumbX,\n top: thumbY,\n width: THUMB_SIZE_PX,\n height: THUMB_SIZE_PX,\n borderRadius: \"50%\",\n background: fillColor,\n border: \"2px solid rgba(255,255,255,0.9)\",\n boxShadow: \"0 1px 4px rgba(0,0,0,0.4)\",\n transition: \"left 50ms, top 50ms\",\n }}\n />\n </div>\n <div style={minimapModeStyle}>\n <span style={minimapLabelStyle}>\n {isPaddingMode ? \"⇧ Padding\" : \"Style\"}\n </span>\n </div>\n <div style={minimapValuesStyle}>\n <span style={minimapLabelStyle}>\n {picking\n ? \"Picking…\"\n : isPaddingMode\n ? `↕ ${activeMod?.paddingY ?? 0}px`\n : `${propertyLabel} ${inputValue || \"0\"}`}\n </span>\n {!picking && activeMod && !isPaddingMode && (\n <span style={minimapLabelStyle}>\n {`${activeMod.fontSize}px`}\n </span>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n );\n};\n\nconst baseTextStyle: React.CSSProperties = {\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n};\n\nconst minimapContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n};\n\nconst minimapFieldStyle: React.CSSProperties = {\n position: \"relative\",\n width: MINIMAP_WIDTH_PX,\n height: MINIMAP_HEIGHT_PX,\n borderRadius: 8,\n background: \"rgba(0,0,0,0.25)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n boxShadow: \"0 0 0 1px rgba(255,255,255,0.08) inset\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n};\n\nconst minimapModeStyle: React.CSSProperties = {\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapValuesStyle: React.CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 11,\n color: \"rgba(255,255,255,0.6)\",\n whiteSpace: \"nowrap\",\n};\n\nconst guidelinesContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 9998,\n pointerEvents: \"none\",\n};\n\nconst guidelineLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 10,\n lineHeight: \"16px\",\n color: \"rgba(255, 99, 132, 0.9)\",\n background: \"rgba(255, 99, 132, 0.08)\",\n padding: \"0 5px\",\n borderRadius: 3,\n whiteSpace: \"nowrap\",\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/gray-scales.ts","../src/constants.ts","../src/utils/color.ts","../src/utils/dom.ts","../src/utils/modification.ts","../src/utils/prompt.ts","../src/utils/nearby.ts","../src/tweaker.tsx"],"sourcesContent":["import type { GrayScale } from \"./types\";\n\nexport const GRAY_SCALES: Record<string, GrayScale> = {\n neutral: {\n label: \"Neutral\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.97 0 0)\",\n \"200\": \"oklch(0.922 0 0)\",\n \"300\": \"oklch(0.87 0 0)\",\n \"400\": \"oklch(0.708 0 0)\",\n \"500\": \"oklch(0.556 0 0)\",\n \"600\": \"oklch(0.439 0 0)\",\n \"700\": \"oklch(0.371 0 0)\",\n \"800\": \"oklch(0.269 0 0)\",\n \"900\": \"oklch(0.205 0 0)\",\n \"950\": \"oklch(0.145 0 0)\",\n },\n },\n slate: {\n label: \"Slate\",\n shades: {\n \"50\": \"oklch(0.984 0.003 247.858)\",\n \"100\": \"oklch(0.968 0.007 247.896)\",\n \"200\": \"oklch(0.929 0.013 255.508)\",\n \"300\": \"oklch(0.869 0.022 252.894)\",\n \"400\": \"oklch(0.704 0.04 256.788)\",\n \"500\": \"oklch(0.554 0.046 257.417)\",\n \"600\": \"oklch(0.446 0.043 257.281)\",\n \"700\": \"oklch(0.372 0.044 257.287)\",\n \"800\": \"oklch(0.279 0.041 260.031)\",\n \"900\": \"oklch(0.208 0.042 265.755)\",\n \"950\": \"oklch(0.129 0.042 264.695)\",\n },\n },\n gray: {\n label: \"Gray\",\n shades: {\n \"50\": \"oklch(0.985 0.002 247.839)\",\n \"100\": \"oklch(0.967 0.003 264.542)\",\n \"200\": \"oklch(0.928 0.006 264.531)\",\n \"300\": \"oklch(0.872 0.01 258.338)\",\n \"400\": \"oklch(0.707 0.022 261.325)\",\n \"500\": \"oklch(0.551 0.027 264.364)\",\n \"600\": \"oklch(0.446 0.03 256.802)\",\n \"700\": \"oklch(0.373 0.034 259.733)\",\n \"800\": \"oklch(0.278 0.033 256.848)\",\n \"900\": \"oklch(0.21 0.034 264.665)\",\n \"950\": \"oklch(0.13 0.028 261.692)\",\n },\n },\n zinc: {\n label: \"Zinc\",\n shades: {\n \"50\": \"oklch(0.985 0 0)\",\n \"100\": \"oklch(0.967 0.001 286.375)\",\n \"200\": \"oklch(0.92 0.004 286.32)\",\n \"300\": \"oklch(0.871 0.006 286.286)\",\n \"400\": \"oklch(0.705 0.015 286.067)\",\n \"500\": \"oklch(0.552 0.016 285.938)\",\n \"600\": \"oklch(0.442 0.017 285.786)\",\n \"700\": \"oklch(0.37 0.013 285.805)\",\n \"800\": \"oklch(0.274 0.006 286.033)\",\n \"900\": \"oklch(0.21 0.006 285.885)\",\n \"950\": \"oklch(0.141 0.005 285.823)\",\n },\n },\n stone: {\n label: \"Stone\",\n shades: {\n \"50\": \"oklch(0.985 0.001 106.423)\",\n \"100\": \"oklch(0.97 0.001 106.424)\",\n \"200\": \"oklch(0.923 0.003 48.717)\",\n \"300\": \"oklch(0.869 0.005 56.366)\",\n \"400\": \"oklch(0.709 0.01 56.259)\",\n \"500\": \"oklch(0.553 0.013 58.071)\",\n \"600\": \"oklch(0.444 0.011 73.639)\",\n \"700\": \"oklch(0.374 0.01 67.558)\",\n \"800\": \"oklch(0.268 0.007 34.298)\",\n \"900\": \"oklch(0.216 0.006 56.043)\",\n \"950\": \"oklch(0.147 0.004 49.25)\",\n },\n },\n mauve: {\n label: \"Mauve\",\n shades: {\n \"50\": \"oklch(0.985 0.003 310)\",\n \"100\": \"oklch(0.968 0.006 310)\",\n \"200\": \"oklch(0.925 0.011 310)\",\n \"300\": \"oklch(0.87 0.017 310)\",\n \"400\": \"oklch(0.708 0.03 310)\",\n \"500\": \"oklch(0.556 0.03 310)\",\n \"600\": \"oklch(0.44 0.028 310)\",\n \"700\": \"oklch(0.372 0.025 310)\",\n \"800\": \"oklch(0.27 0.02 310)\",\n \"900\": \"oklch(0.208 0.018 310)\",\n \"950\": \"oklch(0.145 0.014 310)\",\n },\n },\n olive: {\n label: \"Olive\",\n shades: {\n \"50\": \"oklch(0.985 0.003 130)\",\n \"100\": \"oklch(0.968 0.006 130)\",\n \"200\": \"oklch(0.925 0.011 130)\",\n \"300\": \"oklch(0.87 0.017 130)\",\n \"400\": \"oklch(0.708 0.028 130)\",\n \"500\": \"oklch(0.556 0.028 130)\",\n \"600\": \"oklch(0.44 0.024 130)\",\n \"700\": \"oklch(0.372 0.02 130)\",\n \"800\": \"oklch(0.27 0.016 130)\",\n \"900\": \"oklch(0.208 0.014 130)\",\n \"950\": \"oklch(0.145 0.01 130)\",\n },\n },\n};\n","export const SLIDER_MAX = 10;\nexport const TEXT_PREVIEW_MAX_LENGTH = 30;\nexport const TYPING_RESET_DELAY_MS = 1500;\nexport const SHADE_KEYS = [\"50\", \"100\", \"200\", \"300\", \"400\", \"500\", \"600\", \"700\", \"800\", \"900\", \"950\"];\nexport const FONT_SIZE_MIN_PX = 1;\nexport const FONT_SIZE_MAX_PX = 200;\nexport const PADDING_MIN_PX = -200;\nexport const PADDING_MAX_PX = 200;\nexport const MOUSE_COLOR_SENSITIVITY = 0.02;\nexport const MOUSE_SIZE_SENSITIVITY = 0.1;\nexport const MOUSE_PADDING_SENSITIVITY = 0.2;\nexport const MINIMAP_WIDTH_PX = 160;\nexport const MINIMAP_HEIGHT_PX = 100;\nexport const THUMB_SIZE_PX = 10;\nexport const NEARBY_SAMPLE_OFFSET_PX = 20;\n","import type { OKLCH } from \"../types\";\nimport { SHADE_KEYS, SLIDER_MAX } from \"../constants\";\nimport type { GrayScale } from \"../types\";\n\nexport const parseOklch = (oklchStr: string): OKLCH => {\n const match = oklchStr.match(/oklch\\(([\\d.]+)\\s+([\\d.]+)\\s+([\\d.]+)\\)/);\n if (!match) return [0, 0, 0];\n return [Number(match[1]), Number(match[2]), Number(match[3])];\n};\n\nexport const lerpOklch = (colorA: OKLCH, colorB: OKLCH, interpolation: number): OKLCH => [\n colorA[0] + (colorB[0] - colorA[0]) * interpolation,\n colorA[1] + (colorB[1] - colorA[1]) * interpolation,\n colorA[2] + (colorB[2] - colorA[2]) * interpolation,\n];\n\nexport const formatOklch = (oklch: OKLCH): string =>\n `oklch(${oklch[0].toFixed(3)} ${oklch[1].toFixed(3)} ${oklch[2].toFixed(1)})`;\n\nexport const oklchToCssString = (oklch: OKLCH): string =>\n `oklch(${oklch[0]} ${oklch[1]} ${oklch[2]})`;\n\nexport const getColorAtPosition = (scales: Record<string, GrayScale>, scaleKey: string, position: number): OKLCH => {\n const scale = scales[scaleKey];\n if (!scale) return [0.5, 0, 0];\n\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.min(Math.floor(segment), SHADE_KEYS.length - 2);\n const interpolation = segment - index;\n\n const lower = parseOklch(scale.shades[SHADE_KEYS[index]]);\n const upper = parseOklch(scale.shades[SHADE_KEYS[index + 1]]);\n\n return lerpOklch(lower, upper, interpolation);\n};\n\nexport const getClosestShadeLabel = (position: number): string => {\n const inverted = SLIDER_MAX - position;\n const segment = (inverted / SLIDER_MAX) * (SHADE_KEYS.length - 1);\n const index = Math.round(segment);\n return SHADE_KEYS[Math.min(index, SHADE_KEYS.length - 1)];\n};\n\nexport const parseRgb = (color: string): [number, number, number, number] => {\n const match = color.match(\n /rgba?\\(\\s*([\\d.]+),\\s*([\\d.]+),\\s*([\\d.]+)(?:,\\s*([\\d.]+))?\\s*\\)/\n );\n if (!match) return [0, 0, 0, 0];\n return [\n Number(match[1]),\n Number(match[2]),\n Number(match[3]),\n match[4] !== undefined ? Number(match[4]) : 1,\n ];\n};\n\nexport const rgbToOklch = (red: number, green: number, blue: number): OKLCH => {\n const linearize = (channel: number): number => {\n const normalized = channel / 255;\n return normalized <= 0.04045\n ? normalized / 12.92\n : Math.pow((normalized + 0.055) / 1.055, 2.4);\n };\n const linearRed = linearize(red);\n const linearGreen = linearize(green);\n const linearBlue = linearize(blue);\n\n const lmsL = Math.cbrt(0.4122214708 * linearRed + 0.5363325363 * linearGreen + 0.0514459929 * linearBlue);\n const lmsM = Math.cbrt(0.2119034982 * linearRed + 0.6806995451 * linearGreen + 0.1073969566 * linearBlue);\n const lmsS = Math.cbrt(0.0883024619 * linearRed + 0.2817188376 * linearGreen + 0.6299787005 * linearBlue);\n\n const lightness = 0.2104542553 * lmsL + 0.793617785 * lmsM - 0.0040720468 * lmsS;\n const labA = 1.9779984951 * lmsL - 2.428592205 * lmsM + 0.4505937099 * lmsS;\n const labB = 0.0259040371 * lmsL + 0.7827717662 * lmsM - 0.808675766 * lmsS;\n\n const chroma = Math.sqrt(labA * labA + labB * labB);\n const hue = Math.atan2(labB, labA) * (180 / Math.PI);\n\n return [lightness, chroma, hue < 0 ? hue + 360 : hue];\n};\n\nexport const findClosestPosition = (scales: Record<string, GrayScale>, scaleKey: string, targetOklch: OKLCH): number => {\n let bestPosition = 0;\n let bestDistance = Infinity;\n\n for (let position = 0; position <= SLIDER_MAX; position++) {\n const color = getColorAtPosition(scales, scaleKey, position);\n const distance =\n (color[0] - targetOklch[0]) ** 2 +\n (color[1] - targetOklch[1]) ** 2 +\n ((color[2] - targetOklch[2]) / 360) ** 2;\n if (distance < bestDistance) {\n bestDistance = distance;\n bestPosition = position;\n }\n }\n\n return bestPosition;\n};\n","import { TEXT_PREVIEW_MAX_LENGTH } from \"../constants\";\n\nexport const getSelector = (element: HTMLElement): string => {\n const tag = element.tagName.toLowerCase();\n const classes = Array.from(element.classList)\n .filter((className) => !className.startsWith(\"__\"))\n .slice(0, 2)\n .join(\".\");\n return classes ? `${tag}.${classes}` : tag;\n};\n\nexport const getTextPreview = (element: HTMLElement): string => {\n const text = element.textContent?.trim() || \"\";\n return text.length > TEXT_PREVIEW_MAX_LENGTH\n ? `${text.slice(0, TEXT_PREVIEW_MAX_LENGTH)}…`\n : text;\n};\n","import type { GrayScale, Modification } from \"../types\";\nimport { getColorAtPosition, oklchToCssString } from \"./color\";\n\nexport const applyModification = (\n modification: Modification,\n scales: Record<string, GrayScale>,\n scaleKey: string,\n) => {\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const colorValue = oklchToCssString(oklch);\n if (modification.property === \"bg\") {\n modification.element.style.backgroundColor = colorValue;\n } else if (modification.property === \"text\") {\n modification.element.style.color = colorValue;\n } else {\n modification.element.style.borderColor = colorValue;\n }\n modification.element.style.fontSize = `${modification.fontSize}px`;\n\n const paddingY = Math.round(modification.paddingY);\n\n modification.element.style.paddingTop = `${Math.max(0, paddingY)}px`;\n modification.element.style.paddingBottom = `${Math.max(0, paddingY)}px`;\n\n modification.element.style.marginTop = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginTop;\n modification.element.style.marginBottom = paddingY < 0 ? `${paddingY}px` : modification.originalInlineMarginBottom;\n\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n modification.element.style.transform = `translate(${modification.translateX}px, ${modification.translateY}px)`;\n } else {\n modification.element.style.transform = modification.originalInlineTransform;\n }\n};\n\nexport const restoreModification = (modification: Modification) => {\n modification.element.style.backgroundColor = modification.originalInlineBg;\n modification.element.style.color = modification.originalInlineColor;\n modification.element.style.borderColor = modification.originalInlineBorderColor;\n modification.element.style.fontSize = modification.originalInlineFontSize;\n modification.element.style.paddingTop = modification.originalInlinePaddingTop;\n modification.element.style.paddingBottom = modification.originalInlinePaddingBottom;\n modification.element.style.marginTop = modification.originalInlineMarginTop;\n modification.element.style.marginBottom = modification.originalInlineMarginBottom;\n modification.element.style.transform = modification.originalInlineTransform;\n};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\n\nexport const roundToHalf = (value: number): number =>\n Math.round(value * 2) / 2;\n","import type { GrayScale, Modification } from \"../types\";\nimport type { NearbyElementInfo } from \"./nearby\";\nimport { formatOklch, getColorAtPosition, getClosestShadeLabel } from \"./color\";\n\nconst getLayoutContext = (element: HTMLElement): string => {\n const parent = element.parentElement;\n if (!parent) return \"no parent\";\n\n const style = getComputedStyle(parent);\n const display = style.display;\n const parts: string[] = [display];\n\n if (display === \"flex\" || display === \"inline-flex\") {\n parts.push(style.flexDirection);\n if (style.gap && style.gap !== \"normal\" && style.gap !== \"0px\") {\n parts.push(`gap: ${style.gap}`);\n }\n }\n\n if (display === \"grid\" || display === \"inline-grid\") {\n if (style.gap && style.gap !== \"normal\" && style.gap !== \"0px\") {\n parts.push(`gap: ${style.gap}`);\n }\n }\n\n return parts.join(\", \");\n};\n\nconst describeElement = (info: NearbyElementInfo): string => {\n const nameParts: string[] = [];\n if (info.componentName) nameParts.push(`<${info.componentName}>`);\n nameParts.push(info.selector);\n if (info.textPreview) nameParts.push(`(\"${info.textPreview}\")`);\n return nameParts.join(\" \");\n};\n\nexport const generatePrompt = (\n modifications: Modification[],\n scales: Record<string, GrayScale>,\n scaleKey: string,\n nearbyElements?: Map<number, NearbyElementInfo[]>,\n): string => {\n if (modifications.length === 0) return \"\";\n\n const scaleName = scales[scaleKey]?.label || scaleKey;\n const colorLines: string[] = [];\n const sizeLines: string[] = [];\n const paddingLines: string[] = [];\n const positionLines: string[] = [];\n\n modifications.forEach((modification, index) => {\n const nameParts = [modification.selector];\n if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);\n if (modification.textPreview) nameParts.push(`(\"${modification.textPreview}\")`);\n const description = nameParts.join(\" \");\n\n const shade = getClosestShadeLabel(modification.position);\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\n const property =\n modification.property === \"bg\"\n ? \"background color\"\n : modification.property === \"text\"\n ? \"text color\"\n : \"border color\";\n colorLines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);\n if (modification.sourceFile) colorLines.push(` Source: ${modification.sourceFile}`);\n\n sizeLines.push(`- font-size of ${description} → ${modification.fontSize}px`);\n if (modification.sourceFile) sizeLines.push(` Source: ${modification.sourceFile}`);\n\n paddingLines.push(`- vertical padding of ${description} → ${Math.round(modification.paddingY)}px`);\n if (modification.sourceFile) paddingLines.push(` Source: ${modification.sourceFile}`);\n\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n positionLines.push(`- move ${description}`);\n positionLines.push(` Parent layout: ${getLayoutContext(modification.element)}`);\n if (modification.sourceFile) positionLines.push(` Source: ${modification.sourceFile}`);\n\n const nearby = nearbyElements?.get(index);\n if (nearby && nearby.length > 0) {\n positionLines.push(\" Place it near these elements at the target position:\");\n for (const element of nearby) {\n positionLines.push(` - ${element.label}: ${describeElement(element)}`);\n if (element.sourceFile) positionLines.push(` Source: ${element.sourceFile}`);\n }\n }\n }\n });\n\n const sections: string[] = [];\n\n if (colorLines.length > 0) {\n sections.push(\n \"Change the following colors using the design system's gray scale:\",\n \"\",\n ...colorLines,\n );\n }\n\n if (sizeLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following font sizes:\", \"\", ...sizeLines);\n }\n\n if (paddingLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following padding:\", \"\", ...paddingLines);\n }\n\n if (positionLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\n \"Reposition the following elements (use canonical CSS like margin, padding, gap, or flexbox order — do NOT use CSS transforms):\",\n \"\",\n ...positionLines,\n );\n }\n\n return sections.join(\"\\n\");\n};\n","import { NEARBY_SAMPLE_OFFSET_PX } from \"../constants\";\nimport { getSelector, getTextPreview } from \"./dom\";\n\ninterface StackFrame {\n fileName?: string;\n lineNumber?: number;\n functionName?: string;\n}\n\ninterface ReactGrabModule {\n getStack: (element: Element) => Promise<StackFrame[]>;\n}\n\nexport interface NearbyElementInfo {\n label: string;\n selector: string;\n textPreview: string;\n componentName: string | null;\n sourceFile: string | null;\n}\n\nconst getReactGrabModule = (): ReactGrabModule | null => {\n const module = (window as unknown as Record<string, unknown>)\n .__REACT_GRAB_MODULE__ as ReactGrabModule | undefined;\n if (module && typeof module.getStack === \"function\") {\n return module;\n }\n return null;\n};\n\nconst getSourceFromStack = async (\n element: Element,\n reactGrab: ReactGrabModule,\n): Promise<{ componentName: string | null; sourceFile: string | null }> => {\n try {\n const stack = await reactGrab.getStack(element);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n return {\n sourceFile: frame.fileName,\n componentName:\n frame.functionName && /^[A-Z]/.test(frame.functionName)\n ? frame.functionName\n : null,\n };\n }\n }\n }\n } catch {}\n return { componentName: null, sourceFile: null };\n};\n\nexport const findNearbyElements = async (\n draggedElement: HTMLElement,\n): Promise<NearbyElementInfo[]> => {\n const rect = draggedElement.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n\n const samplePoints = [\n { y: rect.top - NEARBY_SAMPLE_OFFSET_PX, label: \"above\" },\n { y: rect.top + rect.height / 2, label: \"at\" },\n { y: rect.bottom + NEARBY_SAMPLE_OFFSET_PX, label: \"below\" },\n ];\n\n const reactGrab = getReactGrabModule();\n const seen = new Set<Element>();\n seen.add(draggedElement);\n const results: NearbyElementInfo[] = [];\n\n for (const point of samplePoints) {\n const elements = document.elementsFromPoint(centerX, point.y);\n for (const element of elements) {\n if (!(element instanceof HTMLElement)) continue;\n if (seen.has(element)) continue;\n if (element.contains(draggedElement) || draggedElement.contains(element))\n continue;\n if (element.closest(\"[data-tweaker]\")) continue;\n if (element.tagName === \"HTML\" || element.tagName === \"BODY\") continue;\n seen.add(element);\n\n let componentName: string | null = null;\n let sourceFile: string | null = null;\n if (reactGrab) {\n const source = await getSourceFromStack(element, reactGrab);\n componentName = source.componentName;\n sourceFile = source.sourceFile;\n }\n\n results.push({\n label: point.label,\n selector: getSelector(element),\n textPreview: getTextPreview(element),\n componentName,\n sourceFile,\n });\n break;\n }\n }\n\n return results;\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, TYPING_RESET_DELAY_MS, FONT_SIZE_MIN_PX, FONT_SIZE_MAX_PX, PADDING_MIN_PX, PADDING_MAX_PX, MOUSE_COLOR_SENSITIVITY, MOUSE_SIZE_SENSITIVITY, MOUSE_PADDING_SENSITIVITY, MINIMAP_WIDTH_PX, MINIMAP_HEIGHT_PX, THUMB_SIZE_PX } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep, roundToHalf } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\nimport { findNearbyElements } from \"./utils/nearby\";\nimport type { NearbyElementInfo } from \"./utils/nearby\";\n\nconst requestLock = () => {\n if (!document.pointerLockElement) {\n document.body.requestPointerLock();\n }\n};\n\nconst releaseLock = () => {\n if (document.pointerLockElement) {\n document.exitPointerLock();\n }\n};\n\nexport const Tweaker = ({ scales = GRAY_SCALES, activeScale = \"neutral\" }: TweakerProps) => {\n const [picking, setPicking] = useState(false);\n const [modifications, setModifications] = useState<Modification[]>([]);\n const [activeIndex, setActiveIndex] = useState(-1);\n const [inputValue, setInputValue] = useState(\"\");\n const [shiftHeld, setShiftHeld] = useState(false);\n const [spaceHeld, setSpaceHeld] = useState(false);\n const [controlHeld, setControlHeld] = useState(false);\n const typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const activeMod = activeIndex >= 0 ? modifications[activeIndex] : null;\n const hasModifications = modifications.length > 0;\n\n const activeIndexRef = useRef(activeIndex);\n const activeScaleRef = useRef(activeScale);\n const modificationsRef = useRef(modifications);\n const scalesRef = useRef(scales);\n activeIndexRef.current = activeIndex;\n activeScaleRef.current = activeScale;\n modificationsRef.current = modifications;\n scalesRef.current = scales;\n\n const updateActivePosition = useCallback(\n (newPosition: number) => {\n if (activeIndex < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n updated[activeIndex] = { ...updated[activeIndex], position: newPosition };\n applyModification(updated[activeIndex], scales, activeScale);\n return updated;\n });\n },\n [activeIndex, activeScale, scales],\n );\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(true);\n if (event.key === \"Control\") setControlHeld(true);\n };\n const handleKeyUp = (event: KeyboardEvent) => {\n setShiftHeld(event.shiftKey);\n if (event.key === \" \") setSpaceHeld(false);\n if (event.key === \"Control\") setControlHeld(false);\n };\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"keyup\", handleKeyUp);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"keyup\", handleKeyUp);\n };\n }, []);\n\n useEffect(() => {\n if (!hasModifications || picking) return;\n\n const handleMouseMove = (event: MouseEvent) => {\n if (!document.pointerLockElement) return;\n const index = activeIndexRef.current;\n if (index < 0) return;\n\n setModifications((previous) => {\n const updated = [...previous];\n const current = updated[index];\n\n if (event.ctrlKey) {\n updated[index] = {\n ...current,\n translateX: current.translateX + event.movementX,\n translateY: current.translateY + event.movementY,\n };\n } else if (event.shiftKey) {\n const newPaddingY = Math.max(PADDING_MIN_PX, Math.min(PADDING_MAX_PX, current.paddingY - event.movementY * MOUSE_PADDING_SENSITIVITY));\n updated[index] = { ...current, paddingY: Math.round(newPaddingY) };\n } else {\n const newPosition = Math.max(0, Math.min(SLIDER_MAX, current.position - event.movementY * MOUSE_COLOR_SENSITIVITY));\n const newSize = Math.max(FONT_SIZE_MIN_PX, Math.min(FONT_SIZE_MAX_PX, current.fontSize + event.movementX * MOUSE_SIZE_SENSITIVITY));\n updated[index] = { ...current, position: roundToStep(newPosition), fontSize: roundToHalf(newSize) };\n }\n\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n setInputValue(String(updated[index].position));\n return updated;\n });\n };\n\n requestLock();\n document.addEventListener(\"mousemove\", handleMouseMove, true);\n return () => {\n document.removeEventListener(\"mousemove\", handleMouseMove, true);\n releaseLock();\n };\n }, [hasModifications, picking]);\n\n const gatherNearbyElements = async (\n modifications: Modification[],\n ): Promise<Map<number, NearbyElementInfo[]>> => {\n const nearbyMap = new Map<number, NearbyElementInfo[]>();\n for (let index = 0; index < modifications.length; index++) {\n const modification = modifications[index];\n if (modification.translateX !== 0 || modification.translateY !== 0) {\n const nearby = await findNearbyElements(modification.element);\n nearbyMap.set(index, nearby);\n }\n }\n return nearbyMap;\n };\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = async (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\n releaseLock();\n const nearbyMap = await gatherNearbyElements(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, nearbyMap);\n navigator.clipboard.writeText(prompt);\n modificationsRef.current.forEach(restoreModification);\n setModifications([]);\n setActiveIndex(-1);\n setInputValue(\"\");\n }\n\n if (event.key === \"Enter\") {\n event.preventDefault();\n releaseLock();\n const nearbyMap = await gatherNearbyElements(modificationsRef.current);\n const prompt = generatePrompt(modificationsRef.current, scalesRef.current, activeScaleRef.current, nearbyMap);\n navigator.clipboard.writeText(prompt);\n setPicking(true);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n if (!activeMod || picking) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"Escape\") return;\n\n if ((event.key >= \"0\" && event.key <= \"9\") || event.key === \".\") {\n event.preventDefault();\n const next = typingBuffer.current + event.key;\n\n if (event.key === \".\" && typingBuffer.current.includes(\".\")) return;\n\n const hasDecimal = typingBuffer.current.includes(\".\");\n if (hasDecimal && event.key !== \".\" && typingBuffer.current.split(\".\")[1]?.length >= 1) {\n return;\n }\n\n const parsed = parseFloat(next);\n if (!isNaN(parsed) && parsed > SLIDER_MAX) {\n typingBuffer.current = event.key === \".\" ? \".\" : event.key;\n } else {\n typingBuffer.current = next;\n }\n\n const value = parseFloat(typingBuffer.current);\n if (!isNaN(value)) {\n const clamped = Math.min(SLIDER_MAX, value);\n updateActivePosition(clamped);\n setInputValue(typingBuffer.current);\n }\n\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n\n if (event.key === \"Backspace\") {\n event.preventDefault();\n typingBuffer.current = typingBuffer.current.slice(0, -1);\n if (typingBuffer.current && typingBuffer.current !== \".\") {\n const value = Math.min(SLIDER_MAX, parseFloat(typingBuffer.current));\n updateActivePosition(value);\n setInputValue(typingBuffer.current);\n }\n clearTimeout(typingTimeout.current);\n typingTimeout.current = setTimeout(() => {\n typingBuffer.current = \"\";\n }, TYPING_RESET_DELAY_MS);\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n clearTimeout(typingTimeout.current);\n };\n }, [activeMod, picking, activeIndex, updateActivePosition]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n const target = event.target as HTMLElement;\n if (target.tagName === \"INPUT\" || target.tagName === \"TEXTAREA\") return;\n if (event.key === \"t\") {\n event.preventDefault();\n setPicking(true);\n }\n if (hasModifications && (event.key === \"b\" || event.key === \"f\" || event.key === \"d\")) {\n event.preventDefault();\n const property: \"bg\" | \"text\" | \"border\" =\n event.key === \"b\" ? \"bg\" : event.key === \"f\" ? \"text\" : \"border\";\n const index = activeIndexRef.current;\n if (index < 0) return;\n setModifications((previous) => {\n const updated = [...previous];\n restoreModification(updated[index]);\n updated[index] = { ...updated[index], property };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n }\n };\n\n const handleMiddleClick = (event: MouseEvent) => {\n if (event.button !== 1) return;\n event.preventDefault();\n setPicking(true);\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n document.addEventListener(\"mousedown\", handleMiddleClick, true);\n document.addEventListener(\"auxclick\", handleMiddleClick, true);\n return () => {\n document.removeEventListener(\"keydown\", handleKeyDown);\n document.removeEventListener(\"mousedown\", handleMiddleClick, true);\n document.removeEventListener(\"auxclick\", handleMiddleClick, true);\n };\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n releaseLock();\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, activeMod?.fontSize, activeMod?.paddingY, activeScale, scales]);\n\n useEffect(() => {\n if (!picking) return;\n\n let hoveredElement: HTMLElement | null = null;\n\n const handleMouseOver = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n hoveredElement = target;\n target.style.outline = \"2px solid #3b82f6\";\n target.style.outlineOffset = \"2px\";\n };\n\n const handleMouseOut = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n if (hoveredElement === target) hoveredElement = null;\n };\n\n const handleClick = async (event: MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n const target = event.target as HTMLElement;\n if (target.closest(\"[data-tweaker]\")) return;\n\n target.style.outline = \"\";\n target.style.outlineOffset = \"\";\n\n const computed = getComputedStyle(target);\n const [bgRed, bgGreen, bgBlue, bgAlpha] = parseRgb(computed.backgroundColor);\n const [textRed, textGreen, textBlue] = parseRgb(computed.color);\n const [borderRed, borderGreen, borderBlue, borderAlpha] = parseRgb(computed.borderColor);\n const hasBorder = borderAlpha > 0 && parseFloat(computed.borderWidth) > 0;\n\n const hasBackground = bgAlpha > 0;\n const defaultProperty: \"bg\" | \"text\" | \"border\" = hasBackground ? \"bg\" : hasBorder ? \"border\" : \"text\";\n const targetOklch =\n defaultProperty === \"bg\"\n ? rgbToOklch(bgRed, bgGreen, bgBlue)\n : defaultProperty === \"border\"\n ? rgbToOklch(borderRed, borderGreen, borderBlue)\n : rgbToOklch(textRed, textGreen, textBlue);\n\n const position = findClosestPosition(scales, activeScale, targetOklch);\n const currentSize = parseFloat(computed.fontSize) || 16;\n const currentPaddingY = parseFloat(computed.paddingTop) || 0;\n\n let componentName: string | null = null;\n let sourceFile: string | null = null;\n try {\n const reactGrab = (window as unknown as Record<string, unknown>).__REACT_GRAB_MODULE__ as {\n getStack: (element: Element) => Promise<Array<{ fileName?: string; lineNumber?: number; functionName?: string }>>;\n } | undefined;\n if (reactGrab?.getStack) {\n const stack = await reactGrab.getStack(target);\n if (stack) {\n for (const frame of stack) {\n if (frame.fileName && !frame.fileName.includes(\"node_modules\")) {\n sourceFile = frame.fileName;\n if (frame.functionName && /^[A-Z]/.test(frame.functionName)) {\n componentName = frame.functionName;\n }\n break;\n }\n }\n }\n }\n } catch {}\n\n const newModification: Modification = {\n element: target,\n selector: getSelector(target),\n componentName,\n sourceFile,\n textPreview: getTextPreview(target),\n originalInlineBg: target.style.backgroundColor,\n originalInlineColor: target.style.color,\n originalInlineBorderColor: target.style.borderColor,\n originalInlineFontSize: target.style.fontSize,\n originalInlinePaddingTop: target.style.paddingTop,\n originalInlinePaddingBottom: target.style.paddingBottom,\n originalInlineMarginTop: target.style.marginTop,\n originalInlineMarginBottom: target.style.marginBottom,\n originalInlineTransform: target.style.transform,\n property: defaultProperty,\n position,\n fontSize: currentSize,\n paddingY: currentPaddingY,\n translateX: 0,\n translateY: 0,\n };\n\n setModifications((previous) => [...previous, newModification]);\n setActiveIndex(modifications.length);\n setInputValue(String(position));\n setPicking(false);\n };\n\n document.addEventListener(\"mouseover\", handleMouseOver, true);\n document.addEventListener(\"mouseout\", handleMouseOut, true);\n document.addEventListener(\"click\", handleClick, true);\n\n return () => {\n document.removeEventListener(\"mouseover\", handleMouseOver, true);\n document.removeEventListener(\"mouseout\", handleMouseOut, true);\n document.removeEventListener(\"click\", handleClick, true);\n if (hoveredElement) {\n hoveredElement.style.outline = \"\";\n hoveredElement.style.outlineOffset = \"\";\n }\n };\n }, [picking, activeScale, scales, modifications.length]);\n\n const fillColor = activeMod\n ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position))\n : scales[activeScale]?.shades[\"500\"] ?? \"rgba(255,255,255,0.3)\";\n\n const propertyLabel =\n activeMod?.property === \"text\" ? \"F\" : activeMod?.property === \"border\" ? \"D\" : \"B\";\n\n const isPaddingMode = shiftHeld && hasModifications && !picking;\n const isDragMode = controlHeld && hasModifications && !picking;\n\n const guideRect = activeMod && !picking && !spaceHeld ? activeMod.element.getBoundingClientRect() : null;\n\n const thumbX = activeMod\n ? isPaddingMode\n ? (MINIMAP_WIDTH_PX - THUMB_SIZE_PX) / 2\n : ((activeMod.fontSize - FONT_SIZE_MIN_PX) / (FONT_SIZE_MAX_PX - FONT_SIZE_MIN_PX)) * (MINIMAP_WIDTH_PX - THUMB_SIZE_PX)\n : 0;\n const thumbY = activeMod\n ? isPaddingMode\n ? (1 - (activeMod.paddingY - PADDING_MIN_PX) / (PADDING_MAX_PX - PADDING_MIN_PX)) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : (1 - activeMod.position / SLIDER_MAX) * (MINIMAP_HEIGHT_PX - THUMB_SIZE_PX)\n : MINIMAP_HEIGHT_PX - THUMB_SIZE_PX;\n\n return (\n <>\n {guideRect && activeMod && (\n <div data-tweaker style={guidelinesContainerStyle}>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: guideRect.height,\n boxSizing: \"border-box\",\n border: \"1px solid rgba(59, 130, 246, 0.5)\",\n borderRadius: 1,\n }}\n />\n {activeMod.paddingY > 0 && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.top,\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderBottom: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n <div\n style={{\n position: \"absolute\",\n left: guideRect.left,\n top: guideRect.bottom - Math.min(activeMod.paddingY, guideRect.height / 2),\n width: guideRect.width,\n height: Math.min(activeMod.paddingY, guideRect.height / 2),\n background: \"rgba(255, 99, 132, 0.1)\",\n borderTop: \"1px dashed rgba(255, 99, 132, 0.35)\",\n }}\n />\n </>\n )}\n <div\n style={{\n position: \"absolute\",\n left: guideRect.right + 8,\n top: guideRect.top,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 4,\n pointerEvents: \"none\",\n }}\n >\n <span style={guidelineLabelStyle}>\n ↕ {activeMod.paddingY}px\n </span>\n <span style={{ ...guidelineLabelStyle, color: \"rgba(59, 130, 246, 0.8)\", background: \"rgba(59, 130, 246, 0.06)\" }}>\n {activeMod.fontSize}px\n </span>\n {(activeMod.translateX !== 0 || activeMod.translateY !== 0) && (\n <span style={{ ...guidelineLabelStyle, color: \"rgba(168, 85, 247, 0.9)\", background: \"rgba(168, 85, 247, 0.08)\" }}>\n {Math.round(activeMod.translateX)}, {Math.round(activeMod.translateY)}\n </span>\n )}\n </div>\n </div>\n )}\n <AnimatePresence>\n {(hasModifications || picking) && (\n <motion.div\n key=\"minimap\"\n data-tweaker\n initial={{ opacity: 0, y: 8 }}\n animate={{ opacity: 1, y: 0 }}\n exit={{ opacity: 0, y: 8 }}\n transition={{ duration: 0.2 }}\n style={minimapContainerStyle}\n >\n <div style={minimapFieldStyle}>\n <div\n style={{\n position: \"absolute\",\n left: thumbX,\n top: thumbY,\n width: THUMB_SIZE_PX,\n height: THUMB_SIZE_PX,\n borderRadius: \"50%\",\n background: fillColor,\n border: \"2px solid rgba(255,255,255,0.9)\",\n boxShadow: \"0 1px 4px rgba(0,0,0,0.4)\",\n transition: \"left 50ms, top 50ms\",\n }}\n />\n </div>\n <div style={minimapModeStyle}>\n <span style={minimapLabelStyle}>\n {isDragMode ? \"⌃ Move\" : isPaddingMode ? \"⇧ Padding\" : \"Style\"}\n </span>\n </div>\n <div style={minimapValuesStyle}>\n <span style={minimapLabelStyle}>\n {picking\n ? \"Picking…\"\n : isDragMode\n ? `x: ${activeMod?.translateX ?? 0}`\n : isPaddingMode\n ? `↕ ${activeMod?.paddingY ?? 0}px`\n : `${propertyLabel} ${inputValue || \"0\"}`}\n </span>\n {!picking && activeMod && isDragMode && (\n <span style={minimapLabelStyle}>\n {`y: ${activeMod.translateY}`}\n </span>\n )}\n {!picking && activeMod && !isPaddingMode && !isDragMode && (\n <span style={minimapLabelStyle}>\n {`${activeMod.fontSize}px`}\n </span>\n )}\n </div>\n </motion.div>\n )}\n </AnimatePresence>\n </>\n );\n};\n\nconst baseTextStyle: React.CSSProperties = {\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n};\n\nconst minimapContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n display: \"flex\",\n flexDirection: \"column\",\n gap: 6,\n};\n\nconst minimapFieldStyle: React.CSSProperties = {\n position: \"relative\",\n width: MINIMAP_WIDTH_PX,\n height: MINIMAP_HEIGHT_PX,\n borderRadius: 8,\n background: \"rgba(0,0,0,0.25)\",\n backdropFilter: \"blur(12px)\",\n WebkitBackdropFilter: \"blur(12px)\",\n boxShadow: \"0 0 0 1px rgba(255,255,255,0.08) inset\",\n overflow: \"hidden\",\n pointerEvents: \"none\",\n};\n\nconst minimapModeStyle: React.CSSProperties = {\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapValuesStyle: React.CSSProperties = {\n display: \"flex\",\n justifyContent: \"space-between\",\n padding: \"0 2px\",\n pointerEvents: \"none\",\n};\n\nconst minimapLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 11,\n color: \"rgba(255,255,255,0.6)\",\n whiteSpace: \"nowrap\",\n};\n\nconst guidelinesContainerStyle: React.CSSProperties = {\n position: \"fixed\",\n inset: 0,\n zIndex: 9998,\n pointerEvents: \"none\",\n};\n\nconst guidelineLabelStyle: React.CSSProperties = {\n ...baseTextStyle,\n fontSize: 10,\n lineHeight: \"16px\",\n color: \"rgba(255, 99, 132, 0.9)\",\n background: \"rgba(255, 99, 132, 0.08)\",\n padding: \"0 5px\",\n borderRadius: 3,\n whiteSpace: \"nowrap\",\n};\n"],"mappings":"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"}
|