@archie/devtools 0.1.4 → 0.1.6

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.
@@ -7,6 +7,15 @@
7
7
  var _rawDocumentQuerySelectorAll = Document.prototype.querySelectorAll
8
8
  var _documentQuerySelectorsPatched = false
9
9
 
10
+ // Design-mode (arrange) overlay elements — HitArea, resize handles,
11
+ // drop-line, etc. — carry this attribute. Single source of truth so every
12
+ // check below (isInspectorElement, inspectorClickHandler, the dblclick
13
+ // descend guard) can never desync from a rename.
14
+ var DESIGN_MODE_UI_SELECTOR = "[data-design-mode-ui]"
15
+ // The grab HitArea specifically (DesignModeOverlay.tsx's `HitArea`) — the
16
+ // ONLY design-mode-ui element the dblclick descend guard below exempts.
17
+ var DESIGN_MODE_HIT_AREA_SELECTOR = '[data-design-mode-ui="hit-area"]'
18
+
10
19
  function runInspector() {
11
20
  var INSPECTOR_PROBLEMATIC_SELECTOR_PATTERNS = [
12
21
  /\/\d+/,
@@ -1100,6 +1109,115 @@
1100
1109
  )
1101
1110
  }
1102
1111
 
1112
+ // The identity a wrapper ancestor climbs AS. A plain instrumented
1113
+ // wrapper climbs as its own direct meta. A kit-rendered wrapper (a
1114
+ // `Kit.Card` host div) carries kit-TEMPLATE direct meta instead, so it
1115
+ // falls back to the projected USAGE one level up in the screen file —
1116
+ // but that usage can itself be kit/chrome, so it's re-checked below.
1117
+ function getVisualUnitMetaForElement(el) {
1118
+ var directMeta = getDirectEditorMetaFromElement(el)
1119
+ if (!directMeta) return null
1120
+ if (!isKitOrChromeMeta(directMeta)) return directMeta
1121
+
1122
+ // The projected USAGE can itself be kit/chrome (e.g. a Kit.Card host
1123
+ // used inside a chrome file) — re-check it so the climb never enters
1124
+ // chrome scaffolding through a kit-rendered wrapper.
1125
+ var usageMeta = projectUsageMetaFromElement(el)
1126
+ return usageMeta && !isKitOrChromeMeta(usageMeta) ? usageMeta : null
1127
+ }
1128
+
1129
+ // True when `el`'s OWN identity is a directly-authored screen/project
1130
+ // node — its own host fiber carries `__editorMeta` that is neither
1131
+ // kit-origin nor chrome, i.e. a plain hand-written wrapper (`<a>`, a
1132
+ // layout `<div>`). FALSE for a component INSTANCE whose selectable
1133
+ // identity only exists by projecting onto an owning fiber — kit-runtime
1134
+ // renders `<Button>`'s `<button>`/`Kit.Card`'s host `<div>` with no such
1135
+ // direct, non-template meta of their own (see `getOwnerEditorMetaFromElement`
1136
+ // and `projectUsageMetaFromElement`'s docstrings above).
1137
+ function isBareAuthoredNode(el) {
1138
+ var direct = getDirectEditorMetaFromElement(el)
1139
+ return !!direct && !isKitOrChromeMeta(direct)
1140
+ }
1141
+
1142
+ function parseCssLengthForUnit(value) {
1143
+ var n = parseFloat(value)
1144
+ return isNaN(n) ? 0 : n
1145
+ }
1146
+
1147
+ function hasVisibleBorderSideForUnit(style, widthProp, styleProp) {
1148
+ var styleValue = style.getPropertyValue(styleProp)
1149
+ return (
1150
+ parseCssLengthForUnit(style.getPropertyValue(widthProp)) > 0 &&
1151
+ styleValue !== "none" &&
1152
+ styleValue !== ""
1153
+ )
1154
+ }
1155
+
1156
+ // A wrapper's OWN visual footprint — background, border, shadow,
1157
+ // radius or padding it renders on its own box, the signal that a click
1158
+ // on it hits something the user perceives as a distinct surface, not
1159
+ // bare layout plumbing (a plain `<a>`/`<div>` with zero box styling of
1160
+ // its own). Used only to decide whether a BARE wrapper (see
1161
+ // `isBareAuthoredNode`) may still swallow a component instance — a
1162
+ // styled wrapper (a card) keeps the pre-existing #52 behavior.
1163
+ function hasOwnVisualStyle(el) {
1164
+ if (!el) return false
1165
+ var style
1166
+ try {
1167
+ style = window.getComputedStyle(el)
1168
+ } catch (styleError) {
1169
+ // Unverifiable — fail OPEN to the pre-existing climb behavior
1170
+ // (never newly block a climb the runtime already performed).
1171
+ return true
1172
+ }
1173
+ if (!style) return true
1174
+
1175
+ var backgroundColor = style.getPropertyValue("background-color")
1176
+ if (
1177
+ backgroundColor &&
1178
+ backgroundColor !== "transparent" &&
1179
+ backgroundColor !== "rgba(0, 0, 0, 0)" &&
1180
+ backgroundColor !== "rgba(0,0,0,0)"
1181
+ ) {
1182
+ return true
1183
+ }
1184
+
1185
+ var backgroundImage = style.getPropertyValue("background-image")
1186
+ if (backgroundImage && backgroundImage !== "none") return true
1187
+
1188
+ var boxShadow = style.getPropertyValue("box-shadow")
1189
+ if (boxShadow && boxShadow !== "none") return true
1190
+
1191
+ if (
1192
+ hasVisibleBorderSideForUnit(style, "border-top-width", "border-top-style") ||
1193
+ hasVisibleBorderSideForUnit(style, "border-right-width", "border-right-style") ||
1194
+ hasVisibleBorderSideForUnit(style, "border-bottom-width", "border-bottom-style") ||
1195
+ hasVisibleBorderSideForUnit(style, "border-left-width", "border-left-style")
1196
+ ) {
1197
+ return true
1198
+ }
1199
+
1200
+ if (
1201
+ parseCssLengthForUnit(style.getPropertyValue("border-top-left-radius")) > 0 ||
1202
+ parseCssLengthForUnit(style.getPropertyValue("border-top-right-radius")) > 0 ||
1203
+ parseCssLengthForUnit(style.getPropertyValue("border-bottom-left-radius")) > 0 ||
1204
+ parseCssLengthForUnit(style.getPropertyValue("border-bottom-right-radius")) > 0
1205
+ ) {
1206
+ return true
1207
+ }
1208
+
1209
+ if (
1210
+ parseCssLengthForUnit(style.getPropertyValue("padding-top")) > 0 ||
1211
+ parseCssLengthForUnit(style.getPropertyValue("padding-right")) > 0 ||
1212
+ parseCssLengthForUnit(style.getPropertyValue("padding-bottom")) > 0 ||
1213
+ parseCssLengthForUnit(style.getPropertyValue("padding-left")) > 0
1214
+ ) {
1215
+ return true
1216
+ }
1217
+
1218
+ return false
1219
+ }
1220
+
1103
1221
  function climbVisualUnitChain(leaf) {
1104
1222
  if (!leaf) return leaf
1105
1223
  var currentFile = getOwnSourceFileForElement(leaf)
@@ -1114,8 +1232,8 @@
1114
1232
  if (isScreenRootWrapperElement(parent)) break
1115
1233
  if (getSoleElementChild(parent) !== current) break
1116
1234
 
1117
- var parentMeta = getDirectEditorMetaFromElement(parent)
1118
- if (!parentMeta || isKitOrChromeMeta(parentMeta)) break
1235
+ var parentMeta = getVisualUnitMetaForElement(parent)
1236
+ if (!parentMeta) break
1119
1237
  if (!parentMeta.file || parentMeta.file !== currentFile) break
1120
1238
  if (isStructuralComponentNameForUnit(parentMeta.componentName)) break
1121
1239
 
@@ -1135,6 +1253,25 @@
1135
1253
  break
1136
1254
  }
