@trops/dash-core 0.1.575 → 0.1.577

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.
@@ -34,7 +34,6 @@ var require$$1$5 = require('http2');
34
34
  var require$$2$5 = require('node-forge');
35
35
  var require$$0$a = require('css');
36
36
  var require$$1$6 = require('node-vibrant/node');
37
- var dashReact = require('@trops/dash-react');
38
37
  var require$$3$3 = require('ws');
39
38
 
40
39
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
@@ -50818,7 +50817,7 @@ function parseColor(str) {
50818
50817
  /^hsla?\(\s*([\d.]+)\s*[,/\s]\s*([\d.]+)%\s*[,/\s]\s*([\d.]+)%/,
50819
50818
  );
50820
50819
  if (hslMatch) {
50821
- return hslToRgb(
50820
+ return hslToRgb$1(
50822
50821
  parseFloat(hslMatch[1]),
50823
50822
  parseFloat(hslMatch[2]),
50824
50823
  parseFloat(hslMatch[3]),
@@ -50832,7 +50831,7 @@ function parseColor(str) {
50832
50831
  }
50833
50832
 
50834
50833
  /** HSL (h: 0-360, s: 0-100, l: 0-100) → { r, g, b } (0-255) */
50835
- function hslToRgb(h, s, l) {
50834
+ function hslToRgb$1(h, s, l) {
50836
50835
  s /= 100;
50837
50836
  l /= 100;
50838
50837
  const k = (n) => (n + h / 30) % 12;
@@ -50847,7 +50846,7 @@ function hslToRgb(h, s, l) {
50847
50846
  }
50848
50847
 
50849
50848
  /** { r, g, b } → hex string "#rrggbb" */
50850
- function rgbToHex({ r, g, b }) {
50849
+ function rgbToHex$1({ r, g, b }) {
50851
50850
  return (
50852
50851
  "#" +
50853
50852
  [r, g, b]
@@ -50857,7 +50856,7 @@ function rgbToHex({ r, g, b }) {
50857
50856
  }
50858
50857
 
50859
50858
  /** { r, g, b } (0-255) → { h, s, l } (h: 0-360, s/l: 0-100) */
50860
- function rgbToHsl$1({ r, g, b }) {
50859
+ function rgbToHsl$2({ r, g, b }) {
50861
50860
  r /= 255;
50862
50861
  g /= 255;
50863
50862
  b /= 255;
@@ -50930,7 +50929,7 @@ function extractMetaColors(htmlContent) {
50930
50929
  const rgb = parseColor(themeColorMatch[1]);
50931
50930
  if (rgb)
50932
50931
  results.push({
50933
- hex: rgbToHex(rgb),
50932
+ hex: rgbToHex$1(rgb),
50934
50933
  source: "meta",
50935
50934
  confidence: 1.0,
50936
50935
  });
@@ -50944,7 +50943,7 @@ function extractMetaColors(htmlContent) {
50944
50943
  const rgb = parseColor(themeColorMatch2[1]);
50945
50944
  if (rgb)
50946
50945
  results.push({
50947
- hex: rgbToHex(rgb),
50946
+ hex: rgbToHex$1(rgb),
50948
50947
  source: "meta",
50949
50948
  confidence: 1.0,
50950
50949
  });
@@ -50958,7 +50957,7 @@ function extractMetaColors(htmlContent) {
50958
50957
  const rgb = parseColor(tileColorMatch[1]);
50959
50958
  if (rgb)
50960
50959
  results.push({
50961
- hex: rgbToHex(rgb),
50960
+ hex: rgbToHex$1(rgb),
50962
50961
  source: "meta",
50963
50962
  confidence: 0.9,
50964
50963
  });
@@ -50972,7 +50971,7 @@ function extractMetaColors(htmlContent) {
50972
50971
  const rgb = parseColor(tileColorMatch2[1]);
50973
50972
  if (rgb)
50974
50973
  results.push({
50975
- hex: rgbToHex(rgb),
50974
+ hex: rgbToHex$1(rgb),
50976
50975
  source: "meta",
50977
50976
  confidence: 0.9,
50978
50977
  });
@@ -50999,7 +50998,7 @@ function extractCssVarColors(cssContent) {
50999
50998
  const rgb = parseColor(value);
51000
50999
  if (rgb) {
51001
51000
  results.push({
51002
- hex: rgbToHex(rgb),
51001
+ hex: rgbToHex$1(rgb),
51003
51002
  source: "cssvar",
51004
51003
  confidence: 0.8,
51005
51004
  });
@@ -51022,7 +51021,7 @@ function extractCssVarColors(cssContent) {
51022
51021
  const rgb = parseColor(decl.value);
51023
51022
  if (rgb) {
51024
51023
  results.push({
51025
- hex: rgbToHex(rgb),
51024
+ hex: rgbToHex$1(rgb),
51026
51025
  source: "cssvar",
51027
51026
  confidence: 0.8,
51028
51027
  });
@@ -51056,7 +51055,7 @@ function extractComputedColors(computedStyles) {
51056
51055
  const rgb = parseColor(styles[prop]);
51057
51056
  if (rgb) {
51058
51057
  results.push({
51059
- hex: rgbToHex(rgb),
51058
+ hex: rgbToHex$1(rgb),
51060
51059
  source: "computed",
51061
51060
  confidence: 0.6,
51062
51061
  });
@@ -51080,7 +51079,7 @@ function extractDomColors(domColors) {
51080
51079
  const rgb = parseColor(entry.color);
51081
51080
  if (!rgb) continue;
51082
51081
  results.push({
51083
- hex: rgbToHex(rgb),
51082
+ hex: rgbToHex$1(rgb),
51084
51083
  source: "dom",
51085
51084
  confidence: 0.7,
51086
51085
  count: entry.count,
@@ -51244,7 +51243,7 @@ async function extractFaviconColors(htmlContent, baseUrl) {
51244
51243
  const swatch = palette[name];
51245
51244
  if (!swatch) continue;
51246
51245
  const [r, g, b] = swatch.rgb;
51247
- const hex = rgbToHex({
51246
+ const hex = rgbToHex$1({
51248
51247
  r: Math.round(r),
51249
51248
  g: Math.round(g),
51250
51249
  b: Math.round(b),
@@ -51282,7 +51281,7 @@ async function extractFaviconColors(htmlContent, baseUrl) {
51282
51281
  function isBoringColor(hex) {
51283
51282
  const rgb = parseColor(hex);
51284
51283
  if (!rgb) return true;
51285
- const hsl = rgbToHsl$1(rgb);
51284
+ const hsl = rgbToHsl$2(rgb);
51286
51285
 
51287
51286
  // Near-black or near-white
51288
51287
  if (hsl.l < 5 || hsl.l > 95) return true;
@@ -51353,7 +51352,7 @@ function mergeAndRank(allColors, maxColors = 6) {
51353
51352
 
51354
51353
  // Score: confidence * frequency weight * saturation bonus
51355
51354
  const scored = interesting.map((c) => {
51356
- const hsl = rgbToHsl$1(c.rgb);
51355
+ const hsl = rgbToHsl$2(c.rgb);
51357
51356
  const freqWeight = Math.min(c.count / 3, 1.5); // cap frequency bonus
51358
51357
  const satBonus = 1 + hsl.s / 200; // slight boost for saturated colors
51359
51358
  return {
@@ -51383,7 +51382,7 @@ function mergeAndRank(allColors, maxColors = 6) {
51383
51382
  // append the top boring color as a candidate for the neutral role
51384
51383
  if (boring.length > 0 && palette.length < maxColors) {
51385
51384
  const bestBoring = boring.sort((a, b) => b.confidence - a.confidence)[0];
51386
- const hsl = rgbToHsl$1(bestBoring.rgb);
51385
+ const hsl = rgbToHsl$2(bestBoring.rgb);
51387
51386
  palette.push({
51388
51387
  hex: bestBoring.hex,
51389
51388
  rgb: {
@@ -51573,18 +51572,91 @@ var require$$8 = /*@__PURE__*/getAugmentedNamespace(colorUtils);
51573
51572
  * Utility for generating themes via presets, random generation,
51574
51573
  * and color-harmony-based generation from a user-selected base color.
51575
51574
  */
51575
+ // All color math is inlined here (no @trops/dash-react import). This
51576
+ // file is reachable from Electron's main process via
51577
+ // `electron/controller/paletteToThemeMapper.js`. Importing dash-react
51578
+ // from a main-process reachable file pulls dash-react's renderer
51579
+ // bundle into the main bundle — that bundle has top-level browser
51580
+ // API access (`window.ResizeObserver` in CodeEditorVS) which throws
51581
+ // when required under Node. Keeping this module pure-JS / no-deps
51582
+ // breaks the chain.
51583
+
51584
+ const HEX_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
51585
+ function isHexColor(value) {
51586
+ return typeof value === "string" && HEX_RE.test(value.trim());
51587
+ }
51588
+ function normalizeHex(input) {
51589
+ if (typeof input !== "string") return null;
51590
+ let s = input.trim().toLowerCase();
51591
+ if (!s.startsWith("#")) s = `#${s}`;
51592
+ if (!HEX_RE.test(s)) return null;
51593
+ if (s.length === 4) s = `#${s[1]}${s[1]}${s[2]}${s[2]}${s[3]}${s[3]}`;
51594
+ else if (s.length === 5) s = `#${s[1]}${s[1]}${s[2]}${s[2]}${s[3]}${s[3]}`;
51595
+ else if (s.length === 9) s = s.slice(0, 7);
51596
+ return s;
51597
+ }
51598
+ function hexToRgb(hex) {
51599
+ const n = normalizeHex(hex);
51600
+ if (!n) return null;
51601
+ const v = parseInt(n.slice(1), 16);
51602
+ return { r: (v >> 16) & 0xff, g: (v >> 8) & 0xff, b: v & 0xff };
51603
+ }
51604
+ function rgbToHex({ r, g, b }) {
51605
+ const c = (x) => Math.max(0, Math.min(255, Math.round(x)));
51606
+ const h = (x) => c(x).toString(16).padStart(2, "0");
51607
+ return `#${h(r)}${h(g)}${h(b)}`;
51608
+ }
51609
+ function rgbToHsl$1({ r, g, b }) {
51610
+ const R = r / 255,
51611
+ G = g / 255,
51612
+ B = b / 255;
51613
+ const max = Math.max(R, G, B),
51614
+ min = Math.min(R, G, B);
51615
+ const l = (max + min) / 2;
51616
+ let h = 0,
51617
+ s = 0;
51618
+ if (max !== min) {
51619
+ const d = max - min;
51620
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
51621
+ switch (max) {
51622
+ case R:
51623
+ h = (G - B) / d + (G < B ? 6 : 0);
51624
+ break;
51625
+ case G:
51626
+ h = (B - R) / d + 2;
51627
+ break;
51628
+ default:
51629
+ h = (R - G) / d + 4;
51630
+ }
51631
+ h *= 60;
51632
+ }
51633
+ return { h, s, l };
51634
+ }
51635
+ function hslToRgb({ h, s, l }) {
51636
+ if (s === 0) {
51637
+ const v = l * 255;
51638
+ return { r: v, g: v, b: v };
51639
+ }
51640
+ const c = (1 - Math.abs(2 * l - 1)) * s;
51641
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
51642
+ const m = l - c / 2;
51643
+ let rp, gp, bp;
51644
+ if (h < 60) [rp, gp, bp] = [c, x, 0];
51645
+ else if (h < 120) [rp, gp, bp] = [x, c, 0];
51646
+ else if (h < 180) [rp, gp, bp] = [0, c, x];
51647
+ else if (h < 240) [rp, gp, bp] = [0, x, c];
51648
+ else if (h < 300) [rp, gp, bp] = [x, 0, c];
51649
+ else [rp, gp, bp] = [c, 0, x];
51650
+ return { r: (rp + m) * 255, g: (gp + m) * 255, b: (bp + m) * 255 };
51651
+ }
51576
51652
 
51577
- // Color harmony helpers — inlined so dash-core can ship the new
51578
- // "From Colors" generator without first publishing matching
51579
- // exports from @trops/dash-react. Same math as the planned dash-react
51580
- // counterparts; can be replaced with a re-export once both ship in
51581
- // the same cycle.
51653
+ // Color harmony helpers — pure JS, no DOM/window access.
51582
51654
  function rotateHex(hex, deltaH) {
51583
- const rgb = dashReact.hexToRgb(hex);
51655
+ const rgb = hexToRgb(hex);
51584
51656
  if (!rgb) return null;
51585
- const { h, s, l } = dashReact.rgbToHsl(rgb);
51657
+ const { h, s, l } = rgbToHsl$1(rgb);
51586
51658
  const newH = (((h + deltaH) % 360) + 360) % 360;
51587
- return dashReact.rgbToHex(dashReact.hslToRgb({ h: newH, s, l }));
51659
+ return rgbToHex(hslToRgb({ h: newH, s, l }));
51588
51660
  }
51589
51661
  function complementHex(hex) {
51590
51662
  return rotateHex(hex, 180);
@@ -51611,26 +51683,26 @@ function tetradicHexes(hex) {
51611
51683
  return a && b && c ? [a, b, c] : null;
51612
51684
  }
51613
51685
  function monochromaticHexes(hex, count = 3) {
51614
- const rgb = dashReact.hexToRgb(hex);
51686
+ const rgb = hexToRgb(hex);
51615
51687
  if (!rgb) return null;
51616
- const { h, s } = dashReact.rgbToHsl(rgb);
51688
+ const { h, s } = rgbToHsl$1(rgb);
51617
51689
  const out = [];
51618
51690
  for (let i = 0; i < count; i++) {
51619
51691
  const t = count === 1 ? 0.5 : i / (count - 1);
51620
51692
  const l = 0.15 + t * 0.7;
51621
51693
  const sAdj = s * (1 - 0.3 * Math.abs(t - 0.5) * 2);
51622
- out.push(dashReact.rgbToHex(dashReact.hslToRgb({ h, s: sAdj, l })));
51694
+ out.push(rgbToHex(hslToRgb({ h, s: sAdj, l })));
51623
51695
  }
51624
51696
  return out;
51625
51697
  }
51626
51698
  function adjustHsl(hex, dH = 0, dS = 0, dL = 0) {
51627
- const rgb = dashReact.hexToRgb(hex);
51699
+ const rgb = hexToRgb(hex);
51628
51700
  if (!rgb) return null;
51629
- const hsl = dashReact.rgbToHsl(rgb);
51701
+ const hsl = rgbToHsl$1(rgb);
51630
51702
  const h = (((hsl.h + dH) % 360) + 360) % 360;
51631
51703
  const s = Math.max(0, Math.min(1, hsl.s + dS));
51632
51704
  const l = Math.max(0, Math.min(1, hsl.l + dL));
51633
- return dashReact.rgbToHex(dashReact.hslToRgb({ h, s, l }));
51705
+ return rgbToHex(hslToRgb({ h, s, l }));
51634
51706
  }
51635
51707
 
51636
51708
  // Color wheel mapping for Tailwind palettes (approximate hue angles)
@@ -51828,6 +51900,28 @@ function generateRandomTheme() {
51828
51900
  return buildRawTheme(name, primary, secondary, tertiary, neutral);
51829
51901
  }
51830
51902
 
51903
+ /**
51904
+ * Generate a random theme with all-hex channels. Picks a random hue
51905
+ * + harmony, runs it through the hex-mode generator, applies the
51906
+ * optional HSL nudge uniformly. Same shape as `generateRandomTheme`
51907
+ * but every channel is a hex string (suitable for the hex-aware
51908
+ * editor + slider nudges).
51909
+ */
51910
+ function generateRandomHexTheme(hslNudge = null) {
51911
+ const h = Math.floor(Math.random() * 360);
51912
+ const baseHex = rgbToHex(hslToRgb({ h, s: 0.65, l: 0.5 }));
51913
+ const strategies = [
51914
+ "complementary",
51915
+ "analogous",
51916
+ "triadic",
51917
+ "split-complementary",
51918
+ "tetradic",
51919
+ "monochromatic",
51920
+ ];
51921
+ const strategy = pick(strategies);
51922
+ return generateHexHarmonyTheme(baseHex, strategy, hslNudge);
51923
+ }
51924
+
51831
51925
  // ─── Color Harmony Generation ────────────────────────────────────────────
51832
51926
 
51833
51927
  /**
@@ -51847,7 +51941,7 @@ function generateHarmonyTheme(
51847
51941
  strategy = "complementary",
51848
51942
  hslNudge = null,
51849
51943
  ) {
51850
- if (typeof baseColor === "string" && dashReact.isHexColor(baseColor)) {
51944
+ if (typeof baseColor === "string" && isHexColor(baseColor)) {
51851
51945
  return generateHexHarmonyTheme(baseColor, strategy, hslNudge);
51852
51946
  }
51853
51947
 
@@ -51896,7 +51990,7 @@ function generateHarmonyTheme(
51896
51990
  * almost fully, keeping the same hue family for a cohesive feel.
51897
51991
  */
51898
51992
  function generateHexHarmonyTheme(baseHex, strategy, hslNudge) {
51899
- const base = dashReact.normalizeHex(baseHex);
51993
+ const base = normalizeHex(baseHex);
51900
51994
  if (!base) return generateRandomTheme();
51901
51995
 
51902
51996
  let primary = base;
@@ -52017,6 +52111,7 @@ var themeGenerator = /*#__PURE__*/Object.freeze({
52017
52111
  HARMONY_STRATEGIES: HARMONY_STRATEGIES,
52018
52112
  generateCustomTheme: generateCustomTheme,
52019
52113
  generateHarmonyTheme: generateHarmonyTheme,
52114
+ generateRandomHexTheme: generateRandomHexTheme,
52020
52115
  generateRandomTheme: generateRandomTheme,
52021
52116
  generateThemeName: generateThemeName$1,
52022
52117
  getBrandPresets: getBrandPresets,