@gnome-ui/react 1.50.1 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/components/AffectedPackage/AffectedPackage.cjs +2 -0
  2. package/dist/components/AffectedPackage/AffectedPackage.cjs.map +1 -0
  3. package/dist/components/AffectedPackage/AffectedPackage.d.ts +20 -0
  4. package/dist/components/AffectedPackage/AffectedPackage.js +61 -0
  5. package/dist/components/AffectedPackage/AffectedPackage.js.map +1 -0
  6. package/dist/components/AffectedPackage/AffectedPackage.module.css.cjs +2 -0
  7. package/dist/components/AffectedPackage/AffectedPackage.module.css.cjs.map +1 -0
  8. package/dist/components/AffectedPackage/AffectedPackage.module.css.js +14 -0
  9. package/dist/components/AffectedPackage/AffectedPackage.module.css.js.map +1 -0
  10. package/dist/components/AffectedPackage/index.d.ts +4 -0
  11. package/dist/components/AffectedPackage/package.cjs +2 -0
  12. package/dist/components/AffectedPackage/package.cjs.map +1 -0
  13. package/dist/components/AffectedPackage/package.d.ts +8 -0
  14. package/dist/components/AffectedPackage/package.js +12 -0
  15. package/dist/components/AffectedPackage/package.js.map +1 -0
  16. package/dist/components/AffectedPackage.cjs +1 -0
  17. package/dist/components/AffectedPackage.d.ts +2 -0
  18. package/dist/components/AffectedPackage.js +3 -0
  19. package/dist/components/CveIdentifier/CveIdentifier.cjs +2 -0
  20. package/dist/components/CveIdentifier/CveIdentifier.cjs.map +1 -0
  21. package/dist/components/CveIdentifier/CveIdentifier.d.ts +22 -0
  22. package/dist/components/CveIdentifier/CveIdentifier.js +33 -0
  23. package/dist/components/CveIdentifier/CveIdentifier.js.map +1 -0
  24. package/dist/components/CveIdentifier/CveIdentifier.module.css.cjs +2 -0
  25. package/dist/components/CveIdentifier/CveIdentifier.module.css.cjs.map +1 -0
  26. package/dist/components/CveIdentifier/CveIdentifier.module.css.js +8 -0
  27. package/dist/components/CveIdentifier/CveIdentifier.module.css.js.map +1 -0
  28. package/dist/components/CveIdentifier/cve.cjs +2 -0
  29. package/dist/components/CveIdentifier/cve.cjs.map +1 -0
  30. package/dist/components/CveIdentifier/cve.d.ts +6 -0
  31. package/dist/components/CveIdentifier/cve.js +20 -0
  32. package/dist/components/CveIdentifier/cve.js.map +1 -0
  33. package/dist/components/CveIdentifier/index.d.ts +4 -0
  34. package/dist/components/CveIdentifier.cjs +1 -0
  35. package/dist/components/CveIdentifier.d.ts +2 -0
  36. package/dist/components/CveIdentifier.js +3 -0
  37. package/dist/components/CvssScore/CvssScore.cjs +2 -0
  38. package/dist/components/CvssScore/CvssScore.cjs.map +1 -0
  39. package/dist/components/CvssScore/CvssScore.d.ts +20 -0
  40. package/dist/components/CvssScore/CvssScore.js +33 -0
  41. package/dist/components/CvssScore/CvssScore.js.map +1 -0
  42. package/dist/components/CvssScore/CvssScore.module.css.cjs +2 -0
  43. package/dist/components/CvssScore/CvssScore.module.css.cjs.map +1 -0
  44. package/dist/components/CvssScore/CvssScore.module.css.js +15 -0
  45. package/dist/components/CvssScore/CvssScore.module.css.js.map +1 -0
  46. package/dist/components/CvssScore/cvss.cjs +2 -0
  47. package/dist/components/CvssScore/cvss.cjs.map +1 -0
  48. package/dist/components/CvssScore/cvss.d.ts +7 -0
  49. package/dist/components/CvssScore/cvss.js +16 -0
  50. package/dist/components/CvssScore/cvss.js.map +1 -0
  51. package/dist/components/CvssScore/index.d.ts +4 -0
  52. package/dist/components/CvssScore.cjs +1 -0
  53. package/dist/components/CvssScore.d.ts +2 -0
  54. package/dist/components/CvssScore.js +3 -0
  55. package/dist/components/CvssVector/CvssVector.cjs +2 -0
  56. package/dist/components/CvssVector/CvssVector.cjs.map +1 -0
  57. package/dist/components/CvssVector/CvssVector.d.ts +13 -0
  58. package/dist/components/CvssVector/CvssVector.js +44 -0
  59. package/dist/components/CvssVector/CvssVector.js.map +1 -0
  60. package/dist/components/CvssVector/CvssVector.module.css.cjs +2 -0
  61. package/dist/components/CvssVector/CvssVector.module.css.cjs.map +1 -0
  62. package/dist/components/CvssVector/CvssVector.module.css.js +13 -0
  63. package/dist/components/CvssVector/CvssVector.module.css.js.map +1 -0
  64. package/dist/components/CvssVector/index.d.ts +4 -0
  65. package/dist/components/CvssVector/vector.cjs +2 -0
  66. package/dist/components/CvssVector/vector.cjs.map +1 -0
  67. package/dist/components/CvssVector/vector.d.ts +21 -0
  68. package/dist/components/CvssVector/vector.js +71 -0
  69. package/dist/components/CvssVector/vector.js.map +1 -0
  70. package/dist/components/CvssVector.cjs +1 -0
  71. package/dist/components/CvssVector.d.ts +2 -0
  72. package/dist/components/CvssVector.js +3 -0
  73. package/dist/components/CweIdentifier/CweIdentifier.cjs +2 -0
  74. package/dist/components/CweIdentifier/CweIdentifier.cjs.map +1 -0
  75. package/dist/components/CweIdentifier/CweIdentifier.d.ts +22 -0
  76. package/dist/components/CweIdentifier/CweIdentifier.js +33 -0
  77. package/dist/components/CweIdentifier/CweIdentifier.js.map +1 -0
  78. package/dist/components/CweIdentifier/CweIdentifier.module.css.cjs +2 -0
  79. package/dist/components/CweIdentifier/CweIdentifier.module.css.cjs.map +1 -0
  80. package/dist/components/CweIdentifier/CweIdentifier.module.css.js +8 -0
  81. package/dist/components/CweIdentifier/CweIdentifier.module.css.js.map +1 -0
  82. package/dist/components/CweIdentifier/cwe.cjs +2 -0
  83. package/dist/components/CweIdentifier/cwe.cjs.map +1 -0
  84. package/dist/components/CweIdentifier/cwe.d.ts +6 -0
  85. package/dist/components/CweIdentifier/cwe.js +21 -0
  86. package/dist/components/CweIdentifier/cwe.js.map +1 -0
  87. package/dist/components/CweIdentifier/index.d.ts +4 -0
  88. package/dist/components/CweIdentifier.cjs +1 -0
  89. package/dist/components/CweIdentifier.d.ts +2 -0
  90. package/dist/components/CweIdentifier.js +3 -0
  91. package/dist/components/SecurityMetric/SecurityMetric.cjs +2 -0
  92. package/dist/components/SecurityMetric/SecurityMetric.cjs.map +1 -0
  93. package/dist/components/SecurityMetric/SecurityMetric.d.ts +21 -0
  94. package/dist/components/SecurityMetric/SecurityMetric.js +43 -0
  95. package/dist/components/SecurityMetric/SecurityMetric.js.map +1 -0
  96. package/dist/components/SecurityMetric/SecurityMetric.module.css.cjs +2 -0
  97. package/dist/components/SecurityMetric/SecurityMetric.module.css.cjs.map +1 -0
  98. package/dist/components/SecurityMetric/SecurityMetric.module.css.js +22 -0
  99. package/dist/components/SecurityMetric/SecurityMetric.module.css.js.map +1 -0
  100. package/dist/components/SecurityMetric/index.d.ts +2 -0
  101. package/dist/components/SecurityMetric.cjs +1 -0
  102. package/dist/components/SecurityMetric.d.ts +2 -0
  103. package/dist/components/SecurityMetric.js +2 -0
  104. package/dist/components/SeverityBadge/SeverityBadge.cjs +2 -0
  105. package/dist/components/SeverityBadge/SeverityBadge.cjs.map +1 -0
  106. package/dist/components/SeverityBadge/SeverityBadge.d.ts +18 -0
  107. package/dist/components/SeverityBadge/SeverityBadge.js +22 -0
  108. package/dist/components/SeverityBadge/SeverityBadge.js.map +1 -0
  109. package/dist/components/SeverityBadge/SeverityBadge.module.css.cjs +2 -0
  110. package/dist/components/SeverityBadge/SeverityBadge.module.css.cjs.map +1 -0
  111. package/dist/components/SeverityBadge/SeverityBadge.module.css.js +13 -0
  112. package/dist/components/SeverityBadge/SeverityBadge.module.css.js.map +1 -0
  113. package/dist/components/SeverityBadge/index.d.ts +4 -0
  114. package/dist/components/SeverityBadge/severity.cjs +2 -0
  115. package/dist/components/SeverityBadge/severity.cjs.map +1 -0
  116. package/dist/components/SeverityBadge/severity.d.ts +4 -0
  117. package/dist/components/SeverityBadge/severity.js +27 -0
  118. package/dist/components/SeverityBadge/severity.js.map +1 -0
  119. package/dist/components/SeverityBadge.cjs +1 -0
  120. package/dist/components/SeverityBadge.d.ts +2 -0
  121. package/dist/components/SeverityBadge.js +3 -0
  122. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.cjs +2 -0
  123. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.cjs.map +1 -0
  124. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.d.ts +30 -0
  125. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.js +76 -0
  126. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.js.map +1 -0
  127. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.module.css.cjs +2 -0
  128. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.module.css.cjs.map +1 -0
  129. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.module.css.js +21 -0
  130. package/dist/components/VulnerabilityFinding/VulnerabilityFinding.module.css.js.map +1 -0
  131. package/dist/components/VulnerabilityFinding/finding.cjs +2 -0
  132. package/dist/components/VulnerabilityFinding/finding.cjs.map +1 -0
  133. package/dist/components/VulnerabilityFinding/finding.d.ts +4 -0
  134. package/dist/components/VulnerabilityFinding/finding.js +20 -0
  135. package/dist/components/VulnerabilityFinding/finding.js.map +1 -0
  136. package/dist/components/VulnerabilityFinding/index.d.ts +4 -0
  137. package/dist/components/VulnerabilityFinding.cjs +1 -0
  138. package/dist/components/VulnerabilityFinding.d.ts +2 -0
  139. package/dist/components/VulnerabilityFinding.js +3 -0
  140. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.cjs +2 -0
  141. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.cjs.map +1 -0
  142. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.d.ts +18 -0
  143. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.js +57 -0
  144. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.js.map +1 -0
  145. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.module.css.cjs +2 -0
  146. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.module.css.cjs.map +1 -0
  147. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.module.css.js +19 -0
  148. package/dist/components/VulnerabilitySummary/VulnerabilitySummary.module.css.js.map +1 -0
  149. package/dist/components/VulnerabilitySummary/index.d.ts +4 -0
  150. package/dist/components/VulnerabilitySummary/summary.cjs +2 -0
  151. package/dist/components/VulnerabilitySummary/summary.cjs.map +1 -0
  152. package/dist/components/VulnerabilitySummary/summary.d.ts +8 -0
  153. package/dist/components/VulnerabilitySummary/summary.js +15 -0
  154. package/dist/components/VulnerabilitySummary/summary.js.map +1 -0
  155. package/dist/components/VulnerabilitySummary.cjs +1 -0
  156. package/dist/components/VulnerabilitySummary.d.ts +2 -0
  157. package/dist/components/VulnerabilitySummary.js +3 -0
  158. package/dist/index.cjs +1 -1
  159. package/dist/index.d.ts +18 -0
  160. package/dist/index.js +113 -96
  161. package/dist/style.css +1 -1
  162. package/package.json +46 -1