1137
1255
 
1256
+ // Bare-wrapper guard (ARCH — instance swallowed by a styleless
1257
+ // wrapper): a plain, directly-authored wrapper (an `<a>`, a layout
1258
+ // `<div>`) with NO visual footprint of its own, whose only child is
1259
+ // a component INSTANCE (its identity reachable only by projecting
1260
+ // onto an owning fiber — never a bare node itself), must not
1261
+ // swallow that instance: the instance is what the user sees and
1262
+ // clicks, the wrapper is invisible plumbing. A wrapper that itself
1263
+ // renders real background/border/shadow/radius/padding (a card)
1264
+ // keeps the existing #52 behavior and still wins the climb, and a
1265
+ // kit-rendered wrapper (itself a projected instance, never a bare
1266
+ // node) is untouched by this guard — see `isBareAuthoredNode`.
1267
+ if (
1268
+ isBareAuthoredNode(parent) &&
1269
+ !isBareAuthoredNode(current) &&
1270
+ !hasOwnVisualStyle(parent)
1271
+ ) {
1272
+ break
1273
+ }
1274
+
1138
1275
  current = parent
1139
1276
  }
1140
1277
  return current
@@ -1203,16 +1340,43 @@
1203
1340
  return null
1204
1341
  }
1205
1342
 
