uilint-react 0.1.46 → 0.1.47

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.
@@ -3,7 +3,7 @@
3
3
  import {
4
4
  useUILintContext,
5
5
  useUILintStore
6
- } from "./chunk-OU5EEQT6.js";
6
+ } from "./chunk-RAPUZC5J.js";
7
7
 
8
8
  // src/components/ui-lint/ElementBadges.tsx
9
9
  import React, { useState, useEffect, useCallback, useMemo } from "react";
@@ -2,9 +2,9 @@
2
2
  "use client";
3
3
  import {
4
4
  InspectionPanel
5
- } from "./chunk-JURUYCUC.js";
5
+ } from "./chunk-UF6KN2JJ.js";
6
6
  import "./chunk-S4IWHBOQ.js";
7
- import "./chunk-OU5EEQT6.js";
7
+ import "./chunk-RAPUZC5J.js";
8
8
  export {
9
9
  InspectionPanel
10
10
  };
@@ -3,8 +3,8 @@
3
3
  import {
4
4
  InspectedElementHighlight,
5
5
  LocatorOverlay
6
- } from "./chunk-LQ3WQYIF.js";
7
- import "./chunk-OU5EEQT6.js";
6
+ } from "./chunk-LNLTM7N6.js";
7
+ import "./chunk-RAPUZC5J.js";
8
8
  export {
9
9
  InspectedElementHighlight,
10
10
  LocatorOverlay
@@ -2,9 +2,9 @@
2
2
  "use client";
3
3
  import {
4
4
  UILintToolbar
5
- } from "./chunk-XUMLILUN.js";
5
+ } from "./chunk-OSYIUF52.js";
6
6
  import "./chunk-S4IWHBOQ.js";
7
- import "./chunk-OU5EEQT6.js";
7
+ import "./chunk-RAPUZC5J.js";
8
8
  export {
9
9
  UILintToolbar
10
10
  };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import {
3
3
  useUILintContext
4
- } from "./chunk-OU5EEQT6.js";
4
+ } from "./chunk-RAPUZC5J.js";
5
5
 
6
6
  // src/components/ui-lint/LocatorOverlay.tsx
7
7
  import { useState, useEffect, useMemo } from "react";
@@ -9,10 +9,10 @@ import {
9
9
  groupBySourceFile,
10
10
  useUILintContext,
11
11
  useUILintStore
12
- } from "./chunk-OU5EEQT6.js";
12
+ } from "./chunk-RAPUZC5J.js";
13
13
 
14
14
  // src/components/ui-lint/UILintToolbar.tsx
