@stn-uiux/pub-ui-react 0.1.84 → 0.1.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1207,12 +1207,13 @@ var StnModal = forwardRef7(function StnModal2({
1207
1207
  }
1208
1208
  ) : null
1209
1209
  ] }),
1210
- /* @__PURE__ */ jsx10("div", { className: cn("stn-pop__body", bodyClassName), children }),
1210
+ /* @__PURE__ */ jsx10("div", { className: cn("stn-pop__body", "stn-scroll", "vertical", "thin", bodyClassName), children }),
1211
1211
  actions ? /* @__PURE__ */ jsx10(
1212
1212
  "div",
1213
1213
  {
1214
1214
  className: cn(
1215
1215
  "stn-pop__actions",
1216
+ actionAlign === "left" && "stn-pop__actions--left",
1216
1217
  actionAlign === "center" && "stn-pop__actions--center",
1217
1218
  actionAlign === "right" && "stn-pop__actions--right",
1218
1219
  actionAlign === "between" && "stn-pop__actions--between"
@@ -1253,7 +1254,8 @@ var SIZE_CLASS2 = {
1253
1254
  sm: "stn-drawer--sm",
1254
1255
  md: "stn-drawer--md",
1255
1256
  lg: "stn-drawer--lg",
1256
- xl: "stn-drawer--xl"
1257
+ xl: "stn-drawer--xl",
1258
+ full: "stn-drawer--full"
1257
1259
  };
1258
1260
  var PLACEMENT_CLASS = {
1259
1261
  right: "stn-drawer--right",
@@ -3663,6 +3665,7 @@ function StnSplitViewSide({
3663
3665
  edge = "start",
3664
3666
  scrollable = true,
3665
3667
  scrollProps,
3668
+ padding,
3666
3669
  ...rest
3667
3670
  }) {
3668
3671
  const { className: scrollClassName, ...scrollRest } = scrollProps ?? {};
@@ -3673,6 +3676,7 @@ function StnSplitViewSide({
3673
3676
  "stn-split-view__side",
3674
3677
  `stn-split-view__side--${width}`,
3675
3678
  edge === "end" && "stn-split-view__side--end",
3679
+ padding && `stn-split-view__side--pad-${padding}`,
3676
3680
  className
3677
3681
  ),
3678
3682
  "data-stn-split-view": "side",
@@ -3693,11 +3697,20 @@ function StnSplitViewSide({
3693
3697
  }
3694
3698
  );
3695
3699
  }
3696
- function StnSplitViewStage({ children, className, ...rest }) {
3700
+ function StnSplitViewStage({
3701
+ children,
3702
+ className,
3703
+ padding = "none",
3704
+ ...rest
3705
+ }) {
3697
3706
  return /* @__PURE__ */ jsx24(
3698
3707
  "div",
3699
3708
  {
3700
- className: cn("stn-split-view__stage", className),
3709
+ className: cn(
3710
+ "stn-split-view__stage",
3711
+ padding !== "none" && `stn-split-view__stage--pad-${padding}`,
3712
+ className
3713
+ ),
3701
3714
  "data-stn-split-view": "stage",
3702
3715
  ...rest,
3703
3716
  children
@@ -3724,12 +3737,17 @@ function StnSplitViewOverlay({
3724
3737
  }
3725
3738
  );
3726
3739
  }
3727
- var StnSplitView = forwardRef20(function StnSplitView2({ children, className, fill = true, ...rest }, ref) {
3740
+ var StnSplitView = forwardRef20(function StnSplitView2({ children, className, fill = true, padding, ...rest }, ref) {
3728
3741
  return /* @__PURE__ */ jsx24(
3729
3742
  "div",
3730
3743
  {
3731
3744
  ref,
3732
- className: cn("stn-split-view", fill && "stn-split-view--fill", className),
3745
+ className: cn(
3746
+ "stn-split-view",
3747
+ fill && "stn-split-view--fill",
3748
+ padding && `stn-split-view--pad-${padding}`,
3749
+ className
3750
+ ),
3733
3751
  "data-stn-split-view": "root",
3734
3752
  ...rest,
3735
3753
  children
@@ -5912,6 +5930,9 @@ var StnTextArea = forwardRef34(function StnTextArea2({
5912
5930
  const widthProps = resolveInputWidthProps("stn-text-area", fullWidth, width);
5913
5931
  const textAreaClass = cn(
5914
5932
  "stn-text-area",
5933
+ "stn-scroll",
5934
+ "vertical",
5935
+ "thin",
5915
5936
  variantClass3(variant),
5916
5937
  normalizeSize2(size),
5917
5938
  colorClass2(color),
@@ -7768,6 +7789,18 @@ var StnStack = forwardRef36(function StnStack2({
7768
7789
  });
7769
7790
 
7770
7791
  // src/components/topology/stnTopologyShared.ts
7792
+ var TOPOLOGY_NODE_SIZE_MAP = {
7793
+ xs: 12,
7794
+ // var(--stn-topology-node-radius-xs) = 12px (직경 24px, --stn-topology-node-size-xs)
7795
+ sm: 16,
7796
+ // var(--stn-topology-node-radius-sm) = 16px (직경 32px, --stn-topology-node-size-sm)
7797
+ md: 20,
7798
+ // var(--stn-topology-node-radius-md) = 20px (직경 40px, --stn-topology-node-size-md)
7799
+ lg: 24,
7800
+ // var(--stn-topology-node-radius-lg) = 24px (직경 48px, --stn-topology-node-size-lg)
7801
+ xl: 28
7802
+ // var(--stn-topology-node-radius-xl) = 28px (직경 56px, --stn-topology-node-size-xl)
7803
+ };
7771
7804
  var STN_TOPOLOGY_NODE_SHAPES = [
7772
7805
  "circle",
7773
7806
  "square",
@@ -7784,13 +7817,15 @@ var STN_TOPOLOGY_LINK_VARIANTS = [
7784
7817
  "line",
7785
7818
  "dot"
7786
7819
  ];
7787
- var STN_TOPOLOGY_NODE_SIZES = ["xs", "sm", "md", "lg"];
7820
+ var STN_TOPOLOGY_NODE_SIZES = ["xs", "sm", "md", "lg", "xl"];
7788
7821
  var STN_TOPOLOGY_NODE_STATUSES = [
7822
+ "point",
7789
7823
  "normal",
7790
7824
  "warning",
7791
7825
  "minor",
7792
7826
  "major",
7793
- "critical"
7827
+ "critical",
7828
+ "neutral"
7794
7829
  ];
7795
7830
  var STN_TOPOLOGY_NODE_ICONS = [
7796
7831
  "topology-wifi",
@@ -7826,6 +7861,12 @@ function resolveTopologyIconName(icon) {
7826
7861
  }
7827
7862
  }
7828
7863
  var STN_TOPOLOGY_STATUS_COLORS = {
7864
+ point: {
7865
+ main: "var(--stn-primary)",
7866
+ glow: "color-mix(in srgb, var(--stn-primary) 50%, transparent)",
7867
+ text: "var(--stn-primary)",
7868
+ label: "\uD3EC\uC778\uD2B8/\uAC70\uC810"
7869
+ },
7829
7870
  normal: {
7830
7871
  main: "var(--stn-grade-normal)",
7831
7872
  glow: "color-mix(in srgb, var(--stn-grade-normal) 35%, transparent)",
@@ -7855,13 +7896,20 @@ var STN_TOPOLOGY_STATUS_COLORS = {
7855
7896
  glow: "color-mix(in srgb, var(--stn-grade-critical) 80%, transparent)",
7856
7897
  text: "var(--stn-grade-critical)",
7857
7898
  label: "\uC2EC\uAC01"
7899
+ },
7900
+ neutral: {
7901
+ main: "var(--stn-grade-neutral)",
7902
+ glow: "color-mix(in srgb, var(--stn-grade-neutral) 30%, transparent)",
7903
+ text: "var(--stn-grade-neutral)",
7904
+ label: "\uC911\uB9BD/\uB300\uAE30"
7858
7905
  }
7859
7906
  };
7860
7907
  var STN_TOPOLOGY_NODE_SIZE = {
7861
7908
  xs: { r: 12, icon: 14, countFont: 9, labelFont: 11, statusFont: 10, stroke: 1.2 },
7862
7909
  sm: { r: 16, icon: 16, countFont: 10, labelFont: 11, statusFont: 10, stroke: 1.4 },
7863
7910
  md: { r: 20, icon: 18, countFont: 11, labelFont: 12, statusFont: 11, stroke: 1.6 },
7864
- lg: { r: 24, icon: 22, countFont: 12, labelFont: 13, statusFont: 12, stroke: 1.8 }
7911
+ lg: { r: 24, icon: 22, countFont: 12, labelFont: 13, statusFont: 12, stroke: 1.8 },
7912
+ xl: { r: 28, icon: 26, countFont: 14, labelFont: 14, statusFont: 13, stroke: 2 }
7865
7913
  };
7866
7914
  function formatTopologyCount(count) {
7867
7915
  if (count == null || count === "") return "0";
@@ -7921,7 +7969,8 @@ var NODE_TITLE_VARIANT = {
7921
7969
  xs: "label-4",
7922
7970
  sm: "caption",
7923
7971
  md: "caption",
7924
- lg: "body-small"
7972
+ lg: "body-small",
7973
+ xl: "body-2"
7925
7974
  };
7926
7975
  function renderTopologyIcon(icon, color = "currentColor", px = 18) {
7927
7976
  if (!icon) return null;
@@ -8441,7 +8490,21 @@ import {
8441
8490
  // src/patterns/toolbar/StnFloatingToolbar.tsx
8442
8491
  import React3 from "react";
8443
8492
  import { jsx as jsx59 } from "react/jsx-runtime";
8444
- var StnFloatingToolbar = React3.forwardRef(
8493
+ var StnFloatingToolbarDivider = React3.forwardRef(
8494
+ ({ className, ...restProps }, ref) => {
8495
+ return /* @__PURE__ */ jsx59(
8496
+ "span",
8497
+ {
8498
+ ref,
8499
+ className: cn("stn-floating-toolbar__divider", className),
8500
+ "aria-hidden": "true",
8501
+ ...restProps
8502
+ }
8503
+ );
8504
+ }
8505
+ );
8506
+ StnFloatingToolbarDivider.displayName = "StnFloatingToolbar.Divider";
8507
+ var StnFloatingToolbarRoot = React3.forwardRef(
8445
8508
  ({ placement = "none", orientation = "horizontal", className, children, ...restProps }, ref) => {
8446
8509
  const placementClass = placement !== "none" ? `stn-floating-toolbar--${placement}` : "";
8447
8510
  const orientationClass = orientation === "vertical" ? "stn-floating-toolbar--vertical" : "";
@@ -8458,10 +8521,41 @@ var StnFloatingToolbar = React3.forwardRef(
8458
8521
  );
8459
8522
  }
8460
8523
  );
8461
- StnFloatingToolbar.displayName = "StnFloatingToolbar";
8524
+ StnFloatingToolbarRoot.displayName = "StnFloatingToolbar";
8525
+ var StnFloatingToolbar = Object.assign(StnFloatingToolbarRoot, {
8526
+ Divider: StnFloatingToolbarDivider
8527
+ });
8462
8528
 
8463
8529
  // src/components/topology/StnTopologyGraph.tsx
8464
8530
  import { Fragment as Fragment8, jsx as jsx60, jsxs as jsxs47 } from "react/jsx-runtime";
8531
+ var TOPOLOGY_STROKE_WIDTH_MAP = {
8532
+ xs: 1,
8533
+ sm: 1.6,
8534
+ md: 2.4,
8535
+ lg: 4,
8536
+ xl: 6
8537
+ };
8538
+ var TOPOLOGY_OPACITY_MAP = {
8539
+ faint: 0.15,
8540
+ dim: 0.4,
8541
+ solid: 1
8542
+ };
8543
+ function resolveTopologyStrokeWidth(strokeWidth, depthScale, zoom) {
8544
+ const baseScale = depthScale * Math.min(1.2, Math.max(0.7, zoom));
8545
+ if (typeof strokeWidth === "number") {
8546
+ return Math.max(0.5, strokeWidth * baseScale);
8547
+ }
8548
+ const factor = strokeWidth ? TOPOLOGY_STROKE_WIDTH_MAP[strokeWidth] ?? 2.4 : 2.4;
8549
+ return Math.max(0.8, factor * baseScale);
8550
+ }
8551
+ function resolveTopologyOpacity(opacity, baseDepthOpacity) {
8552
+ if (opacity === void 0) return baseDepthOpacity;
8553
+ if (typeof opacity === "number") {
8554
+ return Math.max(0, Math.min(1, opacity));
8555
+ }
8556
+ const ratio = TOPOLOGY_OPACITY_MAP[opacity] ?? 1;
8557
+ return Math.max(0.05, Math.min(1, baseDepthOpacity * ratio));
8558
+ }
8465
8559
  var DEFAULT_3D_GRAPH_NODES = [
8466
8560
  { id: 0, x: 0, y: 0, z: 0, isCore: true, status: "normal", label: "[\uC911\uC559 \uCF54\uC5B4] CORE-SW (10.10.1.1)" },
8467
8561
  // Top Branch
@@ -8689,6 +8783,10 @@ function StnTopologyGraphMinimap({ className, style }) {
8689
8783
  const n1 = nodeMap.get(link.source);
8690
8784
  const n2 = nodeMap.get(link.target);
8691
8785
  if (!n1 || !n2) return null;
8786
+ const statusColor = link.status === "critical" ? "var(--stn-grade-critical)" : link.status === "major" ? "var(--stn-grade-major)" : link.status === "minor" ? "var(--stn-grade-minor)" : link.status === "warning" ? "var(--stn-grade-warning)" : link.status === "point" ? "var(--stn-primary)" : null;
8787
+ const strokeColor = link.color ?? statusColor ?? "var(--stn-border-strong)";
8788
+ const miniStrokeWidth = typeof link.strokeWidth === "number" ? Math.max(0.6, link.strokeWidth * 0.4) : link.strokeWidth === "xs" ? 0.7 : link.strokeWidth === "sm" ? 1 : link.strokeWidth === "lg" ? 1.8 : link.strokeWidth === "xl" ? 2.5 : 1.2;
8789
+ const miniOpacity = resolveTopologyOpacity(link.opacity, 0.7);
8692
8790
  return /* @__PURE__ */ jsx60(
8693
8791
  "line",
8694
8792
  {
@@ -8696,8 +8794,9 @@ function StnTopologyGraphMinimap({ className, style }) {
8696
8794
  y1: n1.sy * 0.5,
8697
8795
  x2: n2.sx * 0.5,
8698
8796
  y2: n2.sy * 0.5,
8699
- stroke: "var(--stn-border-strong)",
8700
- strokeWidth: "1.2"
8797
+ stroke: strokeColor,
8798
+ strokeWidth: miniStrokeWidth,
8799
+ opacity: miniOpacity
8701
8800
  },
8702
8801
  `mini-link-${idx}`
8703
8802
  );
@@ -8705,6 +8804,7 @@ function StnTopologyGraphMinimap({ className, style }) {
8705
8804
  projectedNodes.map((n) => {
8706
8805
  const cx = n.sx * 0.5;
8707
8806
  const cy = n.sy * 0.5;
8807
+ const nodeOpacity = resolveTopologyOpacity(n.opacity, 1);
8708
8808
  if (n.isCore) {
8709
8809
  return /* @__PURE__ */ jsx60(
8710
8810
  "polygon",
@@ -8712,7 +8812,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8712
8812
  points: `${cx},${cy - 5} ${cx + 5},${cy} ${cx},${cy + 5} ${cx - 5},${cy}`,
8713
8813
  fill: "var(--stn-primary)",
8714
8814
  stroke: "var(--stn-primary)",
8715
- strokeWidth: "1"
8815
+ strokeWidth: "1",
8816
+ opacity: nodeOpacity
8716
8817
  },
8717
8818
  `mini-node-${n.id}`
8718
8819
  );
@@ -8724,7 +8825,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8724
8825
  cx,
8725
8826
  cy,
8726
8827
  r: "3.5",
8727
- fill: "var(--stn-grade-critical)"
8828
+ fill: "var(--stn-grade-critical)",
8829
+ opacity: nodeOpacity
8728
8830
  },
8729
8831
  `mini-node-${n.id}`
8730
8832
  );
@@ -8736,7 +8838,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8736
8838
  cx,
8737
8839
  cy,
8738
8840
  r: "3",
8739
- fill: "var(--stn-grade-warning)"
8841
+ fill: "var(--stn-grade-warning)",
8842
+ opacity: nodeOpacity
8740
8843
  },
8741
8844
  `mini-node-${n.id}`
8742
8845
  );
@@ -8747,7 +8850,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8747
8850
  cx,
8748
8851
  cy,
8749
8852
  r: "3",
8750
- fill: "var(--stn-border-subtle)"
8853
+ fill: "var(--stn-border-subtle)",
8854
+ opacity: nodeOpacity
8751
8855
  },
8752
8856
  `mini-node-${n.id}`
8753
8857
  );
@@ -8765,16 +8869,17 @@ function render3DNodeGlyph({
8765
8869
  strokeWidth
8766
8870
  }) {
8767
8871
  const surfaceBg = "var(--stn-elevation-surface-0)";
8768
- const innerRatio = 0.52;
8769
- const rSmall = r * innerRatio;
8872
+ const innerRatioCircleSquare = 0.653;
8873
+ const innerRatioOther = 0.52;
8874
+ const rSmall = r * innerRatioCircleSquare;
8770
8875
  const strokeWSmall = Math.max(1.2, strokeWidth * 0.85);
8771
8876
  if (shape === "square") {
8772
8877
  const s = r * 1.8;
8773
8878
  const half = s / 2;
8774
8879
  const rx = Math.max(1.5, 2.5 * (r / 10));
8775
- const sSmall = s * innerRatio;
8880
+ const sSmall = s * innerRatioCircleSquare;
8776
8881
  const halfSmall = sSmall / 2;
8777
- const rxSmall = rx * 0.65;
8882
+ const rxSmall = rx * 0.75;
8778
8883
  if (variant === "solid") {
8779
8884
  return /* @__PURE__ */ jsx60("rect", { x: -halfSmall, y: -halfSmall, width: sSmall, height: sSmall, rx: rxSmall, fill: statusColor });
8780
8885
  }
@@ -8788,7 +8893,7 @@ function render3DNodeGlyph({
8788
8893
  }
8789
8894
  if (shape === "triangle") {
8790
8895
  const R2 = r * 1.25;
8791
- const RSmall = R2 * innerRatio;
8896
+ const RSmall = R2 * innerRatioOther;
8792
8897
  const pts = trianglePoints(0, 0, R2);
8793
8898
  const ptsSmall = trianglePoints(0, 0, RSmall);
8794
8899
  if (variant === "solid") {
@@ -8805,8 +8910,8 @@ function render3DNodeGlyph({
8805
8910
  if (shape === "star") {
8806
8911
  const R2 = r * 1.3;
8807
8912
  const rIn = R2 * 0.48;
8808
- const RSmall = R2 * innerRatio;
8809
- const rInSmall = rIn * innerRatio;
8913
+ const RSmall = R2 * innerRatioOther;
8914
+ const rInSmall = rIn * innerRatioOther;
8810
8915
  const pts = starPoints(0, 0, R2, rIn);
8811
8916
  const ptsSmall = starPoints(0, 0, RSmall, rInSmall);
8812
8917
  if (variant === "solid") {
@@ -8822,7 +8927,7 @@ function render3DNodeGlyph({
8822
8927
  }
8823
8928
  if (shape === "diamond") {
8824
8929
  const R2 = r * 1.2;
8825
- const RSmall = R2 * innerRatio;
8930
+ const RSmall = R2 * innerRatioOther;
8826
8931
  const pts = diamondPoints(0, 0, R2);
8827
8932
  const ptsSmall = diamondPoints(0, 0, RSmall);
8828
8933
  if (variant === "solid") {
@@ -8847,6 +8952,75 @@ function render3DNodeGlyph({
8847
8952
  }
8848
8953
  return /* @__PURE__ */ jsx60("circle", { cx: "0", cy: "0", r: rSmall, fill: surfaceBg, stroke: statusColor, strokeWidth: strokeWSmall });
8849
8954
  }
8955
+ function renderCurrentNodeRing({
8956
+ shape,
8957
+ r
8958
+ }) {
8959
+ const bg = "var(--stn-topology-node-current-bg)";
8960
+ if (shape === "square") {
8961
+ const s = r * 1.8;
8962
+ const half = s / 2;
8963
+ const rx = Math.max(2, 2.5 * (r / 10));
8964
+ return /* @__PURE__ */ jsx60("g", { className: "stn-topology-node__current-ring", children: /* @__PURE__ */ jsx60(
8965
+ "rect",
8966
+ {
8967
+ x: -half - 7.5,
8968
+ y: -half - 7.5,
8969
+ width: s + 15,
8970
+ height: s + 15,
8971
+ rx: rx + 3.5,
8972
+ fill: bg,
8973
+ stroke: "none"
8974
+ }
8975
+ ) });
8976
+ }
8977
+ if (shape === "triangle") {
8978
+ const R2 = r * 1.25;
8979
+ return /* @__PURE__ */ jsx60("g", { className: "stn-topology-node__current-ring", children: /* @__PURE__ */ jsx60(
8980
+ "polygon",
8981
+ {
8982
+ points: trianglePoints(0, 0, R2 + 8.5),
8983
+ fill: bg,
8984
+ stroke: "none",
8985
+ strokeLinejoin: "round"
8986
+ }
8987
+ ) });
8988
+ }
8989
+ if (shape === "star") {
8990
+ const R2 = r * 1.3;
8991
+ const rIn = R2 * 0.48;
8992
+ return /* @__PURE__ */ jsx60("g", { className: "stn-topology-node__current-ring", children: /* @__PURE__ */ jsx60(
8993
+ "polygon",
8994
+ {
8995
+ points: starPoints(0, 0, R2 + 7.5, rIn + 3.5),
8996
+ fill: bg,
8997
+ stroke: "none",
8998
+ strokeLinejoin: "round"
8999
+ }
9000
+ ) });
9001
+ }
9002
+ if (shape === "diamond") {
9003
+ const R2 = r * 1.2;
9004
+ return /* @__PURE__ */ jsx60("g", { className: "stn-topology-node__current-ring", children: /* @__PURE__ */ jsx60(
9005
+ "polygon",
9006
+ {
9007
+ points: diamondPoints(0, 0, R2 + 8),
9008
+ fill: bg,
9009
+ stroke: "none"
9010
+ }
9011
+ ) });
9012
+ }
9013
+ return /* @__PURE__ */ jsx60("g", { className: "stn-topology-node__current-ring", children: /* @__PURE__ */ jsx60(
9014
+ "circle",
9015
+ {
9016
+ cx: "0",
9017
+ cy: "0",
9018
+ r: r + 8.5,
9019
+ fill: bg,
9020
+ stroke: "none"
9021
+ }
9022
+ ) });
9023
+ }
8850
9024
  function StnTopologyGraphViewport({ className, style }) {
8851
9025
  const {
8852
9026
  renderGridLines,
@@ -8877,23 +9051,21 @@ function StnTopologyGraphViewport({ className, style }) {
8877
9051
  if (!link.n1 || !link.n2) return null;
8878
9052
  const { n1, n2 } = link;
8879
9053
  const depthScale = 550 / (550 + link.avgDepth);
8880
- const opacity = Math.max(0.65, Math.min(1, depthScale));
8881
- const hasDot = link.variant === "dot" || link.variant !== "line" && Boolean(link.status);
9054
+ const baseOpacity = Math.max(0.65, Math.min(1, depthScale));
9055
+ const opacity = resolveTopologyOpacity(link.opacity, baseOpacity);
9056
+ const isDot = link.variant === "dot";
9057
+ const effectiveStatus = link.status ?? (isDot ? n1.status === "critical" || n2.status === "critical" ? "critical" : n1.status === "major" || n2.status === "major" ? "major" : n1.status === "minor" || n2.status === "minor" ? "minor" : n1.status === "warning" || n2.status === "warning" ? "warning" : void 0 : void 0);
9058
+ const statusColor = effectiveStatus === "critical" ? "var(--stn-grade-critical)" : effectiveStatus === "major" ? "var(--stn-grade-major)" : effectiveStatus === "minor" ? "var(--stn-grade-minor)" : effectiveStatus === "warning" ? "var(--stn-grade-warning)" : effectiveStatus === "point" ? "var(--stn-primary)" : null;
8882
9059
  let dotElement = null;
8883
- if (hasDot) {
9060
+ if (isDot) {
8884
9061
  const midSX = (n1.sx + n2.sx) / 2;
8885
9062
  const midSY = (n1.sy + n2.sy) / 2;
8886
9063
  const dotRadius = Math.max(2, 3 * depthScale * Math.min(1.2, Math.max(0.6, zoom)));
8887
- const isCritical = n1.status === "critical" || n2.status === "critical" || link.status === "critical";
8888
- const isMajor = n1.status === "major" || n2.status === "major" || link.status === "major";
8889
- const isMinor = n1.status === "minor" || n2.status === "minor" || link.status === "minor";
8890
- const isWarning = n1.status === "warning" || n2.status === "warning" || link.status === "warning";
8891
- const statusColor = isCritical ? "var(--stn-grade-critical)" : isMajor ? "var(--stn-grade-major)" : isMinor ? "var(--stn-grade-minor)" : isWarning ? "var(--stn-grade-warning)" : null;
8892
- const dotFill = statusColor ?? "var(--stn-grade-neutral)";
9064
+ const dotFill = link.color ?? statusColor ?? "var(--stn-grade-neutral)";
8893
9065
  dotElement = /* @__PURE__ */ jsx60("circle", { cx: midSX, cy: midSY, r: dotRadius, fill: dotFill });
8894
9066
  }
8895
- const lineColor = "var(--stn-border-strong)";
8896
- const effectiveStrokeWidth = Math.max(1.4, 1.8 * depthScale * Math.min(1.2, Math.max(0.7, zoom)));
9067
+ const lineColor = link.color ?? (!isDot && statusColor ? statusColor : "var(--stn-border-strong)");
9068
+ const effectiveStrokeWidth = resolveTopologyStrokeWidth(link.strokeWidth, depthScale, zoom);
8897
9069
  return /* @__PURE__ */ jsxs47("g", { opacity, children: [
8898
9070
  /* @__PURE__ */ jsx60(
8899
9071
  "line",
@@ -8913,20 +9085,26 @@ function StnTopologyGraphViewport({ className, style }) {
8913
9085
  /* @__PURE__ */ jsx60("g", { className: "stn-topology-nodes-group", children: sortedNodes.map((n) => {
8914
9086
  const depthScale = 550 / (550 + n.depth);
8915
9087
  const scale = Math.max(0.4, n.scale);
8916
- const opacity = Math.max(0.75, Math.min(1, depthScale));
8917
- const isSelected = selectedId === n.id;
9088
+ const baseOpacity = Math.max(0.75, Math.min(1, depthScale));
9089
+ const opacity = resolveTopologyOpacity(n.opacity, baseOpacity);
9090
+ const isSelected = selectedId === n.id || Boolean(n.isCurrent) || Boolean(n.isSelected);
8918
9091
  const isCore = Boolean(n.isCore);
8919
- const isCritical = n.status === "critical" || Boolean(n.pulse);
9092
+ const isPoint = n.status === "point";
9093
+ const isCritical = n.status === "critical";
8920
9094
  const isWarning = n.status === "warning";
8921
9095
  const isMajor = n.status === "major";
8922
9096
  const isMinor = n.status === "minor";
9097
+ const isNeutral = n.status === "neutral";
9098
+ const isNormal = n.status === "normal";
9099
+ const hasPulse = isCritical || Boolean(n.pulse);
8923
9100
  const shape = n.shape ?? (isCore ? "diamond" : "circle");
8924
9101
  const variant = n.variant ?? (isCore ? "combined" : "outline");
8925
- const statusColor = n.color ? n.color : isCritical ? "var(--stn-grade-critical)" : isMajor ? "var(--stn-grade-major)" : isMinor ? "var(--stn-grade-minor)" : isWarning ? "var(--stn-grade-warning)" : isCore ? "var(--stn-primary)" : "var(--stn-grade-neutral)";
8926
- const r = 14 * scale;
9102
+ const statusColor = n.color ? n.color : isCritical ? "var(--stn-grade-critical)" : isMajor ? "var(--stn-grade-major)" : isMinor ? "var(--stn-grade-minor)" : isWarning ? "var(--stn-grade-warning)" : isPoint || isCore ? "var(--stn-primary)" : isNeutral ? "var(--stn-grade-neutral)" : isNormal ? "var(--stn-grade-normal)" : "var(--stn-grade-neutral)";
9103
+ const baseRadius = typeof n.size === "number" ? n.size : n.size && TOPOLOGY_NODE_SIZE_MAP[n.size] ? TOPOLOGY_NODE_SIZE_MAP[n.size] : isCore ? TOPOLOGY_NODE_SIZE_MAP.lg : TOPOLOGY_NODE_SIZE_MAP.md;
9104
+ const r = baseRadius * scale;
8927
9105
  const strokeWidth = Math.max(1.4, 2 * depthScale);
8928
- const rOuter = Math.max(14, 16 * scale);
8929
- const pulseRing = isCritical && /* @__PURE__ */ jsxs47("g", { children: [
9106
+ const rOuter = Math.max(baseRadius, (baseRadius + 2) * scale);
9107
+ const pulseRing = hasPulse && /* @__PURE__ */ jsxs47("g", { children: [
8930
9108
  /* @__PURE__ */ jsx60(
8931
9109
  "circle",
8932
9110
  {
@@ -8950,6 +9128,7 @@ function StnTopologyGraphViewport({ className, style }) {
8950
9128
  }
8951
9129
  )
8952
9130
  ] });
9131
+ const currentRing = isSelected && renderCurrentNodeRing({ shape, r });
8953
9132
  const glyph = render3DNodeGlyph({
8954
9133
  shape,
8955
9134
  variant,
@@ -8957,14 +9136,65 @@ function StnTopologyGraphViewport({ className, style }) {
8957
9136
  statusColor,
8958
9137
  strokeWidth
8959
9138
  });
9139
+ let badgeElement = null;
9140
+ if (n.badge) {
9141
+ const badgeText = String(n.badge);
9142
+ const isSubtle = n.badgeAppearance === "subtle";
9143
+ const badgeColorTheme = n.badgeColor ?? "inverted";
9144
+ let badgeBg = "var(--stn-topology-badge-bg)";
9145
+ let badgeTextColor = "var(--stn-topology-badge-text)";
9146
+ if (badgeColorTheme === "inverted" || badgeColorTheme === "mono") {
9147
+ badgeBg = isSubtle ? "var(--stn-opacity-white-10)" : "var(--stn-topology-badge-bg)";
9148
+ badgeTextColor = isSubtle ? "var(--stn-topology-badge-bg)" : "var(--stn-topology-badge-text)";
9149
+ } else {
9150
+ const solidColor = badgeColorTheme === "primary" ? "var(--stn-primary)" : badgeColorTheme === "success" ? "var(--stn-feedback-success)" : badgeColorTheme === "critical" || badgeColorTheme === "error" ? "var(--stn-grade-critical)" : badgeColorTheme === "major" ? "var(--stn-grade-major)" : badgeColorTheme === "minor" ? "var(--stn-grade-minor)" : badgeColorTheme === "warning" ? "var(--stn-grade-warning)" : badgeColorTheme === "secondary" ? "var(--stn-secondary)" : badgeColorTheme === "neutral" ? "var(--stn-grade-neutral)" : badgeColorTheme;
9151
+ badgeBg = isSubtle ? `color-mix(in srgb, ${solidColor} 18%, var(--stn-elevation-surface-0))` : solidColor;
9152
+ badgeTextColor = isSubtle ? solidColor : "var(--stn-static-white)";
9153
+ }
9154
+ const charCount = badgeText.length;
9155
+ const badgeW = Math.max(26, charCount * 11 + 10);
9156
+ const badgeH = 16;
9157
+ const badgeY = -r - badgeH - 4;
9158
+ badgeElement = /* @__PURE__ */ jsxs47("g", { className: "stn-topology-node__badge", transform: `translate(0, ${badgeY})`, children: [
9159
+ /* @__PURE__ */ jsx60(
9160
+ "rect",
9161
+ {
9162
+ x: -badgeW / 2,
9163
+ y: 0,
9164
+ width: badgeW,
9165
+ height: badgeH,
9166
+ rx: badgeH / 2,
9167
+ fill: badgeBg,
9168
+ stroke: "var(--stn-elevation-surface-0)",
9169
+ strokeWidth: 1.5
9170
+ }
9171
+ ),
9172
+ /* @__PURE__ */ jsx60(
9173
+ "text",
9174
+ {
9175
+ x: 0,
9176
+ y: badgeH / 2 + 0.5,
9177
+ textAnchor: "middle",
9178
+ dominantBaseline: "central",
9179
+ fill: badgeTextColor,
9180
+ fontSize: 10,
9181
+ fontWeight: 700,
9182
+ style: { userSelect: "none", pointerEvents: "none" },
9183
+ children: badgeText
9184
+ }
9185
+ )
9186
+ ] });
9187
+ }
8960
9188
  const nodeContent = /* @__PURE__ */ jsxs47("g", { children: [
9189
+ currentRing,
8961
9190
  pulseRing,
8962
- glyph
9191
+ glyph,
9192
+ badgeElement
8963
9193
  ] });
8964
9194
  return /* @__PURE__ */ jsx60(
8965
9195
  "g",
8966
9196
  {
8967
- className: cn("stn-topology-node", isSelected && "selected"),
9197
+ className: cn("stn-topology-node", isSelected && "selected", isSelected && "is-current"),
8968
9198
  transform: `translate(${n.sx}, ${n.sy})`,
8969
9199
  opacity,
8970
9200
  style: { cursor: "pointer" },
@@ -11218,7 +11448,9 @@ function StnBreadcrumb({
11218
11448
  onHomeClick,
11219
11449
  showHome = true,
11220
11450
  homeLabel = "\uD648",
11221
- renderItem
11451
+ renderItem,
11452
+ reverse = false,
11453
+ leadSeparator = false
11222
11454
  }) {
11223
11455
  const menuId = useId17();
11224
11456
  const currentIndex = items.findIndex((item, index) => item.current ?? index === items.length - 1);
@@ -11226,15 +11458,17 @@ function StnBreadcrumb({
11226
11458
  const previousItem = currentIndex > 0 ? items[currentIndex - 1] : null;
11227
11459
  const backHref = previousItem?.href ?? (showHome ? homeHref : void 0);
11228
11460
  const backOnClick = previousItem?.onClick ?? onHomeClick;
11461
+ const explicitCurrent = items.find((i) => i.current);
11462
+ const targetCurrentId = leadSeparator ? explicitCurrent?.id : explicitCurrent?.id ?? items[items.length - 1]?.id;
11463
+ const displayItems = reverse ? [...items].reverse() : items;
11229
11464
  const { head, hidden, tail } = splitCollapsedItems(
11230
- items,
11465
+ displayItems,
11231
11466
  maxItems,
11232
11467
  itemsBeforeCollapse,
11233
11468
  itemsAfterCollapse
11234
11469
  );
11235
- const lastId = items[items.length - 1]?.id;
11236
11470
  const renderTrailItem = (item) => {
11237
- const isCurrent = Boolean(item.current) || item.id === lastId;
11471
+ const isCurrent = Boolean(item.current) || item.id === targetCurrentId;
11238
11472
  const segment = /* @__PURE__ */ jsx82(BreadcrumbSegment, { item, isCurrent });
11239
11473
  return /* @__PURE__ */ jsx82(
11240
11474
  "li",
@@ -11250,16 +11484,22 @@ function StnBreadcrumb({
11250
11484
  return /* @__PURE__ */ jsx82(
11251
11485
  "nav",
11252
11486
  {
11253
- className: cn("stn-breadcrumb", size, variant === "chip" && "chip", className),
11487
+ className: cn(
11488
+ "stn-breadcrumb",
11489
+ size,
11490
+ variant === "chip" && "chip",
11491
+ reverse && "reverse",
11492
+ className
11493
+ ),
11254
11494
  "aria-label": "Breadcrumb",
11255
11495
  children: /* @__PURE__ */ jsxs60("ol", { className: "stn-breadcrumb__list", children: [
11256
11496
  currentItem ? /* @__PURE__ */ jsx82("li", { className: "stn-breadcrumb__item stn-breadcrumb__item--back", children: /* @__PURE__ */ jsx82(BreadcrumbBack, { label: currentItem.label, href: backHref, onClick: backOnClick }) }) : null,
11257
- showHome ? /* @__PURE__ */ jsx82("li", { className: "stn-breadcrumb__item stn-breadcrumb__item--home", children: /* @__PURE__ */ jsxs60("a", { className: "stn-breadcrumb__home", href: homeHref, onClick: onHomeClick, children: [
11497
+ !reverse && showHome ? /* @__PURE__ */ jsx82("li", { className: "stn-breadcrumb__item stn-breadcrumb__item--home", children: /* @__PURE__ */ jsxs60("a", { className: "stn-breadcrumb__home", href: homeHref, onClick: onHomeClick, children: [
11258
11498
  /* @__PURE__ */ jsx82(BreadcrumbIcon, { src: STN_BREADCRUMB_ICON_SRC.home }),
11259
11499
  /* @__PURE__ */ jsx82("span", { className: "blind", children: homeLabel })
11260
11500
  ] }) }) : null,
11261
11501
  head.map((item, index) => /* @__PURE__ */ jsxs60(Fragment12, { children: [
11262
- showHome || index > 0 ? /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}) : null,
11502
+ !reverse && (showHome || index > 0 || leadSeparator) || reverse && (index > 0 || leadSeparator) ? /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}) : null,
11263
11503
  renderTrailItem(item)
11264
11504
  ] }, item.id)),
11265
11505
  hidden.length > 0 ? /* @__PURE__ */ jsxs60(Fragment13, { children: [
@@ -11269,7 +11509,14 @@ function StnBreadcrumb({
11269
11509
  tail.map((item) => /* @__PURE__ */ jsxs60(Fragment12, { children: [
11270
11510
  /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}),
11271
11511
  renderTrailItem(item)
11272
- ] }, item.id))
11512
+ ] }, item.id)),
11513
+ reverse && showHome ? /* @__PURE__ */ jsxs60(Fragment13, { children: [
11514
+ /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}),
11515
+ /* @__PURE__ */ jsx82("li", { className: "stn-breadcrumb__item stn-breadcrumb__item--home", children: /* @__PURE__ */ jsxs60("a", { className: "stn-breadcrumb__home", href: homeHref, onClick: onHomeClick, children: [
11516
+ /* @__PURE__ */ jsx82(BreadcrumbIcon, { src: STN_BREADCRUMB_ICON_SRC.home }),
11517
+ /* @__PURE__ */ jsx82("span", { className: "blind", children: homeLabel })
11518
+ ] }) })
11519
+ ] }) : null
11273
11520
  ] })
11274
11521
  }
11275
11522
  );
@@ -14234,6 +14481,7 @@ export {
14234
14481
  StnEmptyState,
14235
14482
  StnEventBanner,
14236
14483
  StnFloatingToolbar,
14484
+ StnFloatingToolbarDivider,
14237
14485
  StnGaugeChart,
14238
14486
  StnGradeRow,
14239
14487
  StnGradeRowList,
@@ -14398,6 +14646,8 @@ export {
14398
14646
  StnWidgetStatusItem,
14399
14647
  StnWidgetStatusList,
14400
14648
  StnWidgetTitle,
14649
+ TOPOLOGY_OPACITY_MAP,
14650
+ TOPOLOGY_STROKE_WIDTH_MAP,
14401
14651
  applyLnbSideToModifiers,
14402
14652
  buildPaginationItems,
14403
14653
  buildStnTreeNodeCells,