@flytedan/flytebot-design-system 0.48.0 → 0.48.1
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 +33 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -11
- package/dist/index.d.ts +34 -11
- package/dist/index.js +63 -48
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +41 -0
package/dist/index.d.cts
CHANGED
|
@@ -294,15 +294,22 @@ interface CardProps {
|
|
|
294
294
|
* with no new colour. */
|
|
295
295
|
draft?: boolean;
|
|
296
296
|
/** Renders the card as a real `<a>` (keeps `hoverable`'s lift, adds real
|
|
297
|
-
* hover/focus-visible/press states, MP-271). Takes precedence over `onClick`.
|
|
297
|
+
* hover/focus-visible/press states, MP-271). Takes precedence over `onClick`.
|
|
298
|
+
* Review (comment 2920, finding 3): when either `href` or `onClick` is set, `action`
|
|
299
|
+
* and `footer` are rendered OUTSIDE the `<a>`/`<button>` (as ordinary siblings, via
|
|
300
|
+
* `.fd-card-shell`) rather than inside it — an interactive Card can never nest another
|
|
301
|
+
* interactive element, whatever `action`/`footer` contain. */
|
|
298
302
|
href?: string;
|
|
299
303
|
/** Renders the card as a real `<button type="button">` when there's no `href`
|
|
300
304
|
* (MP-271) — never a `<div onClick>`, so it's reachable by Tab and activates on
|
|
301
305
|
* both Enter and Space for free, and gets the kit's global `:focus-visible`
|
|
302
|
-
* ring (styles/foundations.css) without this component drawing its own.
|
|
306
|
+
* ring (styles/foundations.css) without this component drawing its own. Same
|
|
307
|
+
* `action`/`footer`-stay-outside rule as `href` above applies here too. */
|
|
303
308
|
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
304
|
-
/** Passed through to the root element
|
|
305
|
-
*
|
|
309
|
+
/** Passed through to the root element. A Card rendered inside CardGrid does NOT need this
|
|
310
|
+
* set — CardGrid (MP-271) wraps each item in its own `<div role="listitem">` rather than
|
|
311
|
+
* setting `role` on the card itself; set this only when Card is used outside CardGrid and
|
|
312
|
+
* needs a specific ARIA role of its own. */
|
|
306
313
|
role?: string;
|
|
307
314
|
tabIndex?: number;
|
|
308
315
|
className?: string;
|
|
@@ -391,7 +398,10 @@ declare function ScreenHead({ kicker, title, lede, actions }: ScreenHeadProps):
|
|
|
391
398
|
* other block box. `--card-grid-min` (default 280px) is the floor a card may shrink to before
|
|
392
399
|
* a track drops; two 280px cards plus the gap don't fit in a 375px-wide content column, so
|
|
393
400
|
* that width is always exactly one column, and a typical ~1280px desktop content column fits
|
|
394
|
-
* four (see CardGrid.browser.test.tsx for the measured counts this rests on
|
|
401
|
+
* four (see CardGrid.browser.test.tsx for the measured counts this rests on, including the
|
|
402
|
+
* container-vs-viewport regression case added under review comment 2920 finding 1: a fixed-
|
|
403
|
+
* width container nested inside a differently-sized real viewport still shows the container's
|
|
404
|
+
* own column count, which a `@media` breakpoint on `.fd-card-grid` could never do).
|
|
395
405
|
*
|
|
396
406
|
* Equal-height rows fall out of the grid's own default `align-items: stretch` (restated below
|
|
397
407
|
* for clarity, not because the default would otherwise fail): every item in a row stretches to
|
|
@@ -403,12 +413,25 @@ declare function ScreenHead({ kicker, title, lede, actions }: ScreenHeadProps):
|
|
|
403
413
|
* property `fd-gap-*` already sets on a flex container, so extending that vocabulary to grids
|
|
404
414
|
* costs nothing new and keeps "the medium gap" meaning one token everywhere it's used.
|
|
405
415
|
*
|
|
406
|
-
* List semantics: the grid itself is `role="list"`, and
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
416
|
+
* List semantics (review comment 2920 finding 2): the grid itself is `role="list"`, and every
|
|
417
|
+
* item WRAPS in a plain `<div role="listitem">`, rather than cloning `role` onto the child's own
|
|
418
|
+
* props. Wrapping instead of cloning is deliberate: `React.cloneElement` on a child whose type is
|
|
419
|
+
* `React.Fragment` silently drops an added `role` prop (Fragments only accept `key`/`children`),
|
|
420
|
+
* so cloning left a Fragment child with NO listitem semantics at all and no warning either. A
|
|
421
|
+
* wrapper element needs no such prop-cloning heuristic, and it works identically no matter what
|
|
422
|
+
* the child is — an element, a Fragment, a string, a number — because it never inspects or
|
|
423
|
+
* touches the child's own props. Two behaviours fall out on top of "wrap by default":
|
|
424
|
+
* - Fragments are flattened first (recursively), so `<><Card/><Card/></>` as one CardGrid
|
|
425
|
+
* child becomes TWO listitems, not one listitem wrapping a Fragment.
|
|
426
|
+
* - A child that already sets its own `role` opts out of being a listitem at all (left
|
|
427
|
+
* unwrapped, exactly where React put it) — e.g. an inline empty-state message that should
|
|
428
|
+
* span every column rather than sit inside the list structure. This is the one case where
|
|
429
|
+
* "leave it alone" (the old cloning behaviour) is still correct, since wrapping it would
|
|
430
|
+
* just move the opt-out problem one level down.
|
|
431
|
+
* The wrapper needs a stylesheet counterpart (`.fd-card-grid > [role="listitem"]`, components.css)
|
|
432
|
+
* so the wrapper — now the actual grid item — passes the row's stretched height through to its
|
|
433
|
+
* one real child, the same way `.fd-card`'s own internal flex column already passes extra height
|
|
434
|
+
* down to `.fd-card-foot`.
|
|
412
435
|
*/
|
|
413
436
|
interface CardGridProps {
|
|
414
437
|
children?: React.ReactNode;
|
package/dist/index.d.ts
CHANGED
|
@@ -294,15 +294,22 @@ interface CardProps {
|
|
|
294
294
|
* with no new colour. */
|
|
295
295
|
draft?: boolean;
|
|
296
296
|
/** Renders the card as a real `<a>` (keeps `hoverable`'s lift, adds real
|
|
297
|
-
* hover/focus-visible/press states, MP-271). Takes precedence over `onClick`.
|
|
297
|
+
* hover/focus-visible/press states, MP-271). Takes precedence over `onClick`.
|
|
298
|
+
* Review (comment 2920, finding 3): when either `href` or `onClick` is set, `action`
|
|
299
|
+
* and `footer` are rendered OUTSIDE the `<a>`/`<button>` (as ordinary siblings, via
|
|
300
|
+
* `.fd-card-shell`) rather than inside it — an interactive Card can never nest another
|
|
301
|
+
* interactive element, whatever `action`/`footer` contain. */
|
|
298
302
|
href?: string;
|
|
299
303
|
/** Renders the card as a real `<button type="button">` when there's no `href`
|
|
300
304
|
* (MP-271) — never a `<div onClick>`, so it's reachable by Tab and activates on
|
|
301
305
|
* both Enter and Space for free, and gets the kit's global `:focus-visible`
|
|
302
|
-
* ring (styles/foundations.css) without this component drawing its own.
|
|
306
|
+
* ring (styles/foundations.css) without this component drawing its own. Same
|
|
307
|
+
* `action`/`footer`-stay-outside rule as `href` above applies here too. */
|
|
303
308
|
onClick?: (e: React.MouseEvent<HTMLElement>) => void;
|
|
304
|
-
/** Passed through to the root element
|
|
305
|
-
*
|
|
309
|
+
/** Passed through to the root element. A Card rendered inside CardGrid does NOT need this
|
|
310
|
+
* set — CardGrid (MP-271) wraps each item in its own `<div role="listitem">` rather than
|
|
311
|
+
* setting `role` on the card itself; set this only when Card is used outside CardGrid and
|
|
312
|
+
* needs a specific ARIA role of its own. */
|
|
306
313
|
role?: string;
|
|
307
314
|
tabIndex?: number;
|
|
308
315
|
className?: string;
|
|
@@ -391,7 +398,10 @@ declare function ScreenHead({ kicker, title, lede, actions }: ScreenHeadProps):
|
|
|
391
398
|
* other block box. `--card-grid-min` (default 280px) is the floor a card may shrink to before
|
|
392
399
|
* a track drops; two 280px cards plus the gap don't fit in a 375px-wide content column, so
|
|
393
400
|
* that width is always exactly one column, and a typical ~1280px desktop content column fits
|
|
394
|
-
* four (see CardGrid.browser.test.tsx for the measured counts this rests on
|
|
401
|
+
* four (see CardGrid.browser.test.tsx for the measured counts this rests on, including the
|
|
402
|
+
* container-vs-viewport regression case added under review comment 2920 finding 1: a fixed-
|
|
403
|
+
* width container nested inside a differently-sized real viewport still shows the container's
|
|
404
|
+
* own column count, which a `@media` breakpoint on `.fd-card-grid` could never do).
|
|
395
405
|
*
|
|
396
406
|
* Equal-height rows fall out of the grid's own default `align-items: stretch` (restated below
|
|
397
407
|
* for clarity, not because the default would otherwise fail): every item in a row stretches to
|
|
@@ -403,12 +413,25 @@ declare function ScreenHead({ kicker, title, lede, actions }: ScreenHeadProps):
|
|
|
403
413
|
* property `fd-gap-*` already sets on a flex container, so extending that vocabulary to grids
|
|
404
414
|
* costs nothing new and keeps "the medium gap" meaning one token everywhere it's used.
|
|
405
415
|
*
|
|
406
|
-
* List semantics: the grid itself is `role="list"`, and
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
*
|
|
411
|
-
*
|
|
416
|
+
* List semantics (review comment 2920 finding 2): the grid itself is `role="list"`, and every
|
|
417
|
+
* item WRAPS in a plain `<div role="listitem">`, rather than cloning `role` onto the child's own
|
|
418
|
+
* props. Wrapping instead of cloning is deliberate: `React.cloneElement` on a child whose type is
|
|
419
|
+
* `React.Fragment` silently drops an added `role` prop (Fragments only accept `key`/`children`),
|
|
420
|
+
* so cloning left a Fragment child with NO listitem semantics at all and no warning either. A
|
|
421
|
+
* wrapper element needs no such prop-cloning heuristic, and it works identically no matter what
|
|
422
|
+
* the child is — an element, a Fragment, a string, a number — because it never inspects or
|
|
423
|
+
* touches the child's own props. Two behaviours fall out on top of "wrap by default":
|
|
424
|
+
* - Fragments are flattened first (recursively), so `<><Card/><Card/></>` as one CardGrid
|
|
425
|
+
* child becomes TWO listitems, not one listitem wrapping a Fragment.
|
|
426
|
+
* - A child that already sets its own `role` opts out of being a listitem at all (left
|
|
427
|
+
* unwrapped, exactly where React put it) — e.g. an inline empty-state message that should
|
|
428
|
+
* span every column rather than sit inside the list structure. This is the one case where
|
|
429
|
+
* "leave it alone" (the old cloning behaviour) is still correct, since wrapping it would
|
|
430
|
+
* just move the opt-out problem one level down.
|
|
431
|
+
* The wrapper needs a stylesheet counterpart (`.fd-card-grid > [role="listitem"]`, components.css)
|
|
432
|
+
* so the wrapper — now the actual grid item — passes the row's stretched height through to its
|
|
433
|
+
* one real child, the same way `.fd-card`'s own internal flex column already passes extra height
|
|
434
|
+
* down to `.fd-card-foot`.
|
|
412
435
|
*/
|
|
413
436
|
interface CardGridProps {
|
|
414
437
|
children?: React.ReactNode;
|
package/dist/index.js
CHANGED
|
@@ -851,28 +851,28 @@ function Card({
|
|
|
851
851
|
interactive ? "fd-card-interactive" : "",
|
|
852
852
|
className
|
|
853
853
|
].filter(Boolean).join(" ");
|
|
854
|
-
const
|
|
854
|
+
const titleOnlyHead = title ? /* @__PURE__ */ jsxs4("div", { className: "fd-card-head", children: [
|
|
855
855
|
/* @__PURE__ */ jsx7("span", { className: "fd-card-head-title", title: truncationTitle(title), children: title }),
|
|
856
|
-
action
|
|
856
|
+
!interactive && action
|
|
857
857
|
] }) : null;
|
|
858
858
|
const body = padded ? /* @__PURE__ */ jsx7("div", { className: "fd-card-body", children }) : children;
|
|
859
859
|
const foot = footer ? /* @__PURE__ */ jsx7("div", { className: "fd-card-foot", children: footer }) : null;
|
|
860
|
-
if (
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
body
|
|
864
|
-
|
|
860
|
+
if (interactive) {
|
|
861
|
+
const inner = href != null ? /* @__PURE__ */ jsxs4("a", { href, onClick, className: cls, role, tabIndex, ...rest, children: [
|
|
862
|
+
titleOnlyHead,
|
|
863
|
+
body
|
|
864
|
+
] }) : /* @__PURE__ */ jsxs4("button", { type: "button", onClick, className: cls, role, tabIndex, ...rest, children: [
|
|
865
|
+
titleOnlyHead,
|
|
866
|
+
body
|
|
865
867
|
] });
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
head,
|
|
870
|
-
body,
|
|
868
|
+
return /* @__PURE__ */ jsxs4("div", { className: "fd-card-shell", children: [
|
|
869
|
+
inner,
|
|
870
|
+
action ? /* @__PURE__ */ jsx7("div", { className: "fd-card-shell-action", children: action }) : null,
|
|
871
871
|
foot
|
|
872
872
|
] });
|
|
873
873
|
}
|
|
874
874
|
return /* @__PURE__ */ jsxs4("div", { className: cls, role, tabIndex, ...rest, children: [
|
|
875
|
-
|
|
875
|
+
titleOnlyHead,
|
|
876
876
|
body,
|
|
877
877
|
foot
|
|
878
878
|
] });
|
|
@@ -1046,8 +1046,21 @@ function ScreenHead({ kicker, title, lede, actions }) {
|
|
|
1046
1046
|
// src/components/layout/CardGrid.tsx
|
|
1047
1047
|
import * as React8 from "react";
|
|
1048
1048
|
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1049
|
+
function flattenFragments(children) {
|
|
1050
|
+
const out = [];
|
|
1051
|
+
React8.Children.forEach(children, (child) => {
|
|
1052
|
+
if (child === null || child === void 0 || typeof child === "boolean") return;
|
|
1053
|
+
if (React8.isValidElement(child) && child.type === React8.Fragment) {
|
|
1054
|
+
const fragmentChildren = child.props.children;
|
|
1055
|
+
out.push(...flattenFragments(fragmentChildren));
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
out.push(child);
|
|
1059
|
+
});
|
|
1060
|
+
return out;
|
|
1061
|
+
}
|
|
1049
1062
|
function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", style }) {
|
|
1050
|
-
const items =
|
|
1063
|
+
const items = flattenFragments(children);
|
|
1051
1064
|
return /* @__PURE__ */ jsx12(
|
|
1052
1065
|
"div",
|
|
1053
1066
|
{
|
|
@@ -1055,10 +1068,12 @@ function CardGrid({ children, minCardWidth = 280, gap = "lg", className = "", st
|
|
|
1055
1068
|
className: ["fd-card-grid", "fd-gap-" + gap, className].filter(Boolean).join(" "),
|
|
1056
1069
|
style: { ["--card-grid-min"]: minCardWidth + "px", ...style },
|
|
1057
1070
|
children: items.map((child, i) => {
|
|
1058
|
-
if (
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1071
|
+
if (React8.isValidElement(child)) {
|
|
1072
|
+
const existingRole = child.props.role;
|
|
1073
|
+
if (existingRole) return child;
|
|
1074
|
+
return /* @__PURE__ */ jsx12("div", { role: "listitem", children: child }, child.key ?? i);
|
|
1075
|
+
}
|
|
1076
|
+
return /* @__PURE__ */ jsx12("div", { role: "listitem", children: child }, i);
|
|
1062
1077
|
})
|
|
1063
1078
|
}
|
|
1064
1079
|
);
|
|
@@ -1330,7 +1345,7 @@ var SidebarNav = React11.forwardRef(function SidebarNav2({ brand, groups = [], c
|
|
|
1330
1345
|
|
|
1331
1346
|
// src/components/navigation/Topbar.tsx
|
|
1332
1347
|
import * as React12 from "react";
|
|
1333
|
-
import { Fragment as
|
|
1348
|
+
import { Fragment as Fragment4, jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1334
1349
|
function useIsNarrow(breakpoint) {
|
|
1335
1350
|
const [narrow, setNarrow] = React12.useState(
|
|
1336
1351
|
() => typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia(`(max-width: ${breakpoint}px)`).matches
|
|
@@ -1379,7 +1394,7 @@ function Topbar({
|
|
|
1379
1394
|
}
|
|
1380
1395
|
)
|
|
1381
1396
|
] }, i)) }),
|
|
1382
|
-
overflowActions != null ? narrow ? /* @__PURE__ */ jsxs14(
|
|
1397
|
+
overflowActions != null ? narrow ? /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
1383
1398
|
/* @__PURE__ */ jsx20(
|
|
1384
1399
|
"button",
|
|
1385
1400
|
{
|
|
@@ -1689,12 +1704,12 @@ function EmptyState({ icon = "tray", title, children, action, className = "", ..
|
|
|
1689
1704
|
}
|
|
1690
1705
|
|
|
1691
1706
|
// src/components/feedback/Flag.tsx
|
|
1692
|
-
import { Fragment as
|
|
1707
|
+
import { Fragment as Fragment5, jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1693
1708
|
function Flag({ statement, cost, actions, tone = "warning", className = "", ...rest }) {
|
|
1694
1709
|
return /* @__PURE__ */ jsxs22("div", { className: ["fd-flag", "fd-flag-" + tone, className].filter(Boolean).join(" "), role: "status", ...rest, children: [
|
|
1695
1710
|
/* @__PURE__ */ jsxs22("span", { className: "fd-flag-text", children: [
|
|
1696
1711
|
statement,
|
|
1697
|
-
cost ? /* @__PURE__ */ jsxs22(
|
|
1712
|
+
cost ? /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
1698
1713
|
" ",
|
|
1699
1714
|
/* @__PURE__ */ jsx28("span", { className: "fd-flag-cost", children: cost })
|
|
1700
1715
|
] }) : null
|
|
@@ -1921,7 +1936,7 @@ function Tooltip({ label, placement = "top", children, className = "" }) {
|
|
|
1921
1936
|
|
|
1922
1937
|
// src/components/data/AnimNum.tsx
|
|
1923
1938
|
import * as React15 from "react";
|
|
1924
|
-
import { Fragment as
|
|
1939
|
+
import { Fragment as Fragment6, jsx as jsx33 } from "react/jsx-runtime";
|
|
1925
1940
|
function shouldSkipEasing() {
|
|
1926
1941
|
if (typeof document !== "undefined" && document.hidden) return true;
|
|
1927
1942
|
return window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ?? false;
|
|
@@ -1953,7 +1968,7 @@ function AnimNum({ value, format, duration = 550 }) {
|
|
|
1953
1968
|
setDisplay(to);
|
|
1954
1969
|
};
|
|
1955
1970
|
}, [value, duration]);
|
|
1956
|
-
return /* @__PURE__ */ jsx33(
|
|
1971
|
+
return /* @__PURE__ */ jsx33(Fragment6, { children: format ? format(display) : Math.round(display).toLocaleString() });
|
|
1957
1972
|
}
|
|
1958
1973
|
|
|
1959
1974
|
// src/components/data/TrendChart.tsx
|
|
@@ -4436,7 +4451,7 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
|
|
|
4436
4451
|
|
|
4437
4452
|
// src/components/data/CodeBlock.tsx
|
|
4438
4453
|
import * as React27 from "react";
|
|
4439
|
-
import { Fragment as
|
|
4454
|
+
import { Fragment as Fragment7, jsx as jsx49, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
4440
4455
|
var JS_KW = /^(?:const|let|var|function|return|if|else|for|while|do|new|class|extends|import|from|export|default|await|async|try|catch|finally|throw|typeof|instanceof|of|in|switch|case|break|continue|delete|void|yield|static|get|set|this|super|interface|type|enum|implements|public|private|protected|readonly|abstract|as|satisfies|declare|namespace)$/;
|
|
4441
4456
|
var RULES = {
|
|
4442
4457
|
js: [
|
|
@@ -4592,7 +4607,7 @@ function tokenize(src, lang) {
|
|
|
4592
4607
|
}
|
|
4593
4608
|
function Highlighted({ code, lang }) {
|
|
4594
4609
|
const toks = React27.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
4595
|
-
return /* @__PURE__ */ jsx49(
|
|
4610
|
+
return /* @__PURE__ */ jsx49(Fragment7, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ jsx49("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
4596
4611
|
}
|
|
4597
4612
|
function useCopy() {
|
|
4598
4613
|
const [done, setDone] = React27.useState(false);
|
|
@@ -4956,7 +4971,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
|
|
|
4956
4971
|
}
|
|
4957
4972
|
|
|
4958
4973
|
// src/components/data/Pagination.tsx
|
|
4959
|
-
import { Fragment as
|
|
4974
|
+
import { Fragment as Fragment9, jsx as jsx52, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4960
4975
|
var unitPluralRules = new Intl.PluralRules("en-US");
|
|
4961
4976
|
function pluralizeUnit(n, singular, irregularPlural) {
|
|
4962
4977
|
return unitPluralRules.select(n) === "one" ? singular : irregularPlural ?? `${singular}s`;
|
|
@@ -4988,10 +5003,10 @@ function Pagination({
|
|
|
4988
5003
|
else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
|
|
4989
5004
|
}
|
|
4990
5005
|
return /* @__PURE__ */ jsxs44("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
|
|
4991
|
-
/* @__PURE__ */ jsx52("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx52("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs44(
|
|
5006
|
+
/* @__PURE__ */ jsx52("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ jsx52("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ jsxs44(Fragment9, { children: [
|
|
4992
5007
|
"No ",
|
|
4993
5008
|
unitLabel
|
|
4994
|
-
] }) : /* @__PURE__ */ jsxs44(
|
|
5009
|
+
] }) : /* @__PURE__ */ jsxs44(Fragment9, { children: [
|
|
4995
5010
|
/* @__PURE__ */ jsxs44("strong", { children: [
|
|
4996
5011
|
from.toLocaleString(),
|
|
4997
5012
|
"\u2013",
|
|
@@ -7256,7 +7271,7 @@ function useSessionContext() {
|
|
|
7256
7271
|
}
|
|
7257
7272
|
|
|
7258
7273
|
// src/components/platform/AccountMenu.tsx
|
|
7259
|
-
import { Fragment as
|
|
7274
|
+
import { Fragment as Fragment16, jsx as jsx72, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
7260
7275
|
var DEFAULT_LINKS = [];
|
|
7261
7276
|
var DEFAULT_GROUPS = [];
|
|
7262
7277
|
function Item({ item, onPick }) {
|
|
@@ -7318,7 +7333,7 @@ function AccountMenu({
|
|
|
7318
7333
|
}
|
|
7319
7334
|
};
|
|
7320
7335
|
const showSwitcher = allowUserSwitch && !!demo;
|
|
7321
|
-
return /* @__PURE__ */ jsxs63(
|
|
7336
|
+
return /* @__PURE__ */ jsxs63(Fragment16, { children: [
|
|
7322
7337
|
/* @__PURE__ */ jsxs63(
|
|
7323
7338
|
"button",
|
|
7324
7339
|
{
|
|
@@ -8076,7 +8091,7 @@ function ProfilePage({
|
|
|
8076
8091
|
|
|
8077
8092
|
// src/components/platform/SignInPage.tsx
|
|
8078
8093
|
import * as React50 from "react";
|
|
8079
|
-
import { Fragment as
|
|
8094
|
+
import { Fragment as Fragment19, jsx as jsx77, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
8080
8095
|
function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
8081
8096
|
const [signingIn, setSigningIn] = React50.useState(false);
|
|
8082
8097
|
const [resuming, setResuming] = React50.useState(false);
|
|
@@ -8164,7 +8179,7 @@ function SignInPage({ productName, onSignIn, continueAs, error }) {
|
|
|
8164
8179
|
/* @__PURE__ */ jsx77("p", { className: "fd-body-sm fd-muted", style: { marginTop: "var(--s-4)" }, children: continueAs ? "Your session timed out, but you're likely still signed in" : "Sign in with your flytedesk workspace account" })
|
|
8165
8180
|
] }),
|
|
8166
8181
|
error ? /* @__PURE__ */ jsx77("div", { role: "alert", style: { width: "100%" }, children: /* @__PURE__ */ jsx77(Banner, { tone: "danger", title: error }) }) : null,
|
|
8167
|
-
continueAs ? /* @__PURE__ */ jsxs68(
|
|
8182
|
+
continueAs ? /* @__PURE__ */ jsxs68(Fragment19, { children: [
|
|
8168
8183
|
/* @__PURE__ */ jsx77(
|
|
8169
8184
|
Button,
|
|
8170
8185
|
{
|
|
@@ -10281,7 +10296,7 @@ function RoadmapTimeline({ onOpenFlag, title = "Roadmap", lede }) {
|
|
|
10281
10296
|
// src/components/platform/ComingSoon.tsx
|
|
10282
10297
|
import * as React54 from "react";
|
|
10283
10298
|
import { createPortal as createPortal5 } from "react-dom";
|
|
10284
|
-
import { Fragment as
|
|
10299
|
+
import { Fragment as Fragment21, jsx as jsx79, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
10285
10300
|
var BYPASS_STORE = "fd.soon.bypass.v1";
|
|
10286
10301
|
function readBypassed() {
|
|
10287
10302
|
try {
|
|
@@ -10311,7 +10326,7 @@ function useBypass(key) {
|
|
|
10311
10326
|
return [on, set];
|
|
10312
10327
|
}
|
|
10313
10328
|
function SoonCard({ label, detail, backend, eta, effort, onRoadmap, allowed, onBypass }) {
|
|
10314
|
-
return /* @__PURE__ */ jsxs70(
|
|
10329
|
+
return /* @__PURE__ */ jsxs70(Fragment21, { children: [
|
|
10315
10330
|
/* @__PURE__ */ jsxs70("span", { className: "fd-soon-badge", children: [
|
|
10316
10331
|
/* @__PURE__ */ jsx79("i", { className: "ph ph-traffic-cone", "aria-hidden": "true" }),
|
|
10317
10332
|
label
|
|
@@ -10698,7 +10713,7 @@ function PermissionHint({ perm, children }) {
|
|
|
10698
10713
|
}
|
|
10699
10714
|
|
|
10700
10715
|
// src/components/platform/ModeSwitch.tsx
|
|
10701
|
-
import { Fragment as
|
|
10716
|
+
import { Fragment as Fragment22, jsx as jsx81, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
10702
10717
|
function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog, onOpenSpec, summary }) {
|
|
10703
10718
|
const mode2 = useRuntimeMode();
|
|
10704
10719
|
const panel = useInlinePanel();
|
|
@@ -10753,7 +10768,7 @@ function ModeSwitch({ canToggle = false, requestCount = 0, onClearLog, renderLog
|
|
|
10753
10768
|
s.total,
|
|
10754
10769
|
" features complete"
|
|
10755
10770
|
] }),
|
|
10756
|
-
onOpenSpec ? /* @__PURE__ */ jsxs72(
|
|
10771
|
+
onOpenSpec ? /* @__PURE__ */ jsxs72(Fragment22, { children: [
|
|
10757
10772
|
/* @__PURE__ */ jsx81("span", { style: { flex: 1 } }),
|
|
10758
10773
|
/* @__PURE__ */ jsxs72("button", { type: "button", className: "fd-soon-link", onClick: () => {
|
|
10759
10774
|
setOpen(false);
|
|
@@ -10945,7 +10960,7 @@ function SaturationDistribution({ campuses = [], floorBand, floorScore, onSelect
|
|
|
10945
10960
|
|
|
10946
10961
|
// src/components/planner/MixGap.tsx
|
|
10947
10962
|
import * as React55 from "react";
|
|
10948
|
-
import { Fragment as
|
|
10963
|
+
import { Fragment as Fragment23, jsx as jsx84, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
10949
10964
|
var MIX_GAP_LAYOUT = {
|
|
10950
10965
|
trackHeight: 30,
|
|
10951
10966
|
barHeight: 20,
|
|
@@ -10989,7 +11004,7 @@ function MixGap({ rows = [], loading = false, className = "" }) {
|
|
|
10989
11004
|
onMouseLeave: () => setHover(null),
|
|
10990
11005
|
children: [
|
|
10991
11006
|
/* @__PURE__ */ jsx84("span", { style: { width: 128, flex: "none" }, children: /* @__PURE__ */ jsx84(ChannelTag, { channel: r.channel, size: "sm" }) }),
|
|
10992
|
-
/* @__PURE__ */ jsx84("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx84("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs75(
|
|
11007
|
+
/* @__PURE__ */ jsx84("span", { style: { position: "relative", flex: 1, height: trackHeight, minWidth: 120 }, children: loading ? /* @__PURE__ */ jsx84("span", { className: "fd-skel", style: { position: "absolute", left: 0, right: 0, top: barTop, height: barHeight, borderRadius: 3 } }) : /* @__PURE__ */ jsxs75(Fragment23, { children: [
|
|
10993
11008
|
/* @__PURE__ */ jsx84("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)" } }),
|
|
10994
11009
|
/* @__PURE__ */ jsx84("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 } }),
|
|
10995
11010
|
/* @__PURE__ */ jsxs75("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: [
|
|
@@ -11103,7 +11118,7 @@ function ChannelContribution({
|
|
|
11103
11118
|
|
|
11104
11119
|
// src/components/planner/BudgetReallocator.tsx
|
|
11105
11120
|
import * as React56 from "react";
|
|
11106
|
-
import { Fragment as
|
|
11121
|
+
import { Fragment as Fragment24, jsx as jsx86, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
11107
11122
|
var bandFor = (crp) => crp >= 200 ? "dominant" : crp >= 100 ? "strong" : crp >= 50 ? "adequate" : "weak";
|
|
11108
11123
|
function BudgetReallocator({
|
|
11109
11124
|
campus,
|
|
@@ -11167,7 +11182,7 @@ function BudgetReallocator({
|
|
|
11167
11182
|
/* @__PURE__ */ jsxs77("div", { className: "fd-row", style: { gap: 12, flexWrap: "wrap" }, children: [
|
|
11168
11183
|
/* @__PURE__ */ jsx86("span", { className: "fd-h4", style: { flex: 1, minWidth: 140 }, children: campus }),
|
|
11169
11184
|
/* @__PURE__ */ jsx86(CsiBadge, { band: nowBand, crp, size: "medium" }),
|
|
11170
|
-
dirty ? /* @__PURE__ */ jsxs77(
|
|
11185
|
+
dirty ? /* @__PURE__ */ jsxs77(Fragment24, { children: [
|
|
11171
11186
|
/* @__PURE__ */ jsx86("i", { className: "ph ph-arrow-right fd-muted", "aria-hidden": "true" }),
|
|
11172
11187
|
/* @__PURE__ */ jsx86(CsiBadge, { band: nextBand, crp: nextCrp, size: "medium", preview: true })
|
|
11173
11188
|
] }) : null
|
|
@@ -13122,7 +13137,7 @@ function FileViewer({ file, resolveUrl, sidePanel, sidePanelLabel = "Details", o
|
|
|
13122
13137
|
|
|
13123
13138
|
// src/components/files/FileBrowser.tsx
|
|
13124
13139
|
import * as React65 from "react";
|
|
13125
|
-
import { Fragment as
|
|
13140
|
+
import { Fragment as Fragment28, jsx as jsx96, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
13126
13141
|
function childrenOf(folders, parentId) {
|
|
13127
13142
|
return folders.filter((f) => f.parentId === parentId).sort((a, b) => a.name.localeCompare(b.name));
|
|
13128
13143
|
}
|
|
@@ -13421,7 +13436,7 @@ function FileBrowser({
|
|
|
13421
13436
|
] }),
|
|
13422
13437
|
/* @__PURE__ */ jsxs87("span", { className: "fd-fb-actions", children: [
|
|
13423
13438
|
canCreateFolder ? /* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "folder-simple-plus", onClick: openCreate, children: "New folder" }) : null,
|
|
13424
|
-
canUpload ? /* @__PURE__ */ jsxs87(
|
|
13439
|
+
canUpload ? /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13425
13440
|
/* @__PURE__ */ jsx96(Button, { variant: "secondary", size: "sm", icon: "upload-simple", onClick: () => uploadInputRef.current && uploadInputRef.current.click(), children: "Upload" }),
|
|
13426
13441
|
/* @__PURE__ */ jsx96(
|
|
13427
13442
|
"input",
|
|
@@ -13488,7 +13503,7 @@ function FileBrowser({
|
|
|
13488
13503
|
draggableId: canMove ? { kind: "folder", id: f.id } : void 0,
|
|
13489
13504
|
isDropTarget: canMove,
|
|
13490
13505
|
onDropPayload: (p) => moveIntoFolder(p, f.id),
|
|
13491
|
-
actions: /* @__PURE__ */ jsxs87(
|
|
13506
|
+
actions: /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13492
13507
|
canRenameFolder ? /* @__PURE__ */ jsx96(IconButton, { icon: "pencil-simple", label: "Rename " + f.name, size: "sm", variant: "ghost", onClick: () => openRename(f) }) : null,
|
|
13493
13508
|
canMove ? /* @__PURE__ */ jsx96(
|
|
13494
13509
|
FolderPickerMenu,
|
|
@@ -13511,7 +13526,7 @@ function FileBrowser({
|
|
|
13511
13526
|
meta: file.size ? formatBytes(file.size) : void 0,
|
|
13512
13527
|
onOpen: onOpenFile ? () => onOpenFile(file) : void 0,
|
|
13513
13528
|
draggableId: canMove ? { kind: "file", id: file.id } : void 0,
|
|
13514
|
-
actions: /* @__PURE__ */ jsxs87(
|
|
13529
|
+
actions: /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13515
13530
|
canMove ? /* @__PURE__ */ jsx96(
|
|
13516
13531
|
FolderPickerMenu,
|
|
13517
13532
|
{
|
|
@@ -13529,7 +13544,7 @@ function FileBrowser({
|
|
|
13529
13544
|
}
|
|
13530
13545
|
) })
|
|
13531
13546
|
] }),
|
|
13532
|
-
/* @__PURE__ */ jsx96(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs87(
|
|
13547
|
+
/* @__PURE__ */ jsx96(Modal, { open: createOpen, title: "New folder", onClose: () => setCreateOpen(false), footer: /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13533
13548
|
/* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setCreateOpen(false), children: "Cancel" }),
|
|
13534
13549
|
/* @__PURE__ */ jsx96(Button, { onClick: submitCreate, disabled: !createName.trim(), children: "Create" })
|
|
13535
13550
|
] }), children: /* @__PURE__ */ jsx96(
|
|
@@ -13546,7 +13561,7 @@ function FileBrowser({
|
|
|
13546
13561
|
autoFocus: true
|
|
13547
13562
|
}
|
|
13548
13563
|
) }),
|
|
13549
|
-
/* @__PURE__ */ jsx96(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs87(
|
|
13564
|
+
/* @__PURE__ */ jsx96(Modal, { open: renameTarget != null, title: "Rename folder", onClose: () => setRenameTarget(null), footer: /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13550
13565
|
/* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setRenameTarget(null), children: "Cancel" }),
|
|
13551
13566
|
/* @__PURE__ */ jsx96(Button, { onClick: submitRename, disabled: !renameValue.trim(), children: "Save" })
|
|
13552
13567
|
] }), children: /* @__PURE__ */ jsx96(
|
|
@@ -13570,7 +13585,7 @@ function FileBrowser({
|
|
|
13570
13585
|
title: deleteTarget ? "Delete \u201C" + deleteTarget.name + "\u201D?" : "Delete folder?",
|
|
13571
13586
|
description: "This can't be undone. The folder must be empty.",
|
|
13572
13587
|
onClose: () => setDeleteTarget(null),
|
|
13573
|
-
footer: /* @__PURE__ */ jsxs87(
|
|
13588
|
+
footer: /* @__PURE__ */ jsxs87(Fragment28, { children: [
|
|
13574
13589
|
/* @__PURE__ */ jsx96(Button, { variant: "secondary", onClick: () => setDeleteTarget(null), children: "Cancel" }),
|
|
13575
13590
|
/* @__PURE__ */ jsx96(Button, { variant: "danger", onClick: confirmDelete, children: "Delete" })
|
|
13576
13591
|
] })
|