@skillpet/circuit 0.5.2 → 0.6.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.
@@ -30173,15 +30173,37 @@ var BUILTIN_THEMES = {
30173
30173
  lw: 1.5
30174
30174
  }
30175
30175
  };
30176
+ var CSS_VARS = {
30177
+ bg: "--circuit-bg",
30178
+ stroke: "--circuit-stroke",
30179
+ fill: "--circuit-fill",
30180
+ text: "--circuit-text",
30181
+ font: "--circuit-font",
30182
+ lw: "--circuit-lw"
30183
+ };
30184
+ function readCssTheme() {
30185
+ if (typeof getComputedStyle === "undefined") return { ...BUILTIN_THEMES.light };
30186
+ const s = getComputedStyle(document.documentElement);
30187
+ const v = (name) => s.getPropertyValue(name).trim();
30188
+ return {
30189
+ bg: v(CSS_VARS.bg) || "transparent",
30190
+ stroke: v(CSS_VARS.stroke) || BUILTIN_THEMES.light.stroke,
30191
+ fill: v(CSS_VARS.fill) || "none",
30192
+ text: v(CSS_VARS.text) || BUILTIN_THEMES.light.text,
30193
+ font: v(CSS_VARS.font) || BUILTIN_THEMES.light.font,
30194
+ lw: parseFloat(v(CSS_VARS.lw)) || BUILTIN_THEMES.light.lw
30195
+ };
30196
+ }
30176
30197
  function resolveTheme(theme2) {
30177
30198
  if (theme2 === void 0) {
30178
30199
  return { ...BUILTIN_THEMES.light };
30179
30200
  }
30180
30201
  if (typeof theme2 === "string") {
30202
+ if (theme2 === "auto") return readCssTheme();
30181
30203
  const found = BUILTIN_THEMES[theme2];
30182
30204
  if (!found) {
30183
30205
  throw new Error(
30184
- `Unknown theme "${theme2}". Available: ${Object.keys(BUILTIN_THEMES).join(", ")}`
30206
+ `Unknown theme "${theme2}". Available: ${Object.keys(BUILTIN_THEMES).join(", ")}, auto`
30185
30207
  );
30186
30208
  }
30187
30209
  return { ...found };
@@ -30402,6 +30424,9 @@ var SchemdrawController = class {
30402
30424
  __publicField(this, "_theme");
30403
30425
  __publicField(this, "_destroyed", false);
30404
30426
  __publicField(this, "_tooltipEl", null);
30427
+ __publicField(this, "_autoObserver", null);
30428
+ __publicField(this, "_mediaQuery", null);
30429
+ __publicField(this, "_mediaHandler", null);
30405
30430
  __publicField(this, "_boundClick");
30406
30431
  __publicField(this, "_boundMouseover");
30407
30432
  __publicField(this, "_boundMouseout");
@@ -30419,6 +30444,42 @@ var SchemdrawController = class {
30419
30444
  this._render();
30420
30445
  this._bindEvents();
30421
30446
  this._initTooltip();
30447
+ this._initAutoTheme();
30448
+ }
30449
+ _isAutoTheme() {
30450
+ return (this._opts.theme ?? this._json.theme) === "auto";
30451
+ }
30452
+ _initAutoTheme() {
30453
+ if (!this._isAutoTheme()) return;
30454
+ const rerender = () => {
30455
+ if (this._destroyed) return;
30456
+ this._theme = resolveTheme("auto");
30457
+ this._unbindEvents();
30458
+ this._render();
30459
+ this._bindEvents();
30460
+ this._selectedId = null;
30461
+ };
30462
+ this._autoObserver = new MutationObserver(rerender);
30463
+ this._autoObserver.observe(document.documentElement, {
30464
+ attributes: true,
30465
+ attributeFilter: ["class", "data-theme", "data-color-mode", "style"]
30466
+ });
30467
+ if (typeof matchMedia !== "undefined") {
30468
+ this._mediaQuery = matchMedia("(prefers-color-scheme: dark)");
30469
+ this._mediaHandler = rerender;
30470
+ this._mediaQuery.addEventListener("change", this._mediaHandler);
30471
+ }
30472
+ }
30473
+ _teardownAutoTheme() {
30474
+ if (this._autoObserver) {
30475
+ this._autoObserver.disconnect();
30476
+ this._autoObserver = null;
30477
+ }
30478
+ if (this._mediaQuery && this._mediaHandler) {
30479
+ this._mediaQuery.removeEventListener("change", this._mediaHandler);
30480
+ this._mediaQuery = null;
30481
+ this._mediaHandler = null;
30482
+ }
30422
30483
  }
30423
30484
  _render() {
30424
30485
  const svgString = renderFromJson(this._json, this._opts);
@@ -30652,9 +30713,11 @@ var SchemdrawController = class {
30652
30713
  this._selectedId = null;
30653
30714
  }
30654
30715
  setTheme(theme2) {
30716
+ this._teardownAutoTheme();
30655
30717
  this._opts = { ...this._opts, theme: theme2 };
30656
30718
  this._theme = resolveTheme(theme2);
30657
30719
  this.update(this._json);
30720
+ this._initAutoTheme();
30658
30721
  }
30659
30722
  update(json) {
30660
30723
  const circuit = typeof json === "string" ? JSON.parse(json) : json;
@@ -30668,6 +30731,7 @@ var SchemdrawController = class {
30668
30731
  if (this._destroyed) return;
30669
30732
  this._destroyed = true;
30670
30733
  this._unbindEvents();
30734
+ this._teardownAutoTheme();
30671
30735
  if (this._tooltipEl) {
30672
30736
  this._tooltipEl.remove();
30673
30737
  this._tooltipEl = null;
@@ -30744,6 +30808,7 @@ export {
30744
30808
  BusLine,
30745
30809
  Button,
30746
30810
  CPE,
30811
+ CSS_VARS,
30747
30812
  Capacitor,
30748
30813
  Capacitor2,
30749
30814
  CapacitorTrim,
package/dist/index.cjs CHANGED
@@ -14380,6 +14380,7 @@ __export(index_exports, {
14380
14380
  BusLine: () => BusLine,
14381
14381
  Button: () => Button,
14382
14382
  CPE: () => CPE,
14383
+ CSS_VARS: () => CSS_VARS,
14383
14384
  Capacitor: () => Capacitor,
14384
14385
  Capacitor2: () => Capacitor2,
14385
14386
  CapacitorTrim: () => CapacitorTrim,
@@ -30559,15 +30560,37 @@ var BUILTIN_THEMES = {
30559
30560
  lw: 1.5
30560
30561
  }
30561
30562
  };
30563
+ var CSS_VARS = {
30564
+ bg: "--circuit-bg",
30565
+ stroke: "--circuit-stroke",
30566
+ fill: "--circuit-fill",
30567
+ text: "--circuit-text",
30568
+ font: "--circuit-font",
30569
+ lw: "--circuit-lw"
30570
+ };
30571
+ function readCssTheme() {
30572
+ if (typeof getComputedStyle === "undefined") return { ...BUILTIN_THEMES.light };
30573
+ const s = getComputedStyle(document.documentElement);
30574
+ const v = (name) => s.getPropertyValue(name).trim();
30575
+ return {
30576
+ bg: v(CSS_VARS.bg) || "transparent",
30577
+ stroke: v(CSS_VARS.stroke) || BUILTIN_THEMES.light.stroke,
30578
+ fill: v(CSS_VARS.fill) || "none",
30579
+ text: v(CSS_VARS.text) || BUILTIN_THEMES.light.text,
30580
+ font: v(CSS_VARS.font) || BUILTIN_THEMES.light.font,
30581
+ lw: parseFloat(v(CSS_VARS.lw)) || BUILTIN_THEMES.light.lw
30582
+ };
30583
+ }
30562
30584
  function resolveTheme(theme2) {
30563
30585
  if (theme2 === void 0) {
30564
30586
  return { ...BUILTIN_THEMES.light };
30565
30587
  }
30566
30588
  if (typeof theme2 === "string") {
30589
+ if (theme2 === "auto") return readCssTheme();
30567
30590
  const found = BUILTIN_THEMES[theme2];
30568
30591
  if (!found) {
30569
30592
  throw new Error(
30570
- `Unknown theme "${theme2}". Available: ${Object.keys(BUILTIN_THEMES).join(", ")}`
30593
+ `Unknown theme "${theme2}". Available: ${Object.keys(BUILTIN_THEMES).join(", ")}, auto`
30571
30594
  );
30572
30595
  }
30573
30596
  return { ...found };
@@ -30788,6 +30811,9 @@ var SchemdrawController = class {
30788
30811
  __publicField(this, "_theme");
30789
30812
  __publicField(this, "_destroyed", false);
30790
30813
  __publicField(this, "_tooltipEl", null);
30814
+ __publicField(this, "_autoObserver", null);
30815
+ __publicField(this, "_mediaQuery", null);
30816
+ __publicField(this, "_mediaHandler", null);
30791
30817
  __publicField(this, "_boundClick");
30792
30818
  __publicField(this, "_boundMouseover");
30793
30819
  __publicField(this, "_boundMouseout");
@@ -30805,6 +30831,42 @@ var SchemdrawController = class {
30805
30831
  this._render();
30806
30832
  this._bindEvents();
30807
30833
  this._initTooltip();
30834
+ this._initAutoTheme();
30835
+ }
30836
+ _isAutoTheme() {
30837
+ return (this._opts.theme ?? this._json.theme) === "auto";
30838
+ }
30839
+ _initAutoTheme() {
30840
+ if (!this._isAutoTheme()) return;
30841
+ const rerender = () => {
30842
+ if (this._destroyed) return;
30843
+ this._theme = resolveTheme("auto");
30844
+ this._unbindEvents();
30845
+ this._render();
30846
+ this._bindEvents();
30847
+ this._selectedId = null;
30848
+ };
30849
+ this._autoObserver = new MutationObserver(rerender);
30850
+ this._autoObserver.observe(document.documentElement, {
30851
+ attributes: true,
30852
+ attributeFilter: ["class", "data-theme", "data-color-mode", "style"]
30853
+ });
30854
+ if (typeof matchMedia !== "undefined") {
30855
+ this._mediaQuery = matchMedia("(prefers-color-scheme: dark)");
30856
+ this._mediaHandler = rerender;
30857
+ this._mediaQuery.addEventListener("change", this._mediaHandler);
30858
+ }
30859
+ }
30860
+ _teardownAutoTheme() {
30861
+ if (this._autoObserver) {
30862
+ this._autoObserver.disconnect();
30863
+ this._autoObserver = null;
30864
+ }
30865
+ if (this._mediaQuery && this._mediaHandler) {
30866
+ this._mediaQuery.removeEventListener("change", this._mediaHandler);
30867
+ this._mediaQuery = null;
30868
+ this._mediaHandler = null;
30869
+ }
30808
30870
  }
30809
30871
  _render() {
30810
30872
  const svgString = renderFromJson(this._json, this._opts);
@@ -31038,9 +31100,11 @@ var SchemdrawController = class {
31038
31100
  this._selectedId = null;
31039
31101
  }
31040
31102
  setTheme(theme2) {
31103
+ this._teardownAutoTheme();
31041
31104
  this._opts = { ...this._opts, theme: theme2 };
31042
31105
  this._theme = resolveTheme(theme2);
31043
31106
  this.update(this._json);
31107
+ this._initAutoTheme();
31044
31108
  }
31045
31109
  update(json) {
31046
31110
  const circuit = typeof json === "string" ? JSON.parse(json) : json;
@@ -31054,6 +31118,7 @@ var SchemdrawController = class {
31054
31118
  if (this._destroyed) return;
31055
31119
  this._destroyed = true;
31056
31120
  this._unbindEvents();
31121
+ this._teardownAutoTheme();
31057
31122
  if (this._tooltipEl) {
31058
31123
  this._tooltipEl.remove();
31059
31124
  this._tooltipEl = null;
@@ -31131,6 +31196,7 @@ function mountFromJson(container, json, opts) {
31131
31196
  BusLine,
31132
31197
  Button,
31133
31198
  CPE,
31199
+ CSS_VARS,
31134
31200
  Capacitor,
31135
31201
  Capacitor2,
31136
31202
  CapacitorTrim,
package/dist/index.d.ts CHANGED
@@ -68,7 +68,7 @@ export { OutletA, OutletB, OutletC, OutletD, OutletE, OutletF, OutletG, OutletH,
68
68
  export { VacuumTube, DualVacuumTube, NixieTube, TubeDiode, Triode, Tetrode, Pentode, } from "./elements/tubes.js";
69
69
  export { ElementImage } from "./elements/image.js";
70
70
  export { renderFromJson, type CircuitJson, type DrawingConfig, type ElementObject, type ElementSpec, type LabelSpec, type RenderOptions, } from "./json/render.js";
71
- export { type Theme, BUILTIN_THEMES, resolveTheme } from "./json/theme.js";
71
+ export { type Theme, BUILTIN_THEMES, resolveTheme, CSS_VARS } from "./json/theme.js";
72
72
  export { ELEMENT_REGISTRY, getRegisteredTypes, getAvailableTypes, getAnchors, type ElementFactory } from "./json/registry.js";
73
73
  export { resolvePosition, resolvePositionX, resolvePositionY } from "./json/anchor-ref.js";
74
74
  export { validateCircuitJson, type ValidationResult, type ValidationError } from "./json/validate.js";
@@ -17,12 +17,18 @@ export declare class SchemdrawController {
17
17
  private _theme;
18
18
  private _destroyed;
19
19
  private _tooltipEl;
20
+ private _autoObserver;
21
+ private _mediaQuery;
22
+ private _mediaHandler;
20
23
  private _boundClick;
21
24
  private _boundMouseover;
22
25
  private _boundMouseout;
23
26
  private _boundContextmenu;
24
27
  private _boundMousemove;
25
28
  constructor(container: HTMLElement, json: CircuitJson, opts: RenderOptions);
29
+ private _isAutoTheme;
30
+ private _initAutoTheme;
31
+ private _teardownAutoTheme;
26
32
  private _render;
27
33
  private _initTooltip;
28
34
  private _showTooltip;
@@ -13,5 +13,14 @@ export interface Theme {
13
13
  lw: number;
14
14
  }
15
15
  export declare const BUILTIN_THEMES: Record<string, Theme>;
16
+ /** CSS variable names used by `theme: "auto"`. Host page defines these to control circuit colors. */
17
+ export declare const CSS_VARS: {
18
+ readonly bg: "--circuit-bg";
19
+ readonly stroke: "--circuit-stroke";
20
+ readonly fill: "--circuit-fill";
21
+ readonly text: "--circuit-text";
22
+ readonly font: "--circuit-font";
23
+ readonly lw: "--circuit-lw";
24
+ };
16
25
  export declare function resolveTheme(theme?: string | Partial<Theme>): Theme;
17
26
  export declare function applyThemeToDrawingConfig(theme: Theme, drawingConfig?: Record<string, unknown>): Record<string, unknown>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillpet/circuit",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "Circuit diagram library — render electrical schematics from JSON, with interactive SVG, themes, and Vue/React components",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",