1343
+ // The point-hit stack at (x, y), topmost first. Prefers elementsFromPoint
1344
+ // (so a topmost overlay, e.g. the design-mode grab overlay, doesn't hide
1345
+ // the real element beneath it) and falls back to the single-element
1346
+ // elementFromPoint where the multi-element API isn't available.
1347
+ function collectPointHitList(x, y) {
1348
+ try {
1349
+ if (typeof document.elementsFromPoint === "function") {
1350
+ return document.elementsFromPoint(x, y) || []
1351
+ }
1352
+ } catch (_listError) {
1353
+ // fall through to the single-element lookup below
1354
+ }
1355
+ try {
1356
+ var single = document.elementFromPoint(x, y)
1357
+ return single ? [single] : []
1358
+ } catch (_pointError) {
1359
+ return []
1360
+ }
1361
+ }
1362
+
1206
1363
  // The direct child of `container` that sits on the ancestor line to
1207
1364
  // (x, y) — the "select child toward the point" step (double click).
1365
+ // Once a unit is selected, the full-coverage design-mode grab overlay
1366
+ // ([data-design-mode-ui]) sits topmost at that point, so a plain
1367
+ // elementFromPoint would just return the overlay itself — this walks
1368
+ // the hit stack and skips inspector/overlay elements to find the real
1369
+ // element underneath, exactly like getElementFromPoint does for hover.
1208
1370
  function findImmediateChildTowardPoint(container, x, y) {
1371
+ var list = collectPointHitList(x, y)
1209
1372
  var atPoint = null
1210
- try {
1211
- atPoint = document.elementFromPoint(x, y)
1212
- } catch (pointError) {
1213
- atPoint = null
1373
+ for (var i = 0; i < list.length; i++) {
1374
+ if (!isInspectorElement(list[i])) {
1375
+ atPoint = list[i]
1376
+ break
1377
+ }
1214
1378
  }
1215
- if (!atPoint || isInspectorElement(atPoint)) return null
1379
+ if (!atPoint) return null
1216
1380
  if (!container.contains(atPoint) || atPoint === container) return null
1217
1381
 
1218
1382
  var current = atPoint
@@ -2180,7 +2344,7 @@
2180
2344
  // drop-line, etc. These belong to the unified visual editor and must
2181
2345
  // pass mousedown/click events through to React (dnd-kit) instead of
2182
2346
  // being treated as inspect targets.
2183
- (element.closest && element.closest("[data-design-mode-ui]"))
2347
+ (element.closest && element.closest(DESIGN_MODE_UI_SELECTOR))
2184
2348
  )
2185
2349
  }