@@ -0,0 +1,13 @@
1
+ import { HTMLAttributes } from 'react';
2
+ export interface CvssVectorProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** CVSS vector string, for example `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`. */
4
+ vector: string;
5
+ /** Whether to render the raw vector string. */
6
+ showVector?: boolean;
7
+ /** Whether to render expanded metric labels. */
8
+ showMetrics?: boolean;
9
+ }
10
+ /**
11
+ * Readable CVSS vector display for vulnerability reports and scan details.
12
+ */
13
+ export declare const CvssVector: ({ vector, showVector, showMetrics, className, "aria-label": ariaLabel, ...props }: CvssVectorProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ import e from "./CvssVector.module.css.js";
2
+ import { parseCvssVector as t } from "./vector.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/components/CvssVector/CvssVector.tsx
5
+ var i = ({ vector: i, showVector: a = !0, showMetrics: o = !0, className: s, "aria-label": c, ...l }) => {
6
+ let u = t(i), d = u.metrics.map((e) => `${e.label} ${e.valueLabel}`).join(", ");
7
+ return /* @__PURE__ */ r("div", {
8
+ "aria-label": c ?? `CVSS vector${u.version ? ` ${u.version}` : ""}`,
9
+ className: [e.root, s].filter(Boolean).join(" "),
10
+ "data-valid": u.valid ? "true" : "false",
11
+ "data-version": u.version,
12
+ ...l,
13
+ children: [a ? /* @__PURE__ */ n("code", {
14
+ className: e.vector,
15
+ children: i
16
+ }) : null, o && u.metrics.length > 0 ? /* @__PURE__ */ n("dl", {
17
+ "aria-label": d,
18
+ className: e.metrics,
19
+ children: u.metrics.map((t) => /* @__PURE__ */ r("div", {
20
+ className: e.metric,
21
+ "data-known": t.known ? "true" : "false",
22
+ children: [/* @__PURE__ */ n("dt", {
23
+ className: e.metricLabel,
24
+ children: t.label
25
+ }), /* @__PURE__ */ r("dd", {
26
+ className: e.metricValue,
27
+ children: [/* @__PURE__ */ r("span", {
28
+ "aria-hidden": "true",
29
+ className: e.metricCode,
30
+ children: [
31
+ t.key,
32
+ ":",
33
+ t.value
34
+ ]
35
+ }), /* @__PURE__ */ n("span", { children: t.valueLabel })]
36
+ })]
37
+ }, `${t.key}:${t.value}`))
38
+ }) : null]
39
+ });
40
+ };
41
+ //#endregion
42
+ export { i as CvssVector };
43
+
44
+ //# sourceMappingURL=CvssVector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CvssVector.js","names":[],"sources":["../../../src/components/CvssVector/CvssVector.tsx"],"sourcesContent":["import type { HTMLAttributes } from 'react';\n\nimport styles from './CvssVector.module.css';\nimport { parseCvssVector } from './vector';\n\nexport interface CvssVectorProps extends HTMLAttributes<HTMLDivElement> {\n /** CVSS vector string, for example `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`. */\n vector: string;\n /** Whether to render the raw vector string. */\n showVector?: boolean;\n /** Whether to render expanded metric labels. */\n showMetrics?: boolean;\n}\n\n/**\n * Readable CVSS vector display for vulnerability reports and scan details.\n */\nexport const CvssVector = ({\n vector,\n showVector = true,\n showMetrics = true,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: CvssVectorProps) => {\n const parsed = parseCvssVector(vector);\n const metricsLabel = parsed.metrics\n .map((metric) => `${metric.label} ${metric.valueLabel}`)\n .join(', ');\n\n return (\n <div\n aria-label={ariaLabel ?? `CVSS vector${parsed.version ? ` ${parsed.version}` : ''}`}\n className={[styles.root, className].filter(Boolean).join(' ')}\n data-valid={parsed.valid ? 'true' : 'false'}\n data-version={parsed.version}\n {...props}\n >\n {showVector ? <code className={styles.vector}>{vector}</code> : null}\n {showMetrics && parsed.metrics.length > 0 ? (\n <dl aria-label={metricsLabel} className={styles.metrics}>\n {parsed.metrics.map((metric) => (\n <div\n className={styles.metric}\n data-known={metric.known ? 'true' : 'false'}\n key={`${metric.key}:${metric.value}`}\n >\n <dt className={styles.metricLabel}>{metric.label}</dt>\n <dd className={styles.metricValue}>\n <span aria-hidden=\"true\" className={styles.metricCode}>\n {metric.key}:{metric.value}\n </span>\n <span>{metric.valueLabel}</span>\n </dd>\n </div>\n ))}\n </dl>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AAiBA,IAAa,KAAc,EACzB,WACA,gBAAa,IACb,iBAAc,IACd,cACA,cAAc,GACd,GAAG,QACkB;CACrB,IAAM,IAAS,EAAgB,CAAM,GAC/B,IAAe,EAAO,QACzB,KAAK,MAAW,GAAG,EAAO,MAAM,GAAG,EAAO,YAAY,EACtD,KAAK,IAAI;CAEZ,OACE,kBAAC,OAAD;EACE,cAAY,KAAa,cAAc,EAAO,UAAU,IAAI,EAAO,YAAY;EAC/E,WAAW,CAAC,EAAO,MAAM,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;EAC5D,cAAY,EAAO,QAAQ,SAAS;EACpC,gBAAc,EAAO;EACrB,GAAI;YALN,CAOG,IAAa,kBAAC,QAAD;GAAM,WAAW,EAAO;aAAS;EAAa,CAAA,IAAI,MAC/D,KAAe,EAAO,QAAQ,SAAS,IACtC,kBAAC,MAAD;GAAI,cAAY;GAAc,WAAW,EAAO;aAC7C,EAAO,QAAQ,KAAK,MACnB,kBAAC,OAAD;IACE,WAAW,EAAO;IAClB,cAAY,EAAO,QAAQ,SAAS;cAFtC,CAKE,kBAAC,MAAD;KAAI,WAAW,EAAO;eAAc,EAAO;IAAU,CAAA,GACrD,kBAAC,MAAD;KAAI,WAAW,EAAO;eAAtB,CACE,kBAAC,QAAD;MAAM,eAAY;MAAO,WAAW,EAAO;gBAA3C;OACG,EAAO;OAAI;OAAE,EAAO;MACjB;SACN,kBAAC,QAAD,EAAA,UAAO,EAAO,WAAiB,CAAA,CAC7B;MACD;MATE,GAAG,EAAO,IAAI,GAAG,EAAO,OAS1B,CACN;EACC,CAAA,IACF,IACD;;AAET"}
@@ -0,0 +1,2 @@
1
+ var e={root:`_root_1ktho_3`,vector:`_vector_1ktho_17`,metrics:`_metrics_1ktho_32`,metric:`_metric_1ktho_32`,metricLabel:`_metricLabel_1ktho_53`,metricValue:`_metricValue_1ktho_59`,metricCode:`_metricCode_1ktho_69`};exports.default=e;
2
+ //# sourceMappingURL=CvssVector.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CvssVector.module.css.cjs","names":[],"sources":["../../../src/components/CvssVector/CvssVector.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.root {\n --cvss-vector-fg: #241f31;\n --cvss-vector-muted-fg: #5e5c64;\n --cvss-vector-subtle-fg: #77767b;\n --cvss-vector-surface: rgb(255 255 255 / 0.86);\n --cvss-vector-pill-bg: rgb(246 245 244 / 0.95);\n --cvss-vector-border: rgb(0 0 0 / 0.14);\n\n display: grid;\n gap: 8px;\n color: var(--cvss-vector-fg);\n font-family: var(--gnome-font-family);\n}\n\n.vector {\n display: inline-block;\n width: fit-content;\n max-width: 100%;\n padding: 5px 8px;\n overflow-wrap: anywhere;\n border: 1px solid var(--cvss-vector-border);\n border-radius: 6px;\n background: var(--cvss-vector-surface);\n color: var(--cvss-vector-muted-fg);\n font-family: var(--gnome-monospace-font-family, monospace);\n font-size: 0.8125rem;\n line-height: 1.35;\n}\n\n.metrics {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 0;\n}\n\n.metric {\n display: inline-flex;\n align-items: baseline;\n gap: 6px;\n padding: 5px 7px;\n border: 1px solid var(--cvss-vector-border);\n border-radius: 999px;\n background: var(--cvss-vector-pill-bg);\n}\n\n.metric[data-known=\"false\"] {\n border-style: dashed;\n}\n\n.metricLabel {\n color: var(--cvss-vector-muted-fg);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.metricValue {\n display: inline-flex;\n align-items: baseline;\n gap: 4px;\n margin: 0;\n color: var(--cvss-vector-fg);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.metricCode {\n color: var(--cvss-vector-subtle-fg);\n font-family: var(--gnome-monospace-font-family, monospace);\n font-size: 0.6875rem;\n font-weight: 600;\n}\n\n@media (prefers-color-scheme: dark) {\n .root {\n --cvss-vector-fg: rgb(255 255 255 / 0.9);\n --cvss-vector-muted-fg: rgb(255 255 255 / 0.72);\n --cvss-vector-subtle-fg: rgb(255 255 255 / 0.62);\n --cvss-vector-surface: rgb(36 36 36 / 0.88);\n --cvss-vector-pill-bg: rgb(30 30 30 / 0.96);\n --cvss-vector-border: rgb(255 255 255 / 0.14);\n }\n}\n"],"mappings":""}
@@ -0,0 +1,13 @@
1
+ var e = {
2
+ root: "_root_1ktho_3",
3
+ vector: "_vector_1ktho_17",
4
+ metrics: "_metrics_1ktho_32",
5
+ metric: "_metric_1ktho_32",
6
+ metricLabel: "_metricLabel_1ktho_53",
7
+ metricValue: "_metricValue_1ktho_59",
8
+ metricCode: "_metricCode_1ktho_69"
9
+ };
10
+ //#endregion
11
+ export { e as default };
12
+
13
+ //# sourceMappingURL=CvssVector.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CvssVector.module.css.js","names":[],"sources":["../../../src/components/CvssVector/CvssVector.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.root {\n --cvss-vector-fg: #241f31;\n --cvss-vector-muted-fg: #5e5c64;\n --cvss-vector-subtle-fg: #77767b;\n --cvss-vector-surface: rgb(255 255 255 / 0.86);\n --cvss-vector-pill-bg: rgb(246 245 244 / 0.95);\n --cvss-vector-border: rgb(0 0 0 / 0.14);\n\n display: grid;\n gap: 8px;\n color: var(--cvss-vector-fg);\n font-family: var(--gnome-font-family);\n}\n\n.vector {\n display: inline-block;\n width: fit-content;\n max-width: 100%;\n padding: 5px 8px;\n overflow-wrap: anywhere;\n border: 1px solid var(--cvss-vector-border);\n border-radius: 6px;\n background: var(--cvss-vector-surface);\n color: var(--cvss-vector-muted-fg);\n font-family: var(--gnome-monospace-font-family, monospace);\n font-size: 0.8125rem;\n line-height: 1.35;\n}\n\n.metrics {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin: 0;\n}\n\n.metric {\n display: inline-flex;\n align-items: baseline;\n gap: 6px;\n padding: 5px 7px;\n border: 1px solid var(--cvss-vector-border);\n border-radius: 999px;\n background: var(--cvss-vector-pill-bg);\n}\n\n.metric[data-known=\"false\"] {\n border-style: dashed;\n}\n\n.metricLabel {\n color: var(--cvss-vector-muted-fg);\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.metricValue {\n display: inline-flex;\n align-items: baseline;\n gap: 4px;\n margin: 0;\n color: var(--cvss-vector-fg);\n font-size: 0.75rem;\n font-weight: 700;\n}\n\n.metricCode {\n color: var(--cvss-vector-subtle-fg);\n font-family: var(--gnome-monospace-font-family, monospace);\n font-size: 0.6875rem;\n font-weight: 600;\n}\n\n@media (prefers-color-scheme: dark) {\n .root {\n --cvss-vector-fg: rgb(255 255 255 / 0.9);\n --cvss-vector-muted-fg: rgb(255 255 255 / 0.72);\n --cvss-vector-subtle-fg: rgb(255 255 255 / 0.62);\n --cvss-vector-surface: rgb(36 36 36 / 0.88);\n --cvss-vector-pill-bg: rgb(30 30 30 / 0.96);\n --cvss-vector-border: rgb(255 255 255 / 0.14);\n }\n}\n"],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export type { CvssVectorProps } from './CvssVector';
2
+ export { CvssVector } from './CvssVector';
3
+ export type { CvssVectorMetric, ParsedCvssVector } from './vector';
4
+ export { parseCvssVector } from './vector';
@@ -0,0 +1,2 @@
1
+ var e=/^CVSS:(3\.[01])$/,t={AV:`Attack Vector`,AC:`Attack Complexity`,PR:`Privileges Required`,UI:`User Interaction`,S:`Scope`,C:`Confidentiality`,I:`Integrity`,A:`Availability`},n={AV:{N:`Network`,A:`Adjacent`,L:`Local`,P:`Physical`},AC:{L:`Low`,H:`High`},PR:{N:`None`,L:`Low`,H:`High`},UI:{N:`None`,R:`Required`},S:{U:`Unchanged`,C:`Changed`},C:{H:`High`,L:`Low`,N:`None`},I:{H:`High`,L:`Low`,N:`None`},A:{H:`High`,L:`Low`,N:`None`}};function r(r){let[i,...a]=r.trim().split(`/`).map(e=>e.trim()).filter(Boolean),o=i?.match(e)?.[1],s=a.map(e=>{let[r=``,i=``]=e.split(`:`),a=r.toUpperCase(),o=i.toUpperCase();return{key:a,label:t[a]??a,value:o,valueLabel:n[a]?.[o]??o,known:!!(t[a]&&n[a]?.[o])}});return{version:o,metrics:s,valid:!!(o&&s.length>0&&s.every(e=>e.known))}}exports.parseCvssVector=r;
2
+ //# sourceMappingURL=vector.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector.cjs","names":[],"sources":["../../../src/components/CvssVector/vector.ts"],"sourcesContent":["export interface CvssVectorMetric {\n /** Short CVSS metric key, for example `AV`. */\n key: string;\n /** Human-readable metric name. */\n label: string;\n /** Short CVSS metric value, for example `N`. */\n value: string;\n /** Human-readable metric value. */\n valueLabel: string;\n /** Whether the metric key and value are known by this component. */\n known: boolean;\n}\n\nexport interface ParsedCvssVector {\n /** CVSS version from the vector prefix when present. */\n version?: string;\n /** Parsed vector metrics in source order. */\n metrics: CvssVectorMetric[];\n /** Whether the vector includes a supported CVSS 3.x prefix and parseable metrics. */\n valid: boolean;\n}\n\nconst CVSS_VECTOR_PREFIX_PATTERN = /^CVSS:(3\\.[01])$/;\n\nconst CVSS_METRIC_LABELS: Record<string, string> = {\n AV: 'Attack Vector',\n AC: 'Attack Complexity',\n PR: 'Privileges Required',\n UI: 'User Interaction',\n S: 'Scope',\n C: 'Confidentiality',\n I: 'Integrity',\n A: 'Availability',\n};\n\nconst CVSS_METRIC_VALUE_LABELS: Record<string, Record<string, string>> = {\n AV: {\n N: 'Network',\n A: 'Adjacent',\n L: 'Local',\n P: 'Physical',\n },\n AC: {\n L: 'Low',\n H: 'High',\n },\n PR: {\n N: 'None',\n L: 'Low',\n H: 'High',\n },\n UI: {\n N: 'None',\n R: 'Required',\n },\n S: {\n U: 'Unchanged',\n C: 'Changed',\n },\n C: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n I: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n A: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n};\n\nexport function parseCvssVector(vector: string): ParsedCvssVector {\n const segments = vector\n .trim()\n .split('/')\n .map((segment) => segment.trim())\n .filter(Boolean);\n const [prefix, ...metricSegments] = segments;\n const version = prefix?.match(CVSS_VECTOR_PREFIX_PATTERN)?.[1];\n\n const metrics = metricSegments.map((segment) => {\n const [rawKey = '', rawValue = ''] = segment.split(':');\n const key = rawKey.toUpperCase();\n const value = rawValue.toUpperCase();\n const label = CVSS_METRIC_LABELS[key] ?? key;\n const valueLabel = CVSS_METRIC_VALUE_LABELS[key]?.[value] ?? value;\n\n return {\n key,\n label,\n value,\n valueLabel,\n known: Boolean(CVSS_METRIC_LABELS[key] && CVSS_METRIC_VALUE_LABELS[key]?.[value]),\n };\n });\n\n return {\n version,\n metrics,\n valid: Boolean(version && metrics.length > 0 && metrics.every((metric) => metric.known)),\n };\n}\n"],"mappings":"AAsBA,IAAM,EAA6B,mBAE7B,EAA6C,CACjD,GAAI,gBACJ,GAAI,oBACJ,GAAI,sBACJ,GAAI,mBACJ,EAAG,QACH,EAAG,kBACH,EAAG,YACH,EAAG,cACL,EAEM,EAAmE,CACvE,GAAI,CACF,EAAG,UACH,EAAG,WACH,EAAG,QACH,EAAG,UACL,EACA,GAAI,CACF,EAAG,MACH,EAAG,MACL,EACA,GAAI,CACF,EAAG,OACH,EAAG,MACH,EAAG,MACL,EACA,GAAI,CACF,EAAG,OACH,EAAG,UACL,EACA,EAAG,CACD,EAAG,YACH,EAAG,SACL,EACA,EAAG,CACD,EAAG,OACH,EAAG,MACH,EAAG,MACL,EACA,EAAG,CACD,EAAG,OACH,EAAG,MACH,EAAG,MACL,EACA,EAAG,CACD,EAAG,OACH,EAAG,MACH,EAAG,MACL,CACF,EAEA,SAAgB,EAAgB,EAAkC,CAMhE,GAAM,CAAC,EAAQ,GAAG,GALD,EACd,KAAK,EACL,MAAM,GAAG,EACT,IAAK,GAAY,EAAQ,KAAK,CAAC,EAC/B,OAAO,OAC0B,EAC9B,EAAU,GAAQ,MAAM,CAA0B,IAAI,GAEtD,EAAU,EAAe,IAAK,GAAY,CAC9C,GAAM,CAAC,EAAS,GAAI,EAAW,IAAM,EAAQ,MAAM,GAAG,EAChD,EAAM,EAAO,YAAY,EACzB,EAAQ,EAAS,YAAY,EAInC,MAAO,CACL,MACA,MALY,EAAmB,IAAQ,EAMvC,QACA,WANiB,EAAyB,KAAO,IAAU,EAO3D,MAAO,GAAQ,EAAmB,IAAQ,EAAyB,KAAO,GAC5E,CACF,CAAC,EAED,MAAO,CACL,UACA,UACA,MAAO,GAAQ,GAAW,EAAQ,OAAS,GAAK,EAAQ,MAAO,GAAW,EAAO,KAAK,EACxF,CACF"}
@@ -0,0 +1,21 @@
1
+ export interface CvssVectorMetric {
2
+ /** Short CVSS metric key, for example `AV`. */
3
+ key: string;
4
+ /** Human-readable metric name. */
5
+ label: string;
6
+ /** Short CVSS metric value, for example `N`. */
7
+ value: string;
8
+ /** Human-readable metric value. */
9
+ valueLabel: string;
10
+ /** Whether the metric key and value are known by this component. */
11
+ known: boolean;
12
+ }
13
+ export interface ParsedCvssVector {
14
+ /** CVSS version from the vector prefix when present. */
15
+ version?: string;
16
+ /** Parsed vector metrics in source order. */
17
+ metrics: CvssVectorMetric[];
18
+ /** Whether the vector includes a supported CVSS 3.x prefix and parseable metrics. */
19
+ valid: boolean;
20
+ }
21
+ export declare function parseCvssVector(vector: string): ParsedCvssVector;
@@ -0,0 +1,71 @@
1
+ //#region src/components/CvssVector/vector.ts
2
+ var e = /^CVSS:(3\.[01])$/, t = {
3
+ AV: "Attack Vector",
4
+ AC: "Attack Complexity",
5
+ PR: "Privileges Required",
6
+ UI: "User Interaction",
7
+ S: "Scope",
8
+ C: "Confidentiality",
9
+ I: "Integrity",
10
+ A: "Availability"
11
+ }, n = {
12
+ AV: {
13
+ N: "Network",
14
+ A: "Adjacent",
15
+ L: "Local",
16
+ P: "Physical"
17
+ },
18
+ AC: {
19
+ L: "Low",
20
+ H: "High"
21
+ },
22
+ PR: {
23
+ N: "None",
24
+ L: "Low",
25
+ H: "High"
26
+ },
27
+ UI: {
28
+ N: "None",
29
+ R: "Required"
30
+ },
31
+ S: {
32
+ U: "Unchanged",
33
+ C: "Changed"
34
+ },
35
+ C: {
36
+ H: "High",
37
+ L: "Low",
38
+ N: "None"
39
+ },
40
+ I: {
41
+ H: "High",
42
+ L: "Low",
43
+ N: "None"
44
+ },
45
+ A: {
46
+ H: "High",
47
+ L: "Low",
48
+ N: "None"
49
+ }
50
+ };
51
+ function r(r) {
52
+ let [i, ...a] = r.trim().split("/").map((e) => e.trim()).filter(Boolean), o = i?.match(e)?.[1], s = a.map((e) => {
53
+ let [r = "", i = ""] = e.split(":"), a = r.toUpperCase(), o = i.toUpperCase();
54
+ return {
55
+ key: a,
56
+ label: t[a] ?? a,
57
+ value: o,
58
+ valueLabel: n[a]?.[o] ?? o,
59
+ known: !!(t[a] && n[a]?.[o])
60
+ };
61
+ });
62
+ return {
63
+ version: o,
64
+ metrics: s,
65
+ valid: !!(o && s.length > 0 && s.every((e) => e.known))
66
+ };
67
+ }
68
+ //#endregion
69
+ export { r as parseCvssVector };
70
+
71
+ //# sourceMappingURL=vector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector.js","names":[],"sources":["../../../src/components/CvssVector/vector.ts"],"sourcesContent":["export interface CvssVectorMetric {\n /** Short CVSS metric key, for example `AV`. */\n key: string;\n /** Human-readable metric name. */\n label: string;\n /** Short CVSS metric value, for example `N`. */\n value: string;\n /** Human-readable metric value. */\n valueLabel: string;\n /** Whether the metric key and value are known by this component. */\n known: boolean;\n}\n\nexport interface ParsedCvssVector {\n /** CVSS version from the vector prefix when present. */\n version?: string;\n /** Parsed vector metrics in source order. */\n metrics: CvssVectorMetric[];\n /** Whether the vector includes a supported CVSS 3.x prefix and parseable metrics. */\n valid: boolean;\n}\n\nconst CVSS_VECTOR_PREFIX_PATTERN = /^CVSS:(3\\.[01])$/;\n\nconst CVSS_METRIC_LABELS: Record<string, string> = {\n AV: 'Attack Vector',\n AC: 'Attack Complexity',\n PR: 'Privileges Required',\n UI: 'User Interaction',\n S: 'Scope',\n C: 'Confidentiality',\n I: 'Integrity',\n A: 'Availability',\n};\n\nconst CVSS_METRIC_VALUE_LABELS: Record<string, Record<string, string>> = {\n AV: {\n N: 'Network',\n A: 'Adjacent',\n L: 'Local',\n P: 'Physical',\n },\n AC: {\n L: 'Low',\n H: 'High',\n },\n PR: {\n N: 'None',\n L: 'Low',\n H: 'High',\n },\n UI: {\n N: 'None',\n R: 'Required',\n },\n S: {\n U: 'Unchanged',\n C: 'Changed',\n },\n C: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n I: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n A: {\n H: 'High',\n L: 'Low',\n N: 'None',\n },\n};\n\nexport function parseCvssVector(vector: string): ParsedCvssVector {\n const segments = vector\n .trim()\n .split('/')\n .map((segment) => segment.trim())\n .filter(Boolean);\n const [prefix, ...metricSegments] = segments;\n const version = prefix?.match(CVSS_VECTOR_PREFIX_PATTERN)?.[1];\n\n const metrics = metricSegments.map((segment) => {\n const [rawKey = '', rawValue = ''] = segment.split(':');\n const key = rawKey.toUpperCase();\n const value = rawValue.toUpperCase();\n const label = CVSS_METRIC_LABELS[key] ?? key;\n const valueLabel = CVSS_METRIC_VALUE_LABELS[key]?.[value] ?? value;\n\n return {\n key,\n label,\n value,\n valueLabel,\n known: Boolean(CVSS_METRIC_LABELS[key] && CVSS_METRIC_VALUE_LABELS[key]?.[value]),\n };\n });\n\n return {\n version,\n metrics,\n valid: Boolean(version && metrics.length > 0 && metrics.every((metric) => metric.known)),\n };\n}\n"],"mappings":";AAsBA,IAAM,IAA6B,oBAE7B,IAA6C;CACjD,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL,GAEM,IAAmE;CACvE,IAAI;EACF,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAG;CACL;CACA,IAAI;EACF,GAAG;EACH,GAAG;CACL;CACA,IAAI;EACF,GAAG;EACH,GAAG;EACH,GAAG;CACL;CACA,IAAI;EACF,GAAG;EACH,GAAG;CACL;CACA,GAAG;EACD,GAAG;EACH,GAAG;CACL;CACA,GAAG;EACD,GAAG;EACH,GAAG;EACH,GAAG;CACL;CACA,GAAG;EACD,GAAG;EACH,GAAG;EACH,GAAG;CACL;CACA,GAAG;EACD,GAAG;EACH,GAAG;EACH,GAAG;CACL;AACF;AAEA,SAAgB,EAAgB,GAAkC;CAMhE,IAAM,CAAC,GAAQ,GAAG,KALD,EACd,KAAK,EACL,MAAM,GAAG,EACT,KAAK,MAAY,EAAQ,KAAK,CAAC,EAC/B,OAAO,OAC0B,GAC9B,IAAU,GAAQ,MAAM,CAA0B,IAAI,IAEtD,IAAU,EAAe,KAAK,MAAY;EAC9C,IAAM,CAAC,IAAS,IAAI,IAAW,MAAM,EAAQ,MAAM,GAAG,GAChD,IAAM,EAAO,YAAY,GACzB,IAAQ,EAAS,YAAY;EAInC,OAAO;GACL;GACA,OALY,EAAmB,MAAQ;GAMvC;GACA,YANiB,EAAyB,KAAO,MAAU;GAO3D,OAAO,GAAQ,EAAmB,MAAQ,EAAyB,KAAO;EAC5E;CACF,CAAC;CAED,OAAO;EACL;EACA;EACA,OAAO,GAAQ,KAAW,EAAQ,SAAS,KAAK,EAAQ,OAAO,MAAW,EAAO,KAAK;CACxF;AACF"}
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./CvssVector/vector.cjs"),t=require("./CvssVector/CvssVector.cjs");exports.CvssVector=t.CvssVector,exports.parseCvssVector=e.parseCvssVector;
@@ -0,0 +1,2 @@
1
+ export * from './CvssVector/index'
2
+ export {}
@@ -0,0 +1,3 @@
1
+ import { parseCvssVector as e } from "./CvssVector/vector.js";
2
+ import { CvssVector as t } from "./CvssVector/CvssVector.js";
3
+ export { t as CvssVector, e as parseCvssVector };
@@ -0,0 +1,2 @@
1
+ const e=require("./CweIdentifier.module.css.cjs"),t=require("./cwe.cjs");let n=require("react/jsx-runtime");var r=({cweId:r,link:i=!0,source:a=`mitre`,className:o,"aria-label":s,...c})=>{let l=t.normalizeCweId(r),u=t.isCweId(l),d=[e.default.identifier,u?null:e.default.invalid,o].filter(Boolean).join(` `);if(!i)return(0,n.jsx)(`span`,{...c,"aria-label":s??`${l} weakness identifier`,className:d,"data-valid":u?`true`:`false`,children:l});let{href:f,rel:p,target:m,...h}=c,g=f??t.getCweUrl(l,a);return(0,n.jsx)(`a`,{...h,"aria-label":s??`${l} weakness identifier`,className:d,"data-valid":u?`true`:`false`,href:g,rel:m===`_blank`?`noopener noreferrer`:p,target:m,children:l})};exports.CweIdentifier=r;
2
+ //# sourceMappingURL=CweIdentifier.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CweIdentifier.cjs","names":[],"sources":["../../../src/components/CweIdentifier/CweIdentifier.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from 'react';\n\nimport styles from './CweIdentifier.module.css';\nimport { type CweLinkSource, getCweUrl, isCweId, normalizeCweId } from './cwe';\n\ntype CweIdentifierBaseProps = {\n /** CWE identifier, for example `CWE-79`. Numeric strings are normalized. */\n cweId: string;\n};\n\nexport type CweIdentifierProps =\n | (CweIdentifierBaseProps &\n AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** Whether to render as a link. Defaults to `true`. */\n link?: true;\n /** Weakness database used when `href` is omitted. */\n source?: CweLinkSource;\n })\n | (CweIdentifierBaseProps &\n HTMLAttributes<HTMLSpanElement> & {\n /** Render as static text instead of a link. */\n link: false;\n href?: never;\n source?: never;\n });\n\n/**\n * Monospace CWE identifier with optional link to MITRE CWE.\n */\nexport const CweIdentifier = ({\n cweId,\n link = true,\n source = 'mitre',\n className,\n 'aria-label': ariaLabel,\n ...props\n}: CweIdentifierProps) => {\n const normalized = normalizeCweId(cweId);\n const valid = isCweId(normalized);\n const classes = [styles.identifier, valid ? null : styles.invalid, className]\n .filter(Boolean)\n .join(' ');\n\n if (!link) {\n return (\n <span\n {...props}\n aria-label={ariaLabel ?? `${normalized} weakness identifier`}\n className={classes}\n data-valid={valid ? 'true' : 'false'}\n >\n {normalized}\n </span>\n );\n }\n\n const {\n href: customHref,\n rel,\n target,\n ...anchorProps\n } = props as AnchorHTMLAttributes<HTMLAnchorElement>;\n const href = customHref ?? getCweUrl(normalized, source);\n\n return (\n <a\n {...anchorProps}\n aria-label={ariaLabel ?? `${normalized} weakness identifier`}\n className={classes}\n data-valid={valid ? 'true' : 'false'}\n href={href}\n rel={target === '_blank' ? 'noopener noreferrer' : rel}\n target={target}\n >\n {normalized}\n </a>\n );\n};\n"],"mappings":"4GA6BA,IAAa,GAAiB,CAC5B,QACA,OAAO,GACP,SAAS,QACT,YACA,aAAc,EACd,GAAG,KACqB,CACxB,IAAM,EAAa,EAAA,eAAe,CAAK,EACjC,EAAQ,EAAA,QAAQ,CAAU,EAC1B,EAAU,CAAC,EAAA,QAAO,WAAY,EAAQ,KAAO,EAAA,QAAO,QAAS,CAAS,EACzE,OAAO,OAAO,EACd,KAAK,GAAG,EAEX,GAAI,CAAC,EACH,OACE,EAAA,EAAA,KAAC,OAAD,CACE,GAAI,EACJ,aAAY,GAAa,GAAG,EAAW,sBACvC,UAAW,EACX,aAAY,EAAQ,OAAS,iBAE5B,CACG,CAAA,EAIV,GAAM,CACJ,KAAM,EACN,MACA,SACA,GAAG,GACD,EACE,EAAO,GAAc,EAAA,UAAU,EAAY,CAAM,EAEvD,OACE,EAAA,EAAA,KAAC,IAAD,CACE,GAAI,EACJ,aAAY,GAAa,GAAG,EAAW,sBACvC,UAAW,EACX,aAAY,EAAQ,OAAS,QACvB,OACN,IAAK,IAAW,SAAW,sBAAwB,EAC3C,kBAEP,CACA,CAAA,CAEP"}
@@ -0,0 +1,22 @@
1
+ import { AnchorHTMLAttributes, HTMLAttributes } from 'react';
2
+ import { CweLinkSource } from './cwe';
3
+ type CweIdentifierBaseProps = {
4
+ /** CWE identifier, for example `CWE-79`. Numeric strings are normalized. */
5
+ cweId: string;
6
+ };
7
+ export type CweIdentifierProps = (CweIdentifierBaseProps & AnchorHTMLAttributes<HTMLAnchorElement> & {
8
+ /** Whether to render as a link. Defaults to `true`. */
9
+ link?: true;
10
+ /** Weakness database used when `href` is omitted. */
11
+ source?: CweLinkSource;
12
+ }) | (CweIdentifierBaseProps & HTMLAttributes<HTMLSpanElement> & {
13
+ /** Render as static text instead of a link. */
14
+ link: false;
15
+ href?: never;
16
+ source?: never;
17
+ });
18
+ /**
19
+ * Monospace CWE identifier with optional link to MITRE CWE.
20
+ */
21
+ export declare const CweIdentifier: ({ cweId, link, source, className, "aria-label": ariaLabel, ...props }: CweIdentifierProps) => import("react/jsx-runtime").JSX.Element;
22
+ export {};
@@ -0,0 +1,33 @@
1
+ import e from "./CweIdentifier.module.css.js";
2
+ import { getCweUrl as t, isCweId as n, normalizeCweId as r } from "./cwe.js";
3
+ import { jsx as i } from "react/jsx-runtime";
4
+ //#region src/components/CweIdentifier/CweIdentifier.tsx
5
+ var a = ({ cweId: a, link: o = !0, source: s = "mitre", className: c, "aria-label": l, ...u }) => {
6
+ let d = r(a), f = n(d), p = [
7
+ e.identifier,
8
+ f ? null : e.invalid,
9
+ c
10
+ ].filter(Boolean).join(" ");
11
+ if (!o) return /* @__PURE__ */ i("span", {
12
+ ...u,
13
+ "aria-label": l ?? `${d} weakness identifier`,
14
+ className: p,
15
+ "data-valid": f ? "true" : "false",
16
+ children: d
17
+ });
18
+ let { href: m, rel: h, target: g, ..._ } = u, v = m ?? t(d, s);
19
+ return /* @__PURE__ */ i("a", {
20
+ ..._,
21
+ "aria-label": l ?? `${d} weakness identifier`,
22
+ className: p,
23
+ "data-valid": f ? "true" : "false",
24
+ href: v,
25
+ rel: g === "_blank" ? "noopener noreferrer" : h,
26
+ target: g,
27
+ children: d
28
+ });
29
+ };
30
+ //#endregion
31
+ export { a as CweIdentifier };
32
+
33
+ //# sourceMappingURL=CweIdentifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CweIdentifier.js","names":[],"sources":["../../../src/components/CweIdentifier/CweIdentifier.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from 'react';\n\nimport styles from './CweIdentifier.module.css';\nimport { type CweLinkSource, getCweUrl, isCweId, normalizeCweId } from './cwe';\n\ntype CweIdentifierBaseProps = {\n /** CWE identifier, for example `CWE-79`. Numeric strings are normalized. */\n cweId: string;\n};\n\nexport type CweIdentifierProps =\n | (CweIdentifierBaseProps &\n AnchorHTMLAttributes<HTMLAnchorElement> & {\n /** Whether to render as a link. Defaults to `true`. */\n link?: true;\n /** Weakness database used when `href` is omitted. */\n source?: CweLinkSource;\n })\n | (CweIdentifierBaseProps &\n HTMLAttributes<HTMLSpanElement> & {\n /** Render as static text instead of a link. */\n link: false;\n href?: never;\n source?: never;\n });\n\n/**\n * Monospace CWE identifier with optional link to MITRE CWE.\n */\nexport const CweIdentifier = ({\n cweId,\n link = true,\n source = 'mitre',\n className,\n 'aria-label': ariaLabel,\n ...props\n}: CweIdentifierProps) => {\n const normalized = normalizeCweId(cweId);\n const valid = isCweId(normalized);\n const classes = [styles.identifier, valid ? null : styles.invalid, className]\n .filter(Boolean)\n .join(' ');\n\n if (!link) {\n return (\n <span\n {...props}\n aria-label={ariaLabel ?? `${normalized} weakness identifier`}\n className={classes}\n data-valid={valid ? 'true' : 'false'}\n >\n {normalized}\n </span>\n );\n }\n\n const {\n href: customHref,\n rel,\n target,\n ...anchorProps\n } = props as AnchorHTMLAttributes<HTMLAnchorElement>;\n const href = customHref ?? getCweUrl(normalized, source);\n\n return (\n <a\n {...anchorProps}\n aria-label={ariaLabel ?? `${normalized} weakness identifier`}\n className={classes}\n data-valid={valid ? 'true' : 'false'}\n href={href}\n rel={target === '_blank' ? 'noopener noreferrer' : rel}\n target={target}\n >\n {normalized}\n </a>\n );\n};\n"],"mappings":";;;;AA6BA,IAAa,KAAiB,EAC5B,UACA,UAAO,IACP,YAAS,SACT,cACA,cAAc,GACd,GAAG,QACqB;CACxB,IAAM,IAAa,EAAe,CAAK,GACjC,IAAQ,EAAQ,CAAU,GAC1B,IAAU;EAAC,EAAO;EAAY,IAAQ,OAAO,EAAO;EAAS;CAAS,EACzE,OAAO,OAAO,EACd,KAAK,GAAG;CAEX,IAAI,CAAC,GACH,OACE,kBAAC,QAAD;EACE,GAAI;EACJ,cAAY,KAAa,GAAG,EAAW;EACvC,WAAW;EACX,cAAY,IAAQ,SAAS;YAE5B;CACG,CAAA;CAIV,IAAM,EACJ,MAAM,GACN,QACA,WACA,GAAG,MACD,GACE,IAAO,KAAc,EAAU,GAAY,CAAM;CAEvD,OACE,kBAAC,KAAD;EACE,GAAI;EACJ,cAAY,KAAa,GAAG,EAAW;EACvC,WAAW;EACX,cAAY,IAAQ,SAAS;EACvB;EACN,KAAK,MAAW,WAAW,wBAAwB;EAC3C;YAEP;CACA,CAAA;AAEP"}
@@ -0,0 +1,2 @@
1
+ var e={identifier:`_identifier_zbkct_3`,invalid:`_invalid_zbkct_42`};exports.default=e;
2
+ //# sourceMappingURL=CweIdentifier.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CweIdentifier.module.css.cjs","names":[],"sources":["../../../src/components/CweIdentifier/CweIdentifier.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.identifier {\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n padding: 2px 7px;\n border: 1px solid var(--gnome-border-color, rgb(0 0 0 / 0.12));\n border-radius: 6px;\n background-color: var(--gnome-hover-overlay, rgb(0 0 0 / 0.06));\n color: var(--gnome-window-fg-color, rgb(0 0 0 / 0.8));\n font-family: SFMono-Regular, Consolas, \"Liberation Mono\", Menlo, monospace;\n font-size: 0.75rem;\n font-weight: 650;\n line-height: 1.35;\n text-decoration: none;\n white-space: nowrap;\n}\n\na.identifier {\n cursor: pointer;\n transition:\n background-color var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease),\n border-color var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease);\n}\n\na.identifier:hover {\n border-color: var(--gnome-accent-bg-color, #3584e4);\n background-color: var(--gnome-selected-overlay, rgb(53 132 228 / 0.14));\n}\n\n.identifier:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fff),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Invalid identifier ──────────────────────────────────────────────────── */\n\n.invalid {\n border-color: var(--gnome-warning-bg-color, #f6d32d);\n background-color: rgb(246 211 45 / 0.2);\n}\n\n@media (prefers-color-scheme: dark) {\n .identifier {\n border-color: var(--gnome-border-color, rgb(255 255 255 / 0.14));\n background-color: var(--gnome-hover-overlay, rgb(255 255 255 / 0.08));\n color: var(--gnome-window-fg-color, rgb(255 255 255 / 0.87));\n }\n\n .invalid {\n background-color: rgb(248 228 92 / 0.16);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n a.identifier {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,8 @@
1
+ var e = {
2
+ identifier: "_identifier_zbkct_3",
3
+ invalid: "_invalid_zbkct_42"
4
+ };
5
+ //#endregion
6
+ export { e as default };
7
+
8
+ //# sourceMappingURL=CweIdentifier.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CweIdentifier.module.css.js","names":[],"sources":["../../../src/components/CweIdentifier/CweIdentifier.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.identifier {\n display: inline-flex;\n align-items: center;\n vertical-align: middle;\n padding: 2px 7px;\n border: 1px solid var(--gnome-border-color, rgb(0 0 0 / 0.12));\n border-radius: 6px;\n background-color: var(--gnome-hover-overlay, rgb(0 0 0 / 0.06));\n color: var(--gnome-window-fg-color, rgb(0 0 0 / 0.8));\n font-family: SFMono-Regular, Consolas, \"Liberation Mono\", Menlo, monospace;\n font-size: 0.75rem;\n font-weight: 650;\n line-height: 1.35;\n text-decoration: none;\n white-space: nowrap;\n}\n\na.identifier {\n cursor: pointer;\n transition:\n background-color var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease),\n border-color var(--gnome-duration-fast, 150ms) var(--gnome-easing-default, ease);\n}\n\na.identifier:hover {\n border-color: var(--gnome-accent-bg-color, #3584e4);\n background-color: var(--gnome-selected-overlay, rgb(53 132 228 / 0.14));\n}\n\n.identifier:focus-visible {\n outline: none;\n box-shadow:\n 0 0 0 var(--gnome-focus-ring-offset, 2px) var(--gnome-window-bg-color, #fff),\n 0 0 0 calc(var(--gnome-focus-ring-offset, 2px) + var(--gnome-focus-ring-width, 2px))\n var(--gnome-focus-ring-color, #3584e4);\n}\n\n/* ─── Invalid identifier ──────────────────────────────────────────────────── */\n\n.invalid {\n border-color: var(--gnome-warning-bg-color, #f6d32d);\n background-color: rgb(246 211 45 / 0.2);\n}\n\n@media (prefers-color-scheme: dark) {\n .identifier {\n border-color: var(--gnome-border-color, rgb(255 255 255 / 0.14));\n background-color: var(--gnome-hover-overlay, rgb(255 255 255 / 0.08));\n color: var(--gnome-window-fg-color, rgb(255 255 255 / 0.87));\n }\n\n .invalid {\n background-color: rgb(248 228 92 / 0.16);\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n a.identifier {\n transition: none;\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ var e=/^CWE-(\d{1,6})$/i;function t(e){let t=e.trim().toUpperCase();return/^\d{1,6}$/.test(t)?`CWE-${t}`:t}function n(n){return e.test(t(n))}function r(n){let r=t(n).match(e);return r?Number(r[1]):null}function i(e,t=`mitre`){let n=r(e);return n===null?`https://cwe.mitre.org/`:`https://cwe.mitre.org/data/definitions/${n}.html`}exports.CWE_ID_PATTERN=e,exports.getCweNumber=r,exports.getCweUrl=i,exports.isCweId=n,exports.normalizeCweId=t;
2
+ //# sourceMappingURL=cwe.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwe.cjs","names":[],"sources":["../../../src/components/CweIdentifier/cwe.ts"],"sourcesContent":["export type CweLinkSource = 'mitre' | 'cwe';\n\nexport const CWE_ID_PATTERN = /^CWE-(\\d{1,6})$/i;\n\nexport function normalizeCweId(cweId: string) {\n const normalized = cweId.trim().toUpperCase();\n\n if (/^\\d{1,6}$/.test(normalized)) {\n return `CWE-${normalized}`;\n }\n\n return normalized;\n}\n\nexport function isCweId(cweId: string) {\n return CWE_ID_PATTERN.test(normalizeCweId(cweId));\n}\n\nexport function getCweNumber(cweId: string) {\n const match = normalizeCweId(cweId).match(CWE_ID_PATTERN);\n\n return match ? Number(match[1]) : null;\n}\n\nexport function getCweUrl(cweId: string, _source: CweLinkSource = 'mitre') {\n const cweNumber = getCweNumber(cweId);\n\n if (cweNumber === null) {\n return 'https://cwe.mitre.org/';\n }\n\n return `https://cwe.mitre.org/data/definitions/${cweNumber}.html`;\n}\n"],"mappings":"AAEA,IAAa,EAAiB,mBAE9B,SAAgB,EAAe,EAAe,CAC5C,IAAM,EAAa,EAAM,KAAK,EAAE,YAAY,EAM5C,MAJI,YAAY,KAAK,CAAU,EACtB,OAAO,IAGT,CACT,CAEA,SAAgB,EAAQ,EAAe,CACrC,OAAO,EAAe,KAAK,EAAe,CAAK,CAAC,CAClD,CAEA,SAAgB,EAAa,EAAe,CAC1C,IAAM,EAAQ,EAAe,CAAK,EAAE,MAAM,CAAc,EAExD,OAAO,EAAQ,OAAO,EAAM,EAAE,EAAI,IACpC,CAEA,SAAgB,EAAU,EAAe,EAAyB,QAAS,CACzE,IAAM,EAAY,EAAa,CAAK,EAMpC,OAJI,IAAc,KACT,yBAGF,0CAA0C,EAAU,MAC7D"}
@@ -0,0 +1,6 @@
1
+ export type CweLinkSource = 'mitre' | 'cwe';
2
+ export declare const CWE_ID_PATTERN: RegExp;
3
+ export declare function normalizeCweId(cweId: string): string;
4
+ export declare function isCweId(cweId: string): boolean;
5
+ export declare function getCweNumber(cweId: string): number | null;
6
+ export declare function getCweUrl(cweId: string, _source?: CweLinkSource): string;
@@ -0,0 +1,21 @@
1
+ //#region src/components/CweIdentifier/cwe.ts
2
+ var e = /^CWE-(\d{1,6})$/i;
3
+ function t(e) {
4
+ let t = e.trim().toUpperCase();
5
+ return /^\d{1,6}$/.test(t) ? `CWE-${t}` : t;
6
+ }
7
+ function n(n) {
8
+ return e.test(t(n));
9
+ }
10
+ function r(n) {
11
+ let r = t(n).match(e);
12
+ return r ? Number(r[1]) : null;
13
+ }
14
+ function i(e, t = "mitre") {
15
+ let n = r(e);
16
+ return n === null ? "https://cwe.mitre.org/" : `https://cwe.mitre.org/data/definitions/${n}.html`;
17
+ }
18
+ //#endregion
19
+ export { e as CWE_ID_PATTERN, r as getCweNumber, i as getCweUrl, n as isCweId, t as normalizeCweId };
20
+
21
+ //# sourceMappingURL=cwe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cwe.js","names":[],"sources":["../../../src/components/CweIdentifier/cwe.ts"],"sourcesContent":["export type CweLinkSource = 'mitre' | 'cwe';\n\nexport const CWE_ID_PATTERN = /^CWE-(\\d{1,6})$/i;\n\nexport function normalizeCweId(cweId: string) {\n const normalized = cweId.trim().toUpperCase();\n\n if (/^\\d{1,6}$/.test(normalized)) {\n return `CWE-${normalized}`;\n }\n\n return normalized;\n}\n\nexport function isCweId(cweId: string) {\n return CWE_ID_PATTERN.test(normalizeCweId(cweId));\n}\n\nexport function getCweNumber(cweId: string) {\n const match = normalizeCweId(cweId).match(CWE_ID_PATTERN);\n\n return match ? Number(match[1]) : null;\n}\n\nexport function getCweUrl(cweId: string, _source: CweLinkSource = 'mitre') {\n const cweNumber = getCweNumber(cweId);\n\n if (cweNumber === null) {\n return 'https://cwe.mitre.org/';\n }\n\n return `https://cwe.mitre.org/data/definitions/${cweNumber}.html`;\n}\n"],"mappings":";AAEA,IAAa,IAAiB;AAE9B,SAAgB,EAAe,GAAe;CAC5C,IAAM,IAAa,EAAM,KAAK,EAAE,YAAY;CAM5C,OAJI,YAAY,KAAK,CAAU,IACtB,OAAO,MAGT;AACT;AAEA,SAAgB,EAAQ,GAAe;CACrC,OAAO,EAAe,KAAK,EAAe,CAAK,CAAC;AAClD;AAEA,SAAgB,EAAa,GAAe;CAC1C,IAAM,IAAQ,EAAe,CAAK,EAAE,MAAM,CAAc;CAExD,OAAO,IAAQ,OAAO,EAAM,EAAE,IAAI;AACpC;AAEA,SAAgB,EAAU,GAAe,IAAyB,SAAS;CACzE,IAAM,IAAY,EAAa,CAAK;CAMpC,OAJI,MAAc,OACT,2BAGF,0CAA0C,EAAU;AAC7D"}
@@ -0,0 +1,4 @@
1
+ export type { CweIdentifierProps } from './CweIdentifier';
2
+ export { CweIdentifier } from './CweIdentifier';
3
+ export type { CweLinkSource } from './cwe';
4
+ export { CWE_ID_PATTERN, getCweNumber, getCweUrl, isCweId, normalizeCweId } from './cwe';
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./CweIdentifier/cwe.cjs"),t=require("./CweIdentifier/CweIdentifier.cjs");exports.CWE_ID_PATTERN=e.CWE_ID_PATTERN,exports.CweIdentifier=t.CweIdentifier,exports.getCweNumber=e.getCweNumber,exports.getCweUrl=e.getCweUrl,exports.isCweId=e.isCweId,exports.normalizeCweId=e.normalizeCweId;
@@ -0,0 +1,2 @@
1
+ export * from './CweIdentifier/index'
2
+ export {}
@@ -0,0 +1,3 @@
1
+ import { CWE_ID_PATTERN as e, getCweNumber as t, getCweUrl as n, isCweId as r, normalizeCweId as i } from "./CweIdentifier/cwe.js";
2
+ import { CweIdentifier as a } from "./CweIdentifier/CweIdentifier.js";
3
+ export { e as CWE_ID_PATTERN, a as CweIdentifier, t as getCweNumber, n as getCweUrl, r as isCweId, i as normalizeCweId };
@@ -0,0 +1,2 @@
1
+ const e=require("../SeverityBadge/SeverityBadge.cjs"),t=require("./SecurityMetric.module.css.cjs");let n=require("react/jsx-runtime");var r=e=>typeof e==`string`||typeof e==`number`,i=({label:i,value:a,description:o,delta:s,trend:c=`neutral`,severity:l,className:u,"aria-label":d,...f})=>(0,n.jsxs)(`div`,{"aria-label":d??(r(i)&&r(a)?`${i}: ${a}`:void 0),className:[t.default.metric,l?t.default[l]:null,s?t.default[`trend-${c}`]:null,u].filter(Boolean).join(` `),"data-severity":l,"data-trend":s?c:void 0,...f,children:[(0,n.jsxs)(`div`,{className:t.default.header,children:[(0,n.jsx)(`span`,{className:t.default.label,children:i}),l?(0,n.jsx)(e.SeverityBadge,{severity:l}):null]}),(0,n.jsx)(`div`,{className:t.default.value,children:a}),o||s?(0,n.jsxs)(`div`,{className:t.default.footer,children:[o?(0,n.jsx)(`span`,{className:t.default.description,children:o}):null,s?(0,n.jsx)(`span`,{className:t.default.delta,children:s}):null]}):null]});exports.SecurityMetric=i;
2
+ //# sourceMappingURL=SecurityMetric.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityMetric.cjs","names":[],"sources":["../../../src/components/SecurityMetric/SecurityMetric.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport { SeverityBadge, type VulnerabilitySeverity } from '../SeverityBadge';\n\nimport styles from './SecurityMetric.module.css';\n\nexport type SecurityMetricTrend = 'up' | 'down' | 'neutral';\n\nexport interface SecurityMetricProps extends HTMLAttributes<HTMLDivElement> {\n /** Short label for the metric, for example `Critical findings`. */\n label: ReactNode;\n /** Primary value to display. Keep it short: numbers, percentages, or compact text. */\n value: ReactNode;\n /** Optional supporting text shown below the value. */\n description?: ReactNode;\n /** Optional delta text, for example `+3 since last scan`. */\n delta?: ReactNode;\n /** Visual direction for the delta. Defaults to `\"neutral\"` when `delta` is present. */\n trend?: SecurityMetricTrend;\n /** Optional vulnerability severity tone associated with the metric. */\n severity?: VulnerabilitySeverity;\n}\n\nconst isAccessibleText = (value: ReactNode): value is string | number =>\n typeof value === 'string' || typeof value === 'number';\n\n/**\n * Compact KPI card for vulnerability reports and security dashboards.\n */\nexport const SecurityMetric = ({\n label,\n value,\n description,\n delta,\n trend = 'neutral',\n severity,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: SecurityMetricProps) => {\n const accessibleLabel =\n ariaLabel ??\n (isAccessibleText(label) && isAccessibleText(value) ? `${label}: ${value}` : undefined);\n\n return (\n <div\n aria-label={accessibleLabel}\n className={[\n styles.metric,\n severity ? styles[severity] : null,\n delta ? styles[`trend-${trend}`] : null,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n data-severity={severity}\n data-trend={delta ? trend : undefined}\n {...props}\n >\n <div className={styles.header}>\n <span className={styles.label}>{label}</span>\n {severity ? <SeverityBadge severity={severity} /> : null}\n </div>\n <div className={styles.value}>{value}</div>\n {description || delta ? (\n <div className={styles.footer}>\n {description ? <span className={styles.description}>{description}</span> : null}\n {delta ? <span className={styles.delta}>{delta}</span> : null}\n </div>\n ) : null}\n </div>\n );\n};\n"],"mappings":"sIAuBA,IAAM,EAAoB,GACxB,OAAO,GAAU,UAAY,OAAO,GAAU,SAKnC,GAAkB,CAC7B,QACA,QACA,cACA,QACA,QAAQ,UACR,WACA,YACA,aAAc,EACd,GAAG,MAOD,EAAA,EAAA,MAAC,MAAD,CACE,aALF,IACC,EAAiB,CAAK,GAAK,EAAiB,CAAK,EAAI,GAAG,EAAM,IAAI,IAAU,IAAA,IAK3E,UAAW,CACT,EAAA,QAAO,OACP,EAAW,EAAA,QAAO,GAAY,KAC9B,EAAQ,EAAA,QAAO,SAAS,KAAW,KACnC,CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG,EACX,gBAAe,EACf,aAAY,EAAQ,EAAQ,IAAA,GAC5B,GAAI,WAZN,EAcE,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAA,QAAO,gBAAvB,EACE,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,eAAQ,CAAY,CAAA,EAC3C,GAAW,EAAA,EAAA,KAAC,EAAA,cAAD,CAAyB,UAAW,CAAA,EAAI,IACjD,KACL,EAAA,EAAA,KAAC,MAAD,CAAK,UAAW,EAAA,QAAO,eAAQ,CAAW,CAAA,EACzC,GAAe,GACd,EAAA,EAAA,MAAC,MAAD,CAAK,UAAW,EAAA,QAAO,gBAAvB,CACG,GAAc,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,qBAAc,CAAkB,CAAA,EAAI,KAC1E,GAAQ,EAAA,EAAA,KAAC,OAAD,CAAM,UAAW,EAAA,QAAO,eAAQ,CAAY,CAAA,EAAI,IACtD,IACH,IACD"}
@@ -0,0 +1,21 @@
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ import { VulnerabilitySeverity } from '../SeverityBadge';
3
+ export type SecurityMetricTrend = 'up' | 'down' | 'neutral';
4
+ export interface SecurityMetricProps extends HTMLAttributes<HTMLDivElement> {
5
+ /** Short label for the metric, for example `Critical findings`. */
6
+ label: ReactNode;
7
+ /** Primary value to display. Keep it short: numbers, percentages, or compact text. */
8
+ value: ReactNode;
9
+ /** Optional supporting text shown below the value. */
10
+ description?: ReactNode;
11
+ /** Optional delta text, for example `+3 since last scan`. */
12
+ delta?: ReactNode;
13
+ /** Visual direction for the delta. Defaults to `"neutral"` when `delta` is present. */
14
+ trend?: SecurityMetricTrend;
15
+ /** Optional vulnerability severity tone associated with the metric. */
16
+ severity?: VulnerabilitySeverity;
17
+ }
18
+ /**
19
+ * Compact KPI card for vulnerability reports and security dashboards.
20
+ */
21
+ export declare const SecurityMetric: ({ label, value, description, delta, trend, severity, className, "aria-label": ariaLabel, ...props }: SecurityMetricProps) => import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,43 @@
1
+ import { SeverityBadge as e } from "../SeverityBadge/SeverityBadge.js";
2
+ import t from "./SecurityMetric.module.css.js";
3
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
4
+ //#region src/components/SecurityMetric/SecurityMetric.tsx
5
+ var i = (e) => typeof e == "string" || typeof e == "number", a = ({ label: a, value: o, description: s, delta: c, trend: l = "neutral", severity: u, className: d, "aria-label": f, ...p }) => /* @__PURE__ */ r("div", {
6
+ "aria-label": f ?? (i(a) && i(o) ? `${a}: ${o}` : void 0),
7
+ className: [
8
+ t.metric,
9
+ u ? t[u] : null,
10
+ c ? t[`trend-${l}`] : null,
11
+ d
12
+ ].filter(Boolean).join(" "),
13
+ "data-severity": u,
14
+ "data-trend": c ? l : void 0,
15
+ ...p,
16
+ children: [
17
+ /* @__PURE__ */ r("div", {
18
+ className: t.header,
19
+ children: [/* @__PURE__ */ n("span", {
20
+ className: t.label,
21
+ children: a
22
+ }), u ? /* @__PURE__ */ n(e, { severity: u }) : null]
23
+ }),
24
+ /* @__PURE__ */ n("div", {
25
+ className: t.value,
26
+ children: o
27
+ }),
28
+ s || c ? /* @__PURE__ */ r("div", {
29
+ className: t.footer,
30
+ children: [s ? /* @__PURE__ */ n("span", {
31
+ className: t.description,
32
+ children: s
33
+ }) : null, c ? /* @__PURE__ */ n("span", {
34
+ className: t.delta,
35
+ children: c
36
+ }) : null]
37
+ }) : null
38
+ ]
39
+ });
40
+ //#endregion
41
+ export { a as SecurityMetric };
42
+
43
+ //# sourceMappingURL=SecurityMetric.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityMetric.js","names":[],"sources":["../../../src/components/SecurityMetric/SecurityMetric.tsx"],"sourcesContent":["import type { HTMLAttributes, ReactNode } from 'react';\n\nimport { SeverityBadge, type VulnerabilitySeverity } from '../SeverityBadge';\n\nimport styles from './SecurityMetric.module.css';\n\nexport type SecurityMetricTrend = 'up' | 'down' | 'neutral';\n\nexport interface SecurityMetricProps extends HTMLAttributes<HTMLDivElement> {\n /** Short label for the metric, for example `Critical findings`. */\n label: ReactNode;\n /** Primary value to display. Keep it short: numbers, percentages, or compact text. */\n value: ReactNode;\n /** Optional supporting text shown below the value. */\n description?: ReactNode;\n /** Optional delta text, for example `+3 since last scan`. */\n delta?: ReactNode;\n /** Visual direction for the delta. Defaults to `\"neutral\"` when `delta` is present. */\n trend?: SecurityMetricTrend;\n /** Optional vulnerability severity tone associated with the metric. */\n severity?: VulnerabilitySeverity;\n}\n\nconst isAccessibleText = (value: ReactNode): value is string | number =>\n typeof value === 'string' || typeof value === 'number';\n\n/**\n * Compact KPI card for vulnerability reports and security dashboards.\n */\nexport const SecurityMetric = ({\n label,\n value,\n description,\n delta,\n trend = 'neutral',\n severity,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: SecurityMetricProps) => {\n const accessibleLabel =\n ariaLabel ??\n (isAccessibleText(label) && isAccessibleText(value) ? `${label}: ${value}` : undefined);\n\n return (\n <div\n aria-label={accessibleLabel}\n className={[\n styles.metric,\n severity ? styles[severity] : null,\n delta ? styles[`trend-${trend}`] : null,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n data-severity={severity}\n data-trend={delta ? trend : undefined}\n {...props}\n >\n <div className={styles.header}>\n <span className={styles.label}>{label}</span>\n {severity ? <SeverityBadge severity={severity} /> : null}\n </div>\n <div className={styles.value}>{value}</div>\n {description || delta ? (\n <div className={styles.footer}>\n {description ? <span className={styles.description}>{description}</span> : null}\n {delta ? <span className={styles.delta}>{delta}</span> : null}\n </div>\n ) : null}\n </div>\n );\n};\n"],"mappings":";;;;AAuBA,IAAM,KAAoB,MACxB,OAAO,KAAU,YAAY,OAAO,KAAU,UAKnC,KAAkB,EAC7B,UACA,UACA,gBACA,UACA,WAAQ,WACR,aACA,cACA,cAAc,GACd,GAAG,QAOD,kBAAC,OAAD;CACE,cALF,MACC,EAAiB,CAAK,KAAK,EAAiB,CAAK,IAAI,GAAG,EAAM,IAAI,MAAU,KAAA;CAK3E,WAAW;EACT,EAAO;EACP,IAAW,EAAO,KAAY;EAC9B,IAAQ,EAAO,SAAS,OAAW;EACnC;CACF,EACG,OAAO,OAAO,EACd,KAAK,GAAG;CACX,iBAAe;CACf,cAAY,IAAQ,IAAQ,KAAA;CAC5B,GAAI;WAZN;EAcE,kBAAC,OAAD;GAAK,WAAW,EAAO;aAAvB,CACE,kBAAC,QAAD;IAAM,WAAW,EAAO;cAAQ;GAAY,CAAA,GAC3C,IAAW,kBAAC,GAAD,EAAyB,YAAW,CAAA,IAAI,IACjD;;EACL,kBAAC,OAAD;GAAK,WAAW,EAAO;aAAQ;EAAW,CAAA;EACzC,KAAe,IACd,kBAAC,OAAD;GAAK,WAAW,EAAO;aAAvB,CACG,IAAc,kBAAC,QAAD;IAAM,WAAW,EAAO;cAAc;GAAkB,CAAA,IAAI,MAC1E,IAAQ,kBAAC,QAAD;IAAM,WAAW,EAAO;cAAQ;GAAY,CAAA,IAAI,IACtD;OACH;CACD"}
@@ -0,0 +1,2 @@
1
+ var e={metric:`_metric_123od_3`,header:`_header_123od_14`,footer:`_footer_123od_15`,label:`_label_123od_22`,value:`_value_123od_29`,description:`_description_123od_43`,delta:`_delta_123od_47`,none:`_none_123od_54`,minimal:`_minimal_123od_58`,low:`_low_123od_62`,medium:`_medium_123od_66`,high:`_high_123od_70`,critical:`_critical_123od_74`,"trend-up":`_trend-up_123od_80`,"trend-down":`_trend-down_123od_84`,"trend-neutral":`_trend-neutral_123od_88`};exports.default=e;
2
+ //# sourceMappingURL=SecurityMetric.module.css.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityMetric.module.css.cjs","names":[],"sources":["../../../src/components/SecurityMetric/SecurityMetric.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.metric {\n display: grid;\n gap: var(--gnome-space-3, 12px);\n min-width: 180px;\n padding: var(--gnome-space-4, 16px);\n border: 1px solid var(--gnome-card-shade-color, rgb(0 0 0 / 0.07));\n border-radius: var(--gnome-radius-lg, 12px);\n background-color: var(--gnome-card-bg-color, #fff);\n color: var(--gnome-card-fg-color, rgb(0 0 0 / 0.8));\n}\n\n.header,\n.footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--gnome-space-2, 8px);\n}\n\n.label {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n font-size: 0.8125rem;\n font-weight: 600;\n line-height: 1.3;\n}\n\n.value {\n color: var(--gnome-window-fg-color, rgb(0 0 0 / 0.87));\n font-size: 2rem;\n font-weight: 750;\n letter-spacing: -0.035em;\n line-height: 1;\n}\n\n.footer {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n font-size: 0.8125rem;\n line-height: 1.35;\n}\n\n.description {\n min-width: 0;\n}\n\n.delta {\n flex: 0 0 auto;\n font-weight: 650;\n}\n\n/* ─── Severity accents ────────────────────────────────────────────────────── */\n\n.none {\n border-left: 3px solid var(--gnome-success-bg-color, #33d17a);\n}\n\n.minimal {\n border-left: 3px solid var(--gnome-info-bg-color, #62a0ea);\n}\n\n.low {\n border-left: 3px solid var(--gnome-success-bg-color, #57e389);\n}\n\n.medium {\n border-left: 3px solid var(--gnome-warning-bg-color, #f6d32d);\n}\n\n.high {\n border-left: 3px solid var(--gnome-orange-bg-color, #ff7800);\n}\n\n.critical {\n border-left: 3px solid var(--gnome-error-bg-color, #e01b24);\n}\n\n/* ─── Trends ──────────────────────────────────────────────────────────────── */\n\n.trend-up .delta {\n color: var(--gnome-error-fg-color, #c01c28);\n}\n\n.trend-down .delta {\n color: var(--gnome-success-fg-color, #1b8553);\n}\n\n.trend-neutral .delta {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n}\n\n@media (prefers-color-scheme: dark) {\n .metric {\n border-color: var(--gnome-card-shade-color, rgb(255 255 255 / 0.12));\n background-color: var(--gnome-card-bg-color, rgb(255 255 255 / 0.08));\n color: var(--gnome-card-fg-color, rgb(255 255 255 / 0.87));\n }\n\n .label,\n .footer,\n .trend-neutral .delta {\n color: var(--gnome-secondary-fg-color, rgb(255 255 255 / 0.62));\n }\n\n .value {\n color: var(--gnome-window-fg-color, rgb(255 255 255 / 0.92));\n }\n}\n"],"mappings":""}
@@ -0,0 +1,22 @@
1
+ var e = {
2
+ metric: "_metric_123od_3",
3
+ header: "_header_123od_14",
4
+ footer: "_footer_123od_15",
5
+ label: "_label_123od_22",
6
+ value: "_value_123od_29",
7
+ description: "_description_123od_43",
8
+ delta: "_delta_123od_47",
9
+ none: "_none_123od_54",
10
+ minimal: "_minimal_123od_58",
11
+ low: "_low_123od_62",
12
+ medium: "_medium_123od_66",
13
+ high: "_high_123od_70",
14
+ critical: "_critical_123od_74",
15
+ "trend-up": "_trend-up_123od_80",
16
+ "trend-down": "_trend-down_123od_84",
17
+ "trend-neutral": "_trend-neutral_123od_88"
18
+ };
19
+ //#endregion
20
+ export { e as default };
21
+
22
+ //# sourceMappingURL=SecurityMetric.module.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SecurityMetric.module.css.js","names":[],"sources":["../../../src/components/SecurityMetric/SecurityMetric.module.css"],"sourcesContent":["/* ─── Base ────────────────────────────────────────────────────────────────── */\n\n.metric {\n display: grid;\n gap: var(--gnome-space-3, 12px);\n min-width: 180px;\n padding: var(--gnome-space-4, 16px);\n border: 1px solid var(--gnome-card-shade-color, rgb(0 0 0 / 0.07));\n border-radius: var(--gnome-radius-lg, 12px);\n background-color: var(--gnome-card-bg-color, #fff);\n color: var(--gnome-card-fg-color, rgb(0 0 0 / 0.8));\n}\n\n.header,\n.footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--gnome-space-2, 8px);\n}\n\n.label {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n font-size: 0.8125rem;\n font-weight: 600;\n line-height: 1.3;\n}\n\n.value {\n color: var(--gnome-window-fg-color, rgb(0 0 0 / 0.87));\n font-size: 2rem;\n font-weight: 750;\n letter-spacing: -0.035em;\n line-height: 1;\n}\n\n.footer {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n font-size: 0.8125rem;\n line-height: 1.35;\n}\n\n.description {\n min-width: 0;\n}\n\n.delta {\n flex: 0 0 auto;\n font-weight: 650;\n}\n\n/* ─── Severity accents ────────────────────────────────────────────────────── */\n\n.none {\n border-left: 3px solid var(--gnome-success-bg-color, #33d17a);\n}\n\n.minimal {\n border-left: 3px solid var(--gnome-info-bg-color, #62a0ea);\n}\n\n.low {\n border-left: 3px solid var(--gnome-success-bg-color, #57e389);\n}\n\n.medium {\n border-left: 3px solid var(--gnome-warning-bg-color, #f6d32d);\n}\n\n.high {\n border-left: 3px solid var(--gnome-orange-bg-color, #ff7800);\n}\n\n.critical {\n border-left: 3px solid var(--gnome-error-bg-color, #e01b24);\n}\n\n/* ─── Trends ──────────────────────────────────────────────────────────────── */\n\n.trend-up .delta {\n color: var(--gnome-error-fg-color, #c01c28);\n}\n\n.trend-down .delta {\n color: var(--gnome-success-fg-color, #1b8553);\n}\n\n.trend-neutral .delta {\n color: var(--gnome-secondary-fg-color, rgb(0 0 0 / 0.55));\n}\n\n@media (prefers-color-scheme: dark) {\n .metric {\n border-color: var(--gnome-card-shade-color, rgb(255 255 255 / 0.12));\n background-color: var(--gnome-card-bg-color, rgb(255 255 255 / 0.08));\n color: var(--gnome-card-fg-color, rgb(255 255 255 / 0.87));\n }\n\n .label,\n .footer,\n .trend-neutral .delta {\n color: var(--gnome-secondary-fg-color, rgb(255 255 255 / 0.62));\n }\n\n .value {\n color: var(--gnome-window-fg-color, rgb(255 255 255 / 0.92));\n }\n}\n"],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export type { SecurityMetricProps, SecurityMetricTrend } from './SecurityMetric';
2
+ export { SecurityMetric } from './SecurityMetric';
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./SecurityMetric/SecurityMetric.cjs");exports.SecurityMetric=e.SecurityMetric;
@@ -0,0 +1,2 @@
1
+ export * from './SecurityMetric/index'
2
+ export {}
@@ -0,0 +1,2 @@
1
+ import { SecurityMetric as e } from "./SecurityMetric/SecurityMetric.js";
2
+ export { e as SecurityMetric };
@@ -0,0 +1,2 @@
1
+ const e=require("./SeverityBadge.module.css.cjs"),t=require("./severity.cjs");let n=require("react/jsx-runtime");var r=({severity:r,label:i,className:a,"aria-label":o,...s})=>{let c=i??t.VULNERABILITY_SEVERITY_LABELS[r];return(0,n.jsx)(`span`,{"aria-label":o??`Severity: ${c}`,className:[e.default.badge,e.default[r],a].filter(Boolean).join(` `),"data-severity":r,...s,children:c})};exports.SeverityBadge=r;
2
+ //# sourceMappingURL=SeverityBadge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeverityBadge.cjs","names":[],"sources":["../../../src/components/SeverityBadge/SeverityBadge.tsx"],"sourcesContent":["import type { HTMLAttributes } from 'react';\n\nimport styles from './SeverityBadge.module.css';\nimport { VULNERABILITY_SEVERITY_LABELS, type VulnerabilitySeverity } from './severity';\n\nexport interface SeverityBadgeProps extends HTMLAttributes<HTMLSpanElement> {\n /**\n * Vulnerability severity to display.\n *\n * `minimal` is included for external scanner compatibility, such as\n * Google Artifact Registry / Grafeas. CVSS qualitative ratings still map\n * to the official `none`, `low`, `medium`, `high`, and `critical` levels.\n */\n severity: VulnerabilitySeverity;\n /** Overrides the default human-readable label. */\n label?: string;\n}\n\n/**\n * Pill-shaped severity label for vulnerability and security report surfaces.\n */\nexport const SeverityBadge = ({\n severity,\n label,\n className,\n 'aria-label': ariaLabel,\n ...props\n}: SeverityBadgeProps) => {\n const displayLabel = label ?? VULNERABILITY_SEVERITY_LABELS[severity];\n\n return (\n <span\n aria-label={ariaLabel ?? `Severity: ${displayLabel}`}\n className={[styles.badge, styles[severity], className].filter(Boolean).join(' ')}\n data-severity={severity}\n {...props}\n >\n {displayLabel}\n </span>\n );\n};\n"],"mappings":"iHAqBA,IAAa,GAAiB,CAC5B,WACA,QACA,YACA,aAAc,EACd,GAAG,KACqB,CACxB,IAAM,EAAe,GAAS,EAAA,8BAA8B,GAE5D,OACE,EAAA,EAAA,KAAC,OAAD,CACE,aAAY,GAAa,aAAa,IACtC,UAAW,CAAC,EAAA,QAAO,MAAO,EAAA,QAAO,GAAW,CAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG,EAC/E,gBAAe,EACf,GAAI,WAEH,CACG,CAAA,CAEV"}