@devfellowship/components 3.4.0 → 3.5.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.
- package/dist/index.cjs +185 -28
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +174 -17
- package/dist/styles/tokens.css +13 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9104,9 +9104,49 @@ function firstFreeRow(taken, columns, from) {
|
|
|
9104
9104
|
}
|
|
9105
9105
|
return row;
|
|
9106
9106
|
}
|
|
9107
|
+
var pointText = (p) => `${p.x} ${p.y}`;
|
|
9108
|
+
var center = (r) => ({ x: (r.left + r.right) / 2, y: (r.top + r.bottom) / 2 });
|
|
9109
|
+
function segmentHits(a, b, r) {
|
|
9110
|
+
return a.x === b.x ? a.x > r.left && a.x < r.right && Math.max(a.y, b.y) > r.top && Math.min(a.y, b.y) < r.bottom : a.y > r.top && a.y < r.bottom && Math.max(a.x, b.x) > r.left && Math.min(a.x, b.x) < r.right;
|
|
9111
|
+
}
|
|
9112
|
+
function routeEdge(source, target, edge, obstacles = []) {
|
|
9113
|
+
const a = center(source), b = center(target);
|
|
9114
|
+
const sameColumn = Math.abs(a.x - b.x) < 1;
|
|
9115
|
+
const vertical = sameColumn || source.left < target.right && target.left < source.right;
|
|
9116
|
+
const down = b.y >= a.y, right = b.x >= a.x;
|
|
9117
|
+
const start = vertical ? { x: a.x, y: down ? source.bottom : source.top } : { x: right ? source.right : source.left, y: a.y };
|
|
9118
|
+
const end = vertical ? { x: b.x, y: down ? target.top : target.bottom } : { x: right ? target.left : target.right, y: b.y };
|
|
9119
|
+
const route = edge.route ?? "auto";
|
|
9120
|
+
if (route === "straight" || route === "auto" && sameColumn) return { start, end, d: `M ${pointText(start)} L ${pointText(end)}` };
|
|
9121
|
+
if (route !== "elbow") {
|
|
9122
|
+
const mid = vertical ? (start.y + end.y) / 2 : (start.x + end.x) / 2;
|
|
9123
|
+
const c1 = vertical ? { x: start.x, y: mid } : { x: mid, y: start.y };
|
|
9124
|
+
const c2 = vertical ? { x: end.x, y: mid } : { x: mid, y: end.y };
|
|
9125
|
+
return { start, end, d: `M ${pointText(start)} C ${pointText(c1)} ${pointText(c2)} ${pointText(end)}` };
|
|
9126
|
+
}
|
|
9127
|
+
const boxes = [.../* @__PURE__ */ new Set([source, target, ...obstacles])];
|
|
9128
|
+
const clearance = 4;
|
|
9129
|
+
const ys = [...new Set(boxes.flatMap((r) => [r.top - clearance, r.bottom + clearance]))];
|
|
9130
|
+
let best, bestLength = Infinity;
|
|
9131
|
+
for (const sx of [source.left, source.right]) for (const tx of [target.left, target.right]) {
|
|
9132
|
+
const s = { x: sx, y: a.y }, t = { x: tx, y: b.y };
|
|
9133
|
+
const gx = sx + (sx === source.left ? -clearance : clearance);
|
|
9134
|
+
const hx = tx + (tx === target.left ? -clearance : clearance);
|
|
9135
|
+
for (const y of [a.y, b.y, ...ys]) {
|
|
9136
|
+
const points2 = [s, { x: gx, y: a.y }, { x: gx, y }, { x: hx, y }, { x: hx, y: b.y }, t];
|
|
9137
|
+
const length = points2.slice(1).reduce((sum, p, i) => sum + Math.abs(p.x - points2[i].x) + Math.abs(p.y - points2[i].y), 0);
|
|
9138
|
+
if (length >= bestLength || points2.slice(1).some((p, i) => boxes.some((r) => segmentHits(points2[i], p, r)))) continue;
|
|
9139
|
+
best = points2;
|
|
9140
|
+
bestLength = length;
|
|
9141
|
+
}
|
|
9142
|
+
}
|
|
9143
|
+
if (!best) return { start, end, d: "" };
|
|
9144
|
+
const points = best.filter((p, i) => i === 0 || p.x !== best[i - 1].x || p.y !== best[i - 1].y);
|
|
9145
|
+
return { start: points[0], end: points[points.length - 1], points, d: points.map((p, i) => `${i ? "L" : "M"} ${pointText(p)}`).join(" ") };
|
|
9146
|
+
}
|
|
9107
9147
|
|
|
9108
9148
|
// src/components/organisms/roadmap/Roadmap.tsx
|
|
9109
|
-
var
|
|
9149
|
+
var import_react8 = require("react");
|
|
9110
9150
|
|
|
9111
9151
|
// src/components/organisms/roadmap/RoadmapNode.tsx
|
|
9112
9152
|
var import_class_variance_authority14 = require("class-variance-authority");
|
|
@@ -9154,7 +9194,7 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
|
|
|
9154
9194
|
const Box = wholeBox && node.href ? "a" : wholeBox && onNodeClick ? "button" : "div";
|
|
9155
9195
|
const primary = Box !== "div" ? label : node.href && !locked ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("a", { href: node.href, className: interactiveClass, onClick: () => onNodeClick?.(node), children: label }) : onNodeClick && !locked ? /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: interactiveClass, onClick: () => onNodeClick(node), children: label }) : label;
|
|
9156
9196
|
const icon = node.icon ?? (badge ? { name: badge.icon ?? "check", side: "right", tone: badge.tone } : void 0);
|
|
9157
|
-
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box, { "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
|
|
9197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
|
|
9158
9198
|
icon && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(RoadmapBadge, { name: icon.name, tone: icon.tone ?? nodeTone, label: badge?.label ?? icon.name, className: `absolute top-1/2 -translate-y-1/2 ${icon.side === "left" ? "left-0 -translate-x-1/2" : "right-0 translate-x-1/2"}` }),
|
|
9159
9199
|
primary,
|
|
9160
9200
|
node.description && node.kind === "paragraph" && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "mt-2 [overflow-wrap:anywhere]", children: node.description }),
|
|
@@ -9169,15 +9209,17 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
|
|
|
9169
9209
|
// src/components/organisms/roadmap/RoadmapGroup.tsx
|
|
9170
9210
|
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
9171
9211
|
function RoadmapGroupView({ group, testIdPrefix }) {
|
|
9212
|
+
const tone = resolveGroupTone(group);
|
|
9213
|
+
const appearance = tone === "accent" ? { "--c-roadmap-node-bg": "var(--c-roadmap-group-accent-bg)", "--c-roadmap-node-fg": "var(--c-roadmap-group-accent-fg)" } : toneStyle(tone);
|
|
9172
9214
|
return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(import_jsx_runtime67.Fragment, { children: groupColumnRuns(group).map((run, index) => /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)(
|
|
9173
9215
|
"div",
|
|
9174
9216
|
{
|
|
9175
9217
|
"data-testid": `${testIdPrefix}-group`,
|
|
9176
9218
|
"data-group-id": group.id,
|
|
9177
|
-
style: {
|
|
9219
|
+
style: { borderColor: "var(--c-roadmap-border)", ...appearance, gridColumn: `${run.start} / span ${run.span}`, gridRow: `${group.from + 1} / span ${group.to - group.from + 1}` },
|
|
9178
9220
|
className: "pointer-events-none relative z-0 min-w-0 self-stretch rounded-[var(--radius)] border-2 border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)] text-[var(--c-roadmap-node-fg)]",
|
|
9179
9221
|
children: [
|
|
9180
|
-
index === 0 && group.title && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "absolute left-2 right-2 top-0 -translate-y-1/2 text-xs leading-normal", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "bg-[var(--c-roadmap-surface)] px-1 [
|
|
9222
|
+
index === 0 && group.title && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { title: group.title, className: "absolute left-2 right-2 top-0 -translate-y-1/2 text-xs leading-normal", children: /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "inline-block max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-[var(--c-roadmap-surface)] px-1 align-top text-[var(--c-roadmap-neutral-fg)]", children: group.title }) }),
|
|
9181
9223
|
index === 0 && group.description && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "sr-only", children: group.description })
|
|
9182
9224
|
]
|
|
9183
9225
|
},
|
|
@@ -9185,49 +9227,164 @@ function RoadmapGroupView({ group, testIdPrefix }) {
|
|
|
9185
9227
|
)) });
|
|
9186
9228
|
}
|
|
9187
9229
|
|
|
9188
|
-
// src/components/organisms/roadmap/
|
|
9230
|
+
// src/components/organisms/roadmap/RoadmapEdgeLayer.tsx
|
|
9231
|
+
var import_react7 = require("react");
|
|
9189
9232
|
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
9190
|
-
function
|
|
9191
|
-
const
|
|
9192
|
-
const
|
|
9233
|
+
function Edge({ edge, path, instance, prefix }) {
|
|
9234
|
+
const pathRef = (0, import_react7.useRef)(null);
|
|
9235
|
+
const [midpoint, setMidpoint] = (0, import_react7.useState)();
|
|
9236
|
+
(0, import_react7.useLayoutEffect)(() => {
|
|
9237
|
+
const element = pathRef.current;
|
|
9238
|
+
if (edge.label && element?.getTotalLength && path.d) {
|
|
9239
|
+
const p = element.getPointAtLength(element.getTotalLength() / 2);
|
|
9240
|
+
setMidpoint({ x: p.x, y: p.y });
|
|
9241
|
+
} else setMidpoint(void 0);
|
|
9242
|
+
}, [path.d, edge.label]);
|
|
9243
|
+
const arrow = resolveEdgeArrow(edge), style = resolveEdgeStyle(edge);
|
|
9244
|
+
const marker = `${instance}-${edge.id}`;
|
|
9245
|
+
const color = edge.tone ? `var(--c-roadmap-${edge.tone}-edge)` : "var(--c-roadmap-edge)";
|
|
9246
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("g", { style: { color }, "data-roadmap-edge": edge.id, children: [
|
|
9247
|
+
arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("marker", { id: marker, viewBox: "0 0 8 8", refX: "8", refY: "4", markerWidth: "8", markerHeight: "8", markerUnits: "userSpaceOnUse", orient: "auto-start-reverse", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("path", { d: "M 0 0 L 8 4 L 0 8 Z", fill: "currentColor" }) }) }),
|
|
9248
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
9249
|
+
"path",
|
|
9250
|
+
{
|
|
9251
|
+
ref: pathRef,
|
|
9252
|
+
"data-testid": `${prefix}-edge`,
|
|
9253
|
+
"data-edge-id": edge.id,
|
|
9254
|
+
"data-source": edge.source,
|
|
9255
|
+
"data-target": edge.target,
|
|
9256
|
+
d: path.d,
|
|
9257
|
+
fill: "none",
|
|
9258
|
+
stroke: "currentColor",
|
|
9259
|
+
strokeLinecap: "round",
|
|
9260
|
+
strokeLinejoin: "round",
|
|
9261
|
+
strokeDasharray: style === "solid" ? void 0 : style === "dotted" ? "0.8 4" : "0.8 8",
|
|
9262
|
+
className: "[stroke-width:2px] md:[stroke-width:3px]",
|
|
9263
|
+
markerStart: arrow === "both" ? `url(#${marker})` : void 0,
|
|
9264
|
+
markerEnd: arrow !== "none" ? `url(#${marker})` : void 0
|
|
9265
|
+
}
|
|
9266
|
+
),
|
|
9267
|
+
edge.label && midpoint && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("foreignObject", { "data-testid": `${prefix}-edge-label`, "data-edge-id": edge.id, x: midpoint.x, y: midpoint.y, width: "1", height: "1", overflow: "visible", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
|
|
9268
|
+
"div",
|
|
9269
|
+
{
|
|
9270
|
+
className: "w-max max-w-[160px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-[var(--c-roadmap-edge-label-bg)] px-2 py-0.5 text-center text-xs leading-normal text-[var(--c-roadmap-edge-label-fg)] [overflow-wrap:anywhere]",
|
|
9271
|
+
style: { boxShadow: "0 0 0 2px var(--c-roadmap-surface)" },
|
|
9272
|
+
children: edge.label
|
|
9273
|
+
}
|
|
9274
|
+
) })
|
|
9275
|
+
] });
|
|
9276
|
+
}
|
|
9277
|
+
function RoadmapEdgeLayer({ containerRef, document: documentModel, testIdPrefix, debugPerf }) {
|
|
9278
|
+
const instance = `roadmap-${(0, import_react7.useId)().replace(/:/g, "")}`;
|
|
9279
|
+
const [measured, setMeasured] = (0, import_react7.useState)([]);
|
|
9280
|
+
(0, import_react7.useEffect)(() => {
|
|
9281
|
+
const container = containerRef.current;
|
|
9282
|
+
if (!container || !documentModel.edges.length) {
|
|
9283
|
+
setMeasured([]);
|
|
9284
|
+
return;
|
|
9285
|
+
}
|
|
9286
|
+
let disposed = false, frame = 0;
|
|
9287
|
+
const observed = /* @__PURE__ */ new Set();
|
|
9288
|
+
const measure = () => {
|
|
9289
|
+
frame = 0;
|
|
9290
|
+
if (disposed) return;
|
|
9291
|
+
const started = performance.now();
|
|
9292
|
+
const root = container.getBoundingClientRect();
|
|
9293
|
+
const boxes = /* @__PURE__ */ new Map();
|
|
9294
|
+
for (const wrapper of container.querySelectorAll("[data-roadmap-node]")) {
|
|
9295
|
+
if (wrapper.closest("[data-roadmap-grid]") !== container) continue;
|
|
9296
|
+
const id = wrapper.dataset.roadmapNode;
|
|
9297
|
+
const border = Array.from(wrapper.querySelectorAll("[data-roadmap-node-box]")).find((el) => el.dataset.roadmapNodeBox === id);
|
|
9298
|
+
const element = border ?? wrapper.firstElementChild ?? wrapper;
|
|
9299
|
+
for (const target of [wrapper, element]) if (!observed.has(target)) {
|
|
9300
|
+
observer?.observe(target);
|
|
9301
|
+
observed.add(target);
|
|
9302
|
+
}
|
|
9303
|
+
const rect = element.getBoundingClientRect();
|
|
9304
|
+
boxes.set(id, { left: rect.left - root.left, right: rect.right - root.left, top: rect.top - root.top, bottom: rect.bottom - root.top });
|
|
9305
|
+
}
|
|
9306
|
+
for (const element of observed) if (!container.contains(element)) {
|
|
9307
|
+
observer?.unobserve(element);
|
|
9308
|
+
observed.delete(element);
|
|
9309
|
+
}
|
|
9310
|
+
const obstacles = [...boxes.values()];
|
|
9311
|
+
const next = documentModel.edges.flatMap((edge) => {
|
|
9312
|
+
const source = boxes.get(edge.source), target = boxes.get(edge.target);
|
|
9313
|
+
return source && target ? [{ edge, path: routeEdge(source, target, edge, obstacles) }] : [];
|
|
9314
|
+
});
|
|
9315
|
+
setMeasured(next);
|
|
9316
|
+
if (debugPerf) performance.measure("roadmap:edges", { start: started, end: performance.now() });
|
|
9317
|
+
};
|
|
9318
|
+
const schedule = () => {
|
|
9319
|
+
if (!disposed && !frame) frame = requestAnimationFrame(measure);
|
|
9320
|
+
};
|
|
9321
|
+
const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule);
|
|
9322
|
+
observer?.observe(container);
|
|
9323
|
+
const mutations = new MutationObserver((records) => {
|
|
9324
|
+
if (records.some((record) => (record.target instanceof Element ? record.target : record.target.parentElement)?.closest("[data-roadmap-node]"))) schedule();
|
|
9325
|
+
});
|
|
9326
|
+
mutations.observe(container, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
9327
|
+
const fonts = container.ownerDocument.fonts;
|
|
9328
|
+
fonts?.ready.then(schedule);
|
|
9329
|
+
fonts?.addEventListener("loadingdone", schedule);
|
|
9330
|
+
schedule();
|
|
9331
|
+
return () => {
|
|
9332
|
+
disposed = true;
|
|
9333
|
+
cancelAnimationFrame(frame);
|
|
9334
|
+
observer?.disconnect();
|
|
9335
|
+
mutations.disconnect();
|
|
9336
|
+
fonts?.removeEventListener("loadingdone", schedule);
|
|
9337
|
+
};
|
|
9338
|
+
}, [containerRef, documentModel, debugPerf]);
|
|
9339
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
|
|
9340
|
+
}
|
|
9341
|
+
|
|
9342
|
+
// src/components/organisms/roadmap/Roadmap.tsx
|
|
9343
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
9344
|
+
function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf }) {
|
|
9345
|
+
const gridRef = (0, import_react8.useRef)(null);
|
|
9346
|
+
const { placements } = (0, import_react8.useMemo)(() => placeNodes(document2), [document2]);
|
|
9347
|
+
const badges = (0, import_react8.useMemo)(() => new Map(document2.legend?.entries.map((entry) => [entry.id, entry])), [document2.legend]);
|
|
9193
9348
|
const legendPlacement = document2.legend ? resolveLegendPlacement(document2.legend) : void 0;
|
|
9194
|
-
const legend = document2.legend && /* @__PURE__ */ (0,
|
|
9195
|
-
return /* @__PURE__ */ (0,
|
|
9196
|
-
legendPlacement === "top" && /* @__PURE__ */ (0,
|
|
9197
|
-
/* @__PURE__ */ (0,
|
|
9198
|
-
|
|
9349
|
+
const legend = document2.legend && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapLegendView, { legend: document2.legend, testIdPrefix });
|
|
9350
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", className: `min-w-0 bg-[var(--c-roadmap-surface)] p-3 text-[var(--c-roadmap-neutral-fg)] ${className}`, children: [
|
|
9351
|
+
legendPlacement === "top" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "mb-6", children: legend }),
|
|
9352
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-3 gap-y-2 md:gap-x-8", children: [
|
|
9353
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapEdgeLayer, { containerRef: gridRef, document: document2, testIdPrefix, debugPerf }),
|
|
9354
|
+
document2.groups.map((group) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapGroupView, { group, testIdPrefix }, group.id)),
|
|
9199
9355
|
placements.map(({ node, row, column }) => {
|
|
9200
9356
|
const resolvedState = resolveNodeState(node, state);
|
|
9201
|
-
return /* @__PURE__ */ (0,
|
|
9357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(
|
|
9202
9358
|
"div",
|
|
9203
9359
|
{
|
|
9204
9360
|
role: "listitem",
|
|
9205
9361
|
"data-testid": `${testIdPrefix}-node`,
|
|
9206
9362
|
"data-node-id": node.id,
|
|
9363
|
+
"data-roadmap-node": node.id,
|
|
9207
9364
|
"data-state": resolvedState,
|
|
9208
9365
|
style: { gridColumn: `${column.start} / span ${column.span}`, gridRow: `${row.start} / span 1` },
|
|
9209
|
-
className: "relative z-10 min-w-0 px-2 py-
|
|
9210
|
-
children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */ (0,
|
|
9366
|
+
className: "relative z-10 min-w-0 px-2 py-2",
|
|
9367
|
+
children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(RoadmapNodeView, { node, state: resolvedState, badge: node.badge ? badges.get(node.badge) : void 0, onNodeClick, onAction, testIdPrefix })
|
|
9211
9368
|
},
|
|
9212
9369
|
node.id
|
|
9213
9370
|
);
|
|
9214
9371
|
})
|
|
9215
9372
|
] }),
|
|
9216
|
-
legendPlacement === "bottom" && /* @__PURE__ */ (0,
|
|
9373
|
+
legendPlacement === "bottom" && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "mt-6", children: legend })
|
|
9217
9374
|
] });
|
|
9218
9375
|
}
|
|
9219
9376
|
|
|
9220
9377
|
// src/hooks/use-iframe-auth.ts
|
|
9221
|
-
var
|
|
9378
|
+
var import_react9 = require("react");
|
|
9222
9379
|
function useIframeAuth() {
|
|
9223
|
-
const ctx = (0,
|
|
9380
|
+
const ctx = (0, import_react9.useContext)(IframeContext);
|
|
9224
9381
|
return { token: ctx.token, userId: ctx.userId, ready: ctx.ready };
|
|
9225
9382
|
}
|
|
9226
9383
|
|
|
9227
9384
|
// src/hooks/use-iframe-navigate.ts
|
|
9228
|
-
var
|
|
9385
|
+
var import_react10 = require("react");
|
|
9229
9386
|
function useIframeNavigate() {
|
|
9230
|
-
return (0,
|
|
9387
|
+
return (0, import_react10.useCallback)((path) => {
|
|
9231
9388
|
if (!window.parent || window.parent === window) return;
|
|
9232
9389
|
window.parent.postMessage(
|
|
9233
9390
|
{ type: "DFL_NAVIGATE", path },
|
|
@@ -9237,9 +9394,9 @@ function useIframeNavigate() {
|
|
|
9237
9394
|
}
|
|
9238
9395
|
|
|
9239
9396
|
// src/providers/feature-flag-provider.tsx
|
|
9240
|
-
var
|
|
9241
|
-
var
|
|
9242
|
-
var FeatureFlagContext = (0,
|
|
9397
|
+
var import_react11 = require("react");
|
|
9398
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
9399
|
+
var FeatureFlagContext = (0, import_react11.createContext)({
|
|
9243
9400
|
flags: {},
|
|
9244
9401
|
isEnabled: () => false
|
|
9245
9402
|
});
|
|
@@ -9247,21 +9404,21 @@ var FeatureFlagProvider = ({
|
|
|
9247
9404
|
children,
|
|
9248
9405
|
flags
|
|
9249
9406
|
}) => {
|
|
9250
|
-
const value = (0,
|
|
9407
|
+
const value = (0, import_react11.useMemo)(
|
|
9251
9408
|
() => ({
|
|
9252
9409
|
flags,
|
|
9253
9410
|
isEnabled: (flag) => Boolean(flags[flag])
|
|
9254
9411
|
}),
|
|
9255
9412
|
[flags]
|
|
9256
9413
|
);
|
|
9257
|
-
return /* @__PURE__ */ (0,
|
|
9414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(FeatureFlagContext.Provider, { value, children });
|
|
9258
9415
|
};
|
|
9259
9416
|
var useFeatureFlag = (flag) => {
|
|
9260
|
-
const { isEnabled } = (0,
|
|
9417
|
+
const { isEnabled } = (0, import_react11.useContext)(FeatureFlagContext);
|
|
9261
9418
|
return isEnabled(flag);
|
|
9262
9419
|
};
|
|
9263
9420
|
var useFeatureFlags = () => {
|
|
9264
|
-
const { flags } = (0,
|
|
9421
|
+
const { flags } = (0, import_react11.useContext)(FeatureFlagContext);
|
|
9265
9422
|
return flags;
|
|
9266
9423
|
};
|
|
9267
9424
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.d.cts
CHANGED
|
@@ -3268,11 +3268,12 @@ interface RoadmapProps {
|
|
|
3268
3268
|
renderNode?: (node: RoadmapNode, state: RoadmapNodeState) => ReactNode;
|
|
3269
3269
|
onNodeClick?: (node: RoadmapNode) => void;
|
|
3270
3270
|
onAction?: (actionId: string, node: RoadmapNode) => void;
|
|
3271
|
+
debugPerf?: boolean;
|
|
3271
3272
|
testIdPrefix?: string;
|
|
3272
3273
|
className?: string;
|
|
3273
3274
|
ariaLabel?: string;
|
|
3274
3275
|
}
|
|
3275
3276
|
/** Dark-only, ordinary document scroll. The JSON owns placement; CSS owns the pixels. */
|
|
3276
|
-
declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel }: RoadmapProps): React__default.JSX.Element;
|
|
3277
|
+
declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf }: RoadmapProps): React__default.JSX.Element;
|
|
3277
3278
|
|
|
3278
3279
|
export { ALLOWED_ORIGINS, AVATAR_MEMBER_PALETTE_SIZE, Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, type AlertDialogActionProps, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppNavbar, type AppNavbarProps, AppSidebar, type AppSidebarProps, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, AvatarStatus, type AvatarStatusValue, type AvatarTone, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, type BreadcrumbEntry, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleHeader, CollapsibleItem, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_EDGE_ARROW, DEFAULT_EDGE_ROUTE, DEFAULT_EDGE_STYLE, DEFAULT_GROUP_TONE, DEFAULT_LEGEND_PLACEMENT, DEFAULT_NAME_COL_WIDTH, DEFAULT_NODE_SPAN, DEFAULT_NODE_STATE, type DflIframeMessage, type DflNavigateMessage, type DflReadyMessage, DflRemote, type DflRemoteProps, type DflResizeMessage, type DflSetTokenMessage, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gantt, type GanttDependency, type GanttMilestone, type GanttProps, type GanttStage, HoverCard, HoverCardContent, HoverCardTrigger, IconButton, type IconButtonProps, IframeAware, type IframeAwareProps, IframeContext, type IframeContextValue, type IframeMessageType, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, type KbdProps, Label, LoginPage, type LoginPageProps, LoginScreen, type LoginScreenProps, MEMBER_PALETTE_SIZE, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NODE_KIND_DEFAULT_TONE, type NavGroup, type NavItem, type NavbarUserInfo, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type OTPStatus, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, type PasswordInputProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, type ProgressProps, ProtectedRoute, type ProtectedRouteProps, PublishDrawer, type PublishDrawerProps, type PublishDrawerSupabase, type PublishResult, type PublishStatus, type PublisherAccount, ROADMAP_ARROWS, ROADMAP_COLUMNS, ROADMAP_EDGE_LABEL_MAX, ROADMAP_EDGE_ROUTES, ROADMAP_EDGE_STYLES, ROADMAP_LABEL_MAX, ROADMAP_LEGEND_PLACEMENTS, ROADMAP_NODE_ID_PATTERN, ROADMAP_NODE_KINDS, ROADMAP_NODE_STATES, ROADMAP_TONES, RadioGroup, RadioGroupItem, RadioGroupRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, Roadmap, type RoadmapAction, type RoadmapArrow, type RoadmapColumn, type RoadmapDocument, type RoadmapEdge, type RoadmapEdgeRoute, type RoadmapEdgeStyle, type RoadmapGroup, type RoadmapGroupRange, type RoadmapIcon, type RoadmapLegend, type RoadmapLegendEntry, type RoadmapLegendPlacement, type RoadmapLink, type RoadmapNode, type RoadmapNodeKind, type RoadmapNodeState, type RoadmapOverlap, type RoadmapPlacement, type RoadmapProps, type RoadmapStateOverlay, type RoadmapTone, ScrollArea, type ScrollAreaScrollbars, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeparatorWithLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toast, ToastAction, type ToastActionElement, ToastClose, type ToastComponentProps, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatar, type UserAvatarProps, type UserInfo, UserMenu, type UserMenuItem, type UserMenuProps, avatarMemberColor, badgeVariants, barGridColumn, buttonVariants, clampPct, columnIndex, columnsCovered, columnsUsed, filterPublishableAccounts, firstFreeRow, getInitials, gridColumnFor, groupColumnRuns, groupRanges, iconButtonVariants, isAllowedOrigin, kbdVariants, labelVariants, maxRowOf, memberHueIndex, memberHueVar, navigationMenuTriggerStyle, nodesByRow, parseRoadmapDocument, parseRoadmapStateOverlay, parseTags, placeNodes, resolveEdgeArrow, resolveEdgeRoute, resolveEdgeStyle, resolveGroupColumns, resolveGroupTone, resolveLegendPlacement, resolveNameColWidth, resolveNodeSpan, resolveNodeState, resolveNodeTone, resolveWeekCount, resolveWeekLabels, roadmapActionSchema, roadmapDocumentSchema, roadmapEdgeSchema, roadmapGroupSchema, roadmapIconSchema, roadmapLegendEntrySchema, roadmapLegendSchema, roadmapLinkSchema, roadmapNodeSchema, roadmapNodeStateSchema, roadmapStateOverlaySchema, roadmapStateSchema, rowsOf, safeParseRoadmapDocument, safeParseRoadmapStateOverlay, stageProgress, toggleVariants, useFormField, useSidebar, validateNoOverlap, validatePublishForm };
|
package/dist/index.d.ts
CHANGED
|
@@ -3268,11 +3268,12 @@ interface RoadmapProps {
|
|
|
3268
3268
|
renderNode?: (node: RoadmapNode, state: RoadmapNodeState) => ReactNode;
|
|
3269
3269
|
onNodeClick?: (node: RoadmapNode) => void;
|
|
3270
3270
|
onAction?: (actionId: string, node: RoadmapNode) => void;
|
|
3271
|
+
debugPerf?: boolean;
|
|
3271
3272
|
testIdPrefix?: string;
|
|
3272
3273
|
className?: string;
|
|
3273
3274
|
ariaLabel?: string;
|
|
3274
3275
|
}
|
|
3275
3276
|
/** Dark-only, ordinary document scroll. The JSON owns placement; CSS owns the pixels. */
|
|
3276
|
-
declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel }: RoadmapProps): React__default.JSX.Element;
|
|
3277
|
+
declare function Roadmap({ document, state, renderNode, onNodeClick, onAction, testIdPrefix, className, ariaLabel, debugPerf }: RoadmapProps): React__default.JSX.Element;
|
|
3277
3278
|
|
|
3278
3279
|
export { ALLOWED_ORIGINS, AVATAR_MEMBER_PALETTE_SIZE, Accordion, AccordionContent, AccordionItem, AccordionTrigger, Alert, AlertDescription, AlertDialog, AlertDialogAction, type AlertDialogActionProps, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppNavbar, type AppNavbarProps, AppSidebar, type AppSidebarProps, AspectRatio, Avatar, AvatarFallback, AvatarGroup, AvatarImage, type AvatarSize, AvatarStatus, type AvatarStatusValue, type AvatarTone, Badge, type BadgeProps, Breadcrumb, BreadcrumbEllipsis, type BreadcrumbEntry, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator, Button, type ButtonProps, Calendar, type CalendarProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Carousel, type CarouselApi, CarouselContent, CarouselDots, CarouselItem, CarouselNext, CarouselPrevious, type ChartConfig, ChartContainer, ChartLegend, ChartLegendContent, ChartStyle, ChartTooltip, ChartTooltipContent, Checkbox, Collapsible, CollapsibleContent, CollapsibleHeader, CollapsibleItem, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, ConfirmDialog, type ConfirmDialogProps, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuPortal, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuShortcut, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, DEFAULT_EDGE_ARROW, DEFAULT_EDGE_ROUTE, DEFAULT_EDGE_STYLE, DEFAULT_GROUP_TONE, DEFAULT_LEGEND_PLACEMENT, DEFAULT_NAME_COL_WIDTH, DEFAULT_NODE_SPAN, DEFAULT_NODE_STATE, type DflIframeMessage, type DflNavigateMessage, type DflReadyMessage, DflRemote, type DflRemoteProps, type DflResizeMessage, type DflSetTokenMessage, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, Gantt, type GanttDependency, type GanttMilestone, type GanttProps, type GanttStage, HoverCard, HoverCardContent, HoverCardTrigger, IconButton, type IconButtonProps, IframeAware, type IframeAwareProps, IframeContext, type IframeContextValue, type IframeMessageType, Input, InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, Kbd, type KbdProps, Label, LoginPage, type LoginPageProps, LoginScreen, type LoginScreenProps, MEMBER_PALETTE_SIZE, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarPortal, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarShortcut, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, NODE_KIND_DEFAULT_TONE, type NavGroup, type NavItem, type NavbarUserInfo, NavigationMenu, NavigationMenuContent, NavigationMenuIndicator, NavigationMenuItem, NavigationMenuLink, NavigationMenuList, NavigationMenuTrigger, NavigationMenuViewport, type OTPStatus, Pagination, PaginationContent, PaginationEllipsis, PaginationItem, PaginationLink, PaginationNext, PaginationPrevious, PasswordInput, type PasswordInputProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, Progress, type ProgressProps, ProtectedRoute, type ProtectedRouteProps, PublishDrawer, type PublishDrawerProps, type PublishDrawerSupabase, type PublishResult, type PublishStatus, type PublisherAccount, ROADMAP_ARROWS, ROADMAP_COLUMNS, ROADMAP_EDGE_LABEL_MAX, ROADMAP_EDGE_ROUTES, ROADMAP_EDGE_STYLES, ROADMAP_LABEL_MAX, ROADMAP_LEGEND_PLACEMENTS, ROADMAP_NODE_ID_PATTERN, ROADMAP_NODE_KINDS, ROADMAP_NODE_STATES, ROADMAP_TONES, RadioGroup, RadioGroupItem, RadioGroupRow, ResizableHandle, ResizablePanel, ResizablePanelGroup, Roadmap, type RoadmapAction, type RoadmapArrow, type RoadmapColumn, type RoadmapDocument, type RoadmapEdge, type RoadmapEdgeRoute, type RoadmapEdgeStyle, type RoadmapGroup, type RoadmapGroupRange, type RoadmapIcon, type RoadmapLegend, type RoadmapLegendEntry, type RoadmapLegendPlacement, type RoadmapLink, type RoadmapNode, type RoadmapNodeKind, type RoadmapNodeState, type RoadmapOverlap, type RoadmapPlacement, type RoadmapProps, type RoadmapStateOverlay, type RoadmapTone, ScrollArea, type ScrollAreaScrollbars, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, SeparatorWithLabel, Sheet, SheetClose, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetOverlay, SheetPortal, SheetTitle, SheetTrigger, Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, Skeleton, Slider, SonnerToaster, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, type TextareaProps, Toast, ToastAction, type ToastActionElement, ToastClose, type ToastComponentProps, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserAvatar, type UserAvatarProps, type UserInfo, UserMenu, type UserMenuItem, type UserMenuProps, avatarMemberColor, badgeVariants, barGridColumn, buttonVariants, clampPct, columnIndex, columnsCovered, columnsUsed, filterPublishableAccounts, firstFreeRow, getInitials, gridColumnFor, groupColumnRuns, groupRanges, iconButtonVariants, isAllowedOrigin, kbdVariants, labelVariants, maxRowOf, memberHueIndex, memberHueVar, navigationMenuTriggerStyle, nodesByRow, parseRoadmapDocument, parseRoadmapStateOverlay, parseTags, placeNodes, resolveEdgeArrow, resolveEdgeRoute, resolveEdgeStyle, resolveGroupColumns, resolveGroupTone, resolveLegendPlacement, resolveNameColWidth, resolveNodeSpan, resolveNodeState, resolveNodeTone, resolveWeekCount, resolveWeekLabels, roadmapActionSchema, roadmapDocumentSchema, roadmapEdgeSchema, roadmapGroupSchema, roadmapIconSchema, roadmapLegendEntrySchema, roadmapLegendSchema, roadmapLinkSchema, roadmapNodeSchema, roadmapNodeStateSchema, roadmapStateOverlaySchema, roadmapStateSchema, rowsOf, safeParseRoadmapDocument, safeParseRoadmapStateOverlay, stageProgress, toggleVariants, useFormField, useSidebar, validateNoOverlap, validatePublishForm };
|
package/dist/index.js
CHANGED
|
@@ -8715,9 +8715,49 @@ function firstFreeRow(taken, columns, from) {
|
|
|
8715
8715
|
}
|
|
8716
8716
|
return row;
|
|
8717
8717
|
}
|
|
8718
|
+
var pointText = (p) => `${p.x} ${p.y}`;
|
|
8719
|
+
var center = (r) => ({ x: (r.left + r.right) / 2, y: (r.top + r.bottom) / 2 });
|
|
8720
|
+
function segmentHits(a, b, r) {
|
|
8721
|
+
return a.x === b.x ? a.x > r.left && a.x < r.right && Math.max(a.y, b.y) > r.top && Math.min(a.y, b.y) < r.bottom : a.y > r.top && a.y < r.bottom && Math.max(a.x, b.x) > r.left && Math.min(a.x, b.x) < r.right;
|
|
8722
|
+
}
|
|
8723
|
+
function routeEdge(source, target, edge, obstacles = []) {
|
|
8724
|
+
const a = center(source), b = center(target);
|
|
8725
|
+
const sameColumn = Math.abs(a.x - b.x) < 1;
|
|
8726
|
+
const vertical = sameColumn || source.left < target.right && target.left < source.right;
|
|
8727
|
+
const down = b.y >= a.y, right = b.x >= a.x;
|
|
8728
|
+
const start = vertical ? { x: a.x, y: down ? source.bottom : source.top } : { x: right ? source.right : source.left, y: a.y };
|
|
8729
|
+
const end = vertical ? { x: b.x, y: down ? target.top : target.bottom } : { x: right ? target.left : target.right, y: b.y };
|
|
8730
|
+
const route = edge.route ?? "auto";
|
|
8731
|
+
if (route === "straight" || route === "auto" && sameColumn) return { start, end, d: `M ${pointText(start)} L ${pointText(end)}` };
|
|
8732
|
+
if (route !== "elbow") {
|
|
8733
|
+
const mid = vertical ? (start.y + end.y) / 2 : (start.x + end.x) / 2;
|
|
8734
|
+
const c1 = vertical ? { x: start.x, y: mid } : { x: mid, y: start.y };
|
|
8735
|
+
const c2 = vertical ? { x: end.x, y: mid } : { x: mid, y: end.y };
|
|
8736
|
+
return { start, end, d: `M ${pointText(start)} C ${pointText(c1)} ${pointText(c2)} ${pointText(end)}` };
|
|
8737
|
+
}
|
|
8738
|
+
const boxes = [.../* @__PURE__ */ new Set([source, target, ...obstacles])];
|
|
8739
|
+
const clearance = 4;
|
|
8740
|
+
const ys = [...new Set(boxes.flatMap((r) => [r.top - clearance, r.bottom + clearance]))];
|
|
8741
|
+
let best, bestLength = Infinity;
|
|
8742
|
+
for (const sx of [source.left, source.right]) for (const tx of [target.left, target.right]) {
|
|
8743
|
+
const s = { x: sx, y: a.y }, t = { x: tx, y: b.y };
|
|
8744
|
+
const gx = sx + (sx === source.left ? -clearance : clearance);
|
|
8745
|
+
const hx = tx + (tx === target.left ? -clearance : clearance);
|
|
8746
|
+
for (const y of [a.y, b.y, ...ys]) {
|
|
8747
|
+
const points2 = [s, { x: gx, y: a.y }, { x: gx, y }, { x: hx, y }, { x: hx, y: b.y }, t];
|
|
8748
|
+
const length = points2.slice(1).reduce((sum, p, i) => sum + Math.abs(p.x - points2[i].x) + Math.abs(p.y - points2[i].y), 0);
|
|
8749
|
+
if (length >= bestLength || points2.slice(1).some((p, i) => boxes.some((r) => segmentHits(points2[i], p, r)))) continue;
|
|
8750
|
+
best = points2;
|
|
8751
|
+
bestLength = length;
|
|
8752
|
+
}
|
|
8753
|
+
}
|
|
8754
|
+
if (!best) return { start, end, d: "" };
|
|
8755
|
+
const points = best.filter((p, i) => i === 0 || p.x !== best[i - 1].x || p.y !== best[i - 1].y);
|
|
8756
|
+
return { start: points[0], end: points[points.length - 1], points, d: points.map((p, i) => `${i ? "L" : "M"} ${pointText(p)}`).join(" ") };
|
|
8757
|
+
}
|
|
8718
8758
|
|
|
8719
8759
|
// src/components/organisms/roadmap/Roadmap.tsx
|
|
8720
|
-
import { useMemo as useMemo5 } from "react";
|
|
8760
|
+
import { useMemo as useMemo5, useRef as useRef6 } from "react";
|
|
8721
8761
|
|
|
8722
8762
|
// src/components/organisms/roadmap/RoadmapNode.tsx
|
|
8723
8763
|
import { cva as cva14 } from "class-variance-authority";
|
|
@@ -8765,7 +8805,7 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
|
|
|
8765
8805
|
const Box = wholeBox && node.href ? "a" : wholeBox && onNodeClick ? "button" : "div";
|
|
8766
8806
|
const primary = Box !== "div" ? label : node.href && !locked ? /* @__PURE__ */ jsx66("a", { href: node.href, className: interactiveClass, onClick: () => onNodeClick?.(node), children: label }) : onNodeClick && !locked ? /* @__PURE__ */ jsx66("button", { type: "button", className: interactiveClass, onClick: () => onNodeClick(node), children: label }) : label;
|
|
8767
8807
|
const icon = node.icon ?? (badge ? { name: badge.icon ?? "check", side: "right", tone: badge.tone } : void 0);
|
|
8768
|
-
return /* @__PURE__ */ jsx66("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ jsxs41(Box, { "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
|
|
8808
|
+
return /* @__PURE__ */ jsx66("div", { style: toneStyle(nodeTone), className: "min-w-0", children: /* @__PURE__ */ jsxs41(Box, { style: { borderColor: node.kind === "title" || node.kind === "label" ? "transparent" : "var(--c-roadmap-border)" }, "data-roadmap-node-box": node.id, href: Box === "a" ? node.href : void 0, type: Box === "button" ? "button" : void 0, onClick: Box !== "div" ? () => onNodeClick?.(node) : void 0, className: `${nodeVariants({ kind: node.kind, state })} w-full ${Box !== "div" ? focusClass : ""}`, "aria-disabled": locked || void 0, title: node.kind === "topic" || node.kind === "subtopic" ? node.description : void 0, children: [
|
|
8769
8809
|
icon && /* @__PURE__ */ jsx66(RoadmapBadge, { name: icon.name, tone: icon.tone ?? nodeTone, label: badge?.label ?? icon.name, className: `absolute top-1/2 -translate-y-1/2 ${icon.side === "left" ? "left-0 -translate-x-1/2" : "right-0 translate-x-1/2"}` }),
|
|
8770
8810
|
primary,
|
|
8771
8811
|
node.description && node.kind === "paragraph" && /* @__PURE__ */ jsx66("p", { className: "mt-2 [overflow-wrap:anywhere]", children: node.description }),
|
|
@@ -8780,15 +8820,17 @@ function RoadmapNodeView({ node, state, badge, testIdPrefix, onNodeClick, onActi
|
|
|
8780
8820
|
// src/components/organisms/roadmap/RoadmapGroup.tsx
|
|
8781
8821
|
import { Fragment as Fragment10, jsx as jsx67, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
8782
8822
|
function RoadmapGroupView({ group, testIdPrefix }) {
|
|
8823
|
+
const tone = resolveGroupTone(group);
|
|
8824
|
+
const appearance = tone === "accent" ? { "--c-roadmap-node-bg": "var(--c-roadmap-group-accent-bg)", "--c-roadmap-node-fg": "var(--c-roadmap-group-accent-fg)" } : toneStyle(tone);
|
|
8783
8825
|
return /* @__PURE__ */ jsx67(Fragment10, { children: groupColumnRuns(group).map((run, index) => /* @__PURE__ */ jsxs42(
|
|
8784
8826
|
"div",
|
|
8785
8827
|
{
|
|
8786
8828
|
"data-testid": `${testIdPrefix}-group`,
|
|
8787
8829
|
"data-group-id": group.id,
|
|
8788
|
-
style: {
|
|
8830
|
+
style: { borderColor: "var(--c-roadmap-border)", ...appearance, gridColumn: `${run.start} / span ${run.span}`, gridRow: `${group.from + 1} / span ${group.to - group.from + 1}` },
|
|
8789
8831
|
className: "pointer-events-none relative z-0 min-w-0 self-stretch rounded-[var(--radius)] border-2 border-[var(--c-roadmap-border)] bg-[var(--c-roadmap-node-bg)] text-[var(--c-roadmap-node-fg)]",
|
|
8790
8832
|
children: [
|
|
8791
|
-
index === 0 && group.title && /* @__PURE__ */ jsx67("span", { className: "absolute left-2 right-2 top-0 -translate-y-1/2 text-xs leading-normal", children: /* @__PURE__ */ jsx67("span", { className: "bg-[var(--c-roadmap-surface)] px-1 [
|
|
8833
|
+
index === 0 && group.title && /* @__PURE__ */ jsx67("span", { title: group.title, className: "absolute left-2 right-2 top-0 -translate-y-1/2 text-xs leading-normal", children: /* @__PURE__ */ jsx67("span", { className: "inline-block max-w-full overflow-hidden text-ellipsis whitespace-nowrap bg-[var(--c-roadmap-surface)] px-1 align-top text-[var(--c-roadmap-neutral-fg)]", children: group.title }) }),
|
|
8792
8834
|
index === 0 && group.description && /* @__PURE__ */ jsx67("span", { className: "sr-only", children: group.description })
|
|
8793
8835
|
]
|
|
8794
8836
|
},
|
|
@@ -8796,35 +8838,150 @@ function RoadmapGroupView({ group, testIdPrefix }) {
|
|
|
8796
8838
|
)) });
|
|
8797
8839
|
}
|
|
8798
8840
|
|
|
8799
|
-
// src/components/organisms/roadmap/
|
|
8841
|
+
// src/components/organisms/roadmap/RoadmapEdgeLayer.tsx
|
|
8842
|
+
import { useId as useId4, useEffect as useEffect10, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState13 } from "react";
|
|
8800
8843
|
import { jsx as jsx68, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
8801
|
-
function
|
|
8844
|
+
function Edge({ edge, path, instance, prefix }) {
|
|
8845
|
+
const pathRef = useRef5(null);
|
|
8846
|
+
const [midpoint, setMidpoint] = useState13();
|
|
8847
|
+
useLayoutEffect2(() => {
|
|
8848
|
+
const element = pathRef.current;
|
|
8849
|
+
if (edge.label && element?.getTotalLength && path.d) {
|
|
8850
|
+
const p = element.getPointAtLength(element.getTotalLength() / 2);
|
|
8851
|
+
setMidpoint({ x: p.x, y: p.y });
|
|
8852
|
+
} else setMidpoint(void 0);
|
|
8853
|
+
}, [path.d, edge.label]);
|
|
8854
|
+
const arrow = resolveEdgeArrow(edge), style = resolveEdgeStyle(edge);
|
|
8855
|
+
const marker = `${instance}-${edge.id}`;
|
|
8856
|
+
const color = edge.tone ? `var(--c-roadmap-${edge.tone}-edge)` : "var(--c-roadmap-edge)";
|
|
8857
|
+
return /* @__PURE__ */ jsxs43("g", { style: { color }, "data-roadmap-edge": edge.id, children: [
|
|
8858
|
+
arrow !== "none" && /* @__PURE__ */ jsx68("defs", { children: /* @__PURE__ */ jsx68("marker", { id: marker, viewBox: "0 0 8 8", refX: "8", refY: "4", markerWidth: "8", markerHeight: "8", markerUnits: "userSpaceOnUse", orient: "auto-start-reverse", children: /* @__PURE__ */ jsx68("path", { d: "M 0 0 L 8 4 L 0 8 Z", fill: "currentColor" }) }) }),
|
|
8859
|
+
/* @__PURE__ */ jsx68(
|
|
8860
|
+
"path",
|
|
8861
|
+
{
|
|
8862
|
+
ref: pathRef,
|
|
8863
|
+
"data-testid": `${prefix}-edge`,
|
|
8864
|
+
"data-edge-id": edge.id,
|
|
8865
|
+
"data-source": edge.source,
|
|
8866
|
+
"data-target": edge.target,
|
|
8867
|
+
d: path.d,
|
|
8868
|
+
fill: "none",
|
|
8869
|
+
stroke: "currentColor",
|
|
8870
|
+
strokeLinecap: "round",
|
|
8871
|
+
strokeLinejoin: "round",
|
|
8872
|
+
strokeDasharray: style === "solid" ? void 0 : style === "dotted" ? "0.8 4" : "0.8 8",
|
|
8873
|
+
className: "[stroke-width:2px] md:[stroke-width:3px]",
|
|
8874
|
+
markerStart: arrow === "both" ? `url(#${marker})` : void 0,
|
|
8875
|
+
markerEnd: arrow !== "none" ? `url(#${marker})` : void 0
|
|
8876
|
+
}
|
|
8877
|
+
),
|
|
8878
|
+
edge.label && midpoint && /* @__PURE__ */ jsx68("foreignObject", { "data-testid": `${prefix}-edge-label`, "data-edge-id": edge.id, x: midpoint.x, y: midpoint.y, width: "1", height: "1", overflow: "visible", children: /* @__PURE__ */ jsx68(
|
|
8879
|
+
"div",
|
|
8880
|
+
{
|
|
8881
|
+
className: "w-max max-w-[160px] -translate-x-1/2 -translate-y-1/2 rounded-full bg-[var(--c-roadmap-edge-label-bg)] px-2 py-0.5 text-center text-xs leading-normal text-[var(--c-roadmap-edge-label-fg)] [overflow-wrap:anywhere]",
|
|
8882
|
+
style: { boxShadow: "0 0 0 2px var(--c-roadmap-surface)" },
|
|
8883
|
+
children: edge.label
|
|
8884
|
+
}
|
|
8885
|
+
) })
|
|
8886
|
+
] });
|
|
8887
|
+
}
|
|
8888
|
+
function RoadmapEdgeLayer({ containerRef, document: documentModel, testIdPrefix, debugPerf }) {
|
|
8889
|
+
const instance = `roadmap-${useId4().replace(/:/g, "")}`;
|
|
8890
|
+
const [measured, setMeasured] = useState13([]);
|
|
8891
|
+
useEffect10(() => {
|
|
8892
|
+
const container = containerRef.current;
|
|
8893
|
+
if (!container || !documentModel.edges.length) {
|
|
8894
|
+
setMeasured([]);
|
|
8895
|
+
return;
|
|
8896
|
+
}
|
|
8897
|
+
let disposed = false, frame = 0;
|
|
8898
|
+
const observed = /* @__PURE__ */ new Set();
|
|
8899
|
+
const measure = () => {
|
|
8900
|
+
frame = 0;
|
|
8901
|
+
if (disposed) return;
|
|
8902
|
+
const started = performance.now();
|
|
8903
|
+
const root = container.getBoundingClientRect();
|
|
8904
|
+
const boxes = /* @__PURE__ */ new Map();
|
|
8905
|
+
for (const wrapper of container.querySelectorAll("[data-roadmap-node]")) {
|
|
8906
|
+
if (wrapper.closest("[data-roadmap-grid]") !== container) continue;
|
|
8907
|
+
const id = wrapper.dataset.roadmapNode;
|
|
8908
|
+
const border = Array.from(wrapper.querySelectorAll("[data-roadmap-node-box]")).find((el) => el.dataset.roadmapNodeBox === id);
|
|
8909
|
+
const element = border ?? wrapper.firstElementChild ?? wrapper;
|
|
8910
|
+
for (const target of [wrapper, element]) if (!observed.has(target)) {
|
|
8911
|
+
observer?.observe(target);
|
|
8912
|
+
observed.add(target);
|
|
8913
|
+
}
|
|
8914
|
+
const rect = element.getBoundingClientRect();
|
|
8915
|
+
boxes.set(id, { left: rect.left - root.left, right: rect.right - root.left, top: rect.top - root.top, bottom: rect.bottom - root.top });
|
|
8916
|
+
}
|
|
8917
|
+
for (const element of observed) if (!container.contains(element)) {
|
|
8918
|
+
observer?.unobserve(element);
|
|
8919
|
+
observed.delete(element);
|
|
8920
|
+
}
|
|
8921
|
+
const obstacles = [...boxes.values()];
|
|
8922
|
+
const next = documentModel.edges.flatMap((edge) => {
|
|
8923
|
+
const source = boxes.get(edge.source), target = boxes.get(edge.target);
|
|
8924
|
+
return source && target ? [{ edge, path: routeEdge(source, target, edge, obstacles) }] : [];
|
|
8925
|
+
});
|
|
8926
|
+
setMeasured(next);
|
|
8927
|
+
if (debugPerf) performance.measure("roadmap:edges", { start: started, end: performance.now() });
|
|
8928
|
+
};
|
|
8929
|
+
const schedule = () => {
|
|
8930
|
+
if (!disposed && !frame) frame = requestAnimationFrame(measure);
|
|
8931
|
+
};
|
|
8932
|
+
const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(schedule);
|
|
8933
|
+
observer?.observe(container);
|
|
8934
|
+
const mutations = new MutationObserver((records) => {
|
|
8935
|
+
if (records.some((record) => (record.target instanceof Element ? record.target : record.target.parentElement)?.closest("[data-roadmap-node]"))) schedule();
|
|
8936
|
+
});
|
|
8937
|
+
mutations.observe(container, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
8938
|
+
const fonts = container.ownerDocument.fonts;
|
|
8939
|
+
fonts?.ready.then(schedule);
|
|
8940
|
+
fonts?.addEventListener("loadingdone", schedule);
|
|
8941
|
+
schedule();
|
|
8942
|
+
return () => {
|
|
8943
|
+
disposed = true;
|
|
8944
|
+
cancelAnimationFrame(frame);
|
|
8945
|
+
observer?.disconnect();
|
|
8946
|
+
mutations.disconnect();
|
|
8947
|
+
fonts?.removeEventListener("loadingdone", schedule);
|
|
8948
|
+
};
|
|
8949
|
+
}, [containerRef, documentModel, debugPerf]);
|
|
8950
|
+
return /* @__PURE__ */ jsx68("svg", { "data-testid": `${testIdPrefix}-edges`, "aria-hidden": "true", className: "pointer-events-none absolute inset-0 z-[1] h-full w-full overflow-visible", children: measured.map((item) => /* @__PURE__ */ jsx68(Edge, { ...item, instance, prefix: testIdPrefix }, item.edge.id)) });
|
|
8951
|
+
}
|
|
8952
|
+
|
|
8953
|
+
// src/components/organisms/roadmap/Roadmap.tsx
|
|
8954
|
+
import { jsx as jsx69, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
8955
|
+
function Roadmap({ document: document2, state, renderNode, onNodeClick, onAction, testIdPrefix = "roadmap", className = "", ariaLabel, debugPerf }) {
|
|
8956
|
+
const gridRef = useRef6(null);
|
|
8802
8957
|
const { placements } = useMemo5(() => placeNodes(document2), [document2]);
|
|
8803
8958
|
const badges = useMemo5(() => new Map(document2.legend?.entries.map((entry) => [entry.id, entry])), [document2.legend]);
|
|
8804
8959
|
const legendPlacement = document2.legend ? resolveLegendPlacement(document2.legend) : void 0;
|
|
8805
|
-
const legend = document2.legend && /* @__PURE__ */
|
|
8806
|
-
return /* @__PURE__ */
|
|
8807
|
-
legendPlacement === "top" && /* @__PURE__ */
|
|
8808
|
-
/* @__PURE__ */
|
|
8809
|
-
|
|
8960
|
+
const legend = document2.legend && /* @__PURE__ */ jsx69(RoadmapLegendView, { legend: document2.legend, testIdPrefix });
|
|
8961
|
+
return /* @__PURE__ */ jsxs44("section", { "data-testid": testIdPrefix, "aria-label": ariaLabel ?? document2.title ?? "Roadmap", className: `min-w-0 bg-[var(--c-roadmap-surface)] p-3 text-[var(--c-roadmap-neutral-fg)] ${className}`, children: [
|
|
8962
|
+
legendPlacement === "top" && /* @__PURE__ */ jsx69("div", { className: "mb-6", children: legend }),
|
|
8963
|
+
/* @__PURE__ */ jsxs44("div", { ref: gridRef, "data-roadmap-grid": "", "data-testid": `${testIdPrefix}-grid`, role: "list", "aria-label": "Roadmap nodes", className: "relative isolate grid min-w-0 grid-cols-3 items-center gap-x-3 gap-y-2 md:gap-x-8", children: [
|
|
8964
|
+
/* @__PURE__ */ jsx69(RoadmapEdgeLayer, { containerRef: gridRef, document: document2, testIdPrefix, debugPerf }),
|
|
8965
|
+
document2.groups.map((group) => /* @__PURE__ */ jsx69(RoadmapGroupView, { group, testIdPrefix }, group.id)),
|
|
8810
8966
|
placements.map(({ node, row, column }) => {
|
|
8811
8967
|
const resolvedState = resolveNodeState(node, state);
|
|
8812
|
-
return /* @__PURE__ */
|
|
8968
|
+
return /* @__PURE__ */ jsx69(
|
|
8813
8969
|
"div",
|
|
8814
8970
|
{
|
|
8815
8971
|
role: "listitem",
|
|
8816
8972
|
"data-testid": `${testIdPrefix}-node`,
|
|
8817
8973
|
"data-node-id": node.id,
|
|
8974
|
+
"data-roadmap-node": node.id,
|
|
8818
8975
|
"data-state": resolvedState,
|
|
8819
8976
|
style: { gridColumn: `${column.start} / span ${column.span}`, gridRow: `${row.start} / span 1` },
|
|
8820
|
-
className: "relative z-10 min-w-0 px-2 py-
|
|
8821
|
-
children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */
|
|
8977
|
+
className: "relative z-10 min-w-0 px-2 py-2",
|
|
8978
|
+
children: node.kind === "legend" ? legendPlacement === "inline" ? legend : null : renderNode ? renderNode(node, resolvedState) : /* @__PURE__ */ jsx69(RoadmapNodeView, { node, state: resolvedState, badge: node.badge ? badges.get(node.badge) : void 0, onNodeClick, onAction, testIdPrefix })
|
|
8822
8979
|
},
|
|
8823
8980
|
node.id
|
|
8824
8981
|
);
|
|
8825
8982
|
})
|
|
8826
8983
|
] }),
|
|
8827
|
-
legendPlacement === "bottom" && /* @__PURE__ */
|
|
8984
|
+
legendPlacement === "bottom" && /* @__PURE__ */ jsx69("div", { className: "mt-6", children: legend })
|
|
8828
8985
|
] });
|
|
8829
8986
|
}
|
|
8830
8987
|
|
|
@@ -8853,7 +9010,7 @@ import {
|
|
|
8853
9010
|
useContext as useContext10,
|
|
8854
9011
|
useMemo as useMemo6
|
|
8855
9012
|
} from "react";
|
|
8856
|
-
import { jsx as
|
|
9013
|
+
import { jsx as jsx70 } from "react/jsx-runtime";
|
|
8857
9014
|
var FeatureFlagContext = createContext10({
|
|
8858
9015
|
flags: {},
|
|
8859
9016
|
isEnabled: () => false
|
|
@@ -8869,7 +9026,7 @@ var FeatureFlagProvider = ({
|
|
|
8869
9026
|
}),
|
|
8870
9027
|
[flags]
|
|
8871
9028
|
);
|
|
8872
|
-
return /* @__PURE__ */
|
|
9029
|
+
return /* @__PURE__ */ jsx70(FeatureFlagContext.Provider, { value, children });
|
|
8873
9030
|
};
|
|
8874
9031
|
var useFeatureFlag = (flag) => {
|
|
8875
9032
|
const { isEnabled } = useContext10(FeatureFlagContext);
|
package/dist/styles/tokens.css
CHANGED
|
@@ -1709,6 +1709,19 @@
|
|
|
1709
1709
|
|
|
1710
1710
|
/* Origin: agent — Roadmap. Q1: dark default and dark only. */
|
|
1711
1711
|
:root {
|
|
1712
|
+
--c-roadmap-group-accent-bg: var(--s-surface-elevated);
|
|
1713
|
+
--c-roadmap-group-accent-fg: var(--s-ink-primary);
|
|
1714
|
+
--c-roadmap-edge: var(--s-ink-muted);
|
|
1715
|
+
--c-roadmap-edge-label-bg: var(--s-surface-elevated);
|
|
1716
|
+
--c-roadmap-edge-label-fg: var(--s-ink-secondary);
|
|
1717
|
+
--c-roadmap-primary-edge: var(--s-brand-solid);
|
|
1718
|
+
--c-roadmap-secondary-edge: var(--s-ink-secondary);
|
|
1719
|
+
--c-roadmap-accent-edge: var(--s-ink-primary);
|
|
1720
|
+
--c-roadmap-muted-edge: var(--s-ink-muted);
|
|
1721
|
+
--c-roadmap-neutral-edge: var(--s-ink-secondary);
|
|
1722
|
+
--c-roadmap-success-edge: var(--s-success-fg);
|
|
1723
|
+
--c-roadmap-info-edge: var(--s-info-fg);
|
|
1724
|
+
--c-roadmap-danger-edge: var(--s-danger-fg);
|
|
1712
1725
|
--c-roadmap-surface: var(--s-surface-page);
|
|
1713
1726
|
--c-roadmap-border: var(--s-border-strong);
|
|
1714
1727
|
--c-roadmap-focus: var(--s-border-focus);
|