2186
2350
 
@@ -5777,7 +5941,7 @@
5777
5941
  if (
5778
5942
  e.target &&
5779
5943
  typeof e.target.closest === "function" &&
5780
- e.target.closest("[data-design-mode-ui]")
5944
+ e.target.closest(DESIGN_MODE_UI_SELECTOR)
5781
5945
  ) {
5782
5946
  return
5783
5947
  }
@@ -6214,11 +6378,17 @@
6214
6378
  "dblclick",
6215
6379
  function (e) {
6216
6380
  if (!isInspecting || !isElementSelected || !selectedElement) return
6217
- if (isInspectorElement(e.target)) return
6381
+ // Only the grab HitArea is exempted — it covers the whole selected
6382
+ // unit, so it (not the real element underneath) is what `e.target`
6383
+ // names for a double click inside it. The 8px resize band is NOT a
6384
+ // separate element — it's just the outer edge of that same HitArea
6385
+ // div (detected by pointer position against its rect), so it's
6386
+ // covered by this same exemption and a dblclick there DOES
6387
+ // descend. Every OTHER design-mode-ui element (toolbar, output
6388
+ // modal, …) still bails here, same as any other inspector UI.
6218
6389
  if (
6219
- e.target &&
6220
- typeof e.target.closest === "function" &&
6221
- e.target.closest("[data-design-mode-ui]")
6390
+ isInspectorElement(e.target) &&
6391
+ !(e.target && e.target.closest && e.target.closest(DESIGN_MODE_HIT_AREA_SELECTOR))
6222
6392
  ) {
6223
6393
  return
6224
6394
  }
@@ -7,6 +7,15 @@
7
7
  var _rawDocumentQuerySelectorAll = Document.prototype.querySelectorAll
8
8
  var _documentQuerySelectorsPatched = false
9
9
 
10
+ // Design-mode (arrange) overlay elements — HitArea, resize handles,
11
+ // drop-line, etc. — carry this attribute. Single source of truth so every
12
+ // check below (isInspectorElement, inspectorClickHandler, the dblclick
13
+ // descend guard) can never desync from a rename.
14
+ var DESIGN_MODE_UI_SELECTOR = "[data-design-mode-ui]"
15
+ // The grab HitArea specifically (DesignModeOverlay.tsx's `HitArea`) — the
16
+ // ONLY design-mode-ui element the dblclick descend guard below exempts.
17
+ var DESIGN_MODE_HIT_AREA_SELECTOR = '[data-design-mode-ui="hit-area"]'
18
+
10
19
  function runInspector() {
11
20
  var INSPECTOR_PROBLEMATIC_SELECTOR_PATTERNS = [
12
21
  /\/\d+/,
@@ -1100,6 +1109,115 @@
1100
1109
  )
1101
1110
  }
1102
1111
 
1112
+ // The identity a wrapper ancestor climbs AS. A plain instrumented
1113
+ // wrapper climbs as its own direct meta. A kit-rendered wrapper (a
1114
+ // `Kit.Card` host div) carries kit-TEMPLATE direct meta instead, so it
1115
+ // falls back to the projected USAGE one level up in the screen file —
1116
+ // but that usage can itself be kit/chrome, so it's re-checked below.
1117
+ function getVisualUnitMetaForElement(el) {
1118
+ var directMeta = getDirectEditorMetaFromElement(el)
1119
+ if (!directMeta) return null
1120
+ if (!isKitOrChromeMeta(directMeta)) return directMeta
1121
+
1122
+ // The projected USAGE can itself be kit/chrome (e.g. a Kit.Card host
1123
+ // used inside a chrome file) — re-check it so the climb never enters
1124
+ // chrome scaffolding through a kit-rendered wrapper.
1125
+ var usageMeta = projectUsageMetaFromElement(el)
1126
+ return usageMeta && !isKitOrChromeMeta(usageMeta) ? usageMeta : null
1127
+ }
1128
+
1129
+ // True when `el`'s OWN identity is a directly-authored screen/project
1130
+ // node — its own host fiber carries `__editorMeta` that is neither
1131
+ // kit-origin nor chrome, i.e. a plain hand-written wrapper (`<a>`, a
1132
+ // layout `<div>`). FALSE for a component INSTANCE whose selectable
1133
+ // identity only exists by projecting onto an owning fiber — kit-runtime
1134
+ // renders `<Button>`'s `<button>`/`Kit.Card`'s host `<div>` with no such
1135
+ // direct, non-template meta of their own (see `getOwnerEditorMetaFromElement`
1136
+ // and `projectUsageMetaFromElement`'s docstrings above).
1137
+ function isBareAuthoredNode(el) {
1138
+ var direct = getDirectEditorMetaFromElement(el)
1139
+ return !!direct && !isKitOrChromeMeta(direct)
1140
+ }
1141
+
1142
+ function parseCssLengthForUnit(value) {
1143
+ var n = parseFloat(value)
1144
+ return isNaN(n) ? 0 : n
1145
+ }
1146
+
1147
+ function hasVisibleBorderSideForUnit(style, widthProp, styleProp) {
1148
+ var styleValue = style.getPropertyValue(styleProp)
1149
+ return (
1150
+ parseCssLengthForUnit(style.getPropertyValue(widthProp)) > 0 &&
1151
+ styleValue !== "none" &&
1152
+ styleValue !== ""
1153
+ )
1154
+ }
1155
+
1156
+ // A wrapper's OWN visual footprint — background, border, shadow,
1157
+ // radius or padding it renders on its own box, the signal that a click
1158
+ // on it hits something the user perceives as a distinct surface, not
1159
+ // bare layout plumbing (a plain `<a>`/`<div>` with zero box styling of
1160
+ // its own). Used only to decide whether a BARE wrapper (see
1161
+ // `isBareAuthoredNode`) may still swallow a component instance — a
1162
+ // styled wrapper (a card) keeps the pre-existing #52 behavior.
1163
+ function hasOwnVisualStyle(el) {
1164
+ if (!el) return false
1165
+ var style
1166
+ try {
1167
+ style = window.getComputedStyle(el)
1168
+ } catch (styleError) {
1169
+ // Unverifiable — fail OPEN to the pre-existing climb behavior
1170
+ // (never newly block a climb the runtime already performed).
1171
+ return true
1172
+ }
1173
+ if (!style) return true
1174
+
1175
+ var backgroundColor = style.getPropertyValue("background-color")
1176
+ if (
1177
+ backgroundColor &&
1178
+ backgroundColor !== "transparent" &&
1179
+ backgroundColor !== "rgba(0, 0, 0, 0)" &&
1180
+ backgroundColor !== "rgba(0,0,0,0)"
1181
+ ) {
1182
+ return true
1183
+ }
1184
+
1185
+ var backgroundImage = style.getPropertyValue("background-image")
1186
+ if (backgroundImage && backgroundImage !== "none") return true
1187
+
1188
+ var boxShadow = style.getPropertyValue("box-shadow")
1189
+ if (boxShadow && boxShadow !== "none") return true
1190
+
1191
+ if (
1192
+ hasVisibleBorderSideForUnit(style, "border-top-width", "border-top-style") ||
1193
+ hasVisibleBorderSideForUnit(style, "border-right-width", "border-right-style") ||
1194
+ hasVisibleBorderSideForUnit(style, "border-bottom-width", "border-bottom-style") ||
1195
+ hasVisibleBorderSideForUnit(style, "border-left-width", "border-left-style")
1196
+ ) {
1197
+ return true
1198
+ }
1199
+
1200
+ if (
1201
+ parseCssLengthForUnit(style.getPropertyValue("border-top-left-radius")) > 0 ||
1202
+ parseCssLengthForUnit(style.getPropertyValue("border-top-right-radius")) > 0 ||
1203
+ parseCssLengthForUnit(style.getPropertyValue("border-bottom-left-radius")) > 0 ||
1204
+ parseCssLengthForUnit(style.getPropertyValue("border-bottom-right-radius")) > 0
1205
+ ) {
1206
+ return true
1207
+ }
1208
+
1209
+ if (
1210
+ parseCssLengthForUnit(style.getPropertyValue("padding-top")) > 0 ||
1211
+ parseCssLengthForUnit(style.getPropertyValue("padding-right")) > 0 ||
1212
+ parseCssLengthForUnit(style.getPropertyValue("padding-bottom")) > 0 ||
1213
+ parseCssLengthForUnit(style.getPropertyValue("padding-left")) > 0
1214
+ ) {
1215
+ return true
1216
+ }
1217
+
1218
+ return false
1219
+ }
1220
+
1103
1221
  function climbVisualUnitChain(leaf) {
1104
1222
  if (!leaf) return leaf
1105
1223
  var currentFile = getOwnSourceFileForElement(leaf)
@@ -1114,8 +1232,8 @@
1114
1232
  if (isScreenRootWrapperElement(parent)) break
1115
1233
  if (getSoleElementChild(parent) !== current) break
1116
1234
 
1117
- var parentMeta = getDirectEditorMetaFromElement(parent)
1118
- if (!parentMeta || isKitOrChromeMeta(parentMeta)) break
1235
+ var parentMeta = getVisualUnitMetaForElement(parent)
1236
+ if (!parentMeta) break
1119
1237
  if (!parentMeta.file || parentMeta.file !== currentFile) break
1120
1238
  if (isStructuralComponentNameForUnit(parentMeta.componentName)) break
1121
1239
 
@@ -1135,6 +1253,25 @@
1135
1253
  break
1136
1254
  }
1137
1255
 
1256
+ // Bare-wrapper guard (ARCH — instance swallowed by a styleless
1257
+ // wrapper): a plain, directly-authored wrapper (an `<a>`, a layout
1258
+ // `<div>`) with NO visual footprint of its own, whose only child is
1259
+ // a component INSTANCE (its identity reachable only by projecting
1260
+ // onto an owning fiber — never a bare node itself), must not
1261
+ // swallow that instance: the instance is what the user sees and
1262
+ // clicks, the wrapper is invisible plumbing. A wrapper that itself
1263
+ // renders real background/border/shadow/radius/padding (a card)
1264
+ // keeps the existing #52 behavior and still wins the climb, and a
1265
+ // kit-rendered wrapper (itself a projected instance, never a bare
1266
+ // node) is untouched by this guard — see `isBareAuthoredNode`.
1267
+ if (
1268
+ isBareAuthoredNode(parent) &&
1269
+ !isBareAuthoredNode(current) &&
1270
+ !hasOwnVisualStyle(parent)
1271
+ ) {
1272
+ break
1273
+ }
1274
+
1138
1275
  current = parent
1139
1276
  }
