edododraw 0.1.3 → 0.1.4

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.
@@ -252,6 +252,17 @@ const FILL_PALETTE = {
252
252
  brown: "#e5dbd4",
253
253
  white: "#ffffff"
254
254
  };
255
+ function isLightColor(color) {
256
+ if (!color) return false;
257
+ const c = color.trim().toLowerCase();
258
+ let hex = c.startsWith("#") ? c.slice(1) : "";
259
+ if (hex.length === 3) hex = hex.replace(/./g, (ch) => ch + ch);
260
+ if (hex.length !== 6 || /[^0-9a-f]/.test(hex)) return true;
261
+ const r2 = parseInt(hex.slice(0, 2), 16);
262
+ const g = parseInt(hex.slice(2, 4), 16);
263
+ const b = parseInt(hex.slice(4, 6), 16);
264
+ return 0.299 * r2 + 0.587 * g + 0.114 * b > 150;
265
+ }
255
266
  function resolveStroke(token, fallback) {
256
267
  if (!token) return fallback;
257
268
  const t = token.trim().toLowerCase();
@@ -3355,7 +3366,7 @@ const LIGHT_THEME = {
3355
3366
  background: "#ffffff",
3356
3367
  defaultStroke: STROKE_PALETTE.black,
3357
3368
  defaultText: STROKE_PALETTE.black,
3358
- gridColor: "#eceff3",
3369
+ gridColor: "#d5d9e0",
3359
3370
  mode: "light"
3360
3371
  };
3361
3372
  const DARK_THEME = {
@@ -3363,7 +3374,7 @@ const DARK_THEME = {
3363
3374
  background: "#121212",
3364
3375
  defaultStroke: "#e3e3e3",
3365
3376
  defaultText: "#e3e3e3",
3366
- gridColor: "#22262c",
3377
+ gridColor: "#2c313a",
3367
3378
  mode: "dark"
3368
3379
  };
3369
3380
  function defaultNodeStyle(seed, mode = "light") {
@@ -3769,7 +3780,8 @@ function compileProgram(program, opts = {}) {
3769
3780
  for (const t of themes.get(name).tokens) tokenMap.set(t.name, t.value);
3770
3781
  }
3771
3782
  }
3772
- const mode = themeName?.toLowerCase().includes("dark") ? "dark" : "light";
3783
+ const derivedMode = themeName?.toLowerCase().includes("dark") ? "dark" : "light";
3784
+ const mode = opts.mode ?? derivedMode;
3773
3785
  const classAttrs = (name, seen = /* @__PURE__ */ new Set()) => {
3774
3786
  if (seen.has(name) || !styles.has(name)) return { attrs: [] };
3775
3787
  seen.add(name);
@@ -3795,6 +3807,7 @@ function compileProgram(program, opts = {}) {
3795
3807
  const classes = collectClasses(nd);
3796
3808
  const layered = styleFor("node", classes, nd.attrs);
3797
3809
  const built = buildNodeStyle(layered, tokenMap);
3810
+ applyDarkInk(built.style, mode);
3798
3811
  const shape = mapShape(built.shape ?? nd.shape);
3799
3812
  const label = built.label ?? nd.label ?? prettyId(id);
3800
3813
  const node = makeNode({
@@ -3910,6 +3923,15 @@ function collectTags(nd) {
3910
3923
  }
3911
3924
  return tags;
3912
3925
  }
3926
+ const DARK_INK = "#1e1e1e";
3927
+ const LIGHT_INK = "#e3e3e3";
3928
+ function applyDarkInk(style, mode) {
3929
+ if (mode !== "dark") return;
3930
+ const solidLightFill = style.fillStyle === "solid" && isLightColor(style.fill ?? null);
3931
+ const ink = solidLightFill ? DARK_INK : LIGHT_INK;
3932
+ if (style.textColor === void 0) style.textColor = ink;
3933
+ if (style.stroke === void 0 && solidLightFill) style.stroke = DARK_INK;
3934
+ }
3913
3935
  function buildNodeStyle(attrs, tokens, _mode) {
3914
3936
  const style = {};
3915
3937
  const out = { style };
@@ -4107,6 +4129,7 @@ function ensureInline(scene, nd, tokens, mode, styleFor) {
4107
4129
  if (scene.nodes.some((n) => n.id === nd.id)) return;
4108
4130
  const layered = styleFor("node", nd.classes, nd.attrs);
4109
4131
  const built = buildNodeStyle(layered, tokens);
4132
+ applyDarkInk(built.style, mode);
4110
4133
  scene.nodes.push(
4111
4134
  makeNode({
4112
4135
  id: nd.id,
@@ -4339,9 +4362,9 @@ function normalizeCamOp(op) {
4339
4362
  return "focus";
4340
4363
  }
4341
4364
  }
4342
- function compileEdd(source) {
4365
+ function compileEdd(source, opts = {}) {
4343
4366
  const { program, diagnostics } = parse(source);
4344
- const { scene } = compileProgram(program, { diagnostics });
4367
+ const { scene } = compileProgram(program, { diagnostics, mode: opts.mode });
4345
4368
  const report = diagnostics.items.map((d) => formatDiagnostic(d, source));
4346
4369
  return { scene, diagnostics, report };
4347
4370
  }
@@ -5317,7 +5340,9 @@ class SvgRenderer {
5317
5340
  }
5318
5341
  render(scene) {
5319
5342
  this.scene = scene;
5320
- this.bg.setAttribute("fill", scene.meta.background || scene.theme.background);
5343
+ const bgColor = scene.meta.background || scene.theme.background;
5344
+ this.bg.setAttribute("fill", "transparent");
5345
+ this.container.style.backgroundColor = bgColor;
5321
5346
  for (const name of ["groups", "edges", "nodes"]) this.layers[name].replaceChildren();
5322
5347
  for (const group of scene.groups) {
5323
5348
  if (!group.frame) continue;
@@ -5698,6 +5723,8 @@ class EdodoDraw {
5698
5723
  listeners = /* @__PURE__ */ new Map();
5699
5724
  textInput = null;
5700
5725
  closeInput = null;
5726
+ colorScheme = null;
5727
+ hasRendered = false;
5701
5728
  cleanup = [];
5702
5729
  constructor(container, options = {}) {
5703
5730
  this.container = container;
@@ -5756,7 +5783,7 @@ class EdodoDraw {
5756
5783
  async render(source) {
5757
5784
  this.source = source;
5758
5785
  const seq = ++this.renderSeq;
5759
- const { scene, diagnostics } = compileEdd(source);
5786
+ const { scene, diagnostics } = compileEdd(source, { mode: this.colorScheme ?? void 0 });
5760
5787
  let diags = diagnostics.items;
5761
5788
  const blocks = extractMermaidBlocks(source);
5762
5789
  if (blocks.length) {
@@ -5773,6 +5800,7 @@ class EdodoDraw {
5773
5800
  }
5774
5801
  if (seq !== this.renderSeq) return { scene, diagnostics: diags };
5775
5802
  this.scene = scene;
5803
+ this.hasRendered = true;
5776
5804
  this.renderer.render(scene);
5777
5805
  this.player.load(scene);
5778
5806
  this.renderer.measure();
@@ -5792,6 +5820,21 @@ class EdodoDraw {
5792
5820
  getSource() {
5793
5821
  return this.source;
5794
5822
  }
5823
+ /**
5824
+ * Force light/dark rendering, overriding the diagram's declared theme. Affects
5825
+ * the canvas background, the dotted grid, and the diagram's default ink
5826
+ * (strokes/text adapt for contrast on the dark canvas; explicit colors are
5827
+ * kept). Pass `null` to fall back to the DSL's own theme. Re-renders the
5828
+ * current source. Cheap and idempotent — no-ops if the scheme is unchanged.
5829
+ */
5830
+ setColorScheme(mode) {
5831
+ if (this.colorScheme === mode) return;
5832
+ this.colorScheme = mode;
5833
+ if (this.hasRendered) void this.render(this.source);
5834
+ }
5835
+ getColorScheme() {
5836
+ return this.colorScheme;
5837
+ }
5795
5838
  // ---- camera -------------------------------------------------------------
5796
5839
  fit(animate = true) {
5797
5840
  this.renderer.measure();
@@ -5929,7 +5972,8 @@ class EdodoDraw {
5929
5972
  c.style.backgroundImage = "none";
5930
5973
  return;
5931
5974
  }
5932
- c.style.backgroundImage = "radial-gradient(circle, #d5d9e0 1px, transparent 1px)";
5975
+ const dot = this.scene.theme.gridColor;
5976
+ c.style.backgroundImage = `radial-gradient(circle, ${dot} 1px, transparent 1px)`;
5933
5977
  c.style.backgroundSize = `${cell}px ${cell}px`;
5934
5978
  c.style.backgroundPosition = `${-cam.cx * cam.zoom + w / 2}px ${-cam.cy * cam.zoom + h / 2}px`;
5935
5979
  }
@@ -6013,11 +6057,18 @@ class EdodoDraw {
6013
6057
  }
6014
6058
  /** Inline text editor for renaming a node (double-click / new node). */
6015
6059
  showRenameInput(id, current, screen) {
6060
+ const dark = this.scene.theme.mode === "dark";
6016
6061
  this.openInlineInput({
6017
6062
  value: current,
6018
6063
  placeholder: "label…",
6019
6064
  screen,
6020
- style: { background: "#ffffff", color: "#1e1e1e", textAlign: "center", zIndex: "30", minWidth: "80px" },
6065
+ style: {
6066
+ background: dark ? "#23262d" : "#ffffff",
6067
+ color: dark ? "#e6e7ea" : "#1e1e1e",
6068
+ textAlign: "center",
6069
+ zIndex: "30",
6070
+ minWidth: "80px"
6071
+ },
6021
6072
  onCommit: (v) => this.edit.applyRename(id, v)
6022
6073
  });
6023
6074
  }
@@ -6121,26 +6172,27 @@ export {
6121
6172
  hitTestNode as a3,
6122
6173
  injectMermaid as a4,
6123
6174
  isEmptyBBox as a5,
6124
- lerp$1 as a6,
6125
- listShapePlugins as a7,
6126
- makeEdge as a8,
6127
- makeNode as a9,
6128
- nodeBBox as aa,
6129
- nodeRect as ab,
6130
- nodeRectOf as ac,
6131
- pairedStrokeForFill as ad,
6132
- pointInRect as ae,
6133
- rectCenter as af,
6134
- rectToBBox as ag,
6135
- registerShape as ah,
6136
- renameNode as ai,
6137
- resolveAnchor as aj,
6138
- resolveFill as ak,
6139
- resolveMarker as al,
6140
- resolveStroke as am,
6141
- sceneBBox as an,
6142
- styleNode as ao,
6143
- writeOverrides as ap,
6175
+ isLightColor as a6,
6176
+ lerp$1 as a7,
6177
+ listShapePlugins as a8,
6178
+ makeEdge as a9,
6179
+ makeNode as aa,
6180
+ nodeBBox as ab,
6181
+ nodeRect as ac,
6182
+ nodeRectOf as ad,
6183
+ pairedStrokeForFill as ae,
6184
+ pointInRect as af,
6185
+ rectCenter as ag,
6186
+ rectToBBox as ah,
6187
+ registerShape as ai,
6188
+ renameNode as aj,
6189
+ resolveAnchor as ak,
6190
+ resolveFill as al,
6191
+ resolveMarker as am,
6192
+ resolveStroke as an,
6193
+ sceneBBox as ao,
6194
+ styleNode as ap,
6195
+ writeOverrides as aq,
6144
6196
  EditController as b,
6145
6197
  EdodoDraw as c,
6146
6198
  FONT_FAMILY as d,
@@ -6167,4 +6219,4 @@ export {
6167
6219
  deleteElements as y,
6168
6220
  dist as z
6169
6221
  };
6170
- //# sourceMappingURL=EdodoDraw-BCfKu4Q3.js.map
6222
+ //# sourceMappingURL=EdodoDraw-BdJowisU.js.map