@oyerinde/caliper 0.1.2 → 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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.1.4] - 2026-01-16
6
+
7
+ ### Fixed
8
+
9
+ - Fixed selection triggering underlying element click events (buttons, links, etc.).
10
+
11
+ ### Removed
12
+
13
+ - Removed double-click to remove rulers (use Delete/Backspace instead).
14
+
15
+ ## [0.1.3] - 2026-01-13
16
+
17
+ ### Improved
18
+
19
+ - Shortcuts now function while editable elements are focused.
20
+
5
21
  ## [0.1.2] - 2026-01-13
6
22
 
7
23
  ### Fixed
package/dist/index.cjs CHANGED
@@ -1034,13 +1034,6 @@ function hasSize(element) {
1034
1034
  const rect = element.getBoundingClientRect();
1035
1035
  return rect.width > 0 && rect.height > 0;
1036
1036
  }
1037
- function isEditable(element) {
1038
- if (!element || !(element instanceof HTMLElement)) {
1039
- return false;
1040
- }
1041
- const tagName = element.tagName;
1042
- return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT" || element.isContentEditable;
1043
- }
1044
1037
  function isEligible(element) {
1045
1038
  if (element.closest("[data-caliper-ignore]")) {
1046
1039
  return false;
@@ -2158,7 +2151,7 @@ function createProjectionSystem() {
2158
2151
  };
2159
2152
  const listeners = /* @__PURE__ */ new Set();
2160
2153
  const notify = () => {
2161
- listeners.forEach((l) => l({ ...state }));
2154
+ listeners.forEach((listener) => listener({ ...state }));
2162
2155
  };
2163
2156
  return {
2164
2157
  getState: () => ({ ...state }),
@@ -2217,7 +2210,7 @@ function createRulerSystem() {
2217
2210
  };
2218
2211
  const listeners = /* @__PURE__ */ new Set();
2219
2212
  const notify = () => {
2220
- listeners.forEach((l) => l({ lines: [...state.lines] }));
2213
+ listeners.forEach((listener) => listener({ lines: [...state.lines] }));
2221
2214
  };
2222
2215
  return {
2223
2216
  getState: () => ({ lines: [...state.lines] }),
@@ -2238,14 +2231,14 @@ function createRulerSystem() {
2238
2231
  return vLine.id;
2239
2232
  },
2240
2233
  updateLine: (id, position) => {
2241
- const index = state.lines.findIndex((l) => l.id === id);
2234
+ const index = state.lines.findIndex((line) => line.id === id);
2242
2235
  if (index !== -1 && state.lines[index]) {
2243
2236
  state.lines[index] = { ...state.lines[index], position };
2244
2237
  notify();
2245
2238
  }
2246
2239
  },
2247
2240
  removeLine: (id) => {
2248
- state.lines = state.lines.filter((l) => l.id !== id);
2241
+ state.lines = state.lines.filter((line) => line.id !== id);
2249
2242
  notify();
2250
2243
  },
2251
2244
  clear: () => {
@@ -3607,7 +3600,7 @@ function RulerOverlay(props) {
3607
3600
  const currentIds = selectedIds();
3608
3601
  const validIds = /* @__PURE__ */ new Set();
3609
3602
  currentIds.forEach((id) => {
3610
- if (lines.find((l) => l.id === id)) {
3603
+ if (lines.find((line) => line.id === id)) {
3611
3604
  validIds.add(id);
3612
3605
  }
3613
3606
  });
@@ -3630,7 +3623,7 @@ function RulerOverlay(props) {
3630
3623
  updated = true;
3631
3624
  }
3632
3625
  });
3633
- const lineIds = new Set(lines.map((l) => l.id));
3626
+ const lineIds = new Set(lines.map((line) => line.id));
3634
3627
  newOrigins.forEach((_, id) => {
3635
3628
  if (!lineIds.has(id)) {
3636
3629
  newOrigins.delete(id);
@@ -3715,7 +3708,7 @@ function RulerOverlay(props) {
3715
3708
  return;
3716
3709
  }
3717
3710
  const lines = props.state().lines;
3718
- const activeLines = lines.filter((l) => activeIds.has(l.id));
3711
+ const activeLines = lines.filter((line) => activeIds.has(line.id));
3719
3712
  if (activeLines.length === 0) return;
3720
3713
  let step = 1;
3721
3714
  if (e.shiftKey) step = 10;
@@ -3784,7 +3777,7 @@ function RulerOverlay(props) {
3784
3777
  setDraggingId(id);
3785
3778
  target.setPointerCapture(e.pointerId);
3786
3779
  const vp = props.viewport();
3787
- const line = props.state().lines.find((l) => l.id === id);
3780
+ const line = props.state().lines.find((line2) => line2.id === id);
3788
3781
  if (line) {
3789
3782
  const currentPos = getProportionalPosition(line);
3790
3783
  setRulerOrigins((prev) => {
@@ -3827,18 +3820,6 @@ function RulerOverlay(props) {
3827
3820
  window.addEventListener("pointermove", onPointerMove);
3828
3821
  window.addEventListener("pointerup", onPointerUp);
3829
3822
  };
3830
- const handleDoubleClick = (e) => {
3831
- const target = e.target;
3832
- const id = target.getAttribute("data-ruler-id");
3833
- if (id) {
3834
- props.onRemove(id);
3835
- setSelectedIds((prev) => {
3836
- const next = new Set(prev);
3837
- next.delete(id);
3838
- return next;
3839
- });
3840
- }
3841
- };
3842
3823
  const handlePointerOver = (e) => {
3843
3824
  const target = e.target;
3844
3825
  const id = target.getAttribute("data-ruler-id");
@@ -3851,14 +3832,14 @@ function RulerOverlay(props) {
3851
3832
  const bridges = createMemo(() => {
3852
3833
  const ids = selectedIds();
3853
3834
  if (ids.size < 2) return [];
3854
- const lines = props.state().lines.filter((l) => ids.has(l.id));
3855
- const vLinesWithPos = lines.filter((l) => l.type === "vertical").map((l) => ({
3856
- line: l,
3857
- pos: getProportionalPosition(l)
3835
+ const lines = props.state().lines.filter((line) => ids.has(line.id));
3836
+ const vLinesWithPos = lines.filter((line) => line.type === "vertical").map((line) => ({
3837
+ line,
3838
+ pos: getProportionalPosition(line)
3858
3839
  })).sort((a, b) => a.pos - b.pos);
3859
- const hLinesWithPos = lines.filter((l) => l.type === "horizontal").map((l) => ({
3860
- line: l,
3861
- pos: getProportionalPosition(l)
3840
+ const hLinesWithPos = lines.filter((line) => line.type === "horizontal").map((line) => ({
3841
+ line,
3842
+ pos: getProportionalPosition(line)
3862
3843
  })).sort((a, b) => a.pos - b.pos);
3863
3844
  const result = [];
3864
3845
  const vp = props.viewport();
@@ -3918,7 +3899,6 @@ function RulerOverlay(props) {
3918
3899
  var _el$ = _tmpl$10(), _el$2 = _el$.firstChild;
3919
3900
  _el$.$$pointerout = handlePointerOut;
3920
3901
  _el$.$$pointerover = handlePointerOver;
3921
- _el$.$$dblclick = handleDoubleClick;
3922
3902
  _el$.$$pointerdown = handlePointerDown;
3923
3903
  className(_el$, `${PREFIX}ruler-layer`);
3924
3904
  setAttribute(_el$2, "class", `${PREFIX}viewport-fixed`);
@@ -4095,7 +4075,7 @@ function RulerLineItem(props) {
4095
4075
  }
4096
4076
  })];
4097
4077
  }
4098
- delegateEvents(["pointerdown", "dblclick", "pointerover", "pointerout", "click"]);
4078
+ delegateEvents(["pointerdown", "pointerover", "pointerout", "click"]);
4099
4079
  var _tmpl$11 = /* @__PURE__ */ template(`<div>`);
4100
4080
  function Overlay(props) {
4101
4081
  const resultData = createMemo(() => {
@@ -4459,6 +4439,7 @@ function Root(config) {
4459
4439
  };
4460
4440
  if (isCommandActive(e)) {
4461
4441
  e.preventDefault();
4442
+ e.stopImmediatePropagation();
4462
4443
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4463
4444
  selectionTimeoutId = window.setTimeout(() => {
4464
4445
  performSelection(lastPointerPos.x, lastPointerPos.y);
@@ -4468,6 +4449,12 @@ function Root(config) {
4468
4449
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4469
4450
  }
4470
4451
  };
4452
+ const handleClick = (e) => {
4453
+ if (isCommandActive(e)) {
4454
+ e.preventDefault();
4455
+ e.stopImmediatePropagation();
4456
+ }
4457
+ };
4471
4458
  const handlePointerUp = (e) => {
4472
4459
  if (selectionTimeoutId) {
4473
4460
  window.clearTimeout(selectionTimeoutId);
@@ -4543,7 +4530,7 @@ function Root(config) {
4543
4530
  }
4544
4531
  };
4545
4532
  const handleKeyDown = (e) => {
4546
- if (e.key === commands.clear && !isEditable(e.target)) {
4533
+ if (e.key === commands.clear) {
4547
4534
  if (!isActive()) return;
4548
4535
  e.preventDefault();
4549
4536
  e.stopImmediatePropagation();
@@ -4566,10 +4553,10 @@ function Root(config) {
4566
4553
  }
4567
4554
  return;
4568
4555
  }
4569
- if (e.key === commands.select && !isEditable(e.target)) {
4556
+ if (e.key === commands.select) {
4570
4557
  setIsSelectKeyDown(true);
4571
4558
  }
4572
- if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem && !isEditable(e.target)) {
4559
+ if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem) {
4573
4560
  e.preventDefault();
4574
4561
  const vp = viewport();
4575
4562
  const x = Math.max(0, Math.min(cursor().x, vp.width));
@@ -4592,7 +4579,7 @@ function Root(config) {
4592
4579
  resetCalculatorUI();
4593
4580
  }
4594
4581
  setIsActivatePressed(true);
4595
- } else if (e.key === commands.freeze && !isEditable(e.target) && system) {
4582
+ } else if (e.key === commands.freeze && system) {
4596
4583
  const state = system.getState();
4597
4584
  if (state === "FROZEN") {
4598
4585
  e.preventDefault();
@@ -4640,7 +4627,7 @@ function Root(config) {
4640
4627
  [projection.right]: "right"
4641
4628
  };
4642
4629
  const dir = dirMap[key];
4643
- if (dir && selectionMetadata().element && !isEditable(e.target)) {
4630
+ if (dir && selectionMetadata().element) {
4644
4631
  e.preventDefault();
4645
4632
  e.stopImmediatePropagation();
4646
4633
  setActiveInputFocus("projection");
@@ -4695,7 +4682,7 @@ function Root(config) {
4695
4682
  const targetType = typeMap[key];
4696
4683
  if (targetType) {
4697
4684
  const currentLines = result()?.lines || [];
4698
- const targetLine = currentLines.find((l) => l.type === targetType);
4685
+ const targetLine = currentLines.find((line) => line.type === targetType);
4699
4686
  if (targetLine) {
4700
4687
  e.preventDefault();
4701
4688
  e.stopImmediatePropagation();
@@ -4739,6 +4726,9 @@ function Root(config) {
4739
4726
  window.addEventListener("pointerup", handlePointerUp, {
4740
4727
  capture: true
4741
4728
  });
4729
+ window.addEventListener("click", handleClick, {
4730
+ capture: true
4731
+ });
4742
4732
  window.addEventListener("mousemove", handleMouseMove);
4743
4733
  window.addEventListener("keydown", handleKeyDown, {
4744
4734
  capture: true
@@ -4758,6 +4748,9 @@ function Root(config) {
4758
4748
  window.removeEventListener("pointerup", handlePointerUp, {
4759
4749
  capture: true
4760
4750
  });
4751
+ window.removeEventListener("click", handleClick, {
4752
+ capture: true
4753
+ });
4761
4754
  window.removeEventListener("mousemove", handleMouseMove);
4762
4755
  window.removeEventListener("keydown", handleKeyDown, {
4763
4756
  capture: true
@@ -4926,7 +4919,7 @@ function Root(config) {
4926
4919
  const state = untrack(() => calculatorState());
4927
4920
  if (state?.isActive) {
4928
4921
  viewport().version;
4929
- const matchingLine = currentResult.lines.find((l) => l.type === calcLine.type);
4922
+ const matchingLine = currentResult.lines.find((line) => line.type === calcLine.type);
4930
4923
  if (matchingLine) {
4931
4924
  const liveValue = getLiveLineValue(matchingLine, currentResult);
4932
4925
  const calc = system.getCalculator();
@@ -5127,12 +5120,12 @@ function createOverlay(config) {
5127
5120
  return instance;
5128
5121
  }
5129
5122
  if (IS_BROWSER2) {
5130
- showVersionInfo("0.1.2").catch(() => {
5123
+ showVersionInfo("0.1.4").catch(() => {
5131
5124
  });
5132
5125
  }
5133
5126
 
5134
5127
  // src/index.ts
5135
- var VERSION = "0.1.2";
5128
+ var VERSION = "0.1.4";
5136
5129
 
5137
5130
  exports.VERSION = VERSION;
5138
5131
  exports.getConfig = getConfig;
package/dist/index.d.ts CHANGED
@@ -1,18 +1,2 @@
1
- export { OverlayInstance, createOverlay as init } from '@caliper/overlay';
2
- export { OverlayConfig, getConfig, setConfig } from '@caliper/core';
3
1
 
4
- /**
5
- * @oyerinde/caliper
6
- *
7
- * Browser-based measurement tool overlay.
8
- * This package bundles all dependencies for easy consumption.
9
- *
10
- * Usage:
11
- * 1. Script tag (Auto-mount): <script src="@oyerinde/caliper/dist/index.global.js"></script>
12
- * 2. ESM import (Manual): import { init } from "@oyerinde/caliper"
13
- * 3. Initialize: const caliper = init(); caliper.mount();
14
- */
15
-
16
- declare const VERSION: string;
17
-
18
- export { VERSION };
2
+ export { }
@@ -1035,13 +1035,6 @@
1035
1035
  const rect = element.getBoundingClientRect();
1036
1036
  return rect.width > 0 && rect.height > 0;
1037
1037
  }
1038
- function isEditable(element) {
1039
- if (!element || !(element instanceof HTMLElement)) {
1040
- return false;
1041
- }
1042
- const tagName = element.tagName;
1043
- return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT" || element.isContentEditable;
1044
- }
1045
1038
  function isEligible(element) {
1046
1039
  if (element.closest("[data-caliper-ignore]")) {
1047
1040
  return false;
@@ -2159,7 +2152,7 @@
2159
2152
  };
2160
2153
  const listeners = /* @__PURE__ */ new Set();
2161
2154
  const notify = () => {
2162
- listeners.forEach((l) => l({ ...state }));
2155
+ listeners.forEach((listener) => listener({ ...state }));
2163
2156
  };
2164
2157
  return {
2165
2158
  getState: () => ({ ...state }),
@@ -2218,7 +2211,7 @@
2218
2211
  };
2219
2212
  const listeners = /* @__PURE__ */ new Set();
2220
2213
  const notify = () => {
2221
- listeners.forEach((l) => l({ lines: [...state.lines] }));
2214
+ listeners.forEach((listener) => listener({ lines: [...state.lines] }));
2222
2215
  };
2223
2216
  return {
2224
2217
  getState: () => ({ lines: [...state.lines] }),
@@ -2239,14 +2232,14 @@
2239
2232
  return vLine.id;
2240
2233
  },
2241
2234
  updateLine: (id, position) => {
2242
- const index = state.lines.findIndex((l) => l.id === id);
2235
+ const index = state.lines.findIndex((line) => line.id === id);
2243
2236
  if (index !== -1 && state.lines[index]) {
2244
2237
  state.lines[index] = { ...state.lines[index], position };
2245
2238
  notify();
2246
2239
  }
2247
2240
  },
2248
2241
  removeLine: (id) => {
2249
- state.lines = state.lines.filter((l) => l.id !== id);
2242
+ state.lines = state.lines.filter((line) => line.id !== id);
2250
2243
  notify();
2251
2244
  },
2252
2245
  clear: () => {
@@ -3603,7 +3596,7 @@
3603
3596
  const currentIds = selectedIds();
3604
3597
  const validIds = /* @__PURE__ */ new Set();
3605
3598
  currentIds.forEach((id) => {
3606
- if (lines.find((l) => l.id === id)) {
3599
+ if (lines.find((line) => line.id === id)) {
3607
3600
  validIds.add(id);
3608
3601
  }
3609
3602
  });
@@ -3626,7 +3619,7 @@
3626
3619
  updated = true;
3627
3620
  }
3628
3621
  });
3629
- const lineIds = new Set(lines.map((l) => l.id));
3622
+ const lineIds = new Set(lines.map((line) => line.id));
3630
3623
  newOrigins.forEach((_, id) => {
3631
3624
  if (!lineIds.has(id)) {
3632
3625
  newOrigins.delete(id);
@@ -3711,7 +3704,7 @@
3711
3704
  return;
3712
3705
  }
3713
3706
  const lines = props.state().lines;
3714
- const activeLines = lines.filter((l) => activeIds.has(l.id));
3707
+ const activeLines = lines.filter((line) => activeIds.has(line.id));
3715
3708
  if (activeLines.length === 0) return;
3716
3709
  let step = 1;
3717
3710
  if (e.shiftKey) step = 10;
@@ -3780,7 +3773,7 @@
3780
3773
  setDraggingId(id);
3781
3774
  target.setPointerCapture(e.pointerId);
3782
3775
  const vp = props.viewport();
3783
- const line = props.state().lines.find((l) => l.id === id);
3776
+ const line = props.state().lines.find((line2) => line2.id === id);
3784
3777
  if (line) {
3785
3778
  const currentPos = getProportionalPosition(line);
3786
3779
  setRulerOrigins((prev) => {
@@ -3823,18 +3816,6 @@
3823
3816
  window.addEventListener("pointermove", onPointerMove);
3824
3817
  window.addEventListener("pointerup", onPointerUp);
3825
3818
  };
3826
- const handleDoubleClick = (e) => {
3827
- const target = e.target;
3828
- const id = target.getAttribute("data-ruler-id");
3829
- if (id) {
3830
- props.onRemove(id);
3831
- setSelectedIds((prev) => {
3832
- const next = new Set(prev);
3833
- next.delete(id);
3834
- return next;
3835
- });
3836
- }
3837
- };
3838
3819
  const handlePointerOver = (e) => {
3839
3820
  const target = e.target;
3840
3821
  const id = target.getAttribute("data-ruler-id");
@@ -3847,14 +3828,14 @@
3847
3828
  const bridges = createMemo(() => {
3848
3829
  const ids = selectedIds();
3849
3830
  if (ids.size < 2) return [];
3850
- const lines = props.state().lines.filter((l) => ids.has(l.id));
3851
- const vLinesWithPos = lines.filter((l) => l.type === "vertical").map((l) => ({
3852
- line: l,
3853
- pos: getProportionalPosition(l)
3831
+ const lines = props.state().lines.filter((line) => ids.has(line.id));
3832
+ const vLinesWithPos = lines.filter((line) => line.type === "vertical").map((line) => ({
3833
+ line,
3834
+ pos: getProportionalPosition(line)
3854
3835
  })).sort((a, b) => a.pos - b.pos);
3855
- const hLinesWithPos = lines.filter((l) => l.type === "horizontal").map((l) => ({
3856
- line: l,
3857
- pos: getProportionalPosition(l)
3836
+ const hLinesWithPos = lines.filter((line) => line.type === "horizontal").map((line) => ({
3837
+ line,
3838
+ pos: getProportionalPosition(line)
3858
3839
  })).sort((a, b) => a.pos - b.pos);
3859
3840
  const result = [];
3860
3841
  const vp = props.viewport();
@@ -3914,7 +3895,6 @@
3914
3895
  var _el$ = _tmpl$10(), _el$2 = _el$.firstChild;
3915
3896
  _el$.$$pointerout = handlePointerOut;
3916
3897
  _el$.$$pointerover = handlePointerOver;
3917
- _el$.$$dblclick = handleDoubleClick;
3918
3898
  _el$.$$pointerdown = handlePointerDown;
3919
3899
  className(_el$, `${PREFIX}ruler-layer`);
3920
3900
  setAttribute(_el$2, "class", `${PREFIX}viewport-fixed`);
@@ -4091,7 +4071,7 @@
4091
4071
  }
4092
4072
  })];
4093
4073
  }
4094
- delegateEvents(["pointerdown", "dblclick", "pointerover", "pointerout", "click"]);
4074
+ delegateEvents(["pointerdown", "pointerover", "pointerout", "click"]);
4095
4075
  var _tmpl$11 = /* @__PURE__ */ template(`<div>`);
4096
4076
  function Overlay(props) {
4097
4077
  const resultData = createMemo(() => {
@@ -4455,6 +4435,7 @@
4455
4435
  };
4456
4436
  if (isCommandActive(e)) {
4457
4437
  e.preventDefault();
4438
+ e.stopImmediatePropagation();
4458
4439
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4459
4440
  selectionTimeoutId = window.setTimeout(() => {
4460
4441
  performSelection(lastPointerPos.x, lastPointerPos.y);
@@ -4464,6 +4445,12 @@
4464
4445
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4465
4446
  }
4466
4447
  };
4448
+ const handleClick = (e) => {
4449
+ if (isCommandActive(e)) {
4450
+ e.preventDefault();
4451
+ e.stopImmediatePropagation();
4452
+ }
4453
+ };
4467
4454
  const handlePointerUp = (e) => {
4468
4455
  if (selectionTimeoutId) {
4469
4456
  window.clearTimeout(selectionTimeoutId);
@@ -4539,7 +4526,7 @@
4539
4526
  }
4540
4527
  };
4541
4528
  const handleKeyDown = (e) => {
4542
- if (e.key === commands.clear && !isEditable(e.target)) {
4529
+ if (e.key === commands.clear) {
4543
4530
  if (!isActive()) return;
4544
4531
  e.preventDefault();
4545
4532
  e.stopImmediatePropagation();
@@ -4562,10 +4549,10 @@
4562
4549
  }
4563
4550
  return;
4564
4551
  }
4565
- if (e.key === commands.select && !isEditable(e.target)) {
4552
+ if (e.key === commands.select) {
4566
4553
  setIsSelectKeyDown(true);
4567
4554
  }
4568
- if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem && !isEditable(e.target)) {
4555
+ if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem) {
4569
4556
  e.preventDefault();
4570
4557
  const vp = viewport();
4571
4558
  const x = Math.max(0, Math.min(cursor().x, vp.width));
@@ -4588,7 +4575,7 @@
4588
4575
  resetCalculatorUI();
4589
4576
  }
4590
4577
  setIsActivatePressed(true);
4591
- } else if (e.key === commands.freeze && !isEditable(e.target) && system) {
4578
+ } else if (e.key === commands.freeze && system) {
4592
4579
  const state = system.getState();
4593
4580
  if (state === "FROZEN") {
4594
4581
  e.preventDefault();
@@ -4636,7 +4623,7 @@
4636
4623
  [projection.right]: "right"
4637
4624
  };
4638
4625
  const dir = dirMap[key];
4639
- if (dir && selectionMetadata().element && !isEditable(e.target)) {
4626
+ if (dir && selectionMetadata().element) {
4640
4627
  e.preventDefault();
4641
4628
  e.stopImmediatePropagation();
4642
4629
  setActiveInputFocus("projection");
@@ -4691,7 +4678,7 @@
4691
4678
  const targetType = typeMap[key];
4692
4679
  if (targetType) {
4693
4680
  const currentLines = result()?.lines || [];
4694
- const targetLine = currentLines.find((l) => l.type === targetType);
4681
+ const targetLine = currentLines.find((line) => line.type === targetType);
4695
4682
  if (targetLine) {
4696
4683
  e.preventDefault();
4697
4684
  e.stopImmediatePropagation();
@@ -4735,6 +4722,9 @@
4735
4722
  window.addEventListener("pointerup", handlePointerUp, {
4736
4723
  capture: true
4737
4724
  });
4725
+ window.addEventListener("click", handleClick, {
4726
+ capture: true
4727
+ });
4738
4728
  window.addEventListener("mousemove", handleMouseMove);
4739
4729
  window.addEventListener("keydown", handleKeyDown, {
4740
4730
  capture: true
@@ -4754,6 +4744,9 @@
4754
4744
  window.removeEventListener("pointerup", handlePointerUp, {
4755
4745
  capture: true
4756
4746
  });
4747
+ window.removeEventListener("click", handleClick, {
4748
+ capture: true
4749
+ });
4757
4750
  window.removeEventListener("mousemove", handleMouseMove);
4758
4751
  window.removeEventListener("keydown", handleKeyDown, {
4759
4752
  capture: true
@@ -4922,7 +4915,7 @@
4922
4915
  const state = untrack(() => calculatorState());
4923
4916
  if (state?.isActive) {
4924
4917
  viewport().version;
4925
- const matchingLine = currentResult.lines.find((l) => l.type === calcLine.type);
4918
+ const matchingLine = currentResult.lines.find((line) => line.type === calcLine.type);
4926
4919
  if (matchingLine) {
4927
4920
  const liveValue = getLiveLineValue(matchingLine, currentResult);
4928
4921
  const calc = system.getCalculator();
@@ -5123,7 +5116,7 @@
5123
5116
  return instance;
5124
5117
  }
5125
5118
  if (IS_BROWSER2) {
5126
- showVersionInfo("0.1.2").catch(() => {
5119
+ showVersionInfo("0.1.4").catch(() => {
5127
5120
  });
5128
5121
  }
5129
5122
 
package/dist/index.js CHANGED
@@ -1032,13 +1032,6 @@ function hasSize(element) {
1032
1032
  const rect = element.getBoundingClientRect();
1033
1033
  return rect.width > 0 && rect.height > 0;
1034
1034
  }
1035
- function isEditable(element) {
1036
- if (!element || !(element instanceof HTMLElement)) {
1037
- return false;
1038
- }
1039
- const tagName = element.tagName;
1040
- return tagName === "INPUT" || tagName === "TEXTAREA" || tagName === "SELECT" || element.isContentEditable;
1041
- }
1042
1035
  function isEligible(element) {
1043
1036
  if (element.closest("[data-caliper-ignore]")) {
1044
1037
  return false;
@@ -2156,7 +2149,7 @@ function createProjectionSystem() {
2156
2149
  };
2157
2150
  const listeners = /* @__PURE__ */ new Set();
2158
2151
  const notify = () => {
2159
- listeners.forEach((l) => l({ ...state }));
2152
+ listeners.forEach((listener) => listener({ ...state }));
2160
2153
  };
2161
2154
  return {
2162
2155
  getState: () => ({ ...state }),
@@ -2215,7 +2208,7 @@ function createRulerSystem() {
2215
2208
  };
2216
2209
  const listeners = /* @__PURE__ */ new Set();
2217
2210
  const notify = () => {
2218
- listeners.forEach((l) => l({ lines: [...state.lines] }));
2211
+ listeners.forEach((listener) => listener({ lines: [...state.lines] }));
2219
2212
  };
2220
2213
  return {
2221
2214
  getState: () => ({ lines: [...state.lines] }),
@@ -2236,14 +2229,14 @@ function createRulerSystem() {
2236
2229
  return vLine.id;
2237
2230
  },
2238
2231
  updateLine: (id, position) => {
2239
- const index = state.lines.findIndex((l) => l.id === id);
2232
+ const index = state.lines.findIndex((line) => line.id === id);
2240
2233
  if (index !== -1 && state.lines[index]) {
2241
2234
  state.lines[index] = { ...state.lines[index], position };
2242
2235
  notify();
2243
2236
  }
2244
2237
  },
2245
2238
  removeLine: (id) => {
2246
- state.lines = state.lines.filter((l) => l.id !== id);
2239
+ state.lines = state.lines.filter((line) => line.id !== id);
2247
2240
  notify();
2248
2241
  },
2249
2242
  clear: () => {
@@ -3605,7 +3598,7 @@ function RulerOverlay(props) {
3605
3598
  const currentIds = selectedIds();
3606
3599
  const validIds = /* @__PURE__ */ new Set();
3607
3600
  currentIds.forEach((id) => {
3608
- if (lines.find((l) => l.id === id)) {
3601
+ if (lines.find((line) => line.id === id)) {
3609
3602
  validIds.add(id);
3610
3603
  }
3611
3604
  });
@@ -3628,7 +3621,7 @@ function RulerOverlay(props) {
3628
3621
  updated = true;
3629
3622
  }
3630
3623
  });
3631
- const lineIds = new Set(lines.map((l) => l.id));
3624
+ const lineIds = new Set(lines.map((line) => line.id));
3632
3625
  newOrigins.forEach((_, id) => {
3633
3626
  if (!lineIds.has(id)) {
3634
3627
  newOrigins.delete(id);
@@ -3713,7 +3706,7 @@ function RulerOverlay(props) {
3713
3706
  return;
3714
3707
  }
3715
3708
  const lines = props.state().lines;
3716
- const activeLines = lines.filter((l) => activeIds.has(l.id));
3709
+ const activeLines = lines.filter((line) => activeIds.has(line.id));
3717
3710
  if (activeLines.length === 0) return;
3718
3711
  let step = 1;
3719
3712
  if (e.shiftKey) step = 10;
@@ -3782,7 +3775,7 @@ function RulerOverlay(props) {
3782
3775
  setDraggingId(id);
3783
3776
  target.setPointerCapture(e.pointerId);
3784
3777
  const vp = props.viewport();
3785
- const line = props.state().lines.find((l) => l.id === id);
3778
+ const line = props.state().lines.find((line2) => line2.id === id);
3786
3779
  if (line) {
3787
3780
  const currentPos = getProportionalPosition(line);
3788
3781
  setRulerOrigins((prev) => {
@@ -3825,18 +3818,6 @@ function RulerOverlay(props) {
3825
3818
  window.addEventListener("pointermove", onPointerMove);
3826
3819
  window.addEventListener("pointerup", onPointerUp);
3827
3820
  };
3828
- const handleDoubleClick = (e) => {
3829
- const target = e.target;
3830
- const id = target.getAttribute("data-ruler-id");
3831
- if (id) {
3832
- props.onRemove(id);
3833
- setSelectedIds((prev) => {
3834
- const next = new Set(prev);
3835
- next.delete(id);
3836
- return next;
3837
- });
3838
- }
3839
- };
3840
3821
  const handlePointerOver = (e) => {
3841
3822
  const target = e.target;
3842
3823
  const id = target.getAttribute("data-ruler-id");
@@ -3849,14 +3830,14 @@ function RulerOverlay(props) {
3849
3830
  const bridges = createMemo(() => {
3850
3831
  const ids = selectedIds();
3851
3832
  if (ids.size < 2) return [];
3852
- const lines = props.state().lines.filter((l) => ids.has(l.id));
3853
- const vLinesWithPos = lines.filter((l) => l.type === "vertical").map((l) => ({
3854
- line: l,
3855
- pos: getProportionalPosition(l)
3833
+ const lines = props.state().lines.filter((line) => ids.has(line.id));
3834
+ const vLinesWithPos = lines.filter((line) => line.type === "vertical").map((line) => ({
3835
+ line,
3836
+ pos: getProportionalPosition(line)
3856
3837
  })).sort((a, b) => a.pos - b.pos);
3857
- const hLinesWithPos = lines.filter((l) => l.type === "horizontal").map((l) => ({
3858
- line: l,
3859
- pos: getProportionalPosition(l)
3838
+ const hLinesWithPos = lines.filter((line) => line.type === "horizontal").map((line) => ({
3839
+ line,
3840
+ pos: getProportionalPosition(line)
3860
3841
  })).sort((a, b) => a.pos - b.pos);
3861
3842
  const result = [];
3862
3843
  const vp = props.viewport();
@@ -3916,7 +3897,6 @@ function RulerOverlay(props) {
3916
3897
  var _el$ = _tmpl$10(), _el$2 = _el$.firstChild;
3917
3898
  _el$.$$pointerout = handlePointerOut;
3918
3899
  _el$.$$pointerover = handlePointerOver;
3919
- _el$.$$dblclick = handleDoubleClick;
3920
3900
  _el$.$$pointerdown = handlePointerDown;
3921
3901
  className(_el$, `${PREFIX}ruler-layer`);
3922
3902
  setAttribute(_el$2, "class", `${PREFIX}viewport-fixed`);
@@ -4093,7 +4073,7 @@ function RulerLineItem(props) {
4093
4073
  }
4094
4074
  })];
4095
4075
  }
4096
- delegateEvents(["pointerdown", "dblclick", "pointerover", "pointerout", "click"]);
4076
+ delegateEvents(["pointerdown", "pointerover", "pointerout", "click"]);
4097
4077
  var _tmpl$11 = /* @__PURE__ */ template(`<div>`);
4098
4078
  function Overlay(props) {
4099
4079
  const resultData = createMemo(() => {
@@ -4457,6 +4437,7 @@ function Root(config) {
4457
4437
  };
4458
4438
  if (isCommandActive(e)) {
4459
4439
  e.preventDefault();
4440
+ e.stopImmediatePropagation();
4460
4441
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4461
4442
  selectionTimeoutId = window.setTimeout(() => {
4462
4443
  performSelection(lastPointerPos.x, lastPointerPos.y);
@@ -4466,6 +4447,12 @@ function Root(config) {
4466
4447
  if (selectionTimeoutId) window.clearTimeout(selectionTimeoutId);
4467
4448
  }
4468
4449
  };
4450
+ const handleClick = (e) => {
4451
+ if (isCommandActive(e)) {
4452
+ e.preventDefault();
4453
+ e.stopImmediatePropagation();
4454
+ }
4455
+ };
4469
4456
  const handlePointerUp = (e) => {
4470
4457
  if (selectionTimeoutId) {
4471
4458
  window.clearTimeout(selectionTimeoutId);
@@ -4541,7 +4528,7 @@ function Root(config) {
4541
4528
  }
4542
4529
  };
4543
4530
  const handleKeyDown = (e) => {
4544
- if (e.key === commands.clear && !isEditable(e.target)) {
4531
+ if (e.key === commands.clear) {
4545
4532
  if (!isActive()) return;
4546
4533
  e.preventDefault();
4547
4534
  e.stopImmediatePropagation();
@@ -4564,10 +4551,10 @@ function Root(config) {
4564
4551
  }
4565
4552
  return;
4566
4553
  }
4567
- if (e.key === commands.select && !isEditable(e.target)) {
4554
+ if (e.key === commands.select) {
4568
4555
  setIsSelectKeyDown(true);
4569
4556
  }
4570
- if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem && !isEditable(e.target)) {
4557
+ if (e.key.toLowerCase() === commands.ruler.toLowerCase() && e.shiftKey && rulerSystem) {
4571
4558
  e.preventDefault();
4572
4559
  const vp = viewport();
4573
4560
  const x = Math.max(0, Math.min(cursor().x, vp.width));
@@ -4590,7 +4577,7 @@ function Root(config) {
4590
4577
  resetCalculatorUI();
4591
4578
  }
4592
4579
  setIsActivatePressed(true);
4593
- } else if (e.key === commands.freeze && !isEditable(e.target) && system) {
4580
+ } else if (e.key === commands.freeze && system) {
4594
4581
  const state = system.getState();
4595
4582
  if (state === "FROZEN") {
4596
4583
  e.preventDefault();
@@ -4638,7 +4625,7 @@ function Root(config) {
4638
4625
  [projection.right]: "right"
4639
4626
  };
4640
4627
  const dir = dirMap[key];
4641
- if (dir && selectionMetadata().element && !isEditable(e.target)) {
4628
+ if (dir && selectionMetadata().element) {
4642
4629
  e.preventDefault();
4643
4630
  e.stopImmediatePropagation();
4644
4631
  setActiveInputFocus("projection");
@@ -4693,7 +4680,7 @@ function Root(config) {
4693
4680
  const targetType = typeMap[key];
4694
4681
  if (targetType) {
4695
4682
  const currentLines = result()?.lines || [];
4696
- const targetLine = currentLines.find((l) => l.type === targetType);
4683
+ const targetLine = currentLines.find((line) => line.type === targetType);
4697
4684
  if (targetLine) {
4698
4685
  e.preventDefault();
4699
4686
  e.stopImmediatePropagation();
@@ -4737,6 +4724,9 @@ function Root(config) {
4737
4724
  window.addEventListener("pointerup", handlePointerUp, {
4738
4725
  capture: true
4739
4726
  });
4727
+ window.addEventListener("click", handleClick, {
4728
+ capture: true
4729
+ });
4740
4730
  window.addEventListener("mousemove", handleMouseMove);
4741
4731
  window.addEventListener("keydown", handleKeyDown, {
4742
4732
  capture: true
@@ -4756,6 +4746,9 @@ function Root(config) {
4756
4746
  window.removeEventListener("pointerup", handlePointerUp, {
4757
4747
  capture: true
4758
4748
  });
4749
+ window.removeEventListener("click", handleClick, {
4750
+ capture: true
4751
+ });
4759
4752
  window.removeEventListener("mousemove", handleMouseMove);
4760
4753
  window.removeEventListener("keydown", handleKeyDown, {
4761
4754
  capture: true
@@ -4924,7 +4917,7 @@ function Root(config) {
4924
4917
  const state = untrack(() => calculatorState());
4925
4918
  if (state?.isActive) {
4926
4919
  viewport().version;
4927
- const matchingLine = currentResult.lines.find((l) => l.type === calcLine.type);
4920
+ const matchingLine = currentResult.lines.find((line) => line.type === calcLine.type);
4928
4921
  if (matchingLine) {
4929
4922
  const liveValue = getLiveLineValue(matchingLine, currentResult);
4930
4923
  const calc = system.getCalculator();
@@ -5125,11 +5118,11 @@ function createOverlay(config) {
5125
5118
  return instance;
5126
5119
  }
5127
5120
  if (IS_BROWSER2) {
5128
- showVersionInfo("0.1.2").catch(() => {
5121
+ showVersionInfo("0.1.4").catch(() => {
5129
5122
  });
5130
5123
  }
5131
5124
 
5132
5125
  // src/index.ts
5133
- var VERSION = "0.1.2";
5126
+ var VERSION = "0.1.4";
5134
5127
 
5135
5128
  export { VERSION, getConfig, createOverlay as init, setConfig };
package/dist/version.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
- "version": "0.1.2",
3
- "timestamp": "2026-01-13T21:26:04.784Z"
2
+ "version": "0.1.4",
3
+ "timestamp": "2026-01-16T21:21:40.318Z"
4
4
  }
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@oyerinde/caliper",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "High-precision browser measurements, projections, and layout auditing",
5
5
  "type": "module",
6
- "main": "dist/index.js",
6
+ "main": "dist/index.cjs",
7
7
  "module": "dist/index.js",
8
8
  "types": "dist/index.d.ts",
9
9
  "author": "Daniel Oyerinde <oyerinde.daniel@yahoo.com> (https://danieloyerinde.com)",
@@ -84,10 +84,10 @@
84
84
  "solid-js": "^1.9.10",
85
85
  "tsup": "^8.5.1",
86
86
  "typescript": "5.9.3",
87
- "@caliper/core": "0.0.0",
88
- "@repo/typescript-config": "0.0.0",
89
87
  "@caliper/overlay": "0.0.0",
90
- "@repo/eslint-config": "0.0.0"
88
+ "@caliper/core": "0.0.0",
89
+ "@repo/eslint-config": "0.0.0",
90
+ "@repo/typescript-config": "0.0.0"
91
91
  },
92
92
  "scripts": {
93
93
  "prebuild": "node scripts/write-version.mjs",