1140
1277
  return current
@@ -1203,16 +1340,43 @@
1203
1340
  return null
1204
1341
  }
1205
1342
 
1343
+ // The point-hit stack at (x, y), topmost first. Prefers elementsFromPoint
1344
+ // (so a topmost overlay, e.g. the design-mode grab overlay, doesn't hide
1345
+ // the real element beneath it) and falls back to the single-element
1346
+ // elementFromPoint where the multi-element API isn't available.
1347
+ function collectPointHitList(x, y) {
1348
+ try {
1349
+ if (typeof document.elementsFromPoint === "function") {
1350
+ return document.elementsFromPoint(x, y) || []
1351
+ }
1352
+ } catch (_listError) {
1353
+ // fall through to the single-element lookup below
1354
+ }
1355
+ try {
1356
+ var single = document.elementFromPoint(x, y)
1357
+ return single ? [single] : []
1358
+ } catch (_pointError) {
1359
+ return []
1360
+ }
1361
+ }
1362
+
1206
1363
  // The direct child of `container` that sits on the ancestor line to
1207
1364
  // (x, y) — the "select child toward the point" step (double click).
1365
+ // Once a unit is selected, the full-coverage design-mode grab overlay
1366
+ // ([data-design-mode-ui]) sits topmost at that point, so a plain
1367
+ // elementFromPoint would just return the overlay itself — this walks
1368
+ // the hit stack and skips inspector/overlay elements to find the real
1369
+ // element underneath, exactly like getElementFromPoint does for hover.
1208
1370
  function findImmediateChildTowardPoint(container, x, y) {
1371
+ var list = collectPointHitList(x, y)
1209
1372
  var atPoint = null
1210
- try {
1211
- atPoint = document.elementFromPoint(x, y)
1212
- } catch (pointError) {
1213
- atPoint = null
1373
+ for (var i = 0; i < list.length; i++) {
1374
+ if (!isInspectorElement(list[i])) {
1375
+ atPoint = list[i]
1376
+ break
1377
+ }
1214
1378
  }
1215
- if (!atPoint || isInspectorElement(atPoint)) return null
1379
+ if (!atPoint) return null
1216
1380
  if (!container.contains(atPoint) || atPoint === container) return null
1217
1381
 
1218
1382
  var current = atPoint
@@ -2180,7 +2344,7 @@
2180
2344
  // drop-line, etc. These belong to the unified visual editor and must
2181
2345
  // pass mousedown/click events through to React (dnd-kit) instead of
2182
2346
  // being treated as inspect targets.
2183
- (element.closest && element.closest("[data-design-mode-ui]"))
2347
+ (element.closest && element.closest(DESIGN_MODE_UI_SELECTOR))
2184
2348
  )
2185
2349
  }
