@stn-uiux/pub-ui-react 0.1.85 → 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
@@ -1213,6 +1213,7 @@ var StnModal = forwardRef7(function StnModal2({
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
@@ -7771,6 +7789,18 @@ var StnStack = forwardRef36(function StnStack2({
7771
7789
  });
7772
7790
 
7773
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
+ };
7774
7804
  var STN_TOPOLOGY_NODE_SHAPES = [
7775
7805
  "circle",
7776
7806
  "square",
@@ -7787,13 +7817,15 @@ var STN_TOPOLOGY_LINK_VARIANTS = [
7787
7817
  "line",
7788
7818
  "dot"
7789
7819
  ];
7790
- var STN_TOPOLOGY_NODE_SIZES = ["xs", "sm", "md", "lg"];
7820
+ var STN_TOPOLOGY_NODE_SIZES = ["xs", "sm", "md", "lg", "xl"];
7791
7821
  var STN_TOPOLOGY_NODE_STATUSES = [
7822
+ "point",
7792
7823
  "normal",
7793
7824
  "warning",
7794
7825
  "minor",
7795
7826
  "major",
7796
- "critical"
7827
+ "critical",
7828
+ "neutral"
7797
7829
  ];
7798
7830
  var STN_TOPOLOGY_NODE_ICONS = [
7799
7831
  "topology-wifi",
@@ -7829,6 +7861,12 @@ function resolveTopologyIconName(icon) {
7829
7861
  }
7830
7862
  }
7831
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
+ },
7832
7870
  normal: {
7833
7871
  main: "var(--stn-grade-normal)",
7834
7872
  glow: "color-mix(in srgb, var(--stn-grade-normal) 35%, transparent)",
@@ -7858,13 +7896,20 @@ var STN_TOPOLOGY_STATUS_COLORS = {
7858
7896
  glow: "color-mix(in srgb, var(--stn-grade-critical) 80%, transparent)",
7859
7897
  text: "var(--stn-grade-critical)",
7860
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"
7861
7905
  }
7862
7906
  };
7863
7907
  var STN_TOPOLOGY_NODE_SIZE = {
7864
7908
  xs: { r: 12, icon: 14, countFont: 9, labelFont: 11, statusFont: 10, stroke: 1.2 },
7865
7909
  sm: { r: 16, icon: 16, countFont: 10, labelFont: 11, statusFont: 10, stroke: 1.4 },
7866
7910
  md: { r: 20, icon: 18, countFont: 11, labelFont: 12, statusFont: 11, stroke: 1.6 },
7867
- 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 }
7868
7913
  };
7869
7914
  function formatTopologyCount(count) {
7870
7915
  if (count == null || count === "") return "0";
@@ -7924,7 +7969,8 @@ var NODE_TITLE_VARIANT = {
7924
7969
  xs: "label-4",
7925
7970
  sm: "caption",
7926
7971
  md: "caption",
7927
- lg: "body-small"
7972
+ lg: "body-small",
7973
+ xl: "body-2"
7928
7974
  };
7929
7975
  function renderTopologyIcon(icon, color = "currentColor", px = 18) {
7930
7976
  if (!icon) return null;
@@ -8444,7 +8490,21 @@ import {
8444
8490
  // src/patterns/toolbar/StnFloatingToolbar.tsx
8445
8491
  import React3 from "react";
8446
8492
  import { jsx as jsx59 } from "react/jsx-runtime";
8447
- 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(
8448
8508
  ({ placement = "none", orientation = "horizontal", className, children, ...restProps }, ref) => {
8449
8509
  const placementClass = placement !== "none" ? `stn-floating-toolbar--${placement}` : "";
8450
8510
  const orientationClass = orientation === "vertical" ? "stn-floating-toolbar--vertical" : "";
@@ -8461,10 +8521,41 @@ var StnFloatingToolbar = React3.forwardRef(
8461
8521
  );
8462
8522
  }
8463
8523
  );
8464
- StnFloatingToolbar.displayName = "StnFloatingToolbar";
8524
+ StnFloatingToolbarRoot.displayName = "StnFloatingToolbar";
8525
+ var StnFloatingToolbar = Object.assign(StnFloatingToolbarRoot, {
8526
+ Divider: StnFloatingToolbarDivider
8527
+ });
8465
8528
 
8466
8529
  // src/components/topology/StnTopologyGraph.tsx
8467
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
+ }
8468
8559
  var DEFAULT_3D_GRAPH_NODES = [
8469
8560
  { id: 0, x: 0, y: 0, z: 0, isCore: true, status: "normal", label: "[\uC911\uC559 \uCF54\uC5B4] CORE-SW (10.10.1.1)" },
8470
8561
  // Top Branch
@@ -8692,6 +8783,10 @@ function StnTopologyGraphMinimap({ className, style }) {
8692
8783
  const n1 = nodeMap.get(link.source);
8693
8784
  const n2 = nodeMap.get(link.target);
8694
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);
8695
8790
  return /* @__PURE__ */ jsx60(
8696
8791
  "line",
8697
8792
  {
@@ -8699,8 +8794,9 @@ function StnTopologyGraphMinimap({ className, style }) {
8699
8794
  y1: n1.sy * 0.5,
8700
8795
  x2: n2.sx * 0.5,
8701
8796
  y2: n2.sy * 0.5,
8702
- stroke: "var(--stn-border-strong)",
8703
- strokeWidth: "1.2"
8797
+ stroke: strokeColor,
8798
+ strokeWidth: miniStrokeWidth,
8799
+ opacity: miniOpacity
8704
8800
  },
8705
8801
  `mini-link-${idx}`
8706
8802
  );
@@ -8708,6 +8804,7 @@ function StnTopologyGraphMinimap({ className, style }) {
8708
8804
  projectedNodes.map((n) => {
8709
8805
  const cx = n.sx * 0.5;
8710
8806
  const cy = n.sy * 0.5;
8807
+ const nodeOpacity = resolveTopologyOpacity(n.opacity, 1);
8711
8808
  if (n.isCore) {
8712
8809
  return /* @__PURE__ */ jsx60(
8713
8810
  "polygon",
@@ -8715,7 +8812,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8715
8812
  points: `${cx},${cy - 5} ${cx + 5},${cy} ${cx},${cy + 5} ${cx - 5},${cy}`,
8716
8813
  fill: "var(--stn-primary)",
8717
8814
  stroke: "var(--stn-primary)",
8718
- strokeWidth: "1"
8815
+ strokeWidth: "1",
8816
+ opacity: nodeOpacity
8719
8817
  },
8720
8818
  `mini-node-${n.id}`
8721
8819
  );
@@ -8727,7 +8825,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8727
8825
  cx,
8728
8826
  cy,
8729
8827
  r: "3.5",
8730
- fill: "var(--stn-grade-critical)"
8828
+ fill: "var(--stn-grade-critical)",
8829
+ opacity: nodeOpacity
8731
8830
  },
8732
8831
  `mini-node-${n.id}`
8733
8832
  );
@@ -8739,7 +8838,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8739
8838
  cx,
8740
8839
  cy,
8741
8840
  r: "3",
8742
- fill: "var(--stn-grade-warning)"
8841
+ fill: "var(--stn-grade-warning)",
8842
+ opacity: nodeOpacity
8743
8843
  },
8744
8844
  `mini-node-${n.id}`
8745
8845
  );
@@ -8750,7 +8850,8 @@ function StnTopologyGraphMinimap({ className, style }) {
8750
8850
  cx,
8751
8851
  cy,
8752
8852
  r: "3",
8753
- fill: "var(--stn-border-subtle)"
8853
+ fill: "var(--stn-border-subtle)",
8854
+ opacity: nodeOpacity
8754
8855
  },
8755
8856
  `mini-node-${n.id}`
8756
8857
  );
@@ -8768,16 +8869,17 @@ function render3DNodeGlyph({
8768
8869
  strokeWidth
8769
8870
  }) {
8770
8871
  const surfaceBg = "var(--stn-elevation-surface-0)";
8771
- const innerRatio = 0.52;
8772
- const rSmall = r * innerRatio;
8872
+ const innerRatioCircleSquare = 0.653;
8873
+ const innerRatioOther = 0.52;
8874
+ const rSmall = r * innerRatioCircleSquare;
8773
8875
  const strokeWSmall = Math.max(1.2, strokeWidth * 0.85);
8774
8876
  if (shape === "square") {
8775
8877
  const s = r * 1.8;
8776
8878
  const half = s / 2;
8777
8879
  const rx = Math.max(1.5, 2.5 * (r / 10));
8778
- const sSmall = s * innerRatio;
8880
+ const sSmall = s * innerRatioCircleSquare;
8779
8881
  const halfSmall = sSmall / 2;
8780
- const rxSmall = rx * 0.65;
8882
+ const rxSmall = rx * 0.75;
8781
8883
  if (variant === "solid") {
8782
8884
  return /* @__PURE__ */ jsx60("rect", { x: -halfSmall, y: -halfSmall, width: sSmall, height: sSmall, rx: rxSmall, fill: statusColor });
8783
8885
  }
@@ -8791,7 +8893,7 @@ function render3DNodeGlyph({
8791
8893
  }
8792
8894
  if (shape === "triangle") {
8793
8895
  const R2 = r * 1.25;
8794
- const RSmall = R2 * innerRatio;
8896
+ const RSmall = R2 * innerRatioOther;
8795
8897
  const pts = trianglePoints(0, 0, R2);
8796
8898
  const ptsSmall = trianglePoints(0, 0, RSmall);
8797
8899
  if (variant === "solid") {
@@ -8808,8 +8910,8 @@ function render3DNodeGlyph({
8808
8910
  if (shape === "star") {
8809
8911
  const R2 = r * 1.3;
8810
8912
  const rIn = R2 * 0.48;
8811
- const RSmall = R2 * innerRatio;
8812
- const rInSmall = rIn * innerRatio;
8913
+ const RSmall = R2 * innerRatioOther;
8914
+ const rInSmall = rIn * innerRatioOther;
8813
8915
  const pts = starPoints(0, 0, R2, rIn);
8814
8916
  const ptsSmall = starPoints(0, 0, RSmall, rInSmall);
8815
8917
  if (variant === "solid") {
@@ -8825,7 +8927,7 @@ function render3DNodeGlyph({
8825
8927
  }
8826
8928
  if (shape === "diamond") {
8827
8929
  const R2 = r * 1.2;
8828
- const RSmall = R2 * innerRatio;
8930
+ const RSmall = R2 * innerRatioOther;
8829
8931
  const pts = diamondPoints(0, 0, R2);
8830
8932
  const ptsSmall = diamondPoints(0, 0, RSmall);
8831
8933
  if (variant === "solid") {
@@ -8850,6 +8952,75 @@ function render3DNodeGlyph({
8850
8952
  }
8851
8953
  return /* @__PURE__ */ jsx60("circle", { cx: "0", cy: "0", r: rSmall, fill: surfaceBg, stroke: statusColor, strokeWidth: strokeWSmall });
8852
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
+ }
8853
9024
  function StnTopologyGraphViewport({ className, style }) {
8854
9025
  const {
8855
9026
  renderGridLines,
@@ -8880,23 +9051,21 @@ function StnTopologyGraphViewport({ className, style }) {
8880
9051
  if (!link.n1 || !link.n2) return null;
8881
9052
  const { n1, n2 } = link;
8882
9053
  const depthScale = 550 / (550 + link.avgDepth);
8883
- const opacity = Math.max(0.65, Math.min(1, depthScale));
8884
- 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;
8885
9059
  let dotElement = null;
8886
- if (hasDot) {
9060
+ if (isDot) {
8887
9061
  const midSX = (n1.sx + n2.sx) / 2;
8888
9062
  const midSY = (n1.sy + n2.sy) / 2;
8889
9063
  const dotRadius = Math.max(2, 3 * depthScale * Math.min(1.2, Math.max(0.6, zoom)));
8890
- const isCritical = n1.status === "critical" || n2.status === "critical" || link.status === "critical";
8891
- const isMajor = n1.status === "major" || n2.status === "major" || link.status === "major";
8892
- const isMinor = n1.status === "minor" || n2.status === "minor" || link.status === "minor";
8893
- const isWarning = n1.status === "warning" || n2.status === "warning" || link.status === "warning";
8894
- const statusColor = isCritical ? "var(--stn-grade-critical)" : isMajor ? "var(--stn-grade-major)" : isMinor ? "var(--stn-grade-minor)" : isWarning ? "var(--stn-grade-warning)" : null;
8895
- const dotFill = statusColor ?? "var(--stn-grade-neutral)";
9064
+ const dotFill = link.color ?? statusColor ?? "var(--stn-grade-neutral)";
8896
9065
  dotElement = /* @__PURE__ */ jsx60("circle", { cx: midSX, cy: midSY, r: dotRadius, fill: dotFill });
8897
9066
  }
8898
- const lineColor = "var(--stn-border-strong)";
8899
- 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);
8900
9069
  return /* @__PURE__ */ jsxs47("g", { opacity, children: [
8901
9070
  /* @__PURE__ */ jsx60(
8902
9071
  "line",
@@ -8916,20 +9085,26 @@ function StnTopologyGraphViewport({ className, style }) {
8916
9085
  /* @__PURE__ */ jsx60("g", { className: "stn-topology-nodes-group", children: sortedNodes.map((n) => {
8917
9086
  const depthScale = 550 / (550 + n.depth);
8918
9087
  const scale = Math.max(0.4, n.scale);
8919
- const opacity = Math.max(0.75, Math.min(1, depthScale));
8920
- 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);
8921
9091
  const isCore = Boolean(n.isCore);
8922
- const isCritical = n.status === "critical" || Boolean(n.pulse);
9092
+ const isPoint = n.status === "point";
9093
+ const isCritical = n.status === "critical";
8923
9094
  const isWarning = n.status === "warning";
8924
9095
  const isMajor = n.status === "major";
8925
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);
8926
9100
  const shape = n.shape ?? (isCore ? "diamond" : "circle");
8927
9101
  const variant = n.variant ?? (isCore ? "combined" : "outline");
8928
- 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)";
8929
- 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;
8930
9105
  const strokeWidth = Math.max(1.4, 2 * depthScale);
8931
- const rOuter = Math.max(14, 16 * scale);
8932
- const pulseRing = isCritical && /* @__PURE__ */ jsxs47("g", { children: [
9106
+ const rOuter = Math.max(baseRadius, (baseRadius + 2) * scale);
9107
+ const pulseRing = hasPulse && /* @__PURE__ */ jsxs47("g", { children: [
8933
9108
  /* @__PURE__ */ jsx60(
8934
9109
  "circle",
8935
9110
  {
@@ -8953,6 +9128,7 @@ function StnTopologyGraphViewport({ className, style }) {
8953
9128
  }
8954
9129
  )
8955
9130
  ] });
9131
+ const currentRing = isSelected && renderCurrentNodeRing({ shape, r });
8956
9132
  const glyph = render3DNodeGlyph({
8957
9133
  shape,
8958
9134
  variant,
@@ -8960,14 +9136,65 @@ function StnTopologyGraphViewport({ className, style }) {
8960
9136
  statusColor,
8961
9137
  strokeWidth
8962
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
+ }
8963
9188
  const nodeContent = /* @__PURE__ */ jsxs47("g", { children: [
9189
+ currentRing,
8964
9190
  pulseRing,
8965
- glyph
9191
+ glyph,
9192
+ badgeElement
8966
9193
  ] });
8967
9194
  return /* @__PURE__ */ jsx60(
8968
9195
  "g",
8969
9196
  {
8970
- className: cn("stn-topology-node", isSelected && "selected"),
9197
+ className: cn("stn-topology-node", isSelected && "selected", isSelected && "is-current"),
8971
9198
  transform: `translate(${n.sx}, ${n.sy})`,
8972
9199
  opacity,
8973
9200
  style: { cursor: "pointer" },
@@ -11221,7 +11448,9 @@ function StnBreadcrumb({
11221
11448
  onHomeClick,
11222
11449
  showHome = true,
11223
11450
  homeLabel = "\uD648",
11224
- renderItem
11451
+ renderItem,
11452
+ reverse = false,
11453
+ leadSeparator = false
11225
11454
  }) {
11226
11455
  const menuId = useId17();
11227
11456
  const currentIndex = items.findIndex((item, index) => item.current ?? index === items.length - 1);
@@ -11229,15 +11458,17 @@ function StnBreadcrumb({
11229
11458
  const previousItem = currentIndex > 0 ? items[currentIndex - 1] : null;
11230
11459
  const backHref = previousItem?.href ?? (showHome ? homeHref : void 0);
11231
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;
11232
11464
  const { head, hidden, tail } = splitCollapsedItems(
11233
- items,
11465
+ displayItems,
11234
11466
  maxItems,
11235
11467
  itemsBeforeCollapse,
11236
11468
  itemsAfterCollapse
11237
11469
  );
11238
- const lastId = items[items.length - 1]?.id;
11239
11470
  const renderTrailItem = (item) => {
11240
- const isCurrent = Boolean(item.current) || item.id === lastId;
11471
+ const isCurrent = Boolean(item.current) || item.id === targetCurrentId;
11241
11472
  const segment = /* @__PURE__ */ jsx82(BreadcrumbSegment, { item, isCurrent });
11242
11473
  return /* @__PURE__ */ jsx82(
11243
11474
  "li",
@@ -11253,16 +11484,22 @@ function StnBreadcrumb({
11253
11484
  return /* @__PURE__ */ jsx82(
11254
11485
  "nav",
11255
11486
  {
11256
- 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
+ ),
11257
11494
  "aria-label": "Breadcrumb",
11258
11495
  children: /* @__PURE__ */ jsxs60("ol", { className: "stn-breadcrumb__list", children: [
11259
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,
11260
- 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: [
11261
11498
  /* @__PURE__ */ jsx82(BreadcrumbIcon, { src: STN_BREADCRUMB_ICON_SRC.home }),
11262
11499
  /* @__PURE__ */ jsx82("span", { className: "blind", children: homeLabel })
11263
11500
  ] }) }) : null,
11264
11501
  head.map((item, index) => /* @__PURE__ */ jsxs60(Fragment12, { children: [
11265
- showHome || index > 0 ? /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}) : null,
11502
+ !reverse && (showHome || index > 0 || leadSeparator) || reverse && (index > 0 || leadSeparator) ? /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}) : null,
11266
11503
  renderTrailItem(item)
11267
11504
  ] }, item.id)),
11268
11505
  hidden.length > 0 ? /* @__PURE__ */ jsxs60(Fragment13, { children: [
@@ -11272,7 +11509,14 @@ function StnBreadcrumb({
11272
11509
  tail.map((item) => /* @__PURE__ */ jsxs60(Fragment12, { children: [
11273
11510
  /* @__PURE__ */ jsx82(BreadcrumbSeparator, {}),
11274
11511
  renderTrailItem(item)
11275
- ] }, 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
11276
11520
  ] })
11277
11521
  }
11278
11522
  );
@@ -14237,6 +14481,7 @@ export {
14237
14481
  StnEmptyState,
14238
14482
  StnEventBanner,
14239
14483
  StnFloatingToolbar,
14484
+ StnFloatingToolbarDivider,
14240
14485
  StnGaugeChart,
14241
14486
  StnGradeRow,
14242
14487
  StnGradeRowList,
@@ -14401,6 +14646,8 @@ export {
14401
14646
  StnWidgetStatusItem,
14402
14647
  StnWidgetStatusList,
14403
14648
  StnWidgetTitle,
14649
+ TOPOLOGY_OPACITY_MAP,
14650
+ TOPOLOGY_STROKE_WIDTH_MAP,
14404
14651
  applyLnbSideToModifiers,
14405
14652
  buildPaginationItems,
14406
14653
  buildStnTreeNodeCells,