15
- import { useState as useState2, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
15
+ import React3, { useState as useState2, useRef as useRef2, useEffect as useEffect3, useCallback as useCallback2 } from "react";
16
16
  import { createPortal } from "react-dom";
17
17
 
18
18
  // src/components/ui-lint/toolbar-styles.ts
@@ -1117,10 +1117,10 @@ function ScanPanelStack({ show, onClose }) {
1117
1117
  }
1118
1118
 
1119
1119
  // src/components/ui-lint/UILintToolbar.tsx
1120
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1120
+ import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
1121
1121
  var TOKENS = {
1122
1122
  // Colors
1123
- bgBase: "rgba(15, 15, 15, 0.85)",
1123
+ bgBase: "rgba(15, 15, 15, 0.92)",
1124
1124
  bgElevated: "rgba(25, 25, 25, 0.95)",
1125
1125
  bgHover: "rgba(255, 255, 255, 0.08)",
1126
1126
  bgActive: "rgba(255, 255, 255, 0.12)",
@@ -1131,26 +1131,17 @@ var TOKENS = {
1131
1131
  textMuted: "rgba(255, 255, 255, 0.4)",
1132
1132
  textDisabled: "rgba(255, 255, 255, 0.25)",
1133
1133
  accent: "#63b3ed",
1134
- // Calm blue
1135
1134
  success: BADGE_COLORS.success,
1136
- // Soft green (shared with Badge)
1137
1135
  warning: BADGE_COLORS.warning,
1138
- // Warm orange (shared with Badge)
1139
- // Typography
1136
+ error: "#f56565",
1140
1137
  fontFamily: `-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif`,
1141
1138
  fontMono: `"SF Mono", Monaco, "Cascadia Code", monospace`,
1142
- // Sizing
1143
- pillHeight: "44px",
1144
- // Touch-friendly
1145
- pillRadius: "22px",
1146
- buttonMinWidth: "44px",
1147
- // Touch target minimum
1148
- // Effects
1149
- blur: "blur(20px)",
1150
- shadowSm: "0 2px 8px rgba(0, 0, 0, 0.3)",
1139
+ pillHeight: "40px",
1140
+ pillRadius: "20px",
1141
+ buttonMinWidth: "40px",
1142
+ blur: "blur(16px)",
1151
1143
  shadowMd: "0 4px 20px rgba(0, 0, 0, 0.4)",
1152
- shadowGlow: (color) => `0 0 20px ${color}`,
1153
- // Animation
1144
+ shadowGlow: (color) => `0 0 16px ${color}`,
1154
1145
  transitionFast: "150ms cubic-bezier(0.4, 0, 0.2, 1)",
1155
1146
  transitionBase: "200ms cubic-bezier(0.4, 0, 0.2, 1)",
1156
1147
  transitionSlow: "300ms cubic-bezier(0.4, 0, 0.2, 1)"
@@ -1159,8 +1150,8 @@ var Icons = {
1159
1150
  Eye: () => /* @__PURE__ */ jsxs4(
1160
1151
  "svg",
1161
1152
  {
1162
- width: "18",
1163
- height: "18",
1153
+ width: "16",
1154
+ height: "16",
1164
1155
  viewBox: "0 0 24 24",
1165
1156
  fill: "none",
1166
1157
  stroke: "currentColor",
@@ -1173,11 +1164,11 @@ var Icons = {
1173
1164
  ]
1174
1165
  }
1175
1166
  ),
1176
- EyeOff: () => /* @__PURE__ */ jsxs4(
1167
+ Settings: () => /* @__PURE__ */ jsxs4(
1177
1168
  "svg",
1178
1169
  {
1179
- width: "18",
1180
- height: "18",
1170
+ width: "15",
1171
+ height: "15",
1181
1172
  viewBox: "0 0 24 24",
1182
1173
  fill: "none",
1183
1174
  stroke: "currentColor",
@@ -1185,16 +1176,30 @@ var Icons = {
1185
1176
  strokeLinecap: "round",
1186
1177
  strokeLinejoin: "round",
1187
1178
  children: [
1188
- /* @__PURE__ */ jsx5("path", { d: "M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" }),
1189
- /* @__PURE__ */ jsx5("line", { x1: "1", y1: "1", x2: "23", y2: "23" })
1179
+ /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" }),
1180
+ /* @__PURE__ */ jsx5("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
1190
1181
  ]
1191
1182
  }
1192
1183
  ),
1193
- Scan: () => /* @__PURE__ */ jsxs4(
1184
+ Check: () => /* @__PURE__ */ jsx5(
1194
1185
  "svg",
1195
1186
  {
1196
- width: "16",
1197
- height: "16",
1187
+ width: "12",
1188
+ height: "12",
1189
+ viewBox: "0 0 24 24",
1190
+ fill: "none",
1191
+ stroke: "currentColor",
1192
+ strokeWidth: "2.5",
1193
+ strokeLinecap: "round",
1194
+ strokeLinejoin: "round",
1195
+ children: /* @__PURE__ */ jsx5("polyline", { points: "20 6 9 17 4 12" })
1196
+ }
1197
+ ),
1198
+ AlertTriangle: () => /* @__PURE__ */ jsxs4(
1199
+ "svg",
1200
+ {
1201
+ width: "12",
1202
+ height: "12",
1198
1203
  viewBox: "0 0 24 24",
1199
1204
  fill: "none",
1200
1205
  stroke: "currentColor",
@@ -1202,29 +1207,27 @@ var Icons = {
1202
1207
  strokeLinecap: "round",
1203
1208
  strokeLinejoin: "round",
1204
1209
  children: [
1205
- /* @__PURE__ */ jsx5("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }),
1206
- /* @__PURE__ */ jsx5("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }),
1207
- /* @__PURE__ */ jsx5("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }),
1208
- /* @__PURE__ */ jsx5("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" }),
1209
- /* @__PURE__ */ jsx5("line", { x1: "7", y1: "12", x2: "17", y2: "12" })
1210
+ /* @__PURE__ */ jsx5("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
1211
+ /* @__PURE__ */ jsx5("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
1212
+ /* @__PURE__ */ jsx5("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
1210
1213
  ]
1211
1214
  }
1212
1215
  ),
1213
- Check: () => /* @__PURE__ */ jsx5(
1216
+ ChevronDown: () => /* @__PURE__ */ jsx5(
1214
1217
  "svg",
1215
1218
  {
1216
- width: "14",
1217
- height: "14",
1219
+ width: "12",
1220
+ height: "12",
1218
1221
  viewBox: "0 0 24 24",
1219
1222
  fill: "none",
1220
1223
  stroke: "currentColor",
1221
- strokeWidth: "2.5",
1224
+ strokeWidth: "2",
1222
1225
  strokeLinecap: "round",
1223
1226
  strokeLinejoin: "round",
1224
- children: /* @__PURE__ */ jsx5("polyline", { points: "20 6 9 17 4 12" })
1227
+ children: /* @__PURE__ */ jsx5("polyline", { points: "6 9 12 15 18 9" })
1225
1228
  }
1226
1229
  ),
1227
- AlertTriangle: () => /* @__PURE__ */ jsxs4(
1230
+ X: () => /* @__PURE__ */ jsxs4(
1228
1231
  "svg",
1229
1232
  {
1230
1233
  width: "14",
@@ -1236,17 +1239,16 @@ var Icons = {
1236
1239
  strokeLinecap: "round",
1237
1240
  strokeLinejoin: "round",
1238
1241
  children: [
1239
- /* @__PURE__ */ jsx5("path", { d: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" }),
1240
- /* @__PURE__ */ jsx5("line", { x1: "12", y1: "9", x2: "12", y2: "13" }),
1241
- /* @__PURE__ */ jsx5("line", { x1: "12", y1: "17", x2: "12.01", y2: "17" })
1242
+ /* @__PURE__ */ jsx5("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1243
+ /* @__PURE__ */ jsx5("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1242
1244
  ]
1243
1245
  }
1244
1246
  ),
1245
- Settings: () => /* @__PURE__ */ jsxs4(
1247
+ Unplug: () => /* @__PURE__ */ jsxs4(
1246
1248
  "svg",
1247
1249
  {
1248
- width: "16",
1249
- height: "16",
1250
+ width: "14",
1251
+ height: "14",
1250
1252
  viewBox: "0 0 24 24",
1251
1253
  fill: "none",
1252
1254
  stroke: "currentColor",
@@ -1254,12 +1256,15 @@ var Icons = {
1254
1256
  strokeLinecap: "round",
1255
1257
  strokeLinejoin: "round",
1256
1258
  children: [
1257
- /* @__PURE__ */ jsx5("circle", { cx: "12", cy: "12", r: "3" }),
1258
- /* @__PURE__ */ jsx5("path", { d: "M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" })
1259
+ /* @__PURE__ */ jsx5("path", { d: "M19 5l3-3" }),
1260
+ /* @__PURE__ */ jsx5("path", { d: "M2 22l3-3" }),
1261
+ /* @__PURE__ */ jsx5("path", { d: "M6.3 6.3a10 10 0 0 1 13.4 1.3" }),
1262
+ /* @__PURE__ */ jsx5("path", { d: "M17.7 17.7a10 10 0 0 1-13.4-1.3" }),
1263
+ /* @__PURE__ */ jsx5("path", { d: "m8 15 8-8" })
1259
1264
  ]
1260
1265
  }
1261
1266
  ),
1262
- ChevronRight: () => /* @__PURE__ */ jsx5(
1267
+ Scan: () => /* @__PURE__ */ jsxs4(
1263
1268
  "svg",
1264
1269
  {
1265
1270
  width: "14",
@@ -1270,7 +1275,13 @@ var Icons = {
1270
1275
  strokeWidth: "2",
1271
1276
  strokeLinecap: "round",
1272
1277
  strokeLinejoin: "round",
1273
- children: /* @__PURE__ */ jsx5("polyline", { points: "9 18 15 12 9 6" })
1278
+ children: [
1279
+ /* @__PURE__ */ jsx5("path", { d: "M3 7V5a2 2 0 0 1 2-2h2" }),
1280
+ /* @__PURE__ */ jsx5("path", { d: "M17 3h2a2 2 0 0 1 2 2v2" }),
1281
+ /* @__PURE__ */ jsx5("path", { d: "M21 17v2a2 2 0 0 1-2 2h-2" }),
1282
+ /* @__PURE__ */ jsx5("path", { d: "M7 21H5a2 2 0 0 1-2-2v-2" }),
1283
+ /* @__PURE__ */ jsx5("line", { x1: "7", y1: "12", x2: "17", y2: "12" })
1284
+ ]
1274
1285
  }
1275
1286
  )
1276
1287
  };
@@ -1287,101 +1298,72 @@ var globalStyles = `
1287
1298
 
1288
1299
  @keyframes uilint-pulse {
1289
1300
  0%, 100% { opacity: 1; }
1290
- 50% { opacity: 0.5; }
1291
- }
1292
-
1293
- @keyframes uilint-scan-line {
1294
- 0% { transform: translateX(-100%); }
1295
- 100% { transform: translateX(100%); }
1301
+ 50% { opacity: 0.6; }
1296
1302
  }
1297
1303
 
1298
- @keyframes uilint-spin {
1299
- from { transform: rotate(0deg); }
1300
- to { transform: rotate(360deg); }
1304
+ @keyframes uilint-slide-up {
1305
+ from { opacity: 0; transform: translateY(12px); }
1306
+ to { opacity: 1; transform: translateY(0); }
1301
1307
  }
1302
1308
 
1303
- .uilint-toolbar-btn {
1309
+ .uilint-btn {
1304
1310
  display: flex;
1305
1311
  align-items: center;
1306
1312
  justify-content: center;
1313
+ gap: 6px;
1307
1314
  height: 100%;
1315
+ padding: 0 14px;
1308
1316
  border: none;
1309
1317
  background: transparent;
1310
1318
  color: ${TOKENS.textSecondary};
1319
+ font-family: ${TOKENS.fontFamily};
1320
+ font-size: 13px;
1321
+ font-weight: 500;
1311
1322
  cursor: pointer;
1312
1323
  transition:
1313
1324
  background-color ${TOKENS.transitionFast},
1314
- color ${TOKENS.transitionFast},
1315
- transform ${TOKENS.transitionFast};
1325
+ color ${TOKENS.transitionFast};
1316
1326
  outline: none;
1317
- position: relative;
1327
+ white-space: nowrap;
1318
1328
  }
1319
1329
 
1320
- .uilint-toolbar-btn:hover:not(:disabled) {
1330
+ .uilint-btn:hover:not(:disabled) {
1321
1331
  background: ${TOKENS.bgHover};
1322
1332
  color: ${TOKENS.textPrimary};
1323
1333
  }
1324
1334
 
1325
- .uilint-toolbar-btn:active:not(:disabled) {
1335
+ .uilint-btn:active:not(:disabled) {
1326
1336
  background: ${TOKENS.bgActive};
1327
- transform: scale(0.97);
1328
1337
  }
1329
1338
 
1330
- .uilint-toolbar-btn:focus-visible {
1339
+ .uilint-btn:focus-visible {
1331
1340
  box-shadow: inset 0 0 0 2px ${TOKENS.borderFocus};
1332
1341
  }
1333
1342
 
1334
- .uilint-toolbar-btn:disabled {
1343
+ .uilint-btn:disabled {
1335
1344
  cursor: not-allowed;
1336
1345
  color: ${TOKENS.textDisabled};
1337
1346
  }
1338
1347
 
1339
- .uilint-toolbar-btn--active {
1340
- background: ${TOKENS.bgActive} !important;
1341
- color: ${TOKENS.accent} !important;
1342
- }
1343
-
1344
- .uilint-toolbar-btn--warning {
1345
- color: ${TOKENS.warning} !important;
1346
- }
1347
-
1348
- .uilint-toolbar-btn--success {
1349
- color: ${TOKENS.success} !important;
1348
+ .uilint-btn--icon {
1349
+ padding: 0;
1350
+ min-width: ${TOKENS.buttonMinWidth};
1350
1351
  }
1351
1352
 
1352
- .uilint-hint {
1353
- opacity: 0;
1354
- transform: translateY(4px);
1355
- transition:
1356
- opacity ${TOKENS.transitionBase},
1357
- transform ${TOKENS.transitionBase};
1358
- pointer-events: none;
1353
+ .uilint-btn--primary {
1354
+ color: ${TOKENS.textPrimary};
1359
1355
  }
1360
1356
 
1361
- .uilint-hint--visible {
1362
- opacity: 1;
1363
- transform: translateY(0);
1357
+ .uilint-btn--accent {
1358
+ color: ${TOKENS.accent};
1364
1359
  }
1365
1360
 
1366
- .uilint-scanning-indicator {
1367
- position: relative;
1368
- overflow: hidden;
1361
+ .uilint-btn--warning {
1362
+ color: ${TOKENS.warning};
1369
1363
  }
1370
1364
 
1371
- .uilint-scanning-indicator::after {
1372
- content: '';
1373
- position: absolute;
1374
- top: 0;
1375
- left: 0;
1376
- right: 0;
1377
- bottom: 0;
1378
- background: linear-gradient(
1379
- 90deg,
1380
- transparent,
1381
- rgba(99, 179, 237, 0.3),
1382
- transparent
1383
- );
1384
- animation: uilint-scan-line 1.5s ease-in-out infinite;
1365
+ .uilint-btn--success {
1366
+ color: ${TOKENS.success};
1385
1367
  }
1386
1368
 
1387
1369
  .uilint-popover {
@@ -1392,80 +1374,65 @@ var globalStyles = `
1392
1374
  animation: uilint-fade-out ${TOKENS.transitionBase} forwards;
1393
1375
  }
1394
1376
 
1395
- /* Custom scrollbar styling for dark mode - scoped to uilint components */
1396
- [data-ui-lint] *,
1397
- [data-ui-lint] {
1398
- /* Firefox */
1377
+ .uilint-scanning-bar {
1378
+ animation: uilint-slide-up ${TOKENS.transitionSlow} forwards;
1379
+ }
1380
+
1381
+ .uilint-scanning-dot {
1382
+ width: 6px;
1383
+ height: 6px;
1384
+ border-radius: 50%;
1385
+ background: ${TOKENS.accent};
1386
+ animation: uilint-pulse 1.5s ease-in-out infinite;
1387
+ }
1388
+
1389
+ /* Scrollbar styling */
1390
+ [data-ui-lint] * {
1399
1391
  scrollbar-width: thin;
1400
1392
  scrollbar-color: rgba(255, 255, 255, 0.15) rgba(15, 15, 15, 0.3);
1401
1393
  }
1402
1394
 
1403
- /* WebKit browsers (Chrome, Safari, Edge) */
1404
- [data-ui-lint] *::-webkit-scrollbar,
1405
- [data-ui-lint]::-webkit-scrollbar {
1395
+ [data-ui-lint] *::-webkit-scrollbar {
1406
1396
  width: 8px;
1407
1397
  height: 8px;
1408
1398
  }
1409
1399
 
1410
- [data-ui-lint] *::-webkit-scrollbar-track,
1411
- [data-ui-lint]::-webkit-scrollbar-track {
1400
+ [data-ui-lint] *::-webkit-scrollbar-track {
1412
1401
  background: rgba(15, 15, 15, 0.3);
1413
1402
  border-radius: 4px;
1414
1403
  }
1415
1404
 
1416
- [data-ui-lint] *::-webkit-scrollbar-thumb,
1417
- [data-ui-lint]::-webkit-scrollbar-thumb {
1405
+ [data-ui-lint] *::-webkit-scrollbar-thumb {
1418
1406
  background: rgba(255, 255, 255, 0.15);
1419
1407
  border-radius: 4px;
1420
- border: 1px solid rgba(15, 15, 15, 0.2);
1421
- transition: background ${TOKENS.transitionFast};
1422
1408
  }
1423
1409
 
1424
- [data-ui-lint] *::-webkit-scrollbar-thumb:hover,
1425
- [data-ui-lint]::-webkit-scrollbar-thumb:hover {
1410
+ [data-ui-lint] *::-webkit-scrollbar-thumb:hover {
1426
1411
  background: rgba(255, 255, 255, 0.25);
1427
1412
  }
1428
-
1429
- [data-ui-lint] *::-webkit-scrollbar-thumb:active,
1430
- [data-ui-lint]::-webkit-scrollbar-thumb:active {
1431
- background: rgba(255, 255, 255, 0.35);
1432
- }
1433
-
1434
- [data-ui-lint] *::-webkit-scrollbar-corner,
1435
- [data-ui-lint]::-webkit-scrollbar-corner {
1436
- background: rgba(15, 15, 15, 0.3);
1437
- }
1438
1413
  `;
1439
- function ToolbarButton({
1440
- onClick,
1441
- disabled,
1442
- active,
1443
- variant = "default",
1444
- title,
1445
- ariaLabel,
1446
- width = TOKENS.buttonMinWidth,
1447
- children
1448
- }) {
1449
- const classes = [
1450
- "uilint-toolbar-btn",
1451
- active && "uilint-toolbar-btn--active",
1452
- variant === "warning" && "uilint-toolbar-btn--warning",
1453
- variant === "success" && "uilint-toolbar-btn--success"
1454
- ].filter(Boolean).join(" ");
1455
- return /* @__PURE__ */ jsx5(
1456
- "button",
1457
- {
1458
- className: classes,
1459
- onClick,
1460
- disabled,
1461
- title,
1462
- "aria-label": ariaLabel,
1463
- "aria-pressed": active,
1464
- style: { minWidth: width },
1465
- children
1466
- }
1467
- );
1468
- }
1414
+ var PillContainer = React3.forwardRef(({ children, glow, style }, ref) => /* @__PURE__ */ jsx5(
1415
+ "div",
1416
+ {
1417
+ ref,
1418
+ style: {
1419
+ display: "inline-flex",
1420
+ alignItems: "center",
1421
+ height: TOKENS.pillHeight,
1422
+ borderRadius: TOKENS.pillRadius,
1423
+ border: `1px solid ${TOKENS.border}`,
1424
+ backgroundColor: TOKENS.bgBase,
1425
+ backdropFilter: TOKENS.blur,
1426
+ WebkitBackdropFilter: TOKENS.blur,
1427
+ boxShadow: glow ? `${TOKENS.shadowMd}, ${TOKENS.shadowGlow(glow)}` : TOKENS.shadowMd,
1428
+ overflow: "hidden",
1429
+ transition: `box-shadow ${TOKENS.transitionBase}`,
1430
+ ...style
1431
+ },
1432
+ children
1433
+ }
1434
+ ));
1435
+ PillContainer.displayName = "PillContainer";
1469
1436
  function Divider() {
1470
1437
  return /* @__PURE__ */ jsx5(
1471
1438
  "div",
@@ -1480,98 +1447,112 @@ function Divider() {
1480
1447
  }
1481
1448
  );
1482
1449
  }
1483
- function ScanStatus({ status, issueCount, enabled }) {
1484
- if (!enabled) {
1485
- return /* @__PURE__ */ jsx5(
1486
- "span",
1487
- {
1488
- style: {
1489
- fontSize: "12px",
1490
- color: TOKENS.textDisabled,
1491
- fontStyle: "italic"
1492
- },
1493
- children: "Off"
1494
- }
1495
- );
1496
- }
1497
- if (status === "scanning" || status === "paused") {
1498
- return /* @__PURE__ */ jsxs4(
1499
- "span",
1450
+ function Kbd({ children }) {
1451
+ return /* @__PURE__ */ jsx5(
1452
+ "kbd",
1453
+ {
1454
+ style: {
1455
+ display: "inline-flex",
1456
+ alignItems: "center",
1457
+ padding: "2px 6px",
1458
+ borderRadius: "4px",
1459
+ backgroundColor: TOKENS.bgElevated,
1460
+ border: `1px solid ${TOKENS.border}`,
1461
+ fontSize: "11px",
1462
+ fontFamily: TOKENS.fontMono,
1463
+ color: TOKENS.textSecondary,
1464
+ boxShadow: "0 1px 2px rgba(0, 0, 0, 0.4)"
1465
+ },
1466
+ children
1467
+ }
1468
+ );
1469
+ }
1470
+ function DisconnectedToolbar({
1471
+ onSettingsClick,
1472
+ showSettings
1473
+ }) {
1474
+ return /* @__PURE__ */ jsxs4(PillContainer, { children: [
1475
+ /* @__PURE__ */ jsxs4(
1476
+ "div",
1500
1477
  {
1501
- className: "uilint-scanning-indicator",
1502
1478
  style: {
1503
1479
  display: "flex",
1504
1480
  alignItems: "center",
1505
1481
  gap: "6px",
1506
- padding: "0 4px"
1482
+ padding: "0 12px",
1483
+ color: TOKENS.textMuted,
1484
+ fontSize: "12px"
1507
1485
  },
1508
1486
  children: [
1509
- /* @__PURE__ */ jsx5(Icons.Scan, {}),
1510
- /* @__PURE__ */ jsx5(
1511
- "span",
1512
- {
1513
- style: {
1514
- fontSize: "12px",
1515
- fontFamily: TOKENS.fontMono,
1516
- animation: `uilint-pulse 1s ease-in-out infinite`
1517
- },
1518
- children: "Scanning"
1519
- }
1520
- )
1487
+ /* @__PURE__ */ jsx5(Icons.Unplug, {}),
1488
+ /* @__PURE__ */ jsx5("span", { children: "Not connected" })
1521
1489
  ]
1522
1490
  }
1523
- );
1524
- }
1525
- if (issueCount === 0) {
1526
- return /* @__PURE__ */ jsxs4(
1527
- "span",
1491
+ ),
1492
+ /* @__PURE__ */ jsx5(Divider, {}),
1493
+ /* @__PURE__ */ jsx5(
1494
+ "button",
1528
1495
  {
1529
- style: {
1530
- display: "flex",
1531
- alignItems: "center",
1532
- gap: "5px"
1533
- },
1496
+ className: `uilint-btn uilint-btn--icon ${showSettings ? "uilint-btn--accent" : ""}`,
1497
+ onClick: onSettingsClick,
1498
+ title: "Settings",
1499
+ "aria-label": "Open settings",
1500
+ "aria-pressed": showSettings,
1501
+ children: /* @__PURE__ */ jsx5(Icons.Settings, {})
1502
+ }
1503
+ )
1504
+ ] });
1505
+ }
1506
+ function IdleToolbar({
1507
+ onStartScan,
1508
+ onSettingsClick,
1509
+ showSettings
1510
+ }) {
1511
+ return /* @__PURE__ */ jsxs4(PillContainer, { children: [
1512
+ /* @__PURE__ */ jsxs4(
1513
+ "button",
1514
+ {
1515
+ className: "uilint-btn uilint-btn--primary",
1516
+ onClick: onStartScan,
1517
+ title: "Start scanning (\u2325S)",
1518
+ "aria-label": "Start live scanning",
1534
1519
  children: [
1535
- /* @__PURE__ */ jsx5(
1536
- "span",
1537
- {
1538
- style: {
1539
- display: "flex",
1540
- alignItems: "center",
1541
- justifyContent: "center",
1542
- width: "18px",
1543
- height: "18px",
1544
- borderRadius: "50%",
1545
- backgroundColor: `${TOKENS.success}20`,
1546
- color: TOKENS.success
1547
- },
1548
- children: /* @__PURE__ */ jsx5(Icons.Check, {})
1549
- }
1550
- ),
1551
- /* @__PURE__ */ jsx5(
1552
- "span",
1553
- {
1554
- style: {
1555
- fontSize: "12px",
1556
- fontWeight: 500,
1557
- color: TOKENS.success
1558
- },
1559
- children: "Clear"
1560
- }
1561
- )
1520
+ /* @__PURE__ */ jsx5(Icons.Eye, {}),
1521
+ /* @__PURE__ */ jsx5("span", { children: "Start Scanning" })
1562
1522
  ]
1563
1523
  }
1564
- );
1565
- }
1566
- return /* @__PURE__ */ jsxs4(
1567
- "span",
1568
- {
1569
- style: {
1570
- display: "flex",
1571
- alignItems: "center",
1572
- gap: "5px"
1573
- },
1574
- children: [
1524
+ ),
1525
+ /* @__PURE__ */ jsx5(Divider, {}),
1526
+ /* @__PURE__ */ jsx5(
1527
+ "button",
1528
+ {
1529
+ className: `uilint-btn uilint-btn--icon ${showSettings ? "uilint-btn--accent" : ""}`,
1530
+ onClick: onSettingsClick,
1531
+ title: "Settings",
1532
+ "aria-label": "Open settings",
1533
+ "aria-pressed": showSettings,
1534
+ children: /* @__PURE__ */ jsx5(Icons.Settings, {})
1535
+ }
1536
+ )
1537
+ ] });
1538
+ }
1539
+ function ScanningToolbar({
1540
+ issueCount,
1541
+ isScanning,
1542
+ showResults,
1543
+ onToggleResults,
1544
+ onStopScan
1545
+ }) {
1546
+ const hasIssues = issueCount > 0;
1547
+ const getStatusContent = () => {
1548
+ if (isScanning) {
1549
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1550
+ /* @__PURE__ */ jsx5("div", { className: "uilint-scanning-dot" }),
1551
+ /* @__PURE__ */ jsx5("span", { style: { fontFamily: TOKENS.fontMono, fontSize: "12px" }, children: "Scanning..." })
1552
+ ] });
1553
+ }
1554
+ if (hasIssues) {
1555
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1575
1556
  /* @__PURE__ */ jsx5(
1576
1557
  "span",
1577
1558
  {
@@ -1579,8 +1560,8 @@ function ScanStatus({ status, issueCount, enabled }) {
1579
1560
  display: "flex",
1580
1561
  alignItems: "center",
1581
1562
  justifyContent: "center",
1582
- width: "18px",
1583
- height: "18px",
1563
+ width: "16px",
1564
+ height: "16px",
1584
1565
  borderRadius: "50%",
1585
1566
  backgroundColor: `${TOKENS.warning}20`,
1586
1567
  color: TOKENS.warning
@@ -1589,6 +1570,72 @@ function ScanStatus({ status, issueCount, enabled }) {
1589
1570
  }
1590
1571
  ),
1591
1572
  /* @__PURE__ */ jsx5(Badge, { count: issueCount })
1573
+ ] });
1574
+ }
1575
+ return /* @__PURE__ */ jsxs4(Fragment2, { children: [
1576
+ /* @__PURE__ */ jsx5(
1577
+ "span",
1578
+ {
1579
+ style: {
1580
+ display: "flex",
1581
+ alignItems: "center",
1582
+ justifyContent: "center",
1583
+ width: "16px",
1584
+ height: "16px",
1585
+ borderRadius: "50%",
1586
+ backgroundColor: `${TOKENS.success}20`,
1587
+ color: TOKENS.success
1588
+ },
1589
+ children: /* @__PURE__ */ jsx5(Icons.Check, {})
1590
+ }
1591
+ ),
1592
+ /* @__PURE__ */ jsx5(
1593
+ "span",
1594
+ {
1595
+ style: { fontSize: "12px", fontWeight: 500, color: TOKENS.success },
1596
+ children: "All clear"
1597
+ }
1598
+ )
1599
+ ] });
1600
+ };
1601
+ const statusVariant = hasIssues ? "warning" : isScanning ? "accent" : "success";
1602
+ const glowColor = hasIssues ? `${TOKENS.warning}25` : void 0;
1603
+ return /* @__PURE__ */ jsxs4(
1604
+ "div",
1605
+ {
1606
+ className: "uilint-scanning-bar",
1607
+ style: { display: "flex", alignItems: "center", gap: "10px" },
1608
+ children: [
1609
+ /* @__PURE__ */ jsxs4(PillContainer, { glow: glowColor, children: [
1610
+ /* @__PURE__ */ jsxs4(
1611
+ "button",
1612
+ {
1613
+ className: `uilint-btn uilint-btn--${statusVariant}`,
1614
+ onClick: onToggleResults,
1615
+ title: hasIssues ? `${issueCount} issue${issueCount !== 1 ? "s" : ""} found` : "View scan results",
1616
+ "aria-label": "Toggle scan results",
1617
+ "aria-expanded": showResults,
1618
+ style: { paddingRight: "10px" },
1619
+ children: [
1620
+ getStatusContent(),
1621
+ /* @__PURE__ */ jsx5(Icons.ChevronDown, {})
1622
+ ]
1623
+ }
1624
+ ),
1625
+ /* @__PURE__ */ jsx5(Divider, {}),
1626
+ /* @__PURE__ */ jsx5(
1627
+ "button",
1628
+ {
1629
+ className: "uilint-btn uilint-btn--icon",
1630
+ onClick: onStopScan,
1631
+ title: "Stop scanning (\u2325S)",
1632
+ "aria-label": "Stop scanning",
1633
+ children: /* @__PURE__ */ jsx5(Icons.X, {})
1634
+ }
1635
+ )
1636
+ ] }),
1637
+ /* @__PURE__ */ jsx5(Kbd, { children: "\u2325 + Click" }),
1638
+ /* @__PURE__ */ jsx5("span", { style: { fontSize: "12px", color: TOKENS.textMuted }, children: "to inspect" })
1592
1639
  ]
1593
1640
  }
1594
1641
  );
@@ -1605,6 +1652,7 @@ function UILintToolbar() {
1605
1652
  (s) => s.elementIssuesCache
1606
1653
  );
1607
1654
  const fileIssuesCache = useUILintStore((s) => s.fileIssuesCache);
1655
+ const wsConnected = useUILintStore((s) => s.wsConnected);
1608
1656
  const [showSettings, setShowSettings] = useState2(false);
1609
1657
  const [showResults, setShowResults] = useState2(false);
1610
1658
  const [mounted, setMounted] = useState2(false);
@@ -1612,6 +1660,16 @@ function UILintToolbar() {
1612
1660
  const [nextjsOverlayVisible, setNextjsOverlayVisible] = useState2(false);
1613
1661
  const toolbarRef = useRef2(null);
1614
1662
  const settingsRef = useRef2(null);
1663
+ const isScanning = autoScanState.status === "scanning" || autoScanState.status === "paused";
1664
+ let elementIssues = 0;
1665
+ elementIssuesCache.forEach((el) => {
1666
+ elementIssues += el.issues.length;
1667
+ });
1668
+ let fileLevelIssues = 0;
1669
+ fileIssuesCache.forEach((issues) => {
1670
+ fileLevelIssues += issues.length;
1671
+ });
1672
+ const totalIssues = elementIssues + fileLevelIssues;
1615
1673
  useEffect3(() => {
1616
1674
  const checkForNextOverlay = () => {
1617
1675
  const overlaySelectors = [
@@ -1639,32 +1697,21 @@ function UILintToolbar() {
1639
1697
  });
1640
1698
  return () => observer.disconnect();
1641
1699
  }, []);
1642
- const isScanning = autoScanState.status === "scanning";
1643
- const isComplete = autoScanState.status === "complete";
1644
- let elementIssues = 0;
1645
- elementIssuesCache.forEach((el) => {
1646
- elementIssues += el.issues.length;
1647
- });
1648
- let fileLevelIssues = 0;
1649
- fileIssuesCache.forEach((issues) => {
1650
- fileLevelIssues += issues.length;
1651
- });
1652
- const totalIssues = elementIssues + fileLevelIssues;
1653
- const hasIssues = totalIssues > 0;
1654
1700
  useEffect3(() => {
1655
1701
  setMounted(true);
1656
1702
  }, []);
1657
1703
  useEffect3(() => {
1658
1704
  const handleClickOutside = (e) => {
1659
1705
  const target = e.target;
1660
- if (target?.closest?.("[data-ui-lint]")) {
1661
- return;
1662
- }
1706
+ if (target?.closest?.("[data-ui-lint]")) return;
1663
1707
  if (showSettings && settingsRef.current && toolbarRef.current) {
1664
1708
  if (!settingsRef.current.contains(target) && !toolbarRef.current.contains(target)) {
1665
1709
  handleCloseSettings();
1666
1710
  }
1667
1711
  }
1712
+ if (showResults) {
1713
+ setShowResults(false);
1714
+ }
1668
1715
  };
1669
1716
  const handleEscape = (e) => {
1670
1717
  if (e.key === "Escape") {
@@ -1679,28 +1726,19 @@ function UILintToolbar() {
1679
1726
  document.removeEventListener("keydown", handleEscape);
1680
1727
  };
1681
1728
  }, [showSettings, showResults]);
1682
- const handleToggleClick = useCallback2(() => {
1683
- if (liveScanEnabled) {
1684
- disableLiveScan();
1685
- setShowResults(false);
1686
- } else {
1687
- enableLiveScan();
1688
- }
1689
- if (showSettings) handleCloseSettings();
1690
- }, [liveScanEnabled, enableLiveScan, disableLiveScan, showSettings]);
1691
- const handleIssuesClick = useCallback2(() => {
1692
- if (!liveScanEnabled) {
1693
- enableLiveScan();
1694
- return;
1695
- }
1696
- setShowResults((prev) => !prev);
1697
- }, [liveScanEnabled, enableLiveScan]);
1729
+ const handleStartScan = useCallback2(() => {
1730
+ enableLiveScan();
1731
+ setShowSettings(false);
1732
+ }, [enableLiveScan]);
1733
+ const handleStopScan = useCallback2(() => {
1734
+ disableLiveScan();
1735
+ setShowResults(false);
1736
+ }, [disableLiveScan]);
1698
1737
  const handleSettingsClick = useCallback2(() => {
1699
1738
  if (showSettings) {
1700
1739
  handleCloseSettings();
1701
1740
  } else {
1702
1741
  setShowSettings(true);
1703
- setShowResults(false);
1704
1742
  }
1705
1743
  }, [showSettings]);
1706
1744
  const handleCloseSettings = useCallback2(() => {
@@ -1710,6 +1748,9 @@ function UILintToolbar() {
1710
1748
  setSettingsClosing(false);
1711
1749
  }, 150);
1712
1750
  }, []);
1751
+ const handleToggleResults = useCallback2(() => {
1752
+ setShowResults((prev) => !prev);
1753
+ }, []);
1713
1754
  const handleUILintInteraction = useCallback2(
1714
1755
  (e) => {
1715
1756
  e.stopPropagation();
@@ -1717,8 +1758,38 @@ function UILintToolbar() {
1717
1758
  []
1718
1759
  );
1719
1760
  if (!mounted) return null;
1720
- const issueVariant = !liveScanEnabled ? "default" : hasIssues ? "warning" : isComplete ? "success" : "default";
1721
1761
  const bottomPosition = nextjsOverlayVisible ? "80px" : "20px";
1762
+ const renderToolbar = () => {
1763
+ if (!wsConnected) {
1764
+ return /* @__PURE__ */ jsx5(
1765
+ DisconnectedToolbar,
1766
+ {
1767
+ onSettingsClick: handleSettingsClick,
1768
+ showSettings
1769
+ }
1770
+ );
1771
+ }
1772
+ if (!liveScanEnabled) {
1773
+ return /* @__PURE__ */ jsx5(
1774
+ IdleToolbar,
1775
+ {
1776
+ onStartScan: handleStartScan,
1777
+ onSettingsClick: handleSettingsClick,
1778
+ showSettings
1779
+ }
1780
+ );
1781
+ }
1782
+ return /* @__PURE__ */ jsx5(
1783
+ ScanningToolbar,
1784
+ {
1785
+ issueCount: totalIssues,
1786
+ isScanning,
1787
+ showResults,
1788
+ onToggleResults: handleToggleResults,
1789
+ onStopScan: handleStopScan
1790
+ }
1791
+ );
1792
+ };
1722
1793
  const content = /* @__PURE__ */ jsxs4(
1723
1794
  "div",
1724
1795
  {
@@ -1734,116 +1805,20 @@ function UILintToolbar() {
1734
1805
  fontFamily: TOKENS.fontFamily,
1735
1806
  transition: `bottom ${TOKENS.transitionSlow}`,
1736
1807
  pointerEvents: "none"
1737
- // Allow clicks to pass through empty space
1738
1808
  },
1739
1809
  children: [
1740
1810
  /* @__PURE__ */ jsx5("style", { children: globalStyles }),
1741
1811
  /* @__PURE__ */ jsx5(
1742
- "div",
1743
- {
1744
- className: `uilint-hint ${liveScanEnabled ? "uilint-hint--visible" : ""}`,
1745
- style: {
1746
- textAlign: "center",
1747
- marginBottom: "10px",
1748
- fontSize: "11px",
1749
- color: TOKENS.textMuted,
1750
- letterSpacing: "0.02em",
1751
- pointerEvents: "auto"
1752
- // Re-enable pointer events for hint
1753
- },
1754
- "aria-hidden": !liveScanEnabled,
1755
- children: /* @__PURE__ */ jsx5(
1756
- "kbd",
1757
- {
1758
- style: {
1759
- display: "inline-block",
1760
- padding: "2px 5px",
1761
- marginRight: "4px",
1762
- borderRadius: "4px",
1763
- backgroundColor: TOKENS.bgElevated,
1764
- border: `1px solid ${TOKENS.border}`,
1765
- fontSize: "10px",
1766
- fontFamily: TOKENS.fontMono,
1767
- color: TOKENS.textSecondary,
1768
- boxShadow: `0 1px 3px rgba(0, 0, 0, 0.5)`
1769
- },
1770
- children: "\u2325 + Click to inspect element"
1771
- }
1772
- )
1773
- }
1774
- ),
1775
- /* @__PURE__ */ jsxs4(
1776
1812
  "div",
1777
1813
  {
1778
1814
  ref: toolbarRef,
1779
1815
  role: "toolbar",
1780
1816
  "aria-label": "UI Lint toolbar",
1781
- style: {
1782
- position: "relative",
1783
- display: "inline-flex",
1784
- alignItems: "center",
1785
- height: TOKENS.pillHeight,
1786
- borderRadius: TOKENS.pillRadius,
1787
- border: `1px solid ${TOKENS.border}`,
1788
- backgroundColor: TOKENS.bgBase,
1789
- backdropFilter: TOKENS.blur,
1790
- WebkitBackdropFilter: TOKENS.blur,
1791
- boxShadow: liveScanEnabled && hasIssues ? `${TOKENS.shadowMd}, ${TOKENS.shadowGlow(
1792
- `${TOKENS.warning}30`
1793
- )}` : TOKENS.shadowMd,
1794
- overflow: "hidden",
1795
- transition: `box-shadow ${TOKENS.transitionBase}`,
1796
- pointerEvents: "auto"
1797
- // Re-enable pointer events for interactive toolbar
1798
- },
1799
- children: [
1800
- /* @__PURE__ */ jsx5(
1801
- ToolbarButton,
1802
- {
1803
- onClick: handleToggleClick,
1804
- active: liveScanEnabled,
1805
- title: liveScanEnabled ? "Stop scanning (\u2325S)" : "Start scanning (\u2325S)",
1806
- ariaLabel: liveScanEnabled ? "Stop live scanning" : "Start live scanning",
1807
- width: "48px",
1808
- children: liveScanEnabled ? /* @__PURE__ */ jsx5(Icons.Eye, {}) : /* @__PURE__ */ jsx5(Icons.EyeOff, {})
1809
- }
1810
- ),
1811
- /* @__PURE__ */ jsx5(Divider, {}),
1812
- /* @__PURE__ */ jsx5(
1813
- ToolbarButton,
1814
- {
1815
- onClick: handleIssuesClick,
1816
- active: showResults && liveScanEnabled,
1817
- variant: issueVariant,
1818
- title: !liveScanEnabled ? "Click to enable scanning" : `${totalIssues} issue${totalIssues !== 1 ? "s" : ""} found`,
1819
- ariaLabel: !liveScanEnabled ? "Enable scanning to see issues" : `View ${totalIssues} issues`,
1820
- width: "auto",
1821
- children: /* @__PURE__ */ jsx5("span", { style: { padding: "0 12px" }, children: /* @__PURE__ */ jsx5(
1822
- ScanStatus,
1823
- {
1824
- status: autoScanState.status,
1825
- issueCount: totalIssues,
1826
- enabled: liveScanEnabled
1827
- }
1828
- ) })
1829
- }
1830
- ),
1831
- /* @__PURE__ */ jsx5(Divider, {}),
1832
- /* @__PURE__ */ jsx5(
1833
- ToolbarButton,
1834
- {
1835
- onClick: handleSettingsClick,
1836
- active: showSettings,
1837
- title: "Settings",
1838
- ariaLabel: "Open settings",
1839
- width: "44px",
1840
- children: /* @__PURE__ */ jsx5(Icons.Settings, {})
1841
- }
1842
- )
1843
- ]
1817
+ style: { pointerEvents: "auto" },
1818
+ children: renderToolbar()
1844
1819
  }
1845
1820
  ),
1846
- showSettings && /* @__PURE__ */ jsx5(
1821
+ showSettings && !liveScanEnabled && /* @__PURE__ */ jsx5(
1847
1822
  "div",
1848
1823
  {
1849
1824
  ref: settingsRef,
@@ -1854,7 +1829,6 @@ function UILintToolbar() {
1854
1829
  left: 0,
1855
1830
  marginBottom: "8px",
1856
1831
  pointerEvents: "auto"
1857
- // Re-enable pointer events for popover
1858
1832
  },
1859
1833
  children: /* @__PURE__ */ jsx5(SettingsPopover, { settings })
1860
1834
  }
@@ -1063,10 +1063,10 @@ function UILintUI() {
1063
1063
  const [components, setComponents] = useState(null);
1064
1064
  useEffect2(() => {
1065
1065
  Promise.all([
1066
- import("./UILintToolbar-XJN6LFWZ.js"),
1067
- import("./InspectionPanel-EOW6OJFT.js"),
1068
- import("./LocatorOverlay-BF6EED4N.js"),
1069
- import("./ElementBadges-E35MQ2SV.js")
1066
+ import("./UILintToolbar-FWVC6MNG.js"),
1067
+ import("./InspectionPanel-4P7I4QVY.js"),
1068
+ import("./LocatorOverlay-L3EPYQEF.js"),
1069
+ import("./ElementBadges-N2N3CBLI.js")
1070
1070
  ]).then(([toolbar, panel, locator, badges]) => {
1071
1071
  setComponents({
1072
1072
  Toolbar: toolbar.UILintToolbar,
@@ -7,7 +7,7 @@ import {
7
7
  buildEditorUrl,
8
8
  useUILintContext,
9
9
  useUILintStore
10
- } from "./chunk-OU5EEQT6.js";
10
+ } from "./chunk-RAPUZC5J.js";
11
11
 
12
12
  // src/components/ui-lint/InspectionPanel.tsx
13
13
  import React, {
package/dist/index.d.ts CHANGED
@@ -169,18 +169,12 @@ declare function useUILintContext(): UILintContextValue;
169
169
  declare function UILintProvider({ children, enabled, }: UILintProviderProps): react_jsx_runtime.JSX.Element;
170
170
 
171
171
  /**
172
- * UILint Toolbar - Improved UX Version
172
+ * UILint Toolbar - Simplified Mode-Based Design
173
173
  *
174
- * Key improvements:
175
- * - Clear visual hierarchy: Primary (toggle) Secondary (issues) → Tertiary (settings)
176
- * - Contextual hints that only show when relevant
177
- * - CSS-based hover/focus states (no inline handlers)
178
- * - Full keyboard navigation with visible focus rings
179
- * - Smooth animations for all state changes
180
- * - Better disabled state communication
181
- * - Expanded panel that doesn't conflict with settings
182
- * - Touch-friendly targets (min 44px)
183
- * - ARIA labels and semantic markup
174
+ * Three distinct modes:
175
+ * 1. Disconnected: Minimal pill with settings only
176
+ * 2. Connected/Idle: Two-segment pill (Start Scanning + Settings)
177
+ * 3. Scanning: Compact floating UI with hint, status dropdown, and stop button
184
178
  */
185
179
 
186
180
  declare function UILintToolbar(): React$1.ReactPortal | null;
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  "use client";
2
2
  import {
3
3
  UILintToolbar
4
- } from "./chunk-XUMLILUN.js";
4
+ } from "./chunk-OSYIUF52.js";
5
5
  import {
6
6
  InspectionPanel
7
- } from "./chunk-JURUYCUC.js";
7
+ } from "./chunk-UF6KN2JJ.js";
8
8
  import {
9
9
  clearSourceCache,
10
10
  fetchSource,
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-S4IWHBOQ.js";
15
15
  import {
16
16
  LocatorOverlay
17
- } from "./chunk-LQ3WQYIF.js";
17
+ } from "./chunk-LNLTM7N6.js";
18
18
  import {
19
19
  DATA_UILINT_ID,
20
20
  DEFAULT_SETTINGS,
@@ -30,7 +30,7 @@ import {
30
30
  scanDOMForSources,
31
31
  updateElementRects,
32
32
  useUILintContext
33
- } from "./chunk-OU5EEQT6.js";
33
+ } from "./chunk-RAPUZC5J.js";
34
34
 
35
35
  // src/consistency/snapshot.ts
36
36
  var DATA_ELEMENTS_ATTR = "data-elements";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uilint-react",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "React component for AI-powered UI consistency checking",
5
5
  "author": "Peter Suggate",
6
6
  "repository": {
@@ -34,7 +34,7 @@
34
34
  "node": ">=20.0.0"
35
35
  },
36
36
  "dependencies": {
37
- "uilint-core": "^0.1.46",
37
+ "uilint-core": "^0.1.47",
38
38
  "zustand": "^5.0.5"
39
39
  },
40
40
  "peerDependencies": {