@flytedan/flytebot-design-system 0.11.5 → 0.11.6

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.d.cts CHANGED
@@ -2559,9 +2559,9 @@ declare function SaturationDistribution({ campuses, floorBand, floorScore, onSel
2559
2559
 
2560
2560
  /**
2561
2561
  * Realized media mix against the strategic target, one row per channel.
2562
- * Realized is a solid brand bar, target a neutral tick on the same row, and the
2563
- * gap is labelled directly on the bar — the gap is the story, so it never hides
2564
- * in a legend.
2562
+ * Realized is a solid tone bar, target a striped marker on the same row, and the
2563
+ * realized share is labelled directly beside them — the gap is the story, so it
2564
+ * never hides in a legend.
2565
2565
  */
2566
2566
  interface MixGapRow {
2567
2567
  channel: string;
package/dist/index.d.ts CHANGED
@@ -2559,9 +2559,9 @@ declare function SaturationDistribution({ campuses, floorBand, floorScore, onSel
2559
2559
 
2560
2560
  /**
2561
2561
  * Realized media mix against the strategic target, one row per channel.
2562
- * Realized is a solid brand bar, target a neutral tick on the same row, and the
2563
- * gap is labelled directly on the bar — the gap is the story, so it never hides
2564
- * in a legend.
2562
+ * Realized is a solid tone bar, target a striped marker on the same row, and the
2563
+ * realized share is labelled directly beside them — the gap is the story, so it
2564
+ * never hides in a legend.
2565
2565
  */
2566
2566
  interface MixGapRow {
2567
2567
  channel: string;
package/dist/index.js CHANGED
@@ -8106,11 +8106,24 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
8106
8106
  // src/components/planner/MixGap.tsx
8107
8107
  import * as React37 from "react";
8108
8108
  import { Fragment as Fragment18, jsx as jsx66, jsxs as jsxs61 } from "react/jsx-runtime";
8109
+ var MIX_GAP_LAYOUT = {
8110
+ trackHeight: 30,
8111
+ barHeight: 20,
8112
+ targetWidth: 6,
8113
+ labelGap: 6,
8114
+ labelGutter: 50
8115
+ };
8116
+ var MIX_GAP_TARGET_STRIPE = "repeating-linear-gradient(135deg, var(--n-600) 0 2px, var(--n-300) 2px 4px)";
8117
+ function mixGapOffset(value, max) {
8118
+ return `calc((100% - ${MIX_GAP_LAYOUT.labelGutter}px) * ${value / max})`;
8119
+ }
8109
8120
  function MixGap({ rows = [], loading = false, className = "" }) {
8110
8121
  const max = Math.max(1, ...rows.flatMap((r) => [r.target, r.realized]));
8111
8122
  const [hover, setHover] = React37.useState(null);
8112
8123
  const toneOf = (gap) => gap >= -1 ? "ok" : gap >= -4 ? "warn" : "danger";
8113
8124
  const TONE = { ok: "var(--ok-solid)", warn: "var(--warn-solid)", danger: "var(--danger-solid)" };
8125
+ const { trackHeight, barHeight, targetWidth, labelGap } = MIX_GAP_LAYOUT;
8126
+ const barTop = (trackHeight - barHeight) / 2;
8114
8127
  return /* @__PURE__ */ jsxs61("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 4 }, children: [
8115
8128
  /* @__PURE__ */ jsxs61("div", { className: "fd-row", style: { gap: 16, justifyContent: "flex-end", paddingBottom: 6, flexWrap: "wrap" }, children: [
8116
8129
  [["On target", TONE.ok], ["Close", TONE.warn], ["Short", TONE.danger]].map(([l, c]) => /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
@@ -8118,7 +8131,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8118
8131
  l
8119
8132
  ] }, l)),
8120
8133
  /* @__PURE__ */ jsxs61("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: 6 }, children: [
8121
- /* @__PURE__ */ jsx66("span", { style: { width: 3, height: 14, background: "var(--n-500)" } }),
8134
+ /* @__PURE__ */ jsx66("span", { "data-mixgap-legend-target": "", style: { width: targetWidth, height: 16, borderRadius: 1, background: MIX_GAP_TARGET_STRIPE } }),
8122
8135
  "Target"
8123
8136
  ] })
8124
8137
  ] }),
@@ -8126,6 +8139,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8126
8139
  const gap = r.realized - r.target;
8127
8140
  const tone = toneOf(gap);
8128
8141
  const tip = "Realized " + r.realized + "% vs " + r.target + "% target" + (gap < -1 ? " \xB7 " + Math.abs(gap).toFixed(0) + " pts short" : gap > 1 ? " \xB7 " + gap.toFixed(0) + " pts over" : " \xB7 on target") + (r.note ? " \u2014 " + r.note : "");
8142
+ const labelLeft = r.realized > r.target ? `calc(${mixGapOffset(r.realized, max)} + ${labelGap}px)` : `calc(${mixGapOffset(r.target, max)} + ${targetWidth / 2 + labelGap}px)`;
8129
8143
  return /* @__PURE__ */ jsxs61(
8130
8144
  "div",
8131
8145
  {
@@ -8135,14 +8149,14 @@ function MixGap({ rows = [], loading = false, className = "" }) {
8135
8149
  onMouseLeave: () => setHover(null),
8136
8150
  children: [
8137
8151
  /* @__PURE__ */ jsx66("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx66(ChannelTag, { channel: r.channel, size: "sm" }) }),
8138
- /* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: 22, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", inset: "5px 0", borderRadius: 3 } }) : /* @__PURE__ */ jsxs61(Fragment18, { children: [
8139
- /* @__PURE__ */ jsx66("span", { style: { position: "absolute", left: 0, top: 5, height: 12, width: r.realized / max * 100 + "%", background: TONE[tone], borderRadius: "2px 3px 3px 2px", transition: "width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)" } }),
8140
- /* @__PURE__ */ jsx66("span", { style: { position: "absolute", left: r.target / max * 100 + "%", top: 0, width: 3, height: 22, background: "var(--n-500)", borderRadius: 1 } }),
8141
- /* @__PURE__ */ jsxs61("span", { className: "fd-num", style: { position: "absolute", right: Math.max(r.realized, r.target) / max > 0.82 ? 0 : "auto", left: Math.max(r.realized, r.target) / max > 0.82 ? "auto" : "calc(" + Math.max(r.realized, r.target) / max * 100 + "% + 10px)", top: 2, fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap", background: Math.max(r.realized, r.target) / max > 0.82 ? "var(--surface)" : "none", paddingLeft: 3 }, children: [
8152
+ /* @__PURE__ */ jsx66("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx66("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs61(Fragment18, { children: [
8153
+ /* @__PURE__ */ jsx66("span", { "data-mixgap-bar": "", style: { position: "absolute", left: 0, top: barTop, height: barHeight, width: mixGapOffset(r.realized, max), background: TONE[tone], borderRadius: "2px 3px 3px 2px", transition: "width var(--dur-slow) var(--ease), background var(--dur-base) var(--ease)" } }),
8154
+ /* @__PURE__ */ jsx66("span", { "data-mixgap-target": "", style: { position: "absolute", left: `calc(${mixGapOffset(r.target, max)} - ${targetWidth / 2}px)`, top: 0, width: targetWidth, height: trackHeight, background: MIX_GAP_TARGET_STRIPE, borderRadius: 1 } }),
8155
+ /* @__PURE__ */ jsxs61("span", { "data-mixgap-label": "", className: "fd-num", style: { position: "absolute", left: labelLeft, top: "50%", transform: "translateY(-50%)", fontSize: 12, color: "var(--text-muted)", whiteSpace: "nowrap" }, children: [
8142
8156
  r.realized,
8143
8157
  "%"
8144
8158
  ] }),
8145
- hover === r.channel ? /* @__PURE__ */ jsx66("span", { className: "fd-tooltip", role: "tooltip", style: { position: "absolute", left: 0, right: "auto", bottom: 26, maxWidth: "min(340px, 100%)", whiteSpace: "normal", textAlign: "left", width: "max-content" }, children: tip }) : null
8159
+ hover === r.channel ? /* @__PURE__ */ jsx66("span", { className: "fd-tooltip", role: "tooltip", style: { position: "absolute", left: 0, right: "auto", bottom: trackHeight + 4, maxWidth: "min(340px, 100%)", whiteSpace: "normal", textAlign: "left", width: "max-content" }, children: tip }) : null
8146
8160
  ] }) })
8147
8161
  ]
8148
8162
  },