@principal-ade/code-quality-panels 0.1.13 → 0.1.15

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.
Files changed (34) hide show
  1. package/dist/panels.bundle.js +237 -137
  2. package/dist/panels.bundle.js.map +1 -1
  3. package/package.json +1 -1
  4. package/dist/components/QualityEmptyState.d.ts +0 -22
  5. package/dist/components/QualityEmptyState.d.ts.map +0 -1
  6. package/dist/components/QualityHexagon.d.ts +0 -50
  7. package/dist/components/QualityHexagon.d.ts.map +0 -1
  8. package/dist/components/QualityHexagon.stories.d.ts +0 -54
  9. package/dist/components/QualityHexagon.stories.d.ts.map +0 -1
  10. package/dist/components/RepositoryQualityGrid.d.ts +0 -84
  11. package/dist/components/RepositoryQualityGrid.d.ts.map +0 -1
  12. package/dist/components/RepositoryQualityGrid.stories.d.ts +0 -45
  13. package/dist/components/RepositoryQualityGrid.stories.d.ts.map +0 -1
  14. package/dist/components/index.d.ts +0 -4
  15. package/dist/components/index.d.ts.map +0 -1
  16. package/dist/index.d.ts +0 -18
  17. package/dist/index.d.ts.map +0 -1
  18. package/dist/lib/utils.d.ts +0 -3
  19. package/dist/lib/utils.d.ts.map +0 -1
  20. package/dist/mocks/panelContext.d.ts +0 -33
  21. package/dist/mocks/panelContext.d.ts.map +0 -1
  22. package/dist/panels/QualityHexagonPanel.d.ts +0 -7
  23. package/dist/panels/QualityHexagonPanel.d.ts.map +0 -1
  24. package/dist/panels/QualityHexagonPanel.stories.d.ts +0 -64
  25. package/dist/panels/QualityHexagonPanel.stories.d.ts.map +0 -1
  26. package/dist/panels/RepositoryQualityGridPanel.d.ts +0 -8
  27. package/dist/panels/RepositoryQualityGridPanel.d.ts.map +0 -1
  28. package/dist/panels/RepositoryQualityGridPanel.stories.d.ts +0 -26
  29. package/dist/panels/RepositoryQualityGridPanel.stories.d.ts.map +0 -1
  30. package/dist/tools/index.d.ts +0 -7
  31. package/dist/tools/index.d.ts.map +0 -1
  32. package/dist/tools.bundle.js +0 -7
  33. package/dist/types/index.d.ts +0 -7
  34. package/dist/types/index.d.ts.map +0 -1
@@ -106,47 +106,121 @@ const createLucideIcon = (iconName, iconNode) => {
106
106
  * This source code is licensed under the ISC license.
107
107
  * See the LICENSE file in the root directory of this source tree.
108
108
  */
109
- const __iconNode$7 = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
110
- const Check = createLucideIcon("check", __iconNode$7);
109
+ const __iconNode$d = [
110
+ ["path", { d: "M12 7v14", key: "1akyts" }],
111
+ [
112
+ "path",
113
+ {
114
+ d: "M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z",
115
+ key: "ruj8y"
116
+ }
117
+ ]
118
+ ];
119
+ const BookOpen = createLucideIcon("book-open", __iconNode$d);
120
+ /**
121
+ * @license lucide-react v0.552.0 - ISC
122
+ *
123
+ * This source code is licensed under the ISC license.
124
+ * See the LICENSE file in the root directory of this source tree.
125
+ */
126
+ const __iconNode$c = [
127
+ [
128
+ "path",
129
+ { d: "M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2 2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1", key: "ezmyqa" }
130
+ ],
131
+ [
132
+ "path",
133
+ {
134
+ d: "M16 21h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1",
135
+ key: "e1hn23"
136
+ }
137
+ ]
138
+ ];
139
+ const Braces = createLucideIcon("braces", __iconNode$c);
111
140
  /**
112
141
  * @license lucide-react v0.552.0 - ISC
113
142
  *
114
143
  * This source code is licensed under the ISC license.
115
144
  * See the LICENSE file in the root directory of this source tree.
116
145
  */
117
- const __iconNode$6 = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
118
- const ChevronRight = createLucideIcon("chevron-right", __iconNode$6);
146
+ const __iconNode$b = [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]];
147
+ const Check = createLucideIcon("check", __iconNode$b);
119
148
  /**
120
149
  * @license lucide-react v0.552.0 - ISC
121
150
  *
122
151
  * This source code is licensed under the ISC license.
123
152
  * See the LICENSE file in the root directory of this source tree.
124
153
  */