2186
2350
 
@@ -5777,7 +5941,7 @@
5777
5941
  if (
5778
5942
  e.target &&
5779
5943
  typeof e.target.closest === "function" &&
5780
- e.target.closest("[data-design-mode-ui]")
5944
+ e.target.closest(DESIGN_MODE_UI_SELECTOR)
5781
5945
  ) {
5782
5946
  return
5783
5947
  }
@@ -6214,11 +6378,17 @@
6214
6378
  "dblclick",
6215
6379
  function (e) {
6216
6380
  if (!isInspecting || !isElementSelected || !selectedElement) return
6217
- if (isInspectorElement(e.target)) return
6381
+ // Only the grab HitArea is exempted — it covers the whole selected
6382
+ // unit, so it (not the real element underneath) is what `e.target`
6383
+ // names for a double click inside it. The 8px resize band is NOT a
6384
+ // separate element — it's just the outer edge of that same HitArea
6385
+ // div (detected by pointer position against its rect), so it's
6386
+ // covered by this same exemption and a dblclick there DOES
6387
+ // descend. Every OTHER design-mode-ui element (toolbar, output
6388
+ // modal, …) still bails here, same as any other inspector UI.
6218
6389
  if (
6219
- e.target &&
6220
- typeof e.target.closest === "function" &&
6221
- e.target.closest("[data-design-mode-ui]")
6390
+ isInspectorElement(e.target) &&
6391
+ !(e.target && e.target.closest && e.target.closest(DESIGN_MODE_HIT_AREA_SELECTOR))
6222
6392
  ) {
6223
6393
  return
6224
6394
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archie/devtools",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "DevTools for Archie generated applications - Route synchronization and editor communication",
5
5
  "sideEffects": false,
6
6
  "repository": {