@ben-million/tweaker 0.0.2 → 0.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/dist/index.d.ts.map +1 -1
- package/dist/index.js +41 -16
- 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,UAiBO,YAAA;EACf,MAAA,GAAS,MAAA,SAAe,SAAA;EACxB,WAAA;AAAA;;;cCbW,OAAA;EAAW,MAAA;EAAA;AAAA,GAAmD,YAAA,KAAY,kBAAA,CAAA,GAAA,CAAA,OAAA;;;cCR1E,WAAA,EAAa,MAAA,SAAe,SAAA"}
|
package/dist/index.js
CHANGED
|
@@ -137,6 +137,8 @@ const SHADE_KEYS = [
|
|
|
137
137
|
"900",
|
|
138
138
|
"950"
|
|
139
139
|
];
|
|
140
|
+
const FONT_WEIGHT_MIN = 100;
|
|
141
|
+
const FONT_WEIGHT_MAX = 900;
|
|
140
142
|
|
|
141
143
|
//#endregion
|
|
142
144
|
//#region src/utils/color.ts
|
|
@@ -242,7 +244,15 @@ const getTextPreview = (element) => {
|
|
|
242
244
|
|
|
243
245
|
//#endregion
|
|
244
246
|
//#region src/utils/modification.ts
|
|
247
|
+
const positionToFontWeight = (position) => {
|
|
248
|
+
const weight = FONT_WEIGHT_MIN + position / SLIDER_MAX * (FONT_WEIGHT_MAX - FONT_WEIGHT_MIN);
|
|
249
|
+
return Math.round(weight / 100) * 100;
|
|
250
|
+
};
|
|
245
251
|
const applyModification = (modification, scales, scaleKey) => {
|
|
252
|
+
if (modification.property === "weight") {
|
|
253
|
+
modification.element.style.fontWeight = String(positionToFontWeight(modification.position));
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
246
256
|
const colorValue = oklchToCssString(getColorAtPosition(scales, scaleKey, modification.position));
|
|
247
257
|
if (modification.property === "bg") modification.element.style.backgroundColor = colorValue;
|
|
248
258
|
else if (modification.property === "text") modification.element.style.color = colorValue;
|
|
@@ -252,6 +262,7 @@ const restoreModification = (modification) => {
|
|
|
252
262
|
modification.element.style.backgroundColor = modification.originalInlineBg;
|
|
253
263
|
modification.element.style.color = modification.originalInlineColor;
|
|
254
264
|
modification.element.style.borderColor = modification.originalInlineBorderColor;
|
|
265
|
+
modification.element.style.fontWeight = modification.originalInlineFontWeight;
|
|
255
266
|
};
|
|
256
267
|
const roundToStep = (value) => parseFloat((Math.round(value * 10) / 10).toFixed(1));
|
|
257
268
|
|
|
@@ -260,23 +271,32 @@ const roundToStep = (value) => parseFloat((Math.round(value * 10) / 10).toFixed(
|
|
|
260
271
|
const generatePrompt = (modifications, scales, scaleKey) => {
|
|
261
272
|
if (modifications.length === 0) return "";
|
|
262
273
|
const scaleName = scales[scaleKey]?.label || scaleKey;
|
|
263
|
-
const
|
|
274
|
+
const colorLines = [];
|
|
275
|
+
const weightLines = [];
|
|
264
276
|
modifications.forEach((modification) => {
|
|
265
|
-
const shade = getClosestShadeLabel(modification.position);
|
|
266
|
-
const oklch = getColorAtPosition(scales, scaleKey, modification.position);
|
|
267
277
|
const nameParts = [modification.selector];
|
|
268
278
|
if (modification.componentName) nameParts.unshift(`<${modification.componentName}>`);
|
|
269
279
|
if (modification.textPreview) nameParts.push(`("${modification.textPreview}")`);
|
|
270
280
|
const description = nameParts.join(" ");
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
281
|
+
if (modification.property === "weight") {
|
|
282
|
+
const weight = positionToFontWeight(modification.position);
|
|
283
|
+
weightLines.push(`- font-weight of ${description} → ${weight}`);
|
|
284
|
+
if (modification.sourceFile) weightLines.push(` Source: ${modification.sourceFile}`);
|
|
285
|
+
} else {
|
|
286
|
+
const shade = getClosestShadeLabel(modification.position);
|
|
287
|
+
const oklch = getColorAtPosition(scales, scaleKey, modification.position);
|
|
288
|
+
const property = modification.property === "bg" ? "background color" : modification.property === "text" ? "text color" : "border color";
|
|
289
|
+
colorLines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);
|
|
290
|
+
if (modification.sourceFile) colorLines.push(` Source: ${modification.sourceFile}`);
|
|
291
|
+
}
|
|
274
292
|
});
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
293
|
+
const sections = [];
|
|
294
|
+
if (colorLines.length > 0) sections.push("Change the following colors using the design system's gray scale:", "", ...colorLines);
|
|
295
|
+
if (weightLines.length > 0) {
|
|
296
|
+
if (sections.length > 0) sections.push("");
|
|
297
|
+
sections.push("Change the following font weights:", "", ...weightLines);
|
|
298
|
+
}
|
|
299
|
+
return sections.join("\n");
|
|
280
300
|
};
|
|
281
301
|
|
|
282
302
|
//#endregion
|
|
@@ -428,9 +448,9 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
428
448
|
event.preventDefault();
|
|
429
449
|
setPicking(true);
|
|
430
450
|
}
|
|
431
|
-
if (hasModifications && (event.key === "b" || event.key === "f" || event.key === "d")) {
|
|
451
|
+
if (hasModifications && (event.key === "b" || event.key === "f" || event.key === "d" || event.key === "w")) {
|
|
432
452
|
event.preventDefault();
|
|
433
|
-
const property = event.key === "b" ? "bg" : event.key === "f" ? "text" : "border";
|
|
453
|
+
const property = event.key === "b" ? "bg" : event.key === "f" ? "text" : event.key === "d" ? "border" : "weight";
|
|
434
454
|
const index = activeIndexRef.current;
|
|
435
455
|
if (index < 0) return;
|
|
436
456
|
setModifications((previous) => {
|
|
@@ -499,6 +519,7 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
499
519
|
originalInlineBg: target.style.backgroundColor,
|
|
500
520
|
originalInlineColor: target.style.color,
|
|
501
521
|
originalInlineBorderColor: target.style.borderColor,
|
|
522
|
+
originalInlineFontWeight: target.style.fontWeight,
|
|
502
523
|
property: defaultProperty,
|
|
503
524
|
position
|
|
504
525
|
};
|
|
@@ -525,8 +546,12 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
525
546
|
scales,
|
|
526
547
|
modifications.length
|
|
527
548
|
]);
|
|
528
|
-
const fillColor = activeMod ? oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position)) : scales[activeScale]?.shades["500"] ?? "rgba(255,255,255,0.3)";
|
|
529
|
-
const
|
|
549
|
+
const fillColor = activeMod ? activeMod.property === "weight" ? "rgba(255,255,255,0.5)" : oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position)) : scales[activeScale]?.shades["500"] ?? "rgba(255,255,255,0.3)";
|
|
550
|
+
const getPropertyLabel = () => {
|
|
551
|
+
if (!activeMod) return "";
|
|
552
|
+
if (activeMod.property === "weight") return `W ${positionToFontWeight(activeMod.position)}`;
|
|
553
|
+
return `${activeMod.property === "text" ? "F" : activeMod.property === "border" ? "D" : "B"} ${inputValue || "0"}`;
|
|
554
|
+
};
|
|
530
555
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(AnimatePresence, { children: hasModifications && !picking && /* @__PURE__ */ jsx(motion.div, {
|
|
531
556
|
initial: { opacity: 0 },
|
|
532
557
|
animate: { opacity: 1 },
|
|
@@ -575,7 +600,7 @@ const Tweaker = ({ scales = GRAY_SCALES, activeScale = "neutral" }) => {
|
|
|
575
600
|
exit: { opacity: 0 },
|
|
576
601
|
transition: { duration: .1 },
|
|
577
602
|
style: pillTextStyle,
|
|
578
|
-
children: picking ? "Picking…" : hasModifications ?
|
|
603
|
+
children: picking ? "Picking…" : hasModifications ? getPropertyLabel() : "Tweaker"
|
|
579
604
|
}, picking ? "picking" : hasModifications ? "value" : "idle")
|
|
580
605
|
})
|
|
581
606
|
})] });
|
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 BAR_WIDTH_PX = 3;\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\"];\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};\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};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\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 lines: string[] = [];\n\n modifications.forEach((modification) => {\n const shade = getClosestShadeLabel(modification.position);\n const oklch = getColorAtPosition(scales, scaleKey, modification.position);\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 const property =\n modification.property === \"bg\"\n ? \"background color\"\n : modification.property === \"text\"\n ? \"text color\"\n : \"border color\";\n lines.push(`- ${property} of ${description} → ${scaleName} ${shade} (${formatOklch(oklch)})`);\n if (modification.sourceFile) lines.push(` Source: ${modification.sourceFile}`);\n });\n\n return [\n \"Change the following colors using the design system's gray scale:\",\n \"\",\n ...lines,\n ].join(\"\\n\");\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, useMotionValue, useTransform, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, BAR_WIDTH_PX, TYPING_RESET_DELAY_MS } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\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 typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n const fillPercent = useMotionValue(0);\n const fillHeight = useTransform(fillPercent, (percent) => `${percent}%`);\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 useEffect(() => {\n if (activeMod) {\n fillPercent.jump((activeMod.position / SLIDER_MAX) * 100);\n }\n }, [activeMod?.position, fillPercent]);\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 if (!hasModifications || picking) return;\n\n const updateFromY = (clientY: number) => {\n const percent = Math.max(0, Math.min(1, 1 - clientY / window.innerHeight));\n const value = roundToStep(percent * SLIDER_MAX);\n const index = activeIndexRef.current;\n if (index < 0) return;\n fillPercent.jump(percent * 100);\n setModifications((previous) => {\n const updated = [...previous];\n updated[index] = { ...updated[index], position: value };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n setInputValue(String(value));\n };\n\n const handlePointerMove = (event: PointerEvent) => {\n updateFromY(event.clientY);\n };\n\n document.addEventListener(\"pointermove\", handlePointerMove, true);\n return () => {\n document.removeEventListener(\"pointermove\", handlePointerMove, true);\n };\n }, [hasModifications, picking, fillPercent]);\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\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 === \" \") {\n event.preventDefault();\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 document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, 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\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 property: defaultProperty,\n position,\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 return (\n <>\n <AnimatePresence>\n {hasModifications && !picking && (\n <motion.div\n key=\"bar\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n data-tweaker\n style={{\n position: \"fixed\",\n top: 0,\n right: 0,\n width: BAR_WIDTH_PX,\n height: \"100vh\",\n zIndex: 9999,\n pointerEvents: \"none\",\n }}\n >\n <motion.div\n style={{\n position: \"absolute\",\n left: 0,\n right: 0,\n bottom: 0,\n height: fillHeight,\n background: fillColor,\n }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n\n <motion.div\n data-tweaker\n layout\n style={{\n ...pillStyle,\n ...(!hasModifications ? { cursor: \"pointer\" } : {}),\n }}\n animate={{\n backgroundColor: scales[activeScale]?.shades[\"900\"] ?? \"#1A1A1A\",\n }}\n transition={{\n layout: { type: \"spring\", visualDuration: 0.3, bounce: 0.15 },\n backgroundColor: { duration: 0.3 },\n }}\n onClick={!hasModifications ? () => setPicking(!picking) : undefined}\n >\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={picking ? \"picking\" : hasModifications ? \"value\" : \"idle\"}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.1 }}\n style={pillTextStyle}\n >\n {picking\n ? \"Picking…\"\n : hasModifications\n ? `${propertyLabel} ${inputValue || \"0\"}`\n : \"Tweaker\"}\n </motion.span>\n </AnimatePresence>\n </motion.div>\n </>\n );\n};\n\nconst pillStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n background: \"#1A1A1A\",\n color: \"color(display-p3 1 1 1)\",\n borderRadius: 9999,\n height: 28,\n padding: \"0 12px\",\n fontSize: 11,\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n width: \"fit-content\",\n boxShadow: \"0 4px 24px #0000004D\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n};\n\nconst pillTextStyle: React.CSSProperties = {\n fontSize: 11,\n fontWeight: 500,\n color: \"color(display-p3 1 1 1)\",\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/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 BAR_WIDTH_PX = 3;\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_WEIGHT_MIN = 100;\nexport const FONT_WEIGHT_MAX = 900;\nexport const FONT_WEIGHT_STEPS = [100, 200, 300, 400, 500, 600, 700, 800, 900];\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 { SLIDER_MAX, FONT_WEIGHT_MIN, FONT_WEIGHT_MAX } from \"../constants\";\nimport { getColorAtPosition, oklchToCssString } from \"./color\";\n\nexport const positionToFontWeight = (position: number): number => {\n const weight = FONT_WEIGHT_MIN + (position / SLIDER_MAX) * (FONT_WEIGHT_MAX - FONT_WEIGHT_MIN);\n return Math.round(weight / 100) * 100;\n};\n\nexport const fontWeightToPosition = (weight: number): number => {\n return ((weight - FONT_WEIGHT_MIN) / (FONT_WEIGHT_MAX - FONT_WEIGHT_MIN)) * SLIDER_MAX;\n};\n\nexport const applyModification = (\n modification: Modification,\n scales: Record<string, GrayScale>,\n scaleKey: string,\n) => {\n if (modification.property === \"weight\") {\n modification.element.style.fontWeight = String(positionToFontWeight(modification.position));\n return;\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};\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.fontWeight = modification.originalInlineFontWeight;\n};\n\nexport const roundToStep = (value: number): number =>\n parseFloat((Math.round(value * 10) / 10).toFixed(1));\n","import type { GrayScale, Modification } from \"../types\";\nimport { formatOklch, getColorAtPosition, getClosestShadeLabel } from \"./color\";\nimport { positionToFontWeight } from \"./modification\";\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 weightLines: 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 if (modification.property === \"weight\") {\n const weight = positionToFontWeight(modification.position);\n weightLines.push(`- font-weight of ${description} → ${weight}`);\n if (modification.sourceFile) weightLines.push(` Source: ${modification.sourceFile}`);\n } else {\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 });\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 (weightLines.length > 0) {\n if (sections.length > 0) sections.push(\"\");\n sections.push(\"Change the following font weights:\", \"\", ...weightLines);\n }\n\n return sections.join(\"\\n\");\n};\n","import { useState, useCallback, useEffect, useRef } from \"react\";\nimport { motion, useMotionValue, useTransform, AnimatePresence } from \"motion/react\";\nimport type { Modification, TweakerProps } from \"./types\";\nimport { GRAY_SCALES } from \"./gray-scales\";\nimport { SLIDER_MAX, BAR_WIDTH_PX, TYPING_RESET_DELAY_MS } from \"./constants\";\nimport { getColorAtPosition, oklchToCssString, parseRgb, rgbToOklch, findClosestPosition } from \"./utils/color\";\nimport { getSelector, getTextPreview } from \"./utils/dom\";\nimport { applyModification, restoreModification, roundToStep, positionToFontWeight } from \"./utils/modification\";\nimport { generatePrompt } from \"./utils/prompt\";\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 typingBuffer = useRef(\"\");\n const typingTimeout = useRef<ReturnType<typeof setTimeout>>(undefined);\n const fillPercent = useMotionValue(0);\n const fillHeight = useTransform(fillPercent, (percent) => `${percent}%`);\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 useEffect(() => {\n if (activeMod) {\n fillPercent.jump((activeMod.position / SLIDER_MAX) * 100);\n }\n }, [activeMod?.position, fillPercent]);\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 if (!hasModifications || picking) return;\n\n const updateFromY = (clientY: number) => {\n const percent = Math.max(0, Math.min(1, 1 - clientY / window.innerHeight));\n const value = roundToStep(percent * SLIDER_MAX);\n const index = activeIndexRef.current;\n if (index < 0) return;\n fillPercent.jump(percent * 100);\n setModifications((previous) => {\n const updated = [...previous];\n updated[index] = { ...updated[index], position: value };\n applyModification(updated[index], scalesRef.current, activeScaleRef.current);\n return updated;\n });\n setInputValue(String(value));\n };\n\n const handlePointerMove = (event: PointerEvent) => {\n updateFromY(event.clientY);\n };\n\n document.addEventListener(\"pointermove\", handlePointerMove, true);\n return () => {\n document.removeEventListener(\"pointermove\", handlePointerMove, true);\n };\n }, [hasModifications, picking, fillPercent]);\n\n useEffect(() => {\n if (!hasModifications) return;\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n event.preventDefault();\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 === \" \") {\n event.preventDefault();\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\" || event.key === \"w\")) {\n event.preventDefault();\n const property: \"bg\" | \"text\" | \"border\" | \"weight\" =\n event.key === \"b\" ? \"bg\" : event.key === \"f\" ? \"text\" : event.key === \"d\" ? \"border\" : \"weight\";\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 document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, [hasModifications]);\n\n useEffect(() => {\n return () => {\n modifications.forEach(restoreModification);\n };\n }, []);\n\n useEffect(() => {\n if (activeMod) {\n applyModification(activeMod, scales, activeScale);\n }\n }, [activeMod?.position, 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\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 originalInlineFontWeight: target.style.fontWeight,\n property: defaultProperty,\n position,\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 ? activeMod.property === \"weight\"\n ? \"rgba(255,255,255,0.5)\"\n : oklchToCssString(getColorAtPosition(scales, activeScale, activeMod.position))\n : scales[activeScale]?.shades[\"500\"] ?? \"rgba(255,255,255,0.3)\";\n\n const getPropertyLabel = (): string => {\n if (!activeMod) return \"\";\n if (activeMod.property === \"weight\") return `W ${positionToFontWeight(activeMod.position)}`;\n const prefix = activeMod.property === \"text\" ? \"F\" : activeMod.property === \"border\" ? \"D\" : \"B\";\n return `${prefix} ${inputValue || \"0\"}`;\n };\n\n return (\n <>\n <AnimatePresence>\n {hasModifications && !picking && (\n <motion.div\n key=\"bar\"\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n data-tweaker\n style={{\n position: \"fixed\",\n top: 0,\n right: 0,\n width: BAR_WIDTH_PX,\n height: \"100vh\",\n zIndex: 9999,\n pointerEvents: \"none\",\n }}\n >\n <motion.div\n style={{\n position: \"absolute\",\n left: 0,\n right: 0,\n bottom: 0,\n height: fillHeight,\n background: fillColor,\n }}\n />\n </motion.div>\n )}\n </AnimatePresence>\n\n <motion.div\n data-tweaker\n layout\n style={{\n ...pillStyle,\n ...(!hasModifications ? { cursor: \"pointer\" } : {}),\n }}\n animate={{\n backgroundColor: scales[activeScale]?.shades[\"900\"] ?? \"#1A1A1A\",\n }}\n transition={{\n layout: { type: \"spring\", visualDuration: 0.3, bounce: 0.15 },\n backgroundColor: { duration: 0.3 },\n }}\n onClick={!hasModifications ? () => setPicking(!picking) : undefined}\n >\n <AnimatePresence mode=\"wait\">\n <motion.span\n key={picking ? \"picking\" : hasModifications ? \"value\" : \"idle\"}\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.1 }}\n style={pillTextStyle}\n >\n {picking\n ? \"Picking…\"\n : hasModifications\n ? getPropertyLabel()\n : \"Tweaker\"}\n </motion.span>\n </AnimatePresence>\n </motion.div>\n </>\n );\n};\n\nconst pillStyle: React.CSSProperties = {\n position: \"fixed\",\n left: 16,\n bottom: 16,\n zIndex: 9999,\n background: \"#1A1A1A\",\n color: \"color(display-p3 1 1 1)\",\n borderRadius: 9999,\n height: 28,\n padding: \"0 12px\",\n fontSize: 11,\n fontFamily: \"system-ui, sans-serif\",\n fontWeight: 500,\n letterSpacing: \"-0.03em\",\n fontSynthesis: \"none\",\n WebkitFontSmoothing: \"antialiased\",\n width: \"fit-content\",\n boxShadow: \"0 4px 24px #0000004D\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n};\n\nconst pillTextStyle: React.CSSProperties = {\n fontSize: 11,\n fontWeight: 500,\n color: \"color(display-p3 1 1 1)\",\n whiteSpace: \"nowrap\",\n};\n"],"mappings":"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"}
|