125
- const __iconNode$5 = [
154
+ const __iconNode$a = [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]];
155
+ const ChevronRight = createLucideIcon("chevron-right", __iconNode$a);
156
+ /**
157
+ * @license lucide-react v0.552.0 - ISC
158
+ *
159
+ * This source code is licensed under the ISC license.
160
+ * See the LICENSE file in the root directory of this source tree.
161
+ */
162
+ const __iconNode$9 = [
126
163
  ["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
127
164
  ["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
128
165
  ];
129
- const Copy = createLucideIcon("copy", __iconNode$5);
166
+ const Copy = createLucideIcon("copy", __iconNode$9);
130
167
  /**
131
168
  * @license lucide-react v0.552.0 - ISC
132
169
  *
133
170
  * This source code is licensed under the ISC license.
134
171
  * See the LICENSE file in the root directory of this source tree.
135
172
  */
136
- const __iconNode$4 = [
173
+ const __iconNode$8 = [
174
+ [
175
+ "path",
176
+ {
177
+ d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
178
+ key: "1oefj6"
179
+ }
180
+ ],
181
+ ["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
182
+ ["circle", { cx: "11.5", cy: "14.5", r: "2.5", key: "1bq0ko" }],
183
+ ["path", { d: "M13.3 16.3 15 18", key: "2quom7" }]
184
+ ];
185
+ const FileSearch = createLucideIcon("file-search", __iconNode$8);
186
+ /**
187
+ * @license lucide-react v0.552.0 - ISC
188
+ *
189
+ * This source code is licensed under the ISC license.
190
+ * See the LICENSE file in the root directory of this source tree.
191
+ */
192
+ const __iconNode$7 = [
193
+ [
194
+ "path",
195
+ {
196
+ d: "M14 2v6a2 2 0 0 0 .245.96l5.51 10.08A2 2 0 0 1 18 22H6a2 2 0 0 1-1.755-2.96l5.51-10.08A2 2 0 0 0 10 8V2",
197
+ key: "18mbvz"
198
+ }
199
+ ],
200
+ ["path", { d: "M6.453 15h11.094", key: "3shlmq" }],
201
+ ["path", { d: "M8.5 2h7", key: "csnxdl" }]
202
+ ];
203
+ const FlaskConical = createLucideIcon("flask-conical", __iconNode$7);
204
+ /**
205
+ * @license lucide-react v0.552.0 - ISC
206
+ *
207
+ * This source code is licensed under the ISC license.
208
+ * See the LICENSE file in the root directory of this source tree.
209
+ */
210
+ const __iconNode$6 = [
137
211
  ["line", { x1: "6", x2: "6", y1: "3", y2: "15", key: "17qcm7" }],
138
212
  ["circle", { cx: "18", cy: "6", r: "3", key: "1h7g24" }],
139
213
  ["circle", { cx: "6", cy: "18", r: "3", key: "fqmcym" }],
140
214
  ["path", { d: "M18 9a9 9 0 0 1-9 9", key: "n2h4wq" }]
141
215
  ];
142
- const GitBranch = createLucideIcon("git-branch", __iconNode$4);
216
+ const GitBranch = createLucideIcon("git-branch", __iconNode$6);
143
217
  /**
144
218
  * @license lucide-react v0.552.0 - ISC
145
219
  *
146
220
  * This source code is licensed under the ISC license.
147
221
  * See the LICENSE file in the root directory of this source tree.
148
222
  */
149
- const __iconNode$3 = [
223
+ const __iconNode$5 = [
150
224
  [
151
225
  "path",
152
226
  {
@@ -155,30 +229,63 @@ const __iconNode$3 = [
155
229
  }
156
230
  ]
157
231
  ];
158
- const Hexagon = createLucideIcon("hexagon", __iconNode$3);
232
+ const Hexagon = createLucideIcon("hexagon", __iconNode$5);
159
233
  /**
160
234
  * @license lucide-react v0.552.0 - ISC
161
235
  *
162
236
  * This source code is licensed under the ISC license.
163
237
  * See the LICENSE file in the root directory of this source tree.
164
238
  */
165
- const __iconNode$2 = [
239
+ const __iconNode$4 = [
166
240
  ["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
167
241
  ["path", { d: "M12 16v-4", key: "1dtifu" }],
168
242
  ["path", { d: "M12 8h.01", key: "e9boi3" }]
169
243
  ];
170
- const Info = createLucideIcon("info", __iconNode$2);
244
+ const Info = createLucideIcon("info", __iconNode$4);
171
245
  /**
172
246
  * @license lucide-react v0.552.0 - ISC
173
247
  *
174
248
  * This source code is licensed under the ISC license.
175
249
  * See the LICENSE file in the root directory of this source tree.
176
250
  */
177
- const __iconNode$1 = [
251
+ const __iconNode$3 = [
252
+ [
253
+ "path",
254
+ {
255
+ d: "M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z",
256
+ key: "1s2grr"
257
+ }
258
+ ],
259
+ ["path", { d: "M20 2v4", key: "1rf3ol" }],
260
+ ["path", { d: "M22 4h-4", key: "gwowj6" }],
261
+ ["circle", { cx: "4", cy: "20", r: "2", key: "6kqj1y" }]
262
+ ];
263
+ const Sparkles = createLucideIcon("sparkles", __iconNode$3);
264
+ /**
265
+ * @license lucide-react v0.552.0 - ISC
266
+ *
267
+ * This source code is licensed under the ISC license.
268
+ * See the LICENSE file in the root directory of this source tree.
269
+ */
270
+ const __iconNode$2 = [
178
271
  ["path", { d: "M12 19h8", key: "baeox8" }],
179
272
  ["path", { d: "m4 17 6-6-6-6", key: "1yngyt" }]
180
273
  ];
181
- const Terminal = createLucideIcon("terminal", __iconNode$1);
274
+ const Terminal = createLucideIcon("terminal", __iconNode$2);
275
+ /**
276
+ * @license lucide-react v0.552.0 - ISC
277
+ *
278
+ * This source code is licensed under the ISC license.
279
+ * See the LICENSE file in the root directory of this source tree.
280
+ */
281
+ const __iconNode$1 = [
282
+ ["path", { d: "M10 11v6", key: "nco0om" }],
283
+ ["path", { d: "M14 11v6", key: "outv1u" }],
284
+ ["path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6", key: "miytrc" }],
285
+ ["path", { d: "M3 6h18", key: "d0wm0j" }],
286
+ ["path", { d: "M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2", key: "e791ji" }]
287
+ ];
288
+ const Trash2 = createLucideIcon("trash-2", __iconNode$1);
182
289
  /**
183
290
  * @license lucide-react v0.552.0 - ISC
184
291
  *
@@ -661,7 +768,8 @@ function QualityHexagonExpandable({
661
768
  onRefresh,
662
769
  isRefreshing = false,
663
770
  defaultExpanded = false,
664
- onExpandChange
771
+ onExpandChange,
772
+ onMetricClick
665
773
  }) {
666
774
  const [expanded, setExpanded] = React2.useState(defaultExpanded);
667
775
  const handleToggleExpand = React2.useCallback(() => {
@@ -802,11 +910,28 @@ function QualityHexagonExpandable({
802
910
  return /* @__PURE__ */ jsxs(
803
911
  "div",
804
912
  {
913
+ onClick: (e) => {
914
+ e.stopPropagation();
915
+ onMetricClick == null ? void 0 : onMetricClick(key);
916
+ },
805
917
  style: {
806
918
  display: "flex",
807
919
  alignItems: "center",
808
920
  justifyContent: "space-between",
809
- gap: 12
921
+ gap: 12,
922
+ cursor: onMetricClick ? "pointer" : "default",
923
+ padding: "4px 8px",
924
+ margin: "0 -8px",
925
+ borderRadius: 4,
926
+ transition: "background-color 0.15s ease"
927
+ },
928
+ onMouseEnter: (e) => {
929
+ if (onMetricClick) {
930
+ e.currentTarget.style.backgroundColor = theme.colors.surface;
931
+ }
932
+ },
933
+ onMouseLeave: (e) => {
934
+ e.currentTarget.style.backgroundColor = "transparent";
810
935
  },
811
936
  children: [
812
937
  /* @__PURE__ */ jsxs("span", { style: {
@@ -939,12 +1064,12 @@ const CommandLine = ({ command, theme, label }) => {
939
1064
  };
940
1065
  const MetricsPreview = ({ theme }) => {
941
1066
  const metrics = [
942
- { key: "tests", label: "Tests", description: "Test coverage & pass rate", icon: "🧪" },
943
- { key: "linting", label: "Linting", description: "ESLint code quality", icon: "📝" },
944
- { key: "types", label: "Types", description: "TypeScript type safety", icon: "🔷" },
945
- { key: "formatting", label: "Formatting", description: "Prettier code style", icon: "✨" },
946
- { key: "deadCode", label: "Dead Code", description: "Unused exports & deps", icon: "🧹" },
947
- { key: "documentation", label: "Docs", description: "Code documentation", icon: "📚" }
1067
+ { key: "tests", label: "Tests", description: "Test coverage & pass rate", Icon: FlaskConical },
1068
+ { key: "linting", label: "Linting", description: "ESLint code quality", Icon: FileSearch },
1069
+ { key: "types", label: "Types", description: "TypeScript type safety", Icon: Braces },
1070
+ { key: "formatting", label: "Formatting", description: "Prettier code style", Icon: Sparkles },
1071
+ { key: "deadCode", label: "Dead Code", description: "Unused exports & deps", Icon: Trash2 },
1072
+ { key: "documentation", label: "Docs", description: "Code documentation", Icon: BookOpen }
948
1073
  ];
949
1074
  return /* @__PURE__ */ jsx(
950
1075
  "div",
@@ -970,7 +1095,7 @@ const MetricsPreview = ({ theme }) => {
970
1095
  fontSize: 12
971
1096
  },
972
1097
  children: [
973
- /* @__PURE__ */ jsx("span", { style: { fontSize: 14 }, children: m.icon }),
1098
+ /* @__PURE__ */ jsx(m.Icon, { size: 14, color: theme.colors.textMuted }),
974
1099
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", flexDirection: "column" }, children: [
975
1100
  /* @__PURE__ */ jsx("span", { style: { fontWeight: 500, color: theme.colors.text }, children: m.label }),
976
1101
  /* @__PURE__ */ jsx("span", { style: { fontSize: 11, color: theme.colors.textMuted }, children: m.description })
@@ -1306,14 +1431,14 @@ const mockPackages = [
1306
1431
  }
1307
1432
  }
1308
1433
  ];
1309
- const METRIC_OPTIONS$1 = [
1310
- { key: "types", label: "Types", colorMode: "typescript" },
1311
- { key: "documentation", label: "Docs", colorMode: "alexandria" },
1312
- { key: "tests", label: "Tests", colorMode: "coverage" },
1313
- { key: "deadCode", label: "Dead Code", colorMode: "knip" },
1314
- { key: "formatting", label: "Format", colorMode: "prettier" },
1315
- { key: "linting", label: "Linting", colorMode: "eslint" }
1316
- ];
1434
+ const METRIC_TO_COLOR_MODE = {
1435
+ types: "typescript",
1436
+ documentation: "alexandria",
1437
+ tests: "coverage",
1438
+ deadCode: "knip",
1439
+ formatting: "prettier",
1440
+ linting: "eslint"
1441
+ };
1317
1442
  const QualityHexagonPanelContent = ({
1318
1443
  context,
1319
1444
  events
@@ -1321,7 +1446,6 @@ const QualityHexagonPanelContent = ({
1321
1446
  var _a;
1322
1447
  const { theme } = useTheme();
1323
1448
  const [refreshingPackages, setRefreshingPackages] = React2__default.useState(/* @__PURE__ */ new Set());
1324
- const [selectedMetric, setSelectedMetric] = React2__default.useState(null);
1325
1449
  const qualitySlice = context.getSlice("quality");
1326
1450
  const hasQualitySlice = context.hasSlice("quality");
1327
1451
  const isLoading = (qualitySlice == null ? void 0 : qualitySlice.loading) ?? false;
@@ -1350,31 +1474,6 @@ const QualityHexagonPanelContent = ({
1350
1474
  setRefreshingPackages(/* @__PURE__ */ new Set());
1351
1475
  }
1352
1476
  };
1353
- const handleMetricChange = (metric) => {
1354
- setSelectedMetric(metric);
1355
- if (metric) {
1356
- const option = METRIC_OPTIONS$1.find((o) => o.key === metric);
1357
- if (option) {
1358
- events.emit({
1359
- type: "quality:colorMode:select",
1360
- source: "principal-ade.quality-hexagon-panel",
1361
- timestamp: Date.now(),
1362
- payload: {
1363
- colorMode: option.colorMode
1364
- }
1365
- });
1366
- }
1367
- } else {
1368
- events.emit({
1369
- type: "quality:colorMode:select",
1370
- source: "principal-ade.quality-hexagon-panel",
1371
- timestamp: Date.now(),
1372
- payload: {
1373
- colorMode: "fileTypes"
1374
- }
1375
- });
1376
- }
1377
- };
1378
1477
  React2__default.useEffect(() => {
1379
1478
  const unsubscribers = [
1380
1479
  events.on("principal-ade.quality-panel:refresh", async () => {
@@ -1400,7 +1499,7 @@ const QualityHexagonPanelContent = ({
1400
1499
  documentation: acc.documentation + pkg.metrics.documentation / packages.length
1401
1500
  }), { tests: 0, deadCode: 0, linting: 0, formatting: 0, types: 0, documentation: 0 })
1402
1501
  ) : "none";
1403
- return /* @__PURE__ */ jsx(
1502
+ return /* @__PURE__ */ jsxs(
1404
1503
  "div",
1405
1504
  {
1406
1505
  style: {
@@ -1410,83 +1509,73 @@ const QualityHexagonPanelContent = ({
1410
1509
  backgroundColor: theme.colors.background,
1411
1510
  color: theme.colors.text,
1412
1511
  overflowY: "auto",
1413
- boxSizing: "border-box"
1512
+ boxSizing: "border-box",
1513
+ display: "flex",
1514
+ flexDirection: "column"
1414
1515
  },
1415
- children: /* @__PURE__ */ jsxs(
1416
- "div",
1417
- {
1418
- style: {
1419
- padding: 20,
1420
- display: "flex",
1421
- flexDirection: "column",
1422
- gap: 16
1423
- },
1424
- children: [
1425
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", flexWrap: "wrap", gap: 12 }, children: [
1426
- /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
1427
- /* @__PURE__ */ jsx(Hexagon, { size: 24, color: tierColors[overallTier] }),
1428
- /* @__PURE__ */ jsx(
1429
- "h2",
1430
- {
1431
- style: {
1432
- margin: 0,
1433
- fontSize: 20,
1434
- fontWeight: 600,
1435
- color: theme.colors.text
1436
- },
1437
- children: "Code Quality"
1438
- }
1439
- ),
1440
- /* @__PURE__ */ jsx(
1441
- "span",
1442
- {
1443
- title: "Platinum: 90%+ avg | Gold: 75%+ | Silver: 60%+ | Bronze: 40%+",
1444
- style: {
1445
- display: "inline-flex",
1446
- alignItems: "center",
1447
- justifyContent: "center",
1448
- width: 18,
1449
- height: 18,
1450
- borderRadius: "50%",
1451
- border: `1px solid ${theme.colors.border}`,
1452
- fontSize: 12,
1453
- color: theme.colors.textMuted,
1454
- cursor: "help"
1455
- },
1456
- children: "?"
1457
- }
1458
- ),
1459
- packages.length > 1 && /* @__PURE__ */ jsxs("span", { style: {
1460
- fontSize: 14,
1461
- color: theme.colors.textMuted
1462
- }, children: [
1463
- packages.length,
1464
- " packages"
1465
- ] })
1466
- ] }),
1467
- /* @__PURE__ */ jsxs(
1468
- "select",
1469
- {
1470
- value: selectedMetric ?? "",
1471
- onChange: (e) => handleMetricChange(e.target.value ? e.target.value : null),
1472
- style: {
1473
- padding: "6px 12px",
1474
- fontSize: 13,
1475
- backgroundColor: theme.colors.background,
1476
- color: theme.colors.text,
1477
- border: `1px solid ${theme.colors.border}`,
1478
- borderRadius: 4,
1479
- cursor: "pointer",
1480
- outline: "none"
1481
- },
1482
- children: [
1483
- /* @__PURE__ */ jsx("option", { value: "", children: "Show in File City..." }),
1484
- METRIC_OPTIONS$1.map((option) => /* @__PURE__ */ jsx("option", { value: option.key, children: option.label }, option.key))
1485
- ]
1486
- }
1487
- )
1488
- ] }),
1489
- /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 16, minHeight: 0 }, children: isLoading ? /* @__PURE__ */ jsx("div", { style: {
1516
+ children: [
1517
+ /* @__PURE__ */ jsxs("div", { style: {
1518
+ display: "flex",
1519
+ alignItems: "center",
1520
+ gap: 12,
1521
+ height: 40,
1522
+ flexShrink: 0,
1523
+ padding: "0 16px",
1524
+ borderBottom: `1px solid ${theme.colors.border}`,
1525
+ boxSizing: "border-box"
1526
+ }, children: [
1527
+ /* @__PURE__ */ jsx(Hexagon, { size: 20, color: tierColors[overallTier] }),
1528
+ /* @__PURE__ */ jsx(
1529
+ "h2",
1530
+ {
1531
+ style: {
1532
+ margin: 0,
1533
+ fontSize: 14,
1534
+ fontWeight: 600,
1535
+ color: theme.colors.text
1536
+ },
1537
+ children: "Code Quality"
1538
+ }
1539
+ ),
1540
+ /* @__PURE__ */ jsx(
1541
+ "span",
1542
+ {
1543
+ title: "Platinum: 90%+ avg | Gold: 75%+ | Silver: 60%+ | Bronze: 40%+",
1544
+ style: {
1545
+ display: "inline-flex",
1546
+ alignItems: "center",
1547
+ justifyContent: "center",
1548
+ width: 16,
1549
+ height: 16,
1550
+ borderRadius: "50%",
1551
+ border: `1px solid ${theme.colors.border}`,
1552
+ fontSize: 11,
1553
+ color: theme.colors.textMuted,
1554
+ cursor: "help"
1555
+ },
1556
+ children: "?"
1557
+ }
1558
+ ),
1559
+ packages.length > 1 && /* @__PURE__ */ jsxs("span", { style: {
1560
+ fontSize: 13,
1561
+ color: theme.colors.textMuted
1562
+ }, children: [
1563
+ packages.length,
1564
+ " packages"
1565
+ ] })
1566
+ ] }),
1567
+ /* @__PURE__ */ jsx(
1568
+ "div",
1569
+ {
1570
+ style: {
1571
+ padding: 16,
1572
+ display: "flex",
1573
+ flexDirection: "column",
1574
+ gap: 16,
1575
+ flex: 1,
1576
+ minHeight: 0
1577
+ },
1578
+ children: /* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 16, minHeight: 0 }, children: isLoading ? /* @__PURE__ */ jsx("div", { style: {
1490
1579
  padding: 40,
1491
1580
  textAlign: "center",
1492
1581
  color: theme.colors.textMuted
@@ -1518,14 +1607,25 @@ const QualityHexagonPanelContent = ({
1518
1607
  packageName: info.packageName
1519
1608
  } : null
1520
1609
  });
1610
+ },
1611
+ onMetricClick: (metric) => {
1612
+ const colorMode = METRIC_TO_COLOR_MODE[metric];
1613
+ if (colorMode) {
1614
+ events.emit({
1615
+ type: "quality:colorMode:select",
1616
+ source: "principal-ade.quality-hexagon-panel",
1617
+ timestamp: Date.now(),
1618
+ payload: { colorMode }
1619
+ });
1620
+ }
1521
1621
  }
1522
1622
  },
1523
1623
  pkg.name
1524
1624
  );
1525
1625
  }) })
1526
- ]
1527
- }
1528
- )
1626
+ }
1627
+ )
1628
+ ]
1529
1629
  }
1530
1630
  );
1531
1631
  };