@flytedan/flytebot-design-system 0.27.0 → 0.28.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 +1181 -749
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +90 -10
- package/dist/index.d.ts +90 -10
- package/dist/index.js +1181 -749
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/styles/components.css +2 -12
package/dist/index.cjs
CHANGED
|
@@ -2953,20 +2953,780 @@ function DataTable({
|
|
|
2953
2953
|
}
|
|
2954
2954
|
|
|
2955
2955
|
// src/components/data/FilterBar.tsx
|
|
2956
|
+
var React23 = __toESM(require("react"), 1);
|
|
2957
|
+
|
|
2958
|
+
// src/components/forms/NumberInput.tsx
|
|
2959
|
+
var React21 = __toESM(require("react"), 1);
|
|
2960
|
+
|
|
2961
|
+
// src/components/forms/field.tsx
|
|
2956
2962
|
var React20 = __toESM(require("react"), 1);
|
|
2957
2963
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2964
|
+
function useFieldId(id) {
|
|
2965
|
+
const generated = React20.useId();
|
|
2966
|
+
return id || generated;
|
|
2967
|
+
}
|
|
2968
|
+
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
2969
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
|
|
2970
|
+
children,
|
|
2971
|
+
required ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
|
|
2972
|
+
] });
|
|
2973
|
+
}
|
|
2974
|
+
function useTriggerLabelling(label, id) {
|
|
2975
|
+
const fieldId = useFieldId(id);
|
|
2976
|
+
const labelId = fieldId + "-label";
|
|
2977
|
+
return { fieldId, labelId, ariaLabelledBy: label ? labelId + " " + fieldId : void 0 };
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
// src/components/forms/NumberInput.tsx
|
|
2981
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2982
|
+
function NumberInput({
|
|
2983
|
+
label,
|
|
2984
|
+
help,
|
|
2985
|
+
error,
|
|
2986
|
+
prefix,
|
|
2987
|
+
suffix,
|
|
2988
|
+
required = false,
|
|
2989
|
+
disabled = false,
|
|
2990
|
+
min = -Infinity,
|
|
2991
|
+
max = Infinity,
|
|
2992
|
+
step = 1,
|
|
2993
|
+
bigStep,
|
|
2994
|
+
value,
|
|
2995
|
+
onChange,
|
|
2996
|
+
format = true,
|
|
2997
|
+
className = "",
|
|
2998
|
+
style,
|
|
2999
|
+
placeholder,
|
|
3000
|
+
id,
|
|
3001
|
+
"aria-label": ariaLabel
|
|
3002
|
+
}) {
|
|
3003
|
+
const fieldId = useFieldId(id);
|
|
3004
|
+
const num = (v) => {
|
|
3005
|
+
const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
|
|
3006
|
+
return isNaN(n) ? null : n;
|
|
3007
|
+
};
|
|
3008
|
+
const [text, setText] = React21.useState(value == null || value === "" ? "" : String(value));
|
|
3009
|
+
const [editing, setEditing] = React21.useState(false);
|
|
3010
|
+
const timer = React21.useRef(null);
|
|
3011
|
+
React21.useEffect(() => {
|
|
3012
|
+
if (!editing) setText(value == null || value === "" ? "" : String(value));
|
|
3013
|
+
}, [value, editing]);
|
|
3014
|
+
const clamp = (n) => Math.min(max, Math.max(min, n));
|
|
3015
|
+
const fire = (n) => onChange && onChange({ target: { value: n } });
|
|
3016
|
+
const bump = (dir, mult = 1) => {
|
|
3017
|
+
const cur = num(text) ?? num(value) ?? (min === -Infinity ? 0 : min);
|
|
3018
|
+
const next = clamp(cur + dir * (bigStep && mult > 1 ? bigStep : step) * (bigStep ? 1 : mult));
|
|
3019
|
+
setText(String(next));
|
|
3020
|
+
fire(next);
|
|
3021
|
+
};
|
|
3022
|
+
const hold = (dir) => {
|
|
3023
|
+
bump(dir);
|
|
3024
|
+
let n = 0;
|
|
3025
|
+
const tick = () => {
|
|
3026
|
+
n++;
|
|
3027
|
+
bump(dir, n > 6 ? 4 : 1);
|
|
3028
|
+
timer.current = setTimeout(tick, n > 12 ? 40 : n > 6 ? 70 : 120);
|
|
3029
|
+
};
|
|
3030
|
+
timer.current = setTimeout(tick, 420);
|
|
3031
|
+
};
|
|
3032
|
+
const release = () => {
|
|
3033
|
+
if (timer.current) clearTimeout(timer.current);
|
|
3034
|
+
};
|
|
3035
|
+
React21.useEffect(() => () => {
|
|
3036
|
+
if (timer.current) clearTimeout(timer.current);
|
|
3037
|
+
}, []);
|
|
3038
|
+
const shown = editing ? text : (() => {
|
|
3039
|
+
const n = num(text);
|
|
3040
|
+
return n == null ? "" : format ? n.toLocaleString() : String(n);
|
|
3041
|
+
})();
|
|
3042
|
+
const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
3043
|
+
const fieldName = label || ariaLabel;
|
|
3044
|
+
const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
|
|
3045
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
3046
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
3047
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: box, style: { gap: 8 }, children: [
|
|
3048
|
+
prefix ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "fd-input-affix", children: prefix }) : null,
|
|
3049
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
3050
|
+
"input",
|
|
3051
|
+
{
|
|
3052
|
+
id: fieldId,
|
|
3053
|
+
"aria-label": ariaLabel,
|
|
3054
|
+
inputMode: "numeric",
|
|
3055
|
+
disabled,
|
|
3056
|
+
placeholder,
|
|
3057
|
+
value: shown,
|
|
3058
|
+
onFocus: () => setEditing(true),
|
|
3059
|
+
onBlur: () => {
|
|
3060
|
+
setEditing(false);
|
|
3061
|
+
const n = num(text);
|
|
3062
|
+
if (n != null) {
|
|
3063
|
+
const c = clamp(n);
|
|
3064
|
+
setText(String(c));
|
|
3065
|
+
fire(c);
|
|
3066
|
+
}
|
|
3067
|
+
},
|
|
3068
|
+
onChange: (e) => {
|
|
3069
|
+
setText(e.target.value);
|
|
3070
|
+
const n = num(e.target.value);
|
|
3071
|
+
if (n != null) fire(n);
|
|
3072
|
+
},
|
|
3073
|
+
onKeyDown: (e) => {
|
|
3074
|
+
if (e.key === "ArrowUp") {
|
|
3075
|
+
e.preventDefault();
|
|
3076
|
+
bump(1, e.shiftKey ? 2 : 1);
|
|
3077
|
+
} else if (e.key === "ArrowDown") {
|
|
3078
|
+
e.preventDefault();
|
|
3079
|
+
bump(-1, e.shiftKey ? 2 : 1);
|
|
3080
|
+
}
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
),
|
|
3084
|
+
suffix ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "fd-input-affix", children: suffix }) : null,
|
|
3085
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "fd-row", style: { gap: 4, flex: "none" }, children: [
|
|
3086
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
3087
|
+
"button",
|
|
3088
|
+
{
|
|
3089
|
+
type: "button",
|
|
3090
|
+
className: "fd-stepbtn",
|
|
3091
|
+
"aria-label": stepperName("Decrease"),
|
|
3092
|
+
disabled: disabled || (num(text) ?? 0) <= min,
|
|
3093
|
+
onPointerDown: () => hold(-1),
|
|
3094
|
+
onPointerUp: release,
|
|
3095
|
+
onPointerLeave: release,
|
|
3096
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("i", { className: "ph ph-minus" })
|
|
3097
|
+
}
|
|
3098
|
+
),
|
|
3099
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
|
|
3100
|
+
"button",
|
|
3101
|
+
{
|
|
3102
|
+
type: "button",
|
|
3103
|
+
className: "fd-stepbtn",
|
|
3104
|
+
"aria-label": stepperName("Increase"),
|
|
3105
|
+
disabled: disabled || (num(text) ?? 0) >= max,
|
|
3106
|
+
onPointerDown: () => hold(1),
|
|
3107
|
+
onPointerUp: release,
|
|
3108
|
+
onPointerLeave: release,
|
|
3109
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("i", { className: "ph ph-plus" })
|
|
3110
|
+
}
|
|
3111
|
+
)
|
|
3112
|
+
] })
|
|
3113
|
+
] }),
|
|
3114
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("span", { className: "fd-field-error", children: [
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3116
|
+
error
|
|
3117
|
+
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
3118
|
+
] });
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
// src/components/forms/DatePicker.tsx
|
|
3122
|
+
var React22 = __toESM(require("react"), 1);
|
|
3123
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
3124
|
+
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
3125
|
+
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
3126
|
+
var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
|
|
3127
|
+
var parse = (s) => {
|
|
3128
|
+
if (!s) return null;
|
|
3129
|
+
const [y, m, d] = s.split("-").map(Number);
|
|
3130
|
+
return new Date(y, m - 1, d);
|
|
3131
|
+
};
|
|
3132
|
+
var fmt = (s) => {
|
|
3133
|
+
const d = parse(s);
|
|
3134
|
+
return d ? MONTHS[d.getMonth()].slice(0, 3) + " " + d.getDate() + ", " + d.getFullYear() : "";
|
|
3135
|
+
};
|
|
3136
|
+
function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
3137
|
+
const today = /* @__PURE__ */ new Date();
|
|
3138
|
+
const sel = range ? value || {} : { start: value, end: value };
|
|
3139
|
+
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
3140
|
+
const [vy, setVy] = React22.useState(anchor.getFullYear());
|
|
3141
|
+
const [vm, setVm] = React22.useState(anchor.getMonth());
|
|
3142
|
+
const [mode2, setMode] = React22.useState("days");
|
|
3143
|
+
const [hover, setHover] = React22.useState(null);
|
|
3144
|
+
const s = parse(sel.start), e = parse(sel.end);
|
|
3145
|
+
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
3146
|
+
const inRange = (d) => {
|
|
3147
|
+
const lo = s, hi = e || hoverEnd;
|
|
3148
|
+
return lo && hi && d > (lo < hi ? lo : hi) && d < (lo < hi ? hi : lo);
|
|
3149
|
+
};
|
|
3150
|
+
const isEdge = (d) => s && iso(d) === iso(s) || e && iso(d) === iso(e);
|
|
3151
|
+
const clickDay = (d) => {
|
|
3152
|
+
const v = iso(d);
|
|
3153
|
+
if (!range) {
|
|
3154
|
+
onPick(v);
|
|
3155
|
+
return;
|
|
3156
|
+
}
|
|
3157
|
+
if (!sel.start || sel.start && sel.end) onPick({ start: v, end: "" });
|
|
3158
|
+
else {
|
|
3159
|
+
const a = parse(sel.start);
|
|
3160
|
+
onPick(d < a ? { start: v, end: sel.start } : { start: sel.start, end: v });
|
|
3161
|
+
}
|
|
3162
|
+
};
|
|
3163
|
+
const nav = (d) => {
|
|
3164
|
+
let m = vm + d, y = vy;
|
|
3165
|
+
if (m < 0) {
|
|
3166
|
+
m = 11;
|
|
3167
|
+
y--;
|
|
3168
|
+
}
|
|
3169
|
+
if (m > 11) {
|
|
3170
|
+
m = 0;
|
|
3171
|
+
y++;
|
|
3172
|
+
}
|
|
3173
|
+
setVm(m);
|
|
3174
|
+
setVy(y);
|
|
3175
|
+
};
|
|
3176
|
+
const monthGrid = (y, m) => {
|
|
3177
|
+
const startPad = new Date(y, m, 1).getDay();
|
|
3178
|
+
const cells = [];
|
|
3179
|
+
for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
|
|
3180
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
|
|
3181
|
+
DOW.map((d) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fd-cal-dow", children: d }, d)),
|
|
3182
|
+
cells.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3183
|
+
"button",
|
|
3184
|
+
{
|
|
3185
|
+
type: "button",
|
|
3186
|
+
className: ["fd-cal-day", d.getMonth() !== m ? "is-out" : "", iso(d) === iso(today) ? "is-today" : "", inRange(d) ? "in-range" : "", isEdge(d) ? "is-edge" : ""].filter(Boolean).join(" "),
|
|
3187
|
+
onClick: () => clickDay(d),
|
|
3188
|
+
onMouseEnter: () => range && setHover(iso(d)),
|
|
3189
|
+
children: d.getDate()
|
|
3190
|
+
},
|
|
3191
|
+
i
|
|
3192
|
+
))
|
|
3193
|
+
] });
|
|
3194
|
+
};
|
|
3195
|
+
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
3196
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
|
|
3197
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "fd-cal-head", children: [
|
|
3198
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Previous", onClick: () => mode2 === "years" ? setVy(vy - 12) : mode2 === "months" ? setVy(vy - 1) : nav(-1), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-caret-left" }) }),
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
|
|
3200
|
+
mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
|
|
3201
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
|
|
3202
|
+
] }),
|
|
3203
|
+
months > 1 && mode2 === "days" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
|
|
3204
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Next", onClick: () => mode2 === "years" ? setVy(vy + 12) : mode2 === "months" ? setVy(vy + 1) : nav(1), children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-caret-right" }) })
|
|
3205
|
+
] }),
|
|
3206
|
+
mode2 === "days" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { style: { display: "flex", gap: 18 }, children: [
|
|
3207
|
+
monthGrid(vy, vm),
|
|
3208
|
+
months > 1 ? monthGrid(nextY, nextM) : null
|
|
3209
|
+
] }) : mode2 === "months" ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3210
|
+
"button",
|
|
3211
|
+
{
|
|
3212
|
+
type: "button",
|
|
3213
|
+
className: "fd-cal-cell" + (i === vm && s && s.getFullYear() === vy ? " is-sel" : ""),
|
|
3214
|
+
onClick: () => {
|
|
3215
|
+
setVm(i);
|
|
3216
|
+
setMode("days");
|
|
3217
|
+
},
|
|
3218
|
+
children: m.slice(0, 3)
|
|
3219
|
+
},
|
|
3220
|
+
m
|
|
3221
|
+
)) }) : /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "fd-cal-grid-months", children: Array.from({ length: 12 }, (_, i) => vy - 5 + i).map((y) => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3222
|
+
"button",
|
|
3223
|
+
{
|
|
3224
|
+
type: "button",
|
|
3225
|
+
className: "fd-cal-cell" + (y === vy ? " is-sel" : ""),
|
|
3226
|
+
onClick: () => {
|
|
3227
|
+
setVy(y);
|
|
3228
|
+
setMode("months");
|
|
3229
|
+
},
|
|
3230
|
+
children: y
|
|
3231
|
+
},
|
|
3232
|
+
y
|
|
3233
|
+
)) }),
|
|
3234
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "fd-cal-foot", children: [
|
|
3235
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3236
|
+
"button",
|
|
3237
|
+
{
|
|
3238
|
+
type: "button",
|
|
3239
|
+
className: "fd-btn fd-btn-link",
|
|
3240
|
+
style: { fontSize: 12.5 },
|
|
3241
|
+
onClick: () => {
|
|
3242
|
+
setVy(today.getFullYear());
|
|
3243
|
+
setVm(today.getMonth());
|
|
3244
|
+
setMode("days");
|
|
3245
|
+
},
|
|
3246
|
+
children: "Today"
|
|
3247
|
+
}
|
|
3248
|
+
),
|
|
3249
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { style: { flex: 1 } }),
|
|
3250
|
+
range && sel.start ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
3251
|
+
fmt(sel.start),
|
|
3252
|
+
sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
|
|
3253
|
+
] }) : null
|
|
3254
|
+
] })
|
|
3255
|
+
] });
|
|
3256
|
+
}
|
|
3257
|
+
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
|
|
3258
|
+
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
3259
|
+
const [open, setOpen] = React22.useState(false);
|
|
3260
|
+
const rootRef = React22.useRef(null);
|
|
3261
|
+
const boxRef = React22.useRef(null);
|
|
3262
|
+
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
3263
|
+
const toggle = () => {
|
|
3264
|
+
if (!disabled) setOpen(!open);
|
|
3265
|
+
};
|
|
3266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
3267
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
3268
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
|
|
3269
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fd-input-icon", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
|
|
3270
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3271
|
+
"button",
|
|
3272
|
+
{
|
|
3273
|
+
type: "button",
|
|
3274
|
+
id: fieldId,
|
|
3275
|
+
"aria-labelledby": ariaLabelledBy,
|
|
3276
|
+
title: truncationTitle(display),
|
|
3277
|
+
disabled,
|
|
3278
|
+
onKeyDown: (e) => {
|
|
3279
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3280
|
+
e.preventDefault();
|
|
3281
|
+
toggle();
|
|
3282
|
+
}
|
|
3283
|
+
},
|
|
3284
|
+
style: { all: "unset", flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", cursor: "inherit", color: display ? "var(--text)" : "var(--text-muted)" },
|
|
3285
|
+
...rest,
|
|
3286
|
+
children: display || placeholder || (range ? "Pick a date range" : "Pick a date")
|
|
3287
|
+
}
|
|
3288
|
+
),
|
|
3289
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fd-select-caret", children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-caret-down", "aria-hidden": "true" }) })
|
|
3290
|
+
] }),
|
|
3291
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3292
|
+
Popover,
|
|
3293
|
+
{
|
|
3294
|
+
open,
|
|
3295
|
+
anchorRef: boxRef,
|
|
3296
|
+
triggerRef: rootRef,
|
|
3297
|
+
onClose: () => setOpen(false),
|
|
3298
|
+
placement: "bottom-start",
|
|
3299
|
+
offset: 6,
|
|
3300
|
+
role: "presentation",
|
|
3301
|
+
style: { width: "max-content" },
|
|
3302
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
3303
|
+
Calendar,
|
|
3304
|
+
{
|
|
3305
|
+
range,
|
|
3306
|
+
months: range ? 2 : 1,
|
|
3307
|
+
value,
|
|
3308
|
+
onPick: (v) => {
|
|
3309
|
+
onChange && onChange({ target: { value: v } });
|
|
3310
|
+
if (!range || v.start && v.end) setOpen(false);
|
|
3311
|
+
}
|
|
3312
|
+
}
|
|
3313
|
+
)
|
|
3314
|
+
}
|
|
3315
|
+
),
|
|
3316
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { className: "fd-field-error", children: [
|
|
3317
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3318
|
+
error
|
|
3319
|
+
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
3320
|
+
] });
|
|
3321
|
+
}
|
|
3322
|
+
|
|
3323
|
+
// src/components/forms/Textarea.tsx
|
|
3324
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
3325
|
+
function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
|
|
3326
|
+
const fieldId = useFieldId(id);
|
|
3327
|
+
const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
3328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
3329
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
3330
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: box, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
|
|
3331
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "fd-field-error", children: [
|
|
3332
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
3333
|
+
error
|
|
3334
|
+
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
3335
|
+
] });
|
|
3336
|
+
}
|
|
3337
|
+
|
|
3338
|
+
// src/components/data/FilterBar.tsx
|
|
3339
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2958
3340
|
var isSet = (v) => !(v == null || v === "" || v === false);
|
|
3341
|
+
function isFieldSet(field, value) {
|
|
3342
|
+
switch (field.type) {
|
|
3343
|
+
case "text":
|
|
3344
|
+
case "select":
|
|
3345
|
+
return isSet(value);
|
|
3346
|
+
case "multiSelect":
|
|
3347
|
+
case "pasteList": {
|
|
3348
|
+
const v = value;
|
|
3349
|
+
return !!v && Array.isArray(v.values) && v.values.length > 0;
|
|
3350
|
+
}
|
|
3351
|
+
case "range": {
|
|
3352
|
+
const v = value;
|
|
3353
|
+
return !!v && (v.min != null || v.max != null);
|
|
3354
|
+
}
|
|
3355
|
+
case "date": {
|
|
3356
|
+
const v = value;
|
|
3357
|
+
if (!v) return false;
|
|
3358
|
+
return v.kind === "withinDays" ? v.days != null : !!(v.from || v.to);
|
|
3359
|
+
}
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
function chipLabel(field, value) {
|
|
3363
|
+
switch (field.type) {
|
|
3364
|
+
case "text":
|
|
3365
|
+
return String(value ?? "");
|
|
3366
|
+
case "select": {
|
|
3367
|
+
const chosen = field.options.find((o) => o.value === value);
|
|
3368
|
+
return chosen ? chosen.label : String(value ?? "");
|
|
3369
|
+
}
|
|
3370
|
+
case "multiSelect":
|
|
3371
|
+
case "pasteList": {
|
|
3372
|
+
const v = value;
|
|
3373
|
+
if (!v || !v.values.length) return "";
|
|
3374
|
+
const prefix = v.operator === "notIn" ? "Not " : "";
|
|
3375
|
+
return v.values.length <= 2 ? prefix + v.values.map((o) => o.label).join(", ") : prefix + v.values.length + " selected";
|
|
3376
|
+
}
|
|
3377
|
+
case "range": {
|
|
3378
|
+
const v = value;
|
|
3379
|
+
if (!v) return "";
|
|
3380
|
+
if (v.min != null && v.max != null) return v.min + "\u2013" + v.max;
|
|
3381
|
+
if (v.min != null) return "\u2265 " + v.min;
|
|
3382
|
+
if (v.max != null) return "\u2264 " + v.max;
|
|
3383
|
+
return "";
|
|
3384
|
+
}
|
|
3385
|
+
case "date": {
|
|
3386
|
+
const v = value;
|
|
3387
|
+
if (!v) return "";
|
|
3388
|
+
if (v.kind === "withinDays") return "Last " + v.days + " day" + (v.days === 1 ? "" : "s");
|
|
3389
|
+
return (v.from || "\u2026") + " \u2192 " + (v.to || "\u2026");
|
|
3390
|
+
}
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
function OperatorToggle({
|
|
3394
|
+
operator,
|
|
3395
|
+
onChange,
|
|
3396
|
+
label
|
|
3397
|
+
}) {
|
|
3398
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3399
|
+
SegmentedControl,
|
|
3400
|
+
{
|
|
3401
|
+
"aria-label": label + " \u2014 include or exclude",
|
|
3402
|
+
options: [
|
|
3403
|
+
{ value: "in", label: "Is any of" },
|
|
3404
|
+
{ value: "notIn", label: "Is none of" }
|
|
3405
|
+
],
|
|
3406
|
+
value: operator,
|
|
3407
|
+
onChange: (v) => onChange(v)
|
|
3408
|
+
}
|
|
3409
|
+
);
|
|
3410
|
+
}
|
|
3411
|
+
function EditPopover({ zIndex, width, children }) {
|
|
3412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3413
|
+
"span",
|
|
3414
|
+
{
|
|
3415
|
+
className: "fd-view-enter",
|
|
3416
|
+
style: {
|
|
3417
|
+
position: "absolute",
|
|
3418
|
+
top: "calc(100% + 6px)",
|
|
3419
|
+
left: 0,
|
|
3420
|
+
zIndex,
|
|
3421
|
+
width,
|
|
3422
|
+
maxWidth: "calc(100vw - 32px)",
|
|
3423
|
+
display: "block",
|
|
3424
|
+
background: "var(--surface)",
|
|
3425
|
+
border: "1px solid var(--border)",
|
|
3426
|
+
borderRadius: 10,
|
|
3427
|
+
boxShadow: "0 16px 44px rgba(11,13,17,.18)",
|
|
3428
|
+
padding: "var(--s-8)"
|
|
3429
|
+
},
|
|
3430
|
+
children
|
|
3431
|
+
}
|
|
3432
|
+
) });
|
|
3433
|
+
}
|
|
3434
|
+
function MultiSelectPanel({
|
|
3435
|
+
field,
|
|
3436
|
+
value,
|
|
3437
|
+
onChange,
|
|
3438
|
+
onClose
|
|
3439
|
+
}) {
|
|
3440
|
+
const operator = value?.operator ?? "in";
|
|
3441
|
+
const selected = value?.values ?? [];
|
|
3442
|
+
const [query, setQuery] = React23.useState("");
|
|
3443
|
+
const [asyncOptions, setAsyncOptions] = React23.useState(null);
|
|
3444
|
+
const [loading, setLoading] = React23.useState(!!field.loadOptions);
|
|
3445
|
+
const [active, setActive] = React23.useState(0);
|
|
3446
|
+
const inputRef = React23.useRef(null);
|
|
3447
|
+
const listId = React23.useId();
|
|
3448
|
+
React23.useEffect(() => {
|
|
3449
|
+
inputRef.current?.focus();
|
|
3450
|
+
}, []);
|
|
3451
|
+
React23.useEffect(() => {
|
|
3452
|
+
if (!field.loadOptions) return;
|
|
3453
|
+
let cancelled = false;
|
|
3454
|
+
setLoading(true);
|
|
3455
|
+
const loadOptions = field.loadOptions;
|
|
3456
|
+
const t = setTimeout(() => {
|
|
3457
|
+
loadOptions(query).then((opts) => {
|
|
3458
|
+
if (!cancelled) {
|
|
3459
|
+
setAsyncOptions(opts);
|
|
3460
|
+
setLoading(false);
|
|
3461
|
+
}
|
|
3462
|
+
}).catch(() => {
|
|
3463
|
+
if (!cancelled) {
|
|
3464
|
+
setAsyncOptions([]);
|
|
3465
|
+
setLoading(false);
|
|
3466
|
+
}
|
|
3467
|
+
});
|
|
3468
|
+
}, 300);
|
|
3469
|
+
return () => {
|
|
3470
|
+
cancelled = true;
|
|
3471
|
+
clearTimeout(t);
|
|
3472
|
+
};
|
|
3473
|
+
}, [query, field.loadOptions]);
|
|
3474
|
+
const options = field.loadOptions ? asyncOptions ?? [] : (field.options ?? []).filter((o) => o.label.toLowerCase().includes(query.toLowerCase()));
|
|
3475
|
+
React23.useEffect(() => {
|
|
3476
|
+
setActive(0);
|
|
3477
|
+
}, [query, options.length]);
|
|
3478
|
+
const isSelected = (o) => selected.some((s) => s.value === o.value);
|
|
3479
|
+
const toggle = (o) => {
|
|
3480
|
+
const next = isSelected(o) ? selected.filter((s) => s.value !== o.value) : [...selected, o];
|
|
3481
|
+
onChange({ operator, values: next });
|
|
3482
|
+
};
|
|
3483
|
+
const activeId = options[active] ? listId + "-opt-" + active : void 0;
|
|
3484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", style: { gap: "var(--s-8)", width: 260 }, children: [
|
|
3485
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(OperatorToggle, { operator, onChange: (op) => onChange({ operator: op, values: selected }), label: field.label }),
|
|
3486
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3487
|
+
"input",
|
|
3488
|
+
{
|
|
3489
|
+
ref: inputRef,
|
|
3490
|
+
role: "combobox",
|
|
3491
|
+
"aria-expanded": "true",
|
|
3492
|
+
"aria-controls": listId,
|
|
3493
|
+
"aria-autocomplete": "list",
|
|
3494
|
+
"aria-activedescendant": activeId,
|
|
3495
|
+
"aria-label": field.label,
|
|
3496
|
+
className: "fd-input",
|
|
3497
|
+
style: { width: "100%", padding: "6px 10px" },
|
|
3498
|
+
value: query,
|
|
3499
|
+
placeholder: field.placeholder || "Search\u2026",
|
|
3500
|
+
onChange: (e) => setQuery(e.target.value),
|
|
3501
|
+
onKeyDown: (e) => {
|
|
3502
|
+
if (e.key === "ArrowDown") {
|
|
3503
|
+
e.preventDefault();
|
|
3504
|
+
setActive((a) => Math.min(a + 1, options.length - 1));
|
|
3505
|
+
} else if (e.key === "ArrowUp") {
|
|
3506
|
+
e.preventDefault();
|
|
3507
|
+
setActive((a) => Math.max(a - 1, 0));
|
|
3508
|
+
} else if (e.key === "Enter") {
|
|
3509
|
+
e.preventDefault();
|
|
3510
|
+
if (options[active]) toggle(options[active]);
|
|
3511
|
+
} else if (e.key === "Escape") {
|
|
3512
|
+
e.stopPropagation();
|
|
3513
|
+
onClose();
|
|
3514
|
+
}
|
|
3515
|
+
}
|
|
3516
|
+
}
|
|
3517
|
+
),
|
|
3518
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-row fd-body-sm fd-muted", style: { gap: "var(--s-4)" }, children: [
|
|
3519
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-spinner", "aria-hidden": "true" }),
|
|
3520
|
+
" Loading\u2026"
|
|
3521
|
+
] }) : options.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-body-sm fd-muted", children: "No matches" }) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3522
|
+
"span",
|
|
3523
|
+
{
|
|
3524
|
+
id: listId,
|
|
3525
|
+
role: "listbox",
|
|
3526
|
+
"aria-label": field.label,
|
|
3527
|
+
"aria-multiselectable": "true",
|
|
3528
|
+
className: "fd-stack",
|
|
3529
|
+
style: { gap: 2, maxHeight: 220, overflowY: "auto" },
|
|
3530
|
+
children: options.map((o, i) => {
|
|
3531
|
+
const on = isSelected(o);
|
|
3532
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
3533
|
+
"button",
|
|
3534
|
+
{
|
|
3535
|
+
type: "button",
|
|
3536
|
+
id: listId + "-opt-" + i,
|
|
3537
|
+
role: "option",
|
|
3538
|
+
"aria-selected": on,
|
|
3539
|
+
className: "fd-row",
|
|
3540
|
+
onMouseEnter: () => setActive(i),
|
|
3541
|
+
onClick: () => toggle(o),
|
|
3542
|
+
style: {
|
|
3543
|
+
gap: "var(--s-8)",
|
|
3544
|
+
padding: "4px 8px",
|
|
3545
|
+
borderRadius: 7,
|
|
3546
|
+
border: 0,
|
|
3547
|
+
width: "100%",
|
|
3548
|
+
textAlign: "left",
|
|
3549
|
+
cursor: "pointer",
|
|
3550
|
+
background: i === active ? "var(--surface-brand)" : "transparent"
|
|
3551
|
+
},
|
|
3552
|
+
children: [
|
|
3553
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("i", { className: on ? "ph ph-check-square" : "ph ph-square", "aria-hidden": "true" }),
|
|
3554
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-body-sm", style: { flex: 1, color: "var(--text)" }, children: o.label })
|
|
3555
|
+
]
|
|
3556
|
+
},
|
|
3557
|
+
o.value
|
|
3558
|
+
);
|
|
3559
|
+
})
|
|
3560
|
+
}
|
|
3561
|
+
),
|
|
3562
|
+
selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
3563
|
+
selected.length,
|
|
3564
|
+
" selected"
|
|
3565
|
+
] }) : null
|
|
3566
|
+
] });
|
|
3567
|
+
}
|
|
3568
|
+
function RangePanel({
|
|
3569
|
+
field,
|
|
3570
|
+
value,
|
|
3571
|
+
onChange,
|
|
3572
|
+
onClose
|
|
3573
|
+
}) {
|
|
3574
|
+
const min = value?.min;
|
|
3575
|
+
const max = value?.max;
|
|
3576
|
+
const rangeError = min != null && max != null && min > max ? "Must be \u2265 " + (field.minLabel || "min").toLowerCase() : void 0;
|
|
3577
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", style: { gap: "var(--s-8)", width: 240 }, children: [
|
|
3578
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3579
|
+
NumberInput,
|
|
3580
|
+
{
|
|
3581
|
+
label: field.minLabel || "At least",
|
|
3582
|
+
value: min ?? "",
|
|
3583
|
+
min: field.min,
|
|
3584
|
+
max: field.max,
|
|
3585
|
+
step: field.step,
|
|
3586
|
+
placeholder: field.minPlaceholder,
|
|
3587
|
+
onChange: (e) => onChange({ min: e.target.value, max })
|
|
3588
|
+
}
|
|
3589
|
+
),
|
|
3590
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3591
|
+
NumberInput,
|
|
3592
|
+
{
|
|
3593
|
+
label: field.maxLabel || "At most",
|
|
3594
|
+
value: max ?? "",
|
|
3595
|
+
min: field.min,
|
|
3596
|
+
max: field.max,
|
|
3597
|
+
step: field.step,
|
|
3598
|
+
error: rangeError,
|
|
3599
|
+
placeholder: field.maxPlaceholder,
|
|
3600
|
+
onChange: (e) => onChange({ min, max: e.target.value })
|
|
3601
|
+
}
|
|
3602
|
+
),
|
|
3603
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: onClose, children: "Done" })
|
|
3604
|
+
] });
|
|
3605
|
+
}
|
|
3606
|
+
function DatePanel({
|
|
3607
|
+
field,
|
|
3608
|
+
value,
|
|
3609
|
+
onChange,
|
|
3610
|
+
onClose
|
|
3611
|
+
}) {
|
|
3612
|
+
const kind = value?.kind ?? "withinDays";
|
|
3613
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", style: { gap: "var(--s-8)", width: 300 }, children: [
|
|
3614
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3615
|
+
SegmentedControl,
|
|
3616
|
+
{
|
|
3617
|
+
"aria-label": field.label + " \u2014 relative or between dates",
|
|
3618
|
+
options: [
|
|
3619
|
+
{ value: "withinDays", label: "Within last N days" },
|
|
3620
|
+
{ value: "between", label: "Between dates" }
|
|
3621
|
+
],
|
|
3622
|
+
value: kind,
|
|
3623
|
+
onChange: (k) => {
|
|
3624
|
+
if (k === "withinDays") {
|
|
3625
|
+
onChange({ kind: "withinDays", days: value?.kind === "withinDays" ? value.days : field.defaultDays ?? 30 });
|
|
3626
|
+
} else {
|
|
3627
|
+
onChange({ kind: "between", from: value?.kind === "between" ? value.from : "", to: value?.kind === "between" ? value.to : "" });
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
}
|
|
3631
|
+
),
|
|
3632
|
+
kind === "withinDays" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3633
|
+
NumberInput,
|
|
3634
|
+
{
|
|
3635
|
+
label: "Days",
|
|
3636
|
+
min: 1,
|
|
3637
|
+
value: value?.kind === "withinDays" ? value.days : field.defaultDays ?? 30,
|
|
3638
|
+
onChange: (e) => onChange({ kind: "withinDays", days: e.target.value })
|
|
3639
|
+
}
|
|
3640
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3641
|
+
DatePicker,
|
|
3642
|
+
{
|
|
3643
|
+
range: true,
|
|
3644
|
+
label: "Date range",
|
|
3645
|
+
value: value?.kind === "between" ? { start: value.from, end: value.to } : void 0,
|
|
3646
|
+
onChange: (e) => onChange({ kind: "between", from: e.target.value.start || "", to: e.target.value.end || "" })
|
|
3647
|
+
}
|
|
3648
|
+
),
|
|
3649
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: onClose, children: "Done" })
|
|
3650
|
+
] });
|
|
3651
|
+
}
|
|
3652
|
+
function PasteListPanel({
|
|
3653
|
+
field,
|
|
3654
|
+
value,
|
|
3655
|
+
onChange,
|
|
3656
|
+
onClose
|
|
3657
|
+
}) {
|
|
3658
|
+
const operator = value?.operator ?? "in";
|
|
3659
|
+
const selected = value?.values ?? [];
|
|
3660
|
+
const [text, setText] = React23.useState("");
|
|
3661
|
+
const [loading, setLoading] = React23.useState(false);
|
|
3662
|
+
const [unmatched, setUnmatched] = React23.useState([]);
|
|
3663
|
+
const [error, setError] = React23.useState(null);
|
|
3664
|
+
const wrapRef = React23.useRef(null);
|
|
3665
|
+
React23.useEffect(() => {
|
|
3666
|
+
wrapRef.current?.querySelector("textarea")?.focus();
|
|
3667
|
+
}, []);
|
|
3668
|
+
const doResolve = () => {
|
|
3669
|
+
const tokens = text.split(/[\n,]/).map((t) => t.trim()).filter(Boolean);
|
|
3670
|
+
if (!tokens.length) return;
|
|
3671
|
+
setLoading(true);
|
|
3672
|
+
setError(null);
|
|
3673
|
+
field.resolve(tokens).then((result) => {
|
|
3674
|
+
setLoading(false);
|
|
3675
|
+
setUnmatched(result.unmatched);
|
|
3676
|
+
const merged = new Map(selected.map((s) => [s.value, s]));
|
|
3677
|
+
for (const m of result.matched) merged.set(m.value, { value: m.value, label: m.label });
|
|
3678
|
+
onChange({ operator, values: Array.from(merged.values()) });
|
|
3679
|
+
setText("");
|
|
3680
|
+
}).catch((err) => {
|
|
3681
|
+
setLoading(false);
|
|
3682
|
+
setError(err instanceof Error ? err.message : "Could not resolve the pasted list.");
|
|
3683
|
+
});
|
|
3684
|
+
};
|
|
3685
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", style: { gap: "var(--s-8)", width: 320 }, children: [
|
|
3686
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(OperatorToggle, { operator, onChange: (op) => onChange({ operator: op, values: selected }), label: field.label }),
|
|
3687
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { ref: wrapRef, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3688
|
+
Textarea,
|
|
3689
|
+
{
|
|
3690
|
+
"aria-label": field.label + " \u2014 paste a list",
|
|
3691
|
+
rows: 4,
|
|
3692
|
+
placeholder: field.placeholder || "Paste names, one per line or comma-separated",
|
|
3693
|
+
value: text,
|
|
3694
|
+
disabled: loading,
|
|
3695
|
+
onChange: (e) => setText(e.target.value),
|
|
3696
|
+
onKeyDown: (e) => {
|
|
3697
|
+
if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) {
|
|
3698
|
+
e.preventDefault();
|
|
3699
|
+
doResolve();
|
|
3700
|
+
}
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
) }),
|
|
3704
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: doResolve, disabled: loading || !text.trim(), children: loading ? "Resolving\u2026" : "Resolve" }),
|
|
3705
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Banner, { tone: "danger", title: "Couldn't resolve the list", detail: error }) : null,
|
|
3706
|
+
unmatched.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Banner, { tone: "warn", title: unmatched.length + " didn't match", detail: unmatched.join(", ") }) : null,
|
|
3707
|
+
selected.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", style: { gap: "var(--s-4)" }, children: [
|
|
3708
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
3709
|
+
selected.length,
|
|
3710
|
+
" matched"
|
|
3711
|
+
] }),
|
|
3712
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-row", style: { flexWrap: "wrap", gap: "var(--s-4)" }, children: selected.map((v) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Tag, { onRemove: () => onChange({ operator, values: selected.filter((s) => s.value !== v.value) }), children: v.label }, v.value)) })
|
|
3713
|
+
] }) : null,
|
|
3714
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Button, { size: "sm", variant: "secondary", onClick: onClose, children: "Done" })
|
|
3715
|
+
] });
|
|
3716
|
+
}
|
|
2959
3717
|
function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align = "left", className = "", ...rest }) {
|
|
2960
|
-
const [panel, setPanel] =
|
|
3718
|
+
const [panel, setPanel] = React23.useState(null);
|
|
2961
3719
|
const zIndex = useOverlayLayer(!!panel);
|
|
2962
|
-
const rootRef =
|
|
2963
|
-
const textInputRef =
|
|
2964
|
-
const optionsRef =
|
|
3720
|
+
const rootRef = React23.useRef(null);
|
|
3721
|
+
const textInputRef = React23.useRef(null);
|
|
3722
|
+
const optionsRef = React23.useRef(null);
|
|
2965
3723
|
const editingField = panel && panel.kind === "edit" ? fields.find((f) => f.key === panel.key) : void 0;
|
|
2966
|
-
const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type
|
|
2967
|
-
|
|
3724
|
+
const dismissible = !!panel && (panel.kind === "add" || panel.kind === "edit" && editingField?.type !== "text");
|
|
3725
|
+
React23.useEffect(() => {
|
|
2968
3726
|
if (!dismissible) return;
|
|
2969
3727
|
const away = (e) => {
|
|
3728
|
+
const target = e.target;
|
|
3729
|
+
if (target.closest && target.closest(".fd-pop")) return;
|
|
2970
3730
|
if (rootRef.current && !rootRef.current.contains(e.target)) setPanel(null);
|
|
2971
3731
|
};
|
|
2972
3732
|
const esc = (e) => {
|
|
@@ -2979,7 +3739,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
2979
3739
|
document.removeEventListener("keydown", esc);
|
|
2980
3740
|
};
|
|
2981
3741
|
}, [dismissible]);
|
|
2982
|
-
|
|
3742
|
+
React23.useEffect(() => {
|
|
2983
3743
|
if (!panel || panel.kind !== "edit") return;
|
|
2984
3744
|
if (editingField?.type === "text") {
|
|
2985
3745
|
textInputRef.current?.focus();
|
|
@@ -2988,20 +3748,20 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
2988
3748
|
target?.focus();
|
|
2989
3749
|
}
|
|
2990
3750
|
}, [panel]);
|
|
2991
|
-
const addableFields = fields.filter((f) => !
|
|
3751
|
+
const addableFields = fields.filter((f) => !isFieldSet(f, filters[f.key]));
|
|
2992
3752
|
const startEditing = (key) => setPanel({ kind: "edit", key });
|
|
2993
|
-
return /* @__PURE__ */ (0,
|
|
3753
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className, style: { position: "relative", display: "inline-flex", flexWrap: "wrap", alignItems: "center", gap: 8 }, ref: rootRef, ...rest, children: [
|
|
2994
3754
|
fields.map((field) => {
|
|
2995
3755
|
const value = filters[field.key];
|
|
2996
3756
|
const editing = panel?.kind === "edit" && panel.key === field.key;
|
|
2997
3757
|
if (editing && field.type === "text") {
|
|
2998
|
-
return /* @__PURE__ */ (0,
|
|
3758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
2999
3759
|
"span",
|
|
3000
3760
|
{
|
|
3001
3761
|
className: "fd-tag",
|
|
3002
3762
|
style: { background: "var(--surface-brand)", borderColor: "var(--border-brand)", cursor: "text" },
|
|
3003
3763
|
children: [
|
|
3004
|
-
/* @__PURE__ */ (0,
|
|
3764
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3005
3765
|
"input",
|
|
3006
3766
|
{
|
|
3007
3767
|
ref: textInputRef,
|
|
@@ -3020,7 +3780,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3020
3780
|
style: { all: "unset", minWidth: 90, color: "var(--text-on-surface-brand)" }
|
|
3021
3781
|
}
|
|
3022
3782
|
),
|
|
3023
|
-
isSet(value) ? /* @__PURE__ */ (0,
|
|
3783
|
+
isSet(value) ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3024
3784
|
"span",
|
|
3025
3785
|
{
|
|
3026
3786
|
className: "fd-tag-remove",
|
|
@@ -3031,7 +3791,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3031
3791
|
onFilterRemove(field.key);
|
|
3032
3792
|
setPanel(null);
|
|
3033
3793
|
},
|
|
3034
|
-
children: /* @__PURE__ */ (0,
|
|
3794
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("i", { className: "ph ph-x", "aria-hidden": "true" })
|
|
3035
3795
|
}
|
|
3036
3796
|
) : null
|
|
3037
3797
|
]
|
|
@@ -3041,22 +3801,22 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3041
3801
|
}
|
|
3042
3802
|
if (editing && field.type === "select") {
|
|
3043
3803
|
const chosen = field.options.find((o) => o.value === value);
|
|
3044
|
-
return /* @__PURE__ */ (0,
|
|
3045
|
-
/* @__PURE__ */ (0,
|
|
3804
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3805
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
3046
3806
|
if (isSet(value)) onFilterRemove(field.key);
|
|
3047
3807
|
setPanel(null);
|
|
3048
3808
|
}, children: [
|
|
3049
3809
|
field.label,
|
|
3050
3810
|
chosen ? ": " + chosen.label : ""
|
|
3051
3811
|
] }),
|
|
3052
|
-
/* @__PURE__ */ (0,
|
|
3812
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3053
3813
|
"span",
|
|
3054
3814
|
{
|
|
3055
3815
|
className: "fd-view-enter",
|
|
3056
3816
|
style: { position: "absolute", top: "calc(100% + 6px)", left: 0, zIndex, minWidth: 200, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
|
|
3057
|
-
children: /* @__PURE__ */ (0,
|
|
3817
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-stack", role: "listbox", "aria-label": field.label, ref: optionsRef, style: { gap: 2 }, children: field.options.map((o) => {
|
|
3058
3818
|
const on = o.value === value;
|
|
3059
|
-
return /* @__PURE__ */ (0,
|
|
3819
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3060
3820
|
"button",
|
|
3061
3821
|
{
|
|
3062
3822
|
type: "button",
|
|
@@ -3068,7 +3828,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3068
3828
|
setPanel(null);
|
|
3069
3829
|
},
|
|
3070
3830
|
style: { gap: 8, padding: "4px 8px", borderRadius: 7, border: 0, width: "100%", textAlign: "left", cursor: "pointer", background: on ? "var(--surface-brand)" : "transparent" },
|
|
3071
|
-
children: /* @__PURE__ */ (0,
|
|
3831
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-body-sm", style: { flex: 1, fontWeight: on ? 700 : 500, color: on ? "var(--text-on-surface-brand)" : "var(--text)" }, children: o.label })
|
|
3072
3832
|
},
|
|
3073
3833
|
o.value
|
|
3074
3834
|
);
|
|
@@ -3077,19 +3837,69 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3077
3837
|
) })
|
|
3078
3838
|
] }, field.key);
|
|
3079
3839
|
}
|
|
3080
|
-
if (
|
|
3081
|
-
const
|
|
3082
|
-
|
|
3083
|
-
|
|
3840
|
+
if (editing && field.type === "multiSelect") {
|
|
3841
|
+
const mv = value;
|
|
3842
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3843
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
3844
|
+
if (isFieldSet(field, value)) onFilterRemove(field.key);
|
|
3845
|
+
setPanel(null);
|
|
3846
|
+
}, children: [
|
|
3847
|
+
field.label,
|
|
3848
|
+
isFieldSet(field, value) ? ": " + chipLabel(field, value) : ""
|
|
3849
|
+
] }),
|
|
3850
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(EditPopover, { zIndex, width: 260, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(MultiSelectPanel, { field, value: mv, onChange: (v) => onFilterChange(field.key, v), onClose: () => setPanel(null) }) })
|
|
3851
|
+
] }, field.key);
|
|
3852
|
+
}
|
|
3853
|
+
if (editing && field.type === "range") {
|
|
3854
|
+
const rv = value;
|
|
3855
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3856
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
3857
|
+
if (isFieldSet(field, value)) onFilterRemove(field.key);
|
|
3858
|
+
setPanel(null);
|
|
3859
|
+
}, children: [
|
|
3860
|
+
field.label,
|
|
3861
|
+
isFieldSet(field, value) ? ": " + chipLabel(field, value) : ""
|
|
3862
|
+
] }),
|
|
3863
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(EditPopover, { zIndex, width: 240, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(RangePanel, { field, value: rv, onChange: (v) => onFilterChange(field.key, v), onClose: () => setPanel(null) }) })
|
|
3864
|
+
] }, field.key);
|
|
3865
|
+
}
|
|
3866
|
+
if (editing && field.type === "date") {
|
|
3867
|
+
const dv = value;
|
|
3868
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3869
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
3870
|
+
if (isFieldSet(field, value)) onFilterRemove(field.key);
|
|
3871
|
+
setPanel(null);
|
|
3872
|
+
}, children: [
|
|
3873
|
+
field.label,
|
|
3874
|
+
isFieldSet(field, value) ? ": " + chipLabel(field, value) : ""
|
|
3875
|
+
] }),
|
|
3876
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(EditPopover, { zIndex, width: 300, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(DatePanel, { field, value: dv, onChange: (v) => onFilterChange(field.key, v), onClose: () => setPanel(null) }) })
|
|
3877
|
+
] }, field.key);
|
|
3878
|
+
}
|
|
3879
|
+
if (editing && field.type === "pasteList") {
|
|
3880
|
+
const pv = value;
|
|
3881
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3882
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => setPanel(null), onRemove: () => {
|
|
3883
|
+
if (isFieldSet(field, value)) onFilterRemove(field.key);
|
|
3884
|
+
setPanel(null);
|
|
3885
|
+
}, children: [
|
|
3886
|
+
field.label,
|
|
3887
|
+
isFieldSet(field, value) ? ": " + chipLabel(field, value) : ""
|
|
3888
|
+
] }),
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(EditPopover, { zIndex, width: 320, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PasteListPanel, { field, value: pv, onChange: (v) => onFilterChange(field.key, v), onClose: () => setPanel(null) }) })
|
|
3890
|
+
] }, field.key);
|
|
3891
|
+
}
|
|
3892
|
+
if (isFieldSet(field, value)) {
|
|
3893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(Tag, { selected: true, onClick: () => startEditing(field.key), onRemove: () => onFilterRemove(field.key), children: [
|
|
3084
3894
|
field.label,
|
|
3085
3895
|
": ",
|
|
3086
|
-
|
|
3896
|
+
chipLabel(field, value)
|
|
3087
3897
|
] }, field.key);
|
|
3088
3898
|
}
|
|
3089
3899
|
return null;
|
|
3090
3900
|
}),
|
|
3091
|
-
addableFields.length > 0 ? /* @__PURE__ */ (0,
|
|
3092
|
-
/* @__PURE__ */ (0,
|
|
3901
|
+
addableFields.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { style: { position: "relative", display: "inline-flex" }, children: [
|
|
3902
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3093
3903
|
Button,
|
|
3094
3904
|
{
|
|
3095
3905
|
size: "sm",
|
|
@@ -3101,14 +3911,14 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3101
3911
|
children: "Filter"
|
|
3102
3912
|
}
|
|
3103
3913
|
),
|
|
3104
|
-
panel?.kind === "add" ? /* @__PURE__ */ (0,
|
|
3914
|
+
panel?.kind === "add" ? /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3105
3915
|
"span",
|
|
3106
3916
|
{
|
|
3107
3917
|
className: "fd-view-enter",
|
|
3108
3918
|
style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 220, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 },
|
|
3109
|
-
children: /* @__PURE__ */ (0,
|
|
3110
|
-
/* @__PURE__ */ (0,
|
|
3111
|
-
addableFields.map((f) => /* @__PURE__ */ (0,
|
|
3919
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("span", { className: "fd-stack", role: "menu", "aria-label": "Add filter", style: { gap: 2 }, children: [
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Add filter" }),
|
|
3921
|
+
addableFields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
3112
3922
|
"button",
|
|
3113
3923
|
{
|
|
3114
3924
|
type: "button",
|
|
@@ -3116,7 +3926,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3116
3926
|
className: "fd-row",
|
|
3117
3927
|
onClick: () => startEditing(f.key),
|
|
3118
3928
|
style: { gap: 8, padding: "4px 8px", borderRadius: 7, border: 0, width: "100%", textAlign: "left", cursor: "pointer", background: "transparent" },
|
|
3119
|
-
children: /* @__PURE__ */ (0,
|
|
3929
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "fd-body-sm", style: { flex: 1, color: "var(--text)" }, children: f.label })
|
|
3120
3930
|
},
|
|
3121
3931
|
f.key
|
|
3122
3932
|
))
|
|
@@ -3128,7 +3938,7 @@ function FilterBar({ fields = [], filters, onFilterChange, onFilterRemove, align
|
|
|
3128
3938
|
}
|
|
3129
3939
|
|
|
3130
3940
|
// src/components/data/StatTile.tsx
|
|
3131
|
-
var
|
|
3941
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
3132
3942
|
function isZeroDelta(delta) {
|
|
3133
3943
|
if (!delta) return false;
|
|
3134
3944
|
const match = delta.match(/[\d.]+/);
|
|
@@ -3139,23 +3949,23 @@ function StatTile({ label, value, sub, delta, invert = false, loading = false, c
|
|
|
3139
3949
|
const isZero = isZeroDelta(delta);
|
|
3140
3950
|
const isGood = invert ? isDecrease : !isDecrease;
|
|
3141
3951
|
const deltaToneClass = isZero ? "fd-stat-delta-neutral" : isGood ? "fd-stat-delta-up" : "fd-stat-delta-down";
|
|
3142
|
-
return /* @__PURE__ */ (0,
|
|
3143
|
-
loading ? /* @__PURE__ */ (0,
|
|
3144
|
-
/* @__PURE__ */ (0,
|
|
3145
|
-
delta ? /* @__PURE__ */ (0,
|
|
3146
|
-
/* @__PURE__ */ (0,
|
|
3952
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: ["fd-stat", compact3 ? "fd-stat-compact" : "", className].filter(Boolean).join(" "), ...rest, children: [
|
|
3953
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: compact3 ? 20 : 28, width: "62%" } }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: "fd-stat-top", children: [
|
|
3954
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "fd-stat-figure", children: value }),
|
|
3955
|
+
delta ? /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("span", { className: deltaToneClass, style: { fontWeight: 600, fontSize: "var(--body-sm-size)", flex: "none" }, children: [
|
|
3956
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("i", { className: "ph ph-" + (isZero ? "minus" : "arrow-" + (isDecrease ? "down" : "up") + "-right"), "aria-hidden": "true" }),
|
|
3147
3957
|
" ",
|
|
3148
3958
|
delta
|
|
3149
3959
|
] }) : null
|
|
3150
3960
|
] }),
|
|
3151
|
-
!loading && sub ? /* @__PURE__ */ (0,
|
|
3152
|
-
loading ? /* @__PURE__ */ (0,
|
|
3961
|
+
!loading && sub ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "fd-stat-sub", children: sub }) : null,
|
|
3962
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "fd-skel fd-skel-text", style: { display: "block", height: 10, width: "40%", marginTop: 8 } }) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "fd-stat-label", style: { display: "block" }, children: label })
|
|
3153
3963
|
] });
|
|
3154
3964
|
}
|
|
3155
3965
|
|
|
3156
3966
|
// src/components/data/CodeBlock.tsx
|
|
3157
|
-
var
|
|
3158
|
-
var
|
|
3967
|
+
var React24 = __toESM(require("react"), 1);
|
|
3968
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
3159
3969
|
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)$/;
|
|
3160
3970
|
var RULES = {
|
|
3161
3971
|
js: [
|
|
@@ -3310,13 +4120,13 @@ function tokenize(src, lang) {
|
|
|
3310
4120
|
return out;
|
|
3311
4121
|
}
|
|
3312
4122
|
function Highlighted({ code, lang }) {
|
|
3313
|
-
const toks =
|
|
3314
|
-
return /* @__PURE__ */ (0,
|
|
4123
|
+
const toks = React24.useMemo(() => tokenize(code, lang), [code, lang]);
|
|
4124
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_jsx_runtime47.Fragment, { children: toks.map((tk, i) => tk.c ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "tok-" + tk.c, children: tk.t }, i) : tk.t) });
|
|
3315
4125
|
}
|
|
3316
4126
|
function useCopy() {
|
|
3317
|
-
const [done, setDone] =
|
|
3318
|
-
const timer =
|
|
3319
|
-
|
|
4127
|
+
const [done, setDone] = React24.useState(false);
|
|
4128
|
+
const timer = React24.useRef(null);
|
|
4129
|
+
React24.useEffect(() => () => {
|
|
3320
4130
|
if (timer.current) clearTimeout(timer.current);
|
|
3321
4131
|
}, []);
|
|
3322
4132
|
const copy = (text) => {
|
|
@@ -3352,37 +4162,37 @@ function CodeBlock({
|
|
|
3352
4162
|
actions,
|
|
3353
4163
|
className = ""
|
|
3354
4164
|
}) {
|
|
3355
|
-
const [wrap, setWrap] =
|
|
3356
|
-
const [open, setOpen] =
|
|
4165
|
+
const [wrap, setWrap] = React24.useState(!!wrapDefault);
|
|
4166
|
+
const [open, setOpen] = React24.useState(false);
|
|
3357
4167
|
const [copied, copy] = useCopy();
|
|
3358
4168
|
const body = String(code).replace(/\n$/, "");
|
|
3359
4169
|
const lines = body.split("\n");
|
|
3360
4170
|
const foldable = collapseAfter > 0 && lines.length > collapseAfter + 6;
|
|
3361
4171
|
const shown = foldable && !open ? lines.slice(0, collapseAfter).join("\n") : body;
|
|
3362
|
-
return /* @__PURE__ */ (0,
|
|
3363
|
-
/* @__PURE__ */ (0,
|
|
3364
|
-
filename ? /* @__PURE__ */ (0,
|
|
3365
|
-
/* @__PURE__ */ (0,
|
|
3366
|
-
/* @__PURE__ */ (0,
|
|
4172
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: ["fd-code", wrap ? "is-wrap" : "", className].filter(Boolean).join(" "), children: [
|
|
4173
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fd-code-head", children: [
|
|
4174
|
+
filename ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-file", children: filename }) : null,
|
|
4175
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-lang", children: languageLabel(language) }),
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-spacer" }),
|
|
3367
4177
|
actions,
|
|
3368
|
-
/* @__PURE__ */ (0,
|
|
3369
|
-
copyable ? /* @__PURE__ */ (0,
|
|
3370
|
-
/* @__PURE__ */ (0,
|
|
3371
|
-
/* @__PURE__ */ (0,
|
|
4178
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: "fd-code-act", onClick: () => setWrap((v) => !v), "aria-pressed": wrap, title: wrap ? "No wrap" : "Soft wrap", children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-text-" + (wrap ? "columns" : "align-left"), "aria-hidden": "true" }) }),
|
|
4179
|
+
copyable ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(body), children: [
|
|
4180
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
4181
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { children: copied ? "Copied" : "Copy" })
|
|
3372
4182
|
] }) : null
|
|
3373
4183
|
] }),
|
|
3374
|
-
/* @__PURE__ */ (0,
|
|
3375
|
-
lineNumbers ? /* @__PURE__ */ (0,
|
|
3376
|
-
/* @__PURE__ */ (0,
|
|
4184
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fd-code-body", children: [
|
|
4185
|
+
lineNumbers ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("pre", { className: "fd-code-gutter", "aria-hidden": "true", children: shown.split("\n").map((_, i) => i + 1 + "\n").join("") }) : null,
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("pre", { className: "fd-code-pre", tabIndex: 0, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Highlighted, { code: shown, lang: language }) }) })
|
|
3377
4187
|
] }),
|
|
3378
|
-
foldable ? /* @__PURE__ */ (0,
|
|
3379
|
-
/* @__PURE__ */ (0,
|
|
4188
|
+
foldable ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
4189
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
|
|
3380
4190
|
open ? "Collapse" : "Show all " + lines.length + " lines"
|
|
3381
4191
|
] }) : null
|
|
3382
4192
|
] });
|
|
3383
4193
|
}
|
|
3384
4194
|
function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" }) {
|
|
3385
|
-
const [open, setOpen] =
|
|
4195
|
+
const [open, setOpen] = React24.useState(false);
|
|
3386
4196
|
const [copied, copy] = useCopy();
|
|
3387
4197
|
const raw = String(diff).replace(/\n$/, "");
|
|
3388
4198
|
const all = raw.split("\n").map((line) => {
|
|
@@ -3396,40 +4206,40 @@ function DiffBlock({ diff = "", filename, collapseAfter = 34, className = "" })
|
|
|
3396
4206
|
const dels = all.filter((l) => l.k === "del").length;
|
|
3397
4207
|
const foldable = collapseAfter > 0 && all.length > collapseAfter + 6;
|
|
3398
4208
|
const rows = foldable && !open ? all.slice(0, collapseAfter) : all;
|
|
3399
|
-
return /* @__PURE__ */ (0,
|
|
3400
|
-
/* @__PURE__ */ (0,
|
|
3401
|
-
/* @__PURE__ */ (0,
|
|
3402
|
-
filename ? /* @__PURE__ */ (0,
|
|
3403
|
-
/* @__PURE__ */ (0,
|
|
3404
|
-
/* @__PURE__ */ (0,
|
|
4209
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: ["fd-code", "fd-diff", className].filter(Boolean).join(" "), children: [
|
|
4210
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fd-code-head", children: [
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-git-diff fd-code-icon", "aria-hidden": "true" }),
|
|
4212
|
+
filename ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-file", children: filename }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-lang", children: "Diff" }),
|
|
4213
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "fd-diff-stat fd-tabular", children: [
|
|
4214
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "is-add", children: [
|
|
3405
4215
|
"+",
|
|
3406
4216
|
adds
|
|
3407
4217
|
] }),
|
|
3408
|
-
/* @__PURE__ */ (0,
|
|
4218
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("span", { className: "is-del", children: [
|
|
3409
4219
|
"\u2212",
|
|
3410
4220
|
dels
|
|
3411
4221
|
] })
|
|
3412
4222
|
] }),
|
|
3413
|
-
/* @__PURE__ */ (0,
|
|
3414
|
-
/* @__PURE__ */ (0,
|
|
3415
|
-
/* @__PURE__ */ (0,
|
|
3416
|
-
/* @__PURE__ */ (0,
|
|
4223
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-code-spacer" }),
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: "fd-code-act" + (copied ? " is-done" : ""), onClick: () => copy(raw), children: [
|
|
4225
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-" + (copied ? "check" : "copy"), "aria-hidden": "true" }),
|
|
4226
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { children: copied ? "Copied" : "Copy" })
|
|
3417
4227
|
] })
|
|
3418
4228
|
] }),
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3420
|
-
/* @__PURE__ */ (0,
|
|
3421
|
-
/* @__PURE__ */ (0,
|
|
4229
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "fd-diff-body", children: rows.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "fd-diff-line is-" + r.k, children: [
|
|
4230
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "fd-diff-mark", "aria-hidden": "true", children: r.k === "add" ? "+" : r.k === "del" ? "\u2212" : "" }),
|
|
4231
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("code", { children: r.k === "add" || r.k === "del" ? r.line.slice(1) : r.line })
|
|
3422
4232
|
] }, i)) }),
|
|
3423
|
-
foldable ? /* @__PURE__ */ (0,
|
|
3424
|
-
/* @__PURE__ */ (0,
|
|
4233
|
+
foldable ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("button", { type: "button", className: "fd-code-fold", onClick: () => setOpen((v) => !v), "aria-expanded": open, children: [
|
|
4234
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("i", { className: "ph ph-caret-" + (open ? "up" : "down"), "aria-hidden": "true" }),
|
|
3425
4235
|
open ? "Collapse" : "Show all " + all.length + " lines"
|
|
3426
4236
|
] }) : null
|
|
3427
4237
|
] });
|
|
3428
4238
|
}
|
|
3429
4239
|
|
|
3430
4240
|
// src/components/data/Markdown.tsx
|
|
3431
|
-
var
|
|
3432
|
-
var
|
|
4241
|
+
var React25 = __toESM(require("react"), 1);
|
|
4242
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
3433
4243
|
var SAFE = /^(?:https?:|mailto:|tel:|#|\/|\.{1,2}\/)/i;
|
|
3434
4244
|
var safeHref = (h) => SAFE.test(String(h || "").trim()) ? String(h).trim() : null;
|
|
3435
4245
|
var INLINE = [
|
|
@@ -3459,22 +4269,22 @@ function inlineNodes(src, ctx, keyBase) {
|
|
|
3459
4269
|
const { kind, m } = best;
|
|
3460
4270
|
if (m.index > 0) out.push(rest.slice(0, m.index));
|
|
3461
4271
|
const g = (i) => m[i];
|
|
3462
|
-
if (kind === "code") out.push(/* @__PURE__ */ (0,
|
|
4272
|
+
if (kind === "code") out.push(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("code", { className: "fd-md-code", children: g(1) }, key()));
|
|
3463
4273
|
else if (kind === "image") {
|
|
3464
4274
|
const src2 = safeHref(g(2));
|
|
3465
|
-
out.push(ctx.allowImages && src2 ? /* @__PURE__ */ (0,
|
|
4275
|
+
out.push(ctx.allowImages && src2 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("img", { className: "fd-md-img", src: src2, alt: g(1) || "", title: g(3) || void 0, loading: "lazy" }, key()) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "fd-md-imgalt", children: g(1) || "image" }, key()));
|
|
3466
4276
|
} else if (kind === "link") {
|
|
3467
4277
|
const href = safeHref(g(2));
|
|
3468
|
-
out.push(href ? /* @__PURE__ */ (0,
|
|
4278
|
+
out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("a", { href, title: g(3) || void 0, target: /^https?:/i.test(href) ? "_blank" : void 0, rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: inlineNodes(g(1), ctx, key()) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { children: g(1) }, key()));
|
|
3469
4279
|
} else if (kind === "cite") {
|
|
3470
|
-
out.push(ctx.renderCitation ? /* @__PURE__ */ (0,
|
|
3471
|
-
} else if (kind === "strongem") out.push(/* @__PURE__ */ (0,
|
|
3472
|
-
else if (kind === "strong") out.push(/* @__PURE__ */ (0,
|
|
3473
|
-
else if (kind === "em") out.push(/* @__PURE__ */ (0,
|
|
3474
|
-
else if (kind === "del") out.push(/* @__PURE__ */ (0,
|
|
4280
|
+
out.push(ctx.renderCitation ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(React25.Fragment, { children: ctx.renderCitation(g(1)) }, key()) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("sup", { className: "fd-md-cite", children: g(1) }, key()));
|
|
4281
|
+
} else if (kind === "strongem") out.push(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("strong", { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("em", { children: inlineNodes(g(1), ctx, key()) }) }, key()));
|
|
4282
|
+
else if (kind === "strong") out.push(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("strong", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
4283
|
+
else if (kind === "em") out.push(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("em", { children: inlineNodes(g(1) || g(2), ctx, key()) }, key()));
|
|
4284
|
+
else if (kind === "del") out.push(/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("del", { children: inlineNodes(g(1), ctx, key()) }, key()));
|
|
3475
4285
|
else if (kind === "autolink" || kind === "bare") {
|
|
3476
4286
|
const href = safeHref(g(1));
|
|
3477
|
-
out.push(href ? /* @__PURE__ */ (0,
|
|
4287
|
+
out.push(href ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("a", { href, target: "_blank", rel: "noopener noreferrer", onClick: ctx.onLinkClick, children: g(1).replace(/^mailto:/, "") }, key()) : g(1));
|
|
3478
4288
|
}
|
|
3479
4289
|
rest = rest.slice(m.index + m[0].length);
|
|
3480
4290
|
}
|
|
@@ -3592,33 +4402,33 @@ function renderBlocks(blocks, ctx, path) {
|
|
|
3592
4402
|
const k = path + "-" + i;
|
|
3593
4403
|
switch (b.t) {
|
|
3594
4404
|
case "code": {
|
|
3595
|
-
if ((b.lang || "").toLowerCase() === "diff") return /* @__PURE__ */ (0,
|
|
3596
|
-
return /* @__PURE__ */ (0,
|
|
4405
|
+
if ((b.lang || "").toLowerCase() === "diff") return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(DiffBlock, { diff: b.code, filename: b.file || void 0 }, k);
|
|
4406
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(CodeBlock, { code: b.code, language: b.lang, filename: b.file || void 0, ...ctx.codeProps || {} }, k);
|
|
3597
4407
|
}
|
|
3598
4408
|
case "h": {
|
|
3599
4409
|
const lvl = Math.min(6, Math.max(1, b.level + (ctx.headingOffset || 0)));
|
|
3600
4410
|
const Tag2 = "h" + lvl;
|
|
3601
|
-
return /* @__PURE__ */ (0,
|
|
4411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Tag2, { className: "fd-md-h fd-md-h" + lvl, children: inlineNodes(b.text, ctx, k) }, k);
|
|
3602
4412
|
}
|
|
3603
4413
|
case "hr":
|
|
3604
|
-
return /* @__PURE__ */ (0,
|
|
4414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("hr", { className: "fd-md-hr" }, k);
|
|
3605
4415
|
case "quote":
|
|
3606
|
-
return /* @__PURE__ */ (0,
|
|
4416
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("blockquote", { className: "fd-md-quote", children: renderBlocks(b.children, ctx, k) }, k);
|
|
3607
4417
|
case "list": {
|
|
3608
4418
|
const Tag2 = b.ordered ? "ol" : "ul";
|
|
3609
4419
|
const isTask = b.items.some((it) => it.checked != null);
|
|
3610
|
-
return /* @__PURE__ */ (0,
|
|
3611
|
-
it.checked != null ? /* @__PURE__ */ (0,
|
|
3612
|
-
/* @__PURE__ */ (0,
|
|
4420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Tag2, { className: "fd-md-list" + (isTask ? " is-task" : ""), start: b.ordered && b.start !== 1 ? b.start : void 0, children: b.items.map((it, j) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("li", { className: it.checked != null ? it.checked ? "is-done" : "is-todo" : void 0, children: [
|
|
4421
|
+
it.checked != null ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "fd-md-task", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("i", { className: "ph ph-" + (it.checked ? "check-square" : "square") }) }) : null,
|
|
4422
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "fd-md-li", children: renderBlocks(it.children, ctx, k + "-" + j) })
|
|
3613
4423
|
] }, k + "-" + j)) }, k);
|
|
3614
4424
|
}
|
|
3615
4425
|
case "table":
|
|
3616
|
-
return /* @__PURE__ */ (0,
|
|
3617
|
-
/* @__PURE__ */ (0,
|
|
3618
|
-
/* @__PURE__ */ (0,
|
|
4426
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "fd-md-tablewrap", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("table", { className: "fd-md-table", children: [
|
|
4427
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tr", { children: b.head.map((c, j) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("th", { style: { textAlign: b.align[j] || "left" }, children: inlineNodes(c, ctx, k + "h" + j) }, j)) }) }),
|
|
4428
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tbody", { children: b.rows.map((r, ri) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("tr", { children: b.head.map((_, ci) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("td", { style: { textAlign: b.align[ci] || "left" }, children: inlineNodes(r[ci] || "", ctx, k + ri + "c" + ci) }, ci)) }, ri)) })
|
|
3619
4429
|
] }) }, k);
|
|
3620
4430
|
default:
|
|
3621
|
-
return /* @__PURE__ */ (0,
|
|
4431
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("p", { className: "fd-md-p", children: inlineNodes(b.text, ctx, k) }, k);
|
|
3622
4432
|
}
|
|
3623
4433
|
});
|
|
3624
4434
|
}
|
|
@@ -3632,25 +4442,25 @@ function Markdown({
|
|
|
3632
4442
|
onLinkClick
|
|
3633
4443
|
}) {
|
|
3634
4444
|
const ctx = { allowImages, headingOffset, renderCitation, onLinkClick, codeProps };
|
|
3635
|
-
const blocks =
|
|
3636
|
-
return /* @__PURE__ */ (0,
|
|
4445
|
+
const blocks = React25.useMemo(() => parseBlocks(source), [source]);
|
|
4446
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: ["fd-md", className].filter(Boolean).join(" "), children: renderBlocks(blocks, ctx, "b") });
|
|
3637
4447
|
}
|
|
3638
4448
|
function MarkdownInline({ source = "", className = "", onLinkClick }) {
|
|
3639
|
-
return /* @__PURE__ */ (0,
|
|
4449
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: ["fd-md-inline", className].filter(Boolean).join(" "), children: inlineNodes(source, { allowImages: false, onLinkClick }, "i") });
|
|
3640
4450
|
}
|
|
3641
4451
|
function markdownToText(src) {
|
|
3642
4452
|
return String(src == null ? "" : src).replace(/```[\w+#-]*\n?([\s\S]*?)```/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\([^)]*\)/g, "$1").replace(/^\s{0,3}#{1,6}\s+/gm, "").replace(/\*\*\*([^*]+)\*\*\*|\*\*([^*]+)\*\*|__([^_]+)__/g, "$1$2$3").replace(/(^|\W)[*_]([^*_\n]+)[*_](\W|$)/g, "$1$2$3").replace(/~~([^~]+)~~/g, "$1").replace(/^\s*>\s?/gm, "").trim();
|
|
3643
4453
|
}
|
|
3644
4454
|
|
|
3645
4455
|
// src/components/data/Meter.tsx
|
|
3646
|
-
var
|
|
4456
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
3647
4457
|
function Meter({ segments = [], unallocated = 0, height = 8, label, legend = false, className = "" }) {
|
|
3648
4458
|
const total = segments.reduce((s, x) => s + x.value, 0) + unallocated;
|
|
3649
4459
|
const pct = (v) => total ? v / total * 100 : 0;
|
|
3650
|
-
return /* @__PURE__ */ (0,
|
|
3651
|
-
label ? /* @__PURE__ */ (0,
|
|
3652
|
-
/* @__PURE__ */ (0,
|
|
3653
|
-
segments.map((s, i) => /* @__PURE__ */ (0,
|
|
4460
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: ["fd-stack", className].filter(Boolean).join(" "), style: { gap: 8 }, children: [
|
|
4461
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fd-label-lg fd-secondary", children: label }) : null,
|
|
4462
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "fd-meterbar", style: { height }, children: [
|
|
4463
|
+
segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
|
|
3654
4464
|
"span",
|
|
3655
4465
|
{
|
|
3656
4466
|
className: "fd-meterbar-seg",
|
|
@@ -3659,15 +4469,15 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
|
|
|
3659
4469
|
},
|
|
3660
4470
|
i
|
|
3661
4471
|
)),
|
|
3662
|
-
unallocated > 0 ? /* @__PURE__ */ (0,
|
|
4472
|
+
unallocated > 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fd-meterbar-seg fd-meterbar-unallocated", title: "Unallocated", style: { width: pct(unallocated) + "%" } }) : null
|
|
3663
4473
|
] }),
|
|
3664
|
-
legend ? /* @__PURE__ */ (0,
|
|
3665
|
-
segments.map((s, i) => /* @__PURE__ */ (0,
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
4474
|
+
legend ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "fd-row", style: { gap: 16, flexWrap: "wrap" }, children: [
|
|
4475
|
+
segments.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
|
|
4476
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { style: { width: 9, height: 9, borderRadius: 2, background: s.color || "var(--chart-" + (i % 8 + 1) + ")" } }),
|
|
3667
4477
|
s.label
|
|
3668
4478
|
] }, i)),
|
|
3669
|
-
unallocated > 0 ? /* @__PURE__ */ (0,
|
|
3670
|
-
/* @__PURE__ */ (0,
|
|
4479
|
+
unallocated > 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("span", { className: "fd-row fd-body-sm fd-secondary", style: { gap: 7 }, children: [
|
|
4480
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "fd-meterbar-unallocated", style: { width: 9, height: 9, borderRadius: 2 } }),
|
|
3671
4481
|
"Unallocated"
|
|
3672
4482
|
] }) : null
|
|
3673
4483
|
] }) : null
|
|
@@ -3675,7 +4485,7 @@ function Meter({ segments = [], unallocated = 0, height = 8, label, legend = fal
|
|
|
3675
4485
|
}
|
|
3676
4486
|
|
|
3677
4487
|
// src/components/data/Pagination.tsx
|
|
3678
|
-
var
|
|
4488
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
3679
4489
|
var unitPluralRules = new Intl.PluralRules("en-US");
|
|
3680
4490
|
function pluralizeUnit(n, singular, irregularPlural) {
|
|
3681
4491
|
return unitPluralRules.select(n) === "one" ? singular : irregularPlural ?? `${singular}s`;
|
|
@@ -3706,12 +4516,12 @@ function Pagination({
|
|
|
3706
4516
|
if (i === 1 || i === totalPages || Math.abs(i - page) <= span) nums.push(i);
|
|
3707
4517
|
else if (nums[nums.length - 1] !== "\u2026") nums.push("\u2026");
|
|
3708
4518
|
}
|
|
3709
|
-
return /* @__PURE__ */ (0,
|
|
3710
|
-
/* @__PURE__ */ (0,
|
|
4519
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: ["fd-pag", className].filter(Boolean).join(" "), ...rest, children: [
|
|
4520
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-pag-count", children: loading ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-skel fd-skel-text", style: { display: "inline-block", height: 12, width: 108 } }) : total === 0 ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
|
|
3711
4521
|
"No ",
|
|
3712
4522
|
unitLabel
|
|
3713
|
-
] }) : /* @__PURE__ */ (0,
|
|
3714
|
-
/* @__PURE__ */ (0,
|
|
4523
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
|
|
4524
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("strong", { children: [
|
|
3715
4525
|
from.toLocaleString(),
|
|
3716
4526
|
"\u2013",
|
|
3717
4527
|
to.toLocaleString()
|
|
@@ -3721,14 +4531,14 @@ function Pagination({
|
|
|
3721
4531
|
" ",
|
|
3722
4532
|
unitLabel
|
|
3723
4533
|
] }) }),
|
|
3724
|
-
onPageSizeChange ? /* @__PURE__ */ (0,
|
|
3725
|
-
/* @__PURE__ */ (0,
|
|
3726
|
-
/* @__PURE__ */ (0,
|
|
4534
|
+
onPageSizeChange ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("label", { className: "fd-pag-size", children: [
|
|
4535
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: "Rows" }),
|
|
4536
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("select", { value: pageSize, onChange: (e) => onPageSizeChange(Number(e.target.value)), "aria-label": "Rows per page", children: pageSizes.map((n) => /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("option", { value: n, children: n }, n)) })
|
|
3727
4537
|
] }) : null,
|
|
3728
|
-
/* @__PURE__ */ (0,
|
|
3729
|
-
/* @__PURE__ */ (0,
|
|
3730
|
-
/* @__PURE__ */ (0,
|
|
3731
|
-
nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ (0,
|
|
4538
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { className: "fd-pag-nav", children: [
|
|
4539
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("button", { type: "button", onClick: () => go(1), disabled: page <= 1, "aria-label": "First page", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("i", { className: "ph ph-caret-double-left" }) }),
|
|
4540
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("button", { type: "button", onClick: () => go(page - 1), disabled: page <= 1, "aria-label": "Previous page", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("i", { className: "ph ph-caret-left" }) }),
|
|
4541
|
+
nums.map((n, i) => n === "\u2026" ? /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "fd-pag-gap", "aria-hidden": "true", children: "\u2026" }, "e" + i) : /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
|
|
3732
4542
|
"button",
|
|
3733
4543
|
{
|
|
3734
4544
|
type: "button",
|
|
@@ -3739,15 +4549,15 @@ function Pagination({
|
|
|
3739
4549
|
},
|
|
3740
4550
|
n
|
|
3741
4551
|
)),
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
3743
|
-
/* @__PURE__ */ (0,
|
|
4552
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("button", { type: "button", onClick: () => go(page + 1), disabled: page >= totalPages, "aria-label": "Next page", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("i", { className: "ph ph-caret-right" }) }),
|
|
4553
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("button", { type: "button", onClick: () => go(totalPages), disabled: page >= totalPages, "aria-label": "Last page", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("i", { className: "ph ph-caret-double-right" }) })
|
|
3744
4554
|
] })
|
|
3745
4555
|
] });
|
|
3746
4556
|
}
|
|
3747
4557
|
|
|
3748
4558
|
// src/components/data/RelativeTime.tsx
|
|
3749
|
-
var
|
|
3750
|
-
var
|
|
4559
|
+
var React26 = __toESM(require("react"), 1);
|
|
4560
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
3751
4561
|
var MIN = 6e4;
|
|
3752
4562
|
var HOUR = 36e5;
|
|
3753
4563
|
var DAY = 864e5;
|
|
@@ -3798,9 +4608,9 @@ function formatDuration(ms) {
|
|
|
3798
4608
|
return h + "h" + (m % 60 ? " " + m % 60 + "m" : "");
|
|
3799
4609
|
}
|
|
3800
4610
|
function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true, ...rest }) {
|
|
3801
|
-
const [, force] =
|
|
4611
|
+
const [, force] = React26.useState(0);
|
|
3802
4612
|
const t = value instanceof Date ? value.getTime() : Date.parse(value);
|
|
3803
|
-
|
|
4613
|
+
React26.useEffect(() => {
|
|
3804
4614
|
if (!refresh2 || !t || isNaN(t)) return;
|
|
3805
4615
|
const abs = Math.abs(t - Date.now());
|
|
3806
4616
|
if (abs > DAY) return;
|
|
@@ -3809,15 +4619,15 @@ function RelativeTime({ value, prefix, className = "", refresh: refresh2 = true,
|
|
|
3809
4619
|
return () => clearInterval(id);
|
|
3810
4620
|
}, [t, refresh2]);
|
|
3811
4621
|
if (!t || isNaN(t)) return null;
|
|
3812
|
-
return /* @__PURE__ */ (0,
|
|
4622
|
+
return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("time", { className, dateTime: new Date(t).toISOString(), title: formatAbsolute(new Date(t)), ...rest, children: [
|
|
3813
4623
|
prefix ? prefix + " " : "",
|
|
3814
4624
|
formatRelative(new Date(t))
|
|
3815
4625
|
] });
|
|
3816
4626
|
}
|
|
3817
4627
|
|
|
3818
4628
|
// src/components/data/ScoreMeter.tsx
|
|
3819
|
-
var
|
|
3820
|
-
var
|
|
4629
|
+
var React27 = __toESM(require("react"), 1);
|
|
4630
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
3821
4631
|
function ScoreMeter({
|
|
3822
4632
|
score,
|
|
3823
4633
|
segments,
|
|
@@ -3831,15 +4641,15 @@ function ScoreMeter({
|
|
|
3831
4641
|
breakdownWidth = 280,
|
|
3832
4642
|
className = ""
|
|
3833
4643
|
}) {
|
|
3834
|
-
const [open, setOpen] =
|
|
3835
|
-
const ref =
|
|
4644
|
+
const [open, setOpen] = React27.useState(false);
|
|
4645
|
+
const ref = React27.useRef(null);
|
|
3836
4646
|
const value = Math.max(0, Math.min(100, Math.round(Number(score) || 0)));
|
|
3837
|
-
const body = /* @__PURE__ */ (0,
|
|
3838
|
-
/* @__PURE__ */ (0,
|
|
3839
|
-
showScore ? /* @__PURE__ */ (0,
|
|
4647
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React27.Fragment, { children: [
|
|
4648
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fd-scoremeter-rail", style: { width }, "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(SegmentedMeter, { total: 100, segments, height, showTotal: false, showPercent: false, legend: false }) }),
|
|
4649
|
+
showScore ? /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("span", { className: "fd-scoremeter-value fd-tabular", "aria-hidden": "true", children: value }) : null
|
|
3840
4650
|
] });
|
|
3841
4651
|
if (!breakdown) {
|
|
3842
|
-
return /* @__PURE__ */ (0,
|
|
4652
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
3843
4653
|
"span",
|
|
3844
4654
|
{
|
|
3845
4655
|
className: ["fd-scoremeter", className].filter(Boolean).join(" "),
|
|
@@ -3853,8 +4663,8 @@ function ScoreMeter({
|
|
|
3853
4663
|
}
|
|
3854
4664
|
);
|
|
3855
4665
|
}
|
|
3856
|
-
return /* @__PURE__ */ (0,
|
|
3857
|
-
/* @__PURE__ */ (0,
|
|
4666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(React27.Fragment, { children: [
|
|
4667
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
3858
4668
|
"button",
|
|
3859
4669
|
{
|
|
3860
4670
|
type: "button",
|
|
@@ -3867,7 +4677,7 @@ function ScoreMeter({
|
|
|
3867
4677
|
children: body
|
|
3868
4678
|
}
|
|
3869
4679
|
),
|
|
3870
|
-
/* @__PURE__ */ (0,
|
|
4680
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
|
|
3871
4681
|
Popover,
|
|
3872
4682
|
{
|
|
3873
4683
|
open,
|
|
@@ -3884,13 +4694,13 @@ function ScoreMeter({
|
|
|
3884
4694
|
}
|
|
3885
4695
|
|
|
3886
4696
|
// src/components/data/SortMenu.tsx
|
|
3887
|
-
var
|
|
3888
|
-
var
|
|
4697
|
+
var React28 = __toESM(require("react"), 1);
|
|
4698
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
3889
4699
|
function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", className = "", ...rest }) {
|
|
3890
|
-
const [open, setOpen] =
|
|
4700
|
+
const [open, setOpen] = React28.useState(false);
|
|
3891
4701
|
const zIndex = useOverlayLayer(open);
|
|
3892
|
-
const ref =
|
|
3893
|
-
|
|
4702
|
+
const ref = React28.useRef(null);
|
|
4703
|
+
React28.useEffect(() => {
|
|
3894
4704
|
if (!open) return;
|
|
3895
4705
|
const away = (e) => {
|
|
3896
4706
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -3910,7 +4720,7 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
3910
4720
|
const arrow = (f, d) => {
|
|
3911
4721
|
const on = cur && cur.key === f.key && dir === d;
|
|
3912
4722
|
const label = d === "asc" ? f.numeric ? "lowest first" : "A to Z" : f.numeric ? "highest first" : "Z to A";
|
|
3913
|
-
return /* @__PURE__ */ (0,
|
|
4723
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
|
|
3914
4724
|
"button",
|
|
3915
4725
|
{
|
|
3916
4726
|
type: "button",
|
|
@@ -3928,21 +4738,21 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
3928
4738
|
background: on ? "var(--brand)" : "var(--surface)",
|
|
3929
4739
|
color: on ? "#fff" : "var(--text-muted)"
|
|
3930
4740
|
},
|
|
3931
|
-
children: /* @__PURE__ */ (0,
|
|
4741
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("i", { className: "ph ph-arrow-" + (d === "asc" ? "up" : "down"), style: { fontSize: 13 } })
|
|
3932
4742
|
}
|
|
3933
4743
|
);
|
|
3934
4744
|
};
|
|
3935
|
-
return /* @__PURE__ */ (0,
|
|
3936
|
-
/* @__PURE__ */ (0,
|
|
4745
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className, style: { position: "relative", display: "inline-flex" }, ref, ...rest, children: [
|
|
4746
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Button, { size, variant: "secondary", icon: dir === "asc" ? "sort-ascending" : "sort-descending", onClick: () => setOpen(!open), children: [
|
|
3937
4747
|
cur ? cur.label : "Unsorted",
|
|
3938
|
-
/* @__PURE__ */ (0,
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("i", { className: "ph ph-" + (dir === "asc" ? "arrow-up" : "arrow-down"), style: { fontSize: 12, marginLeft: 6, opacity: 0.75 } })
|
|
3939
4749
|
] }),
|
|
3940
|
-
open ? /* @__PURE__ */ (0,
|
|
3941
|
-
/* @__PURE__ */ (0,
|
|
4750
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(LayerProvider, { zIndex, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "fd-view-enter", style: { position: "absolute", top: "calc(100% + 6px)", [align]: 0, zIndex, width: 280, maxWidth: "calc(100vw - 32px)", display: "block", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 16px 44px rgba(11,13,17,.18)", padding: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "fd-stack", style: { gap: 2 }, children: [
|
|
4751
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "fd-overline fd-muted", style: { padding: "4px 8px 6px" }, children: "Sort by" }),
|
|
3942
4752
|
fields.map((f) => {
|
|
3943
4753
|
const active = cur && cur.key === f.key;
|
|
3944
|
-
return /* @__PURE__ */ (0,
|
|
3945
|
-
/* @__PURE__ */ (0,
|
|
4754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("span", { className: "fd-row", style: { gap: 8, padding: "4px 8px", borderRadius: 7, background: active ? "var(--surface-brand)" : "transparent" }, children: [
|
|
4755
|
+
/* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "fd-body-sm", style: { flex: 1, fontWeight: active ? 700 : 500, color: active ? "var(--text-on-surface-brand)" : "var(--text)" }, children: f.label }),
|
|
3946
4756
|
arrow(f, "asc"),
|
|
3947
4757
|
arrow(f, "desc")
|
|
3948
4758
|
] }, f.key);
|
|
@@ -3952,8 +4762,8 @@ function SortMenu({ fields = [], sort, onSort, align = "right", size = "md", cla
|
|
|
3952
4762
|
}
|
|
3953
4763
|
|
|
3954
4764
|
// src/components/data/StepList.tsx
|
|
3955
|
-
var
|
|
3956
|
-
var
|
|
4765
|
+
var React29 = __toESM(require("react"), 1);
|
|
4766
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
3957
4767
|
var KIND_ICON = { tool: "wrench", search: "magnifying-glass", read: "file-text", write: "pencil-simple", reasoning: "brain", run: "terminal", fetch: "cloud-arrow-down" };
|
|
3958
4768
|
function StepList({
|
|
3959
4769
|
steps = [],
|
|
@@ -3965,9 +4775,9 @@ function StepList({
|
|
|
3965
4775
|
dense = false,
|
|
3966
4776
|
className = ""
|
|
3967
4777
|
}) {
|
|
3968
|
-
const [openState, setOpenState] =
|
|
4778
|
+
const [openState, setOpenState] = React29.useState(defaultOpen);
|
|
3969
4779
|
const open = openProp == null ? openState : openProp;
|
|
3970
|
-
const [expanded, setExpanded] =
|
|
4780
|
+
const [expanded, setExpanded] = React29.useState({});
|
|
3971
4781
|
if (!steps.length) return null;
|
|
3972
4782
|
const running = steps.some((s) => s.status === "running");
|
|
3973
4783
|
const failed = steps.filter((s) => s.status === "error").length;
|
|
@@ -3979,30 +4789,30 @@ function StepList({
|
|
|
3979
4789
|
if (openProp == null) setOpenState(next);
|
|
3980
4790
|
onToggle && onToggle(next);
|
|
3981
4791
|
};
|
|
3982
|
-
return /* @__PURE__ */ (0,
|
|
3983
|
-
/* @__PURE__ */ (0,
|
|
3984
|
-
running ? /* @__PURE__ */ (0,
|
|
3985
|
-
/* @__PURE__ */ (0,
|
|
3986
|
-
/* @__PURE__ */ (0,
|
|
4792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: ["fd-steps", dense ? "is-dense" : "", open ? "is-open" : "", className].filter(Boolean).join(" "), children: [
|
|
4793
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("button", { type: "button", className: "fd-steps-head", onClick: toggle, "aria-expanded": open, children: [
|
|
4794
|
+
running ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-steps-spin", "aria-hidden": "true" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", { className: "ph ph-" + (failed ? "warning-circle" : "check-circle"), "aria-hidden": "true" }),
|
|
4795
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-steps-title", title: truncationTitle(summary), children: summary }),
|
|
4796
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "fd-steps-count fd-tabular", children: [
|
|
3987
4797
|
steps.length,
|
|
3988
4798
|
" step",
|
|
3989
4799
|
steps.length === 1 ? "" : "s",
|
|
3990
|
-
failed ? /* @__PURE__ */ (0,
|
|
4800
|
+
failed ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "fd-steps-failed", children: [
|
|
3991
4801
|
" \xB7 ",
|
|
3992
4802
|
failed,
|
|
3993
4803
|
" failed"
|
|
3994
4804
|
] }) : null
|
|
3995
4805
|
] }),
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
4806
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", { className: "ph ph-caret-" + (open ? "up" : "down") + " fd-steps-caret", "aria-hidden": "true" })
|
|
3997
4807
|
] }),
|
|
3998
|
-
open ? /* @__PURE__ */ (0,
|
|
4808
|
+
open ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("ol", { className: "fd-steps-list", children: steps.map((s, i) => {
|
|
3999
4809
|
const id = s.id || i;
|
|
4000
4810
|
const isOpen = !!expanded[id];
|
|
4001
4811
|
const icon = KIND_ICON[s.kind || ""] || "dot-outline";
|
|
4002
|
-
return /* @__PURE__ */ (0,
|
|
4003
|
-
/* @__PURE__ */ (0,
|
|
4004
|
-
/* @__PURE__ */ (0,
|
|
4005
|
-
s.detail ? /* @__PURE__ */ (0,
|
|
4812
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("li", { className: "fd-step is-" + (s.status || "ok"), children: [
|
|
4813
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "fd-step-row", children: [
|
|
4814
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-step-icon", "aria-hidden": "true", children: s.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-steps-spin" }) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", { className: "ph ph-" + icon }) }),
|
|
4815
|
+
s.detail ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
|
|
4006
4816
|
"button",
|
|
4007
4817
|
{
|
|
4008
4818
|
type: "button",
|
|
@@ -4010,23 +4820,23 @@ function StepList({
|
|
|
4010
4820
|
"aria-expanded": isOpen,
|
|
4011
4821
|
onClick: () => setExpanded((m) => Object.assign({}, m, { [id]: !isOpen })),
|
|
4012
4822
|
children: [
|
|
4013
|
-
/* @__PURE__ */ (0,
|
|
4014
|
-
/* @__PURE__ */ (0,
|
|
4823
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { title: truncationTitle(s.label), children: s.label }),
|
|
4824
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", { className: "ph ph-caret-" + (isOpen ? "up" : "down"), "aria-hidden": "true" })
|
|
4015
4825
|
]
|
|
4016
4826
|
}
|
|
4017
|
-
) : /* @__PURE__ */ (0,
|
|
4018
|
-
s.status === "error" ? /* @__PURE__ */ (0,
|
|
4019
|
-
showDurations && s.durationMs ? /* @__PURE__ */ (0,
|
|
4827
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-step-label is-static", title: truncationTitle(s.label), children: s.label }),
|
|
4828
|
+
s.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-step-badge is-error", children: "failed" }) : null,
|
|
4829
|
+
showDurations && s.durationMs ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "fd-step-dur fd-tabular", children: formatDuration(s.durationMs) }) : null
|
|
4020
4830
|
] }),
|
|
4021
|
-
s.detail && isOpen ? /* @__PURE__ */ (0,
|
|
4831
|
+
s.detail && isOpen ? /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("pre", { className: "fd-step-detail", children: s.detail }) : null
|
|
4022
4832
|
] }, id);
|
|
4023
4833
|
}) }) : null
|
|
4024
4834
|
] });
|
|
4025
4835
|
}
|
|
4026
4836
|
|
|
4027
4837
|
// src/components/data/VirtualList.tsx
|
|
4028
|
-
var
|
|
4029
|
-
var
|
|
4838
|
+
var React30 = __toESM(require("react"), 1);
|
|
4839
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
4030
4840
|
var VIRTUAL_LIST_BUFFER_ROWS = 20;
|
|
4031
4841
|
var VIRTUAL_LIST_ROW_GAP = 6;
|
|
4032
4842
|
function computeVirtualWindow(opts) {
|
|
@@ -4077,35 +4887,35 @@ function VirtualList({
|
|
|
4077
4887
|
className = "",
|
|
4078
4888
|
style
|
|
4079
4889
|
}) {
|
|
4080
|
-
const [scrollTop, setScrollTop] =
|
|
4081
|
-
const loaded =
|
|
4890
|
+
const [scrollTop, setScrollTop] = React30.useState(0);
|
|
4891
|
+
const loaded = React30.useMemo(
|
|
4082
4892
|
() => ({ firstItemIndex, count: items.length }),
|
|
4083
4893
|
[firstItemIndex, items.length]
|
|
4084
4894
|
);
|
|
4085
4895
|
const total = Math.max(totalCount == null ? 0 : totalCount, firstItemIndex + items.length);
|
|
4086
4896
|
const bandKey = firstItemIndex + ":" + items.length;
|
|
4087
|
-
const win =
|
|
4897
|
+
const win = React30.useMemo(
|
|
4088
4898
|
() => computeVirtualWindow({ scrollTop, viewportHeight: height, itemHeight, itemCount: total, loaded }),
|
|
4089
4899
|
[scrollTop, height, itemHeight, total, loaded]
|
|
4090
4900
|
);
|
|
4091
|
-
const need =
|
|
4901
|
+
const need = React30.useMemo(() => computeNeedMore(win, loaded), [win, loaded]);
|
|
4092
4902
|
const wantStart = need.start && hasMore?.start !== false;
|
|
4093
4903
|
const wantEnd = need.end && hasMore?.end !== false;
|
|
4094
4904
|
const bucket2 = Math.floor(win.visibleStart / VIRTUAL_LIST_BUFFER_ROWS);
|
|
4095
4905
|
const askKey = bandKey + "@" + bucket2;
|
|
4096
|
-
const asked =
|
|
4097
|
-
|
|
4906
|
+
const asked = React30.useRef({ start: null, end: null });
|
|
4907
|
+
React30.useEffect(() => {
|
|
4098
4908
|
if (loading || !wantStart || asked.current.start === askKey) return;
|
|
4099
4909
|
asked.current.start = askKey;
|
|
4100
4910
|
onNeedMore("start", win);
|
|
4101
4911
|
}, [wantStart, loading, askKey, onNeedMore, win]);
|
|
4102
|
-
|
|
4912
|
+
React30.useEffect(() => {
|
|
4103
4913
|
if (loading || !wantEnd || asked.current.end === askKey) return;
|
|
4104
4914
|
asked.current.end = askKey;
|
|
4105
4915
|
onNeedMore("end", win);
|
|
4106
4916
|
}, [wantEnd, loading, askKey, onNeedMore, win]);
|
|
4107
|
-
const lastKeysRef =
|
|
4108
|
-
const newKeys =
|
|
4917
|
+
const lastKeysRef = React30.useRef(null);
|
|
4918
|
+
const newKeys = React30.useMemo(() => {
|
|
4109
4919
|
const prev = lastKeysRef.current;
|
|
4110
4920
|
if (!prev) return /* @__PURE__ */ new Set();
|
|
4111
4921
|
const fresh = /* @__PURE__ */ new Set();
|
|
@@ -4115,12 +4925,12 @@ function VirtualList({
|
|
|
4115
4925
|
}
|
|
4116
4926
|
return fresh;
|
|
4117
4927
|
}, [items]);
|
|
4118
|
-
|
|
4928
|
+
React30.useEffect(() => {
|
|
4119
4929
|
lastKeysRef.current = new Set(items.map(keyOf));
|
|
4120
4930
|
}, [items]);
|
|
4121
4931
|
const gapStyle = { "--fd-vlist-gap": rowGap + "px" };
|
|
4122
4932
|
if (!items.length && !loading && !refreshing && emptyState) {
|
|
4123
|
-
return /* @__PURE__ */ (0,
|
|
4933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...style }, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "fd-vlist fd-scrollbar", style: { height: "100%", overflow: "auto" }, children: emptyState }) });
|
|
4124
4934
|
}
|
|
4125
4935
|
const rows = [];
|
|
4126
4936
|
for (let i = win.startIndex; i <= win.endIndex; i++) {
|
|
@@ -4128,40 +4938,40 @@ function VirtualList({
|
|
|
4128
4938
|
if (item === void 0) continue;
|
|
4129
4939
|
const key = keyOf(item);
|
|
4130
4940
|
rows.push(
|
|
4131
|
-
/* @__PURE__ */ (0,
|
|
4941
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
|
|
4132
4942
|
"div",
|
|
4133
4943
|
{
|
|
4134
4944
|
className: "fd-vlist-row",
|
|
4135
4945
|
style: { height: itemHeight, boxSizing: "border-box", transform: "translateY(" + i * itemHeight + "px)" },
|
|
4136
|
-
children: /* @__PURE__ */ (0,
|
|
4946
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: newKeys.has(key) ? "fd-vlist-row-content fd-vlist-row-enter" : "fd-vlist-row-content", children: renderItem(item, i) })
|
|
4137
4947
|
},
|
|
4138
4948
|
key
|
|
4139
4949
|
)
|
|
4140
4950
|
);
|
|
4141
4951
|
}
|
|
4142
|
-
return /* @__PURE__ */ (0,
|
|
4143
|
-
/* @__PURE__ */ (0,
|
|
4952
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: ["fd-vlist-wrap", className].filter(Boolean).join(" "), style: { height, position: "relative", ...gapStyle, ...style }, children: [
|
|
4953
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
|
|
4144
4954
|
"div",
|
|
4145
4955
|
{
|
|
4146
4956
|
className: "fd-vlist fd-scrollbar",
|
|
4147
4957
|
style: { height: "100%", overflowY: "auto", overflowX: "hidden", position: "relative" },
|
|
4148
4958
|
onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
|
|
4149
4959
|
children: [
|
|
4150
|
-
/* @__PURE__ */ (0,
|
|
4151
|
-
loading ? /* @__PURE__ */ (0,
|
|
4960
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { height: win.totalHeight, position: "relative" }, children: rows }),
|
|
4961
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { position: "sticky", bottom: 0, left: 0, right: 0, display: "grid", placeItems: "center", padding: "8px 0", background: "var(--surface)" }, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "fd-spinner", "aria-hidden": "true" }) }) : null
|
|
4152
4962
|
]
|
|
4153
4963
|
}
|
|
4154
4964
|
),
|
|
4155
|
-
refreshing ? /* @__PURE__ */ (0,
|
|
4156
|
-
/* @__PURE__ */ (0,
|
|
4157
|
-
/* @__PURE__ */ (0,
|
|
4965
|
+
refreshing ? /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "fd-vlist-refresh-scrim", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "fd-vlist-refresh-card", children: [
|
|
4966
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "fd-spinner", "aria-hidden": "true" }),
|
|
4967
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "fd-body-sm", children: refreshingLabel })
|
|
4158
4968
|
] }) }) : null
|
|
4159
4969
|
] });
|
|
4160
4970
|
}
|
|
4161
4971
|
|
|
4162
4972
|
// src/components/data/EntityRow.tsx
|
|
4163
|
-
var
|
|
4164
|
-
var
|
|
4973
|
+
var React31 = __toESM(require("react"), 1);
|
|
4974
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
4165
4975
|
var ENTITY_ROW_METRIC_WIDTH = 74;
|
|
4166
4976
|
var METRIC_TONE_COLOR = {
|
|
4167
4977
|
default: "var(--text-2)",
|
|
@@ -4169,16 +4979,16 @@ var METRIC_TONE_COLOR = {
|
|
|
4169
4979
|
danger: "var(--danger-text)"
|
|
4170
4980
|
};
|
|
4171
4981
|
function EntityRowMetrics({ metrics, className = "", style }) {
|
|
4172
|
-
return /* @__PURE__ */ (0,
|
|
4982
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: ["fd-erow-metrics", className].filter(Boolean).join(" "), style, children: metrics.map((m, i) => {
|
|
4173
4983
|
const key = m.id || m.label || i;
|
|
4174
4984
|
const className2 = ["fd-erow-metric", m.tone && m.tone !== "default" ? "is-" + m.tone : "", m.tooltip != null ? "is-described" : ""].filter(Boolean).join(" ");
|
|
4175
4985
|
const tone = { color: METRIC_TONE_COLOR[m.tone || "default"] };
|
|
4176
|
-
const content = /* @__PURE__ */ (0,
|
|
4177
|
-
m.icon ? /* @__PURE__ */ (0,
|
|
4178
|
-
/* @__PURE__ */ (0,
|
|
4179
|
-
/* @__PURE__ */ (0,
|
|
4986
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(React31.Fragment, { children: [
|
|
4987
|
+
m.icon ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("i", { className: "ph ph-" + m.icon, "aria-hidden": "true" }) : null,
|
|
4988
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-metric-value fd-tabular", children: m.value }),
|
|
4989
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-sr", children: " " + m.label })
|
|
4180
4990
|
] });
|
|
4181
|
-
return /* @__PURE__ */ (0,
|
|
4991
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-cell", style: { "--erow-metric-w": (m.width || ENTITY_ROW_METRIC_WIDTH) + "px" }, children: m.tooltip == null ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: className2, style: tone, title: m.label, children: content }) : /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Tooltip, { label: m.tooltip, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("button", { type: "button", className: className2, style: tone, children: content }) }) }, key);
|
|
4182
4992
|
}) });
|
|
4183
4993
|
}
|
|
4184
4994
|
function EntityRow({
|
|
@@ -4195,7 +5005,7 @@ function EntityRow({
|
|
|
4195
5005
|
className = ""
|
|
4196
5006
|
}) {
|
|
4197
5007
|
const hasStrip = metrics && metrics.length > 0 || accessory != null;
|
|
4198
|
-
return /* @__PURE__ */ (0,
|
|
5008
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
4199
5009
|
"div",
|
|
4200
5010
|
{
|
|
4201
5011
|
onPointerDown,
|
|
@@ -4221,33 +5031,33 @@ function EntityRow({
|
|
|
4221
5031
|
// font-size moved to the .fd-erow-grip stylesheet rule, same reason as the
|
|
4222
5032
|
// row's own padding above: .fd-tlist-footer's indent reads it back as
|
|
4223
5033
|
// --erow-grip-size.
|
|
4224
|
-
/* @__PURE__ */ (0,
|
|
5034
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("i", { className: "ph ph-dots-six-vertical fd-erow-grip", "aria-hidden": "true", style: { flex: "none", color: "var(--text-muted)" } })
|
|
4225
5035
|
) : null,
|
|
4226
|
-
/* @__PURE__ */ (0,
|
|
4227
|
-
/* @__PURE__ */ (0,
|
|
4228
|
-
titleIcon ? /* @__PURE__ */ (0,
|
|
5036
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "fd-erow-body", children: [
|
|
5037
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "fd-erow-titleline", children: [
|
|
5038
|
+
titleIcon ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(Tooltip, { label: titleIcon.tooltip, children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
|
|
4229
5039
|
"button",
|
|
4230
5040
|
{
|
|
4231
5041
|
type: "button",
|
|
4232
5042
|
className: ["fd-erow-title-icon", titleIcon.tone ? "is-" + titleIcon.tone : ""].filter(Boolean).join(" "),
|
|
4233
5043
|
children: [
|
|
4234
|
-
/* @__PURE__ */ (0,
|
|
4235
|
-
/* @__PURE__ */ (0,
|
|
5044
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("i", { className: "ph ph-" + titleIcon.icon, "aria-hidden": "true" }),
|
|
5045
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-title fd-body-sm", children: title })
|
|
4236
5046
|
]
|
|
4237
5047
|
}
|
|
4238
5048
|
) }) : (
|
|
4239
5049
|
// MP-141: dense-row identifier, no Tooltip wrapper in this branch — a native
|
|
4240
5050
|
// `title` is the exposure mechanism, same rule as every other identifier.
|
|
4241
|
-
/* @__PURE__ */ (0,
|
|
5051
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-title fd-body-sm", title: truncationTitle(title), children: title })
|
|
4242
5052
|
),
|
|
4243
|
-
meta ? /* @__PURE__ */ (0,
|
|
5053
|
+
meta ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-meta", title: truncationTitle(meta), children: meta }) : null
|
|
4244
5054
|
] }),
|
|
4245
|
-
hasStrip ? /* @__PURE__ */ (0,
|
|
4246
|
-
metrics && metrics.length ? /* @__PURE__ */ (0,
|
|
4247
|
-
accessory ? /* @__PURE__ */ (0,
|
|
5055
|
+
hasStrip ? /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "fd-erow-strip", children: [
|
|
5056
|
+
metrics && metrics.length ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(EntityRowMetrics, { metrics }) : null,
|
|
5057
|
+
accessory ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "fd-erow-accessory", children: accessory }) : null
|
|
4248
5058
|
] }) : null
|
|
4249
5059
|
] }),
|
|
4250
|
-
action ? /* @__PURE__ */ (0,
|
|
5060
|
+
action ? /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
|
|
4251
5061
|
IconButton,
|
|
4252
5062
|
{
|
|
4253
5063
|
icon: action.icon,
|
|
@@ -4265,30 +5075,11 @@ function EntityRow({
|
|
|
4265
5075
|
}
|
|
4266
5076
|
|
|
4267
5077
|
// src/components/data/TransferList.tsx
|
|
4268
|
-
var
|
|
5078
|
+
var React32 = __toESM(require("react"), 1);
|
|
4269
5079
|
var import_react_dom5 = require("react-dom");
|
|
4270
5080
|
|
|
4271
|
-
// src/components/forms/field.tsx
|
|
4272
|
-
var React29 = __toESM(require("react"), 1);
|
|
4273
|
-
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
4274
|
-
function useFieldId(id) {
|
|
4275
|
-
const generated = React29.useId();
|
|
4276
|
-
return id || generated;
|
|
4277
|
-
}
|
|
4278
|
-
function FieldLabel({ htmlFor, id, required = false, onClick, children }) {
|
|
4279
|
-
return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("label", { className: "fd-field-label", htmlFor, id, onClick, children: [
|
|
4280
|
-
children,
|
|
4281
|
-
required ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "fd-field-req", "aria-hidden": "true", children: "*" }) : null
|
|
4282
|
-
] });
|
|
4283
|
-
}
|
|
4284
|
-
function useTriggerLabelling(label, id) {
|
|
4285
|
-
const fieldId = useFieldId(id);
|
|
4286
|
-
const labelId = fieldId + "-label";
|
|
4287
|
-
return { fieldId, labelId, ariaLabelledBy: label ? labelId + " " + fieldId : void 0 };
|
|
4288
|
-
}
|
|
4289
|
-
|
|
4290
5081
|
// src/components/forms/Input.tsx
|
|
4291
|
-
var
|
|
5082
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4292
5083
|
function Input({
|
|
4293
5084
|
label,
|
|
4294
5085
|
help,
|
|
@@ -4315,24 +5106,24 @@ function Input({
|
|
|
4315
5106
|
disabled ? "fd-input-disabled" : "",
|
|
4316
5107
|
size === "lg" ? "fd-input-lg" : ""
|
|
4317
5108
|
].filter(Boolean).join(" ");
|
|
4318
|
-
return /* @__PURE__ */ (0,
|
|
4319
|
-
label ? /* @__PURE__ */ (0,
|
|
4320
|
-
/* @__PURE__ */ (0,
|
|
4321
|
-
icon ? /* @__PURE__ */ (0,
|
|
4322
|
-
prefix ? /* @__PURE__ */ (0,
|
|
4323
|
-
/* @__PURE__ */ (0,
|
|
4324
|
-
loading ? /* @__PURE__ */ (0,
|
|
4325
|
-
suffix && !loading ? /* @__PURE__ */ (0,
|
|
5109
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
5110
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
5111
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: box, children: [
|
|
5112
|
+
icon ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-input-icon", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("i", { className: "ph ph-" + icon, "aria-hidden": "true" }) }) : null,
|
|
5113
|
+
prefix ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-input-affix", children: prefix }) : null,
|
|
5114
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { id: fieldId, disabled, style: inputStyle, "aria-invalid": error ? "true" : void 0, ...rest }),
|
|
5115
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading" }) : null,
|
|
5116
|
+
suffix && !loading ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-input-affix", children: suffix }) : null
|
|
4326
5117
|
] }),
|
|
4327
|
-
error ? /* @__PURE__ */ (0,
|
|
4328
|
-
/* @__PURE__ */ (0,
|
|
5118
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "fd-field-error", children: [
|
|
5119
|
+
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4329
5120
|
error
|
|
4330
|
-
] }) : help ? /* @__PURE__ */ (0,
|
|
5121
|
+
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
4331
5122
|
] });
|
|
4332
5123
|
}
|
|
4333
5124
|
|
|
4334
5125
|
// src/components/forms/SearchField.tsx
|
|
4335
|
-
var
|
|
5126
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
4336
5127
|
function SearchField({
|
|
4337
5128
|
value,
|
|
4338
5129
|
onChange,
|
|
@@ -4347,7 +5138,7 @@ function SearchField({
|
|
|
4347
5138
|
...rest
|
|
4348
5139
|
}) {
|
|
4349
5140
|
const clear = onClear || (() => onChange(""));
|
|
4350
|
-
return /* @__PURE__ */ (0,
|
|
5141
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
4351
5142
|
Input,
|
|
4352
5143
|
{
|
|
4353
5144
|
id,
|
|
@@ -4360,14 +5151,14 @@ function SearchField({
|
|
|
4360
5151
|
style,
|
|
4361
5152
|
className,
|
|
4362
5153
|
onChange: (e) => onChange(e.target.value),
|
|
4363
|
-
suffix: value ? /* @__PURE__ */ (0,
|
|
5154
|
+
suffix: value ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
|
|
4364
5155
|
"button",
|
|
4365
5156
|
{
|
|
4366
5157
|
type: "button",
|
|
4367
5158
|
"aria-label": "Clear search",
|
|
4368
5159
|
onClick: clear,
|
|
4369
5160
|
style: { all: "unset", cursor: "pointer", color: "var(--text-muted)", display: "grid", placeItems: "center", padding: 2 },
|
|
4370
|
-
children: /* @__PURE__ */ (0,
|
|
5161
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("i", { className: "ph ph-x-circle", style: { fontSize: 15 }, "aria-hidden": "true" })
|
|
4371
5162
|
}
|
|
4372
5163
|
) : void 0,
|
|
4373
5164
|
...rest
|
|
@@ -4376,7 +5167,7 @@ function SearchField({
|
|
|
4376
5167
|
}
|
|
4377
5168
|
|
|
4378
5169
|
// src/components/data/TransferList.tsx
|
|
4379
|
-
var
|
|
5170
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
4380
5171
|
var emptyHasMore = {};
|
|
4381
5172
|
var DRAG_THRESHOLD_PX = 5;
|
|
4382
5173
|
function TransferList({
|
|
@@ -4390,12 +5181,12 @@ function TransferList({
|
|
|
4390
5181
|
listHeight = 440,
|
|
4391
5182
|
className = ""
|
|
4392
5183
|
}) {
|
|
4393
|
-
const [drag, setDrag] =
|
|
4394
|
-
const [dragOverSide, setDragOverSide] =
|
|
4395
|
-
const dragRef =
|
|
4396
|
-
const armedRef =
|
|
4397
|
-
const sideRefs =
|
|
4398
|
-
const hitTestSide =
|
|
5184
|
+
const [drag, setDrag] = React32.useState(null);
|
|
5185
|
+
const [dragOverSide, setDragOverSide] = React32.useState(null);
|
|
5186
|
+
const dragRef = React32.useRef(null);
|
|
5187
|
+
const armedRef = React32.useRef(null);
|
|
5188
|
+
const sideRefs = React32.useRef({ left: null, right: null });
|
|
5189
|
+
const hitTestSide = React32.useCallback((x, y) => {
|
|
4399
5190
|
for (const side of ["left", "right"]) {
|
|
4400
5191
|
const el = sideRefs.current[side];
|
|
4401
5192
|
if (!el) continue;
|
|
@@ -4404,7 +5195,7 @@ function TransferList({
|
|
|
4404
5195
|
}
|
|
4405
5196
|
return null;
|
|
4406
5197
|
}, []);
|
|
4407
|
-
const findItem =
|
|
5198
|
+
const findItem = React32.useCallback(
|
|
4408
5199
|
(side, key) => (side === "left" ? left.items : right.items).find((it) => keyOf(it) === key),
|
|
4409
5200
|
[left.items, right.items, keyOf]
|
|
4410
5201
|
);
|
|
@@ -4426,7 +5217,7 @@ function TransferList({
|
|
|
4426
5217
|
height: rect.height
|
|
4427
5218
|
};
|
|
4428
5219
|
};
|
|
4429
|
-
|
|
5220
|
+
React32.useEffect(() => {
|
|
4430
5221
|
const onMovePointer = (e) => {
|
|
4431
5222
|
const armed = armedRef.current;
|
|
4432
5223
|
if (!armed || e.pointerId !== armed.pointerId) return;
|
|
@@ -4479,7 +5270,7 @@ function TransferList({
|
|
|
4479
5270
|
window.removeEventListener("pointercancel", endDrag);
|
|
4480
5271
|
};
|
|
4481
5272
|
}, [hitTestSide, findItem, onMove]);
|
|
4482
|
-
|
|
5273
|
+
React32.useEffect(() => {
|
|
4483
5274
|
if (!drag || typeof document === "undefined") return;
|
|
4484
5275
|
const prev = document.body.style.userSelect;
|
|
4485
5276
|
document.body.style.userSelect = "none";
|
|
@@ -4489,7 +5280,7 @@ function TransferList({
|
|
|
4489
5280
|
}, [drag]);
|
|
4490
5281
|
const renderSide = (side, cfg, opposite) => {
|
|
4491
5282
|
const showOverlay = drag != null && dragOverSide === side;
|
|
4492
|
-
return /* @__PURE__ */ (0,
|
|
5283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
4493
5284
|
"div",
|
|
4494
5285
|
{
|
|
4495
5286
|
ref: (el) => {
|
|
@@ -4497,16 +5288,16 @@ function TransferList({
|
|
|
4497
5288
|
},
|
|
4498
5289
|
className: ["fd-tlist-side", dragOverSide === side ? "is-drop-target" : ""].filter(Boolean).join(" "),
|
|
4499
5290
|
children: [
|
|
4500
|
-
cfg.label ? /* @__PURE__ */ (0,
|
|
5291
|
+
cfg.label ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "fd-overline fd-muted", children: [
|
|
4501
5292
|
cfg.label,
|
|
4502
5293
|
cfg.total != null ? " (" + cfg.total.toLocaleString() + ")" : ""
|
|
4503
5294
|
] }) : null,
|
|
4504
|
-
cfg.header ? /* @__PURE__ */ (0,
|
|
4505
|
-
/* @__PURE__ */ (0,
|
|
4506
|
-
/* @__PURE__ */ (0,
|
|
4507
|
-
/* @__PURE__ */ (0,
|
|
5295
|
+
cfg.header ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "fd-tlist-header", children: cfg.header }) : null,
|
|
5296
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "fd-row", style: { gap: 8 }, children: [
|
|
5297
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SearchField, { value: cfg.search, onChange: cfg.onSearchChange, placeholder: "Search", "aria-label": (cfg.label || side) + " search", style: { flex: 1 } }),
|
|
5298
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(SortMenu, { fields: cfg.sortFields, sort: cfg.sort, onSort: cfg.onSort, align: side === "left" ? "left" : "right" })
|
|
4508
5299
|
] }),
|
|
4509
|
-
/* @__PURE__ */ (0,
|
|
5300
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
4510
5301
|
VirtualList,
|
|
4511
5302
|
{
|
|
4512
5303
|
items: cfg.items,
|
|
@@ -4520,15 +5311,15 @@ function TransferList({
|
|
|
4520
5311
|
firstItemIndex: cfg.firstItemIndex,
|
|
4521
5312
|
totalCount: cfg.totalCount,
|
|
4522
5313
|
onNeedMore: cfg.onNeedMore,
|
|
4523
|
-
emptyState: /* @__PURE__ */ (0,
|
|
5314
|
+
emptyState: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(EmptyState, { icon: "tray", title: "Nothing here" }),
|
|
4524
5315
|
renderItem: (item) => {
|
|
4525
5316
|
const isBeingDragged = drag != null && drag.from === side && drag.key === keyOf(item);
|
|
4526
5317
|
if (isBeingDragged) {
|
|
4527
|
-
return /* @__PURE__ */ (0,
|
|
5318
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "fd-erow-placeholder", "aria-hidden": "true" });
|
|
4528
5319
|
}
|
|
4529
5320
|
const content = renderRow(item);
|
|
4530
5321
|
const destination = (side === "left" ? right : left).label || "the other list";
|
|
4531
|
-
return /* @__PURE__ */ (0,
|
|
5322
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
4532
5323
|
EntityRow,
|
|
4533
5324
|
{
|
|
4534
5325
|
...content,
|
|
@@ -4548,252 +5339,95 @@ function TransferList({
|
|
|
4548
5339
|
}
|
|
4549
5340
|
}
|
|
4550
5341
|
),
|
|
4551
|
-
cfg.footer ? /* @__PURE__ */ (0,
|
|
4552
|
-
showOverlay ? /* @__PURE__ */ (0,
|
|
4553
|
-
/* @__PURE__ */ (0,
|
|
4554
|
-
/* @__PURE__ */ (0,
|
|
5342
|
+
cfg.footer ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "fd-tlist-footer", children: cfg.footer }) : null,
|
|
5343
|
+
showOverlay ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "fd-tlist-drop-overlay", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "fd-tlist-drop-card", children: [
|
|
5344
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("i", { className: "ph ph-tray-arrow-down", style: { fontSize: 18 }, "aria-hidden": "true" }),
|
|
5345
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-body-sm", style: { fontWeight: 600 }, children: cfg.dropLabel || "Drop here" + (cfg.label ? " \u2014 " + cfg.label : "") })
|
|
4555
5346
|
] }) }) : null
|
|
4556
5347
|
]
|
|
4557
5348
|
}
|
|
4558
5349
|
);
|
|
4559
5350
|
};
|
|
4560
|
-
return /* @__PURE__ */ (0,
|
|
4561
|
-
/* @__PURE__ */ (0,
|
|
5351
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: ["fd-tlist", className].filter(Boolean).join(" "), children: [
|
|
5352
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "fd-tlist-panes", children: [
|
|
4562
5353
|
renderSide("left", left, "right"),
|
|
4563
5354
|
renderSide("right", right, "left")
|
|
4564
5355
|
] }),
|
|
4565
5356
|
drag ? (0, import_react_dom5.createPortal)(
|
|
4566
|
-
/* @__PURE__ */ (0,
|
|
5357
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
|
|
4567
5358
|
"div",
|
|
4568
5359
|
{
|
|
4569
|
-
"aria-hidden": "true",
|
|
4570
|
-
className: "fd-erow-ghost",
|
|
4571
|
-
style: {
|
|
4572
|
-
position: "fixed",
|
|
4573
|
-
left: 0,
|
|
4574
|
-
top: 0,
|
|
4575
|
-
width: drag.width,
|
|
4576
|
-
height: drag.height,
|
|
4577
|
-
transform: `translate(${drag.x - drag.offsetX}px, ${drag.y - drag.offsetY}px) rotate(-3deg)`,
|
|
4578
|
-
pointerEvents: "none",
|
|
4579
|
-
zIndex: OVERLAY_CEILING
|
|
4580
|
-
},
|
|
4581
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(EntityRow, { ...renderRow(drag.item), draggable: true, className: "fd-erow-dragging" })
|
|
4582
|
-
}
|
|
4583
|
-
),
|
|
4584
|
-
document.body
|
|
4585
|
-
) : null
|
|
4586
|
-
] });
|
|
4587
|
-
}
|
|
4588
|
-
|
|
4589
|
-
// src/components/forms/Checkbox.tsx
|
|
4590
|
-
var React31 = __toESM(require("react"), 1);
|
|
4591
|
-
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
4592
|
-
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
4593
|
-
const ref = React31.useRef(null);
|
|
4594
|
-
React31.useEffect(() => {
|
|
4595
|
-
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
4596
|
-
}, [indeterminate]);
|
|
4597
|
-
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
4598
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "fd-choice-input", children: [
|
|
4599
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("input", { ref, type: "checkbox", ...rest }),
|
|
4600
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
|
|
4601
|
-
] }),
|
|
4602
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "fd-choice-text", children: [
|
|
4603
|
-
/* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-choice-title", children: label }),
|
|
4604
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
4605
|
-
] })
|
|
4606
|
-
] });
|
|
4607
|
-
}
|
|
4608
|
-
|
|
4609
|
-
// src/components/forms/Radio.tsx
|
|
4610
|
-
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
4611
|
-
function Radio({ label, description, card = false, className = "", ...rest }) {
|
|
4612
|
-
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
4613
|
-
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "fd-choice-input", children: [
|
|
4614
|
-
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("input", { type: "radio", ...rest }),
|
|
4615
|
-
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "fd-choice-dot" }) })
|
|
4616
|
-
] }),
|
|
4617
|
-
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "fd-choice-text", children: [
|
|
4618
|
-
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "fd-choice-title", children: label }),
|
|
4619
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
4620
|
-
] })
|
|
4621
|
-
] });
|
|
4622
|
-
}
|
|
4623
|
-
|
|
4624
|
-
// src/components/forms/Switch.tsx
|
|
4625
|
-
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
4626
|
-
function Switch({ label, description, className = "", ...rest }) {
|
|
4627
|
-
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
|
|
4628
|
-
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { type: "checkbox", role: "switch", ...rest }),
|
|
4629
|
-
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-switch-track", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-switch-thumb" }) }),
|
|
4630
|
-
label ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "fd-choice-text", children: [
|
|
4631
|
-
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-switch-label", children: label }),
|
|
4632
|
-
description ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
4633
|
-
] }) : null
|
|
4634
|
-
] });
|
|
4635
|
-
}
|
|
4636
|
-
|
|
4637
|
-
// src/components/forms/Textarea.tsx
|
|
4638
|
-
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
4639
|
-
function Textarea({ label, help, error, required = false, rows = 4, disabled = false, id, className = "", style, ...rest }) {
|
|
4640
|
-
const fieldId = useFieldId(id);
|
|
4641
|
-
const box = ["fd-input", "fd-input-textarea", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
4642
|
-
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
4643
|
-
label ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
4644
|
-
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: box, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("textarea", { id: fieldId, rows, disabled, "aria-invalid": error ? "true" : void 0, ...rest }) }),
|
|
4645
|
-
error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "fd-field-error", children: [
|
|
4646
|
-
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4647
|
-
error
|
|
4648
|
-
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
4649
|
-
] });
|
|
4650
|
-
}
|
|
4651
|
-
|
|
4652
|
-
// src/components/forms/NumberInput.tsx
|
|
4653
|
-
var React32 = __toESM(require("react"), 1);
|
|
4654
|
-
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
4655
|
-
function NumberInput({
|
|
4656
|
-
label,
|
|
4657
|
-
help,
|
|
4658
|
-
error,
|
|
4659
|
-
prefix,
|
|
4660
|
-
suffix,
|
|
4661
|
-
required = false,
|
|
4662
|
-
disabled = false,
|
|
4663
|
-
min = -Infinity,
|
|
4664
|
-
max = Infinity,
|
|
4665
|
-
step = 1,
|
|
4666
|
-
bigStep,
|
|
4667
|
-
value,
|
|
4668
|
-
onChange,
|
|
4669
|
-
format = true,
|
|
4670
|
-
className = "",
|
|
4671
|
-
style,
|
|
4672
|
-
placeholder,
|
|
4673
|
-
id,
|
|
4674
|
-
"aria-label": ariaLabel
|
|
4675
|
-
}) {
|
|
4676
|
-
const fieldId = useFieldId(id);
|
|
4677
|
-
const num = (v) => {
|
|
4678
|
-
const n = Number(String(v == null ? "" : v).replace(/[^0-9.-]/g, ""));
|
|
4679
|
-
return isNaN(n) ? null : n;
|
|
4680
|
-
};
|
|
4681
|
-
const [text, setText] = React32.useState(value == null || value === "" ? "" : String(value));
|
|
4682
|
-
const [editing, setEditing] = React32.useState(false);
|
|
4683
|
-
const timer = React32.useRef(null);
|
|
4684
|
-
React32.useEffect(() => {
|
|
4685
|
-
if (!editing) setText(value == null || value === "" ? "" : String(value));
|
|
4686
|
-
}, [value, editing]);
|
|
4687
|
-
const clamp = (n) => Math.min(max, Math.max(min, n));
|
|
4688
|
-
const fire = (n) => onChange && onChange({ target: { value: n } });
|
|
4689
|
-
const bump = (dir, mult = 1) => {
|
|
4690
|
-
const cur = num(text) ?? num(value) ?? (min === -Infinity ? 0 : min);
|
|
4691
|
-
const next = clamp(cur + dir * (bigStep && mult > 1 ? bigStep : step) * (bigStep ? 1 : mult));
|
|
4692
|
-
setText(String(next));
|
|
4693
|
-
fire(next);
|
|
4694
|
-
};
|
|
4695
|
-
const hold = (dir) => {
|
|
4696
|
-
bump(dir);
|
|
4697
|
-
let n = 0;
|
|
4698
|
-
const tick = () => {
|
|
4699
|
-
n++;
|
|
4700
|
-
bump(dir, n > 6 ? 4 : 1);
|
|
4701
|
-
timer.current = setTimeout(tick, n > 12 ? 40 : n > 6 ? 70 : 120);
|
|
4702
|
-
};
|
|
4703
|
-
timer.current = setTimeout(tick, 420);
|
|
4704
|
-
};
|
|
4705
|
-
const release = () => {
|
|
4706
|
-
if (timer.current) clearTimeout(timer.current);
|
|
4707
|
-
};
|
|
4708
|
-
React32.useEffect(() => () => {
|
|
4709
|
-
if (timer.current) clearTimeout(timer.current);
|
|
4710
|
-
}, []);
|
|
4711
|
-
const shown = editing ? text : (() => {
|
|
4712
|
-
const n = num(text);
|
|
4713
|
-
return n == null ? "" : format ? n.toLocaleString() : String(n);
|
|
4714
|
-
})();
|
|
4715
|
-
const box = ["fd-input", "fd-input-num", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
4716
|
-
const fieldName = label || ariaLabel;
|
|
4717
|
-
const stepperName = (verb) => fieldName ? verb + " " + fieldName : verb;
|
|
4718
|
-
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: ["fd-field", className].filter(Boolean).join(" "), style, children: [
|
|
4719
|
-
label ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(FieldLabel, { htmlFor: fieldId, required, children: label }) : null,
|
|
4720
|
-
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: box, style: { gap: 8 }, children: [
|
|
4721
|
-
prefix ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-input-affix", children: prefix }) : null,
|
|
4722
|
-
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4723
|
-
"input",
|
|
4724
|
-
{
|
|
4725
|
-
id: fieldId,
|
|
4726
|
-
"aria-label": ariaLabel,
|
|
4727
|
-
inputMode: "numeric",
|
|
4728
|
-
disabled,
|
|
4729
|
-
placeholder,
|
|
4730
|
-
value: shown,
|
|
4731
|
-
onFocus: () => setEditing(true),
|
|
4732
|
-
onBlur: () => {
|
|
4733
|
-
setEditing(false);
|
|
4734
|
-
const n = num(text);
|
|
4735
|
-
if (n != null) {
|
|
4736
|
-
const c = clamp(n);
|
|
4737
|
-
setText(String(c));
|
|
4738
|
-
fire(c);
|
|
4739
|
-
}
|
|
4740
|
-
},
|
|
4741
|
-
onChange: (e) => {
|
|
4742
|
-
setText(e.target.value);
|
|
4743
|
-
const n = num(e.target.value);
|
|
4744
|
-
if (n != null) fire(n);
|
|
5360
|
+
"aria-hidden": "true",
|
|
5361
|
+
className: "fd-erow-ghost",
|
|
5362
|
+
style: {
|
|
5363
|
+
position: "fixed",
|
|
5364
|
+
left: 0,
|
|
5365
|
+
top: 0,
|
|
5366
|
+
width: drag.width,
|
|
5367
|
+
height: drag.height,
|
|
5368
|
+
transform: `translate(${drag.x - drag.offsetX}px, ${drag.y - drag.offsetY}px) rotate(-3deg)`,
|
|
5369
|
+
pointerEvents: "none",
|
|
5370
|
+
zIndex: OVERLAY_CEILING
|
|
4745
5371
|
},
|
|
4746
|
-
|
|
4747
|
-
if (e.key === "ArrowUp") {
|
|
4748
|
-
e.preventDefault();
|
|
4749
|
-
bump(1, e.shiftKey ? 2 : 1);
|
|
4750
|
-
} else if (e.key === "ArrowDown") {
|
|
4751
|
-
e.preventDefault();
|
|
4752
|
-
bump(-1, e.shiftKey ? 2 : 1);
|
|
4753
|
-
}
|
|
4754
|
-
}
|
|
5372
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(EntityRow, { ...renderRow(drag.item), draggable: true, className: "fd-erow-dragging" })
|
|
4755
5373
|
}
|
|
4756
5374
|
),
|
|
4757
|
-
|
|
4758
|
-
|
|
4759
|
-
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4760
|
-
"button",
|
|
4761
|
-
{
|
|
4762
|
-
type: "button",
|
|
4763
|
-
className: "fd-stepbtn",
|
|
4764
|
-
"aria-label": stepperName("Decrease"),
|
|
4765
|
-
disabled: disabled || (num(text) ?? 0) <= min,
|
|
4766
|
-
onPointerDown: () => hold(-1),
|
|
4767
|
-
onPointerUp: release,
|
|
4768
|
-
onPointerLeave: release,
|
|
4769
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("i", { className: "ph ph-minus" })
|
|
4770
|
-
}
|
|
4771
|
-
),
|
|
4772
|
-
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
4773
|
-
"button",
|
|
4774
|
-
{
|
|
4775
|
-
type: "button",
|
|
4776
|
-
className: "fd-stepbtn",
|
|
4777
|
-
"aria-label": stepperName("Increase"),
|
|
4778
|
-
disabled: disabled || (num(text) ?? 0) >= max,
|
|
4779
|
-
onPointerDown: () => hold(1),
|
|
4780
|
-
onPointerUp: release,
|
|
4781
|
-
onPointerLeave: release,
|
|
4782
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("i", { className: "ph ph-plus" })
|
|
4783
|
-
}
|
|
4784
|
-
)
|
|
4785
|
-
] })
|
|
4786
|
-
] }),
|
|
4787
|
-
error ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "fd-field-error", children: [
|
|
4788
|
-
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
4789
|
-
error
|
|
4790
|
-
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
5375
|
+
document.body
|
|
5376
|
+
) : null
|
|
4791
5377
|
] });
|
|
4792
5378
|
}
|
|
4793
5379
|
|
|
4794
|
-
// src/components/forms/
|
|
5380
|
+
// src/components/forms/Checkbox.tsx
|
|
4795
5381
|
var React33 = __toESM(require("react"), 1);
|
|
5382
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
5383
|
+
function Checkbox({ label, description, card = false, indeterminate = false, className = "", ...rest }) {
|
|
5384
|
+
const ref = React33.useRef(null);
|
|
5385
|
+
React33.useEffect(() => {
|
|
5386
|
+
if (ref.current) ref.current.indeterminate = indeterminate;
|
|
5387
|
+
}, [indeterminate]);
|
|
5388
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
5389
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "fd-choice-input", children: [
|
|
5390
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("input", { ref, type: "checkbox", ...rest }),
|
|
5391
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "fd-choice-box", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("i", { className: indeterminate ? "ph ph-minus" : "ph ph-check" }) })
|
|
5392
|
+
] }),
|
|
5393
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "fd-choice-text", children: [
|
|
5394
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "fd-choice-title", children: label }),
|
|
5395
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
5396
|
+
] })
|
|
5397
|
+
] });
|
|
5398
|
+
}
|
|
5399
|
+
|
|
5400
|
+
// src/components/forms/Radio.tsx
|
|
5401
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
5402
|
+
function Radio({ label, description, card = false, className = "", ...rest }) {
|
|
5403
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("label", { className: ["fd-choice", card ? "fd-choice-card" : "", className].filter(Boolean).join(" "), children: [
|
|
5404
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "fd-choice-input", children: [
|
|
5405
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("input", { type: "radio", ...rest }),
|
|
5406
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-choice-box fd-choice-box-round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-choice-dot" }) })
|
|
5407
|
+
] }),
|
|
5408
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { className: "fd-choice-text", children: [
|
|
5409
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-choice-title", children: label }),
|
|
5410
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
5411
|
+
] })
|
|
5412
|
+
] });
|
|
5413
|
+
}
|
|
5414
|
+
|
|
5415
|
+
// src/components/forms/Switch.tsx
|
|
4796
5416
|
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
5417
|
+
function Switch({ label, description, className = "", ...rest }) {
|
|
5418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("label", { className: ["fd-switch", className].filter(Boolean).join(" "), children: [
|
|
5419
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("input", { type: "checkbox", role: "switch", ...rest }),
|
|
5420
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-switch-track", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-switch-thumb" }) }),
|
|
5421
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-choice-text", children: [
|
|
5422
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-switch-label", children: label }),
|
|
5423
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-choice-desc", children: description }) : null
|
|
5424
|
+
] }) : null
|
|
5425
|
+
] });
|
|
5426
|
+
}
|
|
5427
|
+
|
|
5428
|
+
// src/components/forms/Select.tsx
|
|
5429
|
+
var React34 = __toESM(require("react"), 1);
|
|
5430
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
4797
5431
|
var norm = (o) => typeof o === "string" ? { value: o, label: o } : o;
|
|
4798
5432
|
function Select({
|
|
4799
5433
|
label,
|
|
@@ -4819,13 +5453,13 @@ function Select({
|
|
|
4819
5453
|
const isOn = (v) => multiple ? vals.includes(v) : v === value;
|
|
4820
5454
|
const hasSearch = searchable === void 0 ? opts.length > 8 : searchable;
|
|
4821
5455
|
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
4822
|
-
const [open, setOpen] =
|
|
4823
|
-
const [q, setQ] =
|
|
4824
|
-
const [active, setActive] =
|
|
4825
|
-
const rootRef =
|
|
4826
|
-
const boxRef =
|
|
4827
|
-
const listRef =
|
|
4828
|
-
const typeBuf =
|
|
5456
|
+
const [open, setOpen] = React34.useState(false);
|
|
5457
|
+
const [q, setQ] = React34.useState("");
|
|
5458
|
+
const [active, setActive] = React34.useState(-1);
|
|
5459
|
+
const rootRef = React34.useRef(null);
|
|
5460
|
+
const boxRef = React34.useRef(null);
|
|
5461
|
+
const listRef = React34.useRef(null);
|
|
5462
|
+
const typeBuf = React34.useRef({ s: "", t: 0 });
|
|
4829
5463
|
const selected = multiple ? null : opts.find((o) => o.value === value);
|
|
4830
5464
|
const chosen = multiple ? opts.filter((o) => vals.includes(o.value)) : [];
|
|
4831
5465
|
const boxText = multiple ? chosen.length === 0 ? placeholder : chosen.length === 1 ? chosen[0].label : summary ? summary(chosen.map((o) => o.value)) : chosen.length + " selected" : selected ? selected.label : placeholder;
|
|
@@ -4850,7 +5484,7 @@ function Select({
|
|
|
4850
5484
|
}
|
|
4851
5485
|
setOpen(!open);
|
|
4852
5486
|
};
|
|
4853
|
-
|
|
5487
|
+
React34.useEffect(() => {
|
|
4854
5488
|
if (!open || active < 0 || !listRef.current) return;
|
|
4855
5489
|
const el = listRef.current.querySelector('[data-i="' + active + '"]');
|
|
4856
5490
|
if (el) {
|
|
@@ -4903,10 +5537,10 @@ function Select({
|
|
|
4903
5537
|
else last.items.push({ o, i });
|
|
4904
5538
|
});
|
|
4905
5539
|
const box = ["fd-input", "fd-select", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" ");
|
|
4906
|
-
return /* @__PURE__ */ (0,
|
|
4907
|
-
label ? /* @__PURE__ */ (0,
|
|
4908
|
-
/* @__PURE__ */ (0,
|
|
4909
|
-
/* @__PURE__ */ (0,
|
|
5540
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
5541
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
5542
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: box, style: { cursor: disabled ? "not-allowed" : "pointer" }, ref: boxRef, children: [
|
|
5543
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
4910
5544
|
"button",
|
|
4911
5545
|
{
|
|
4912
5546
|
type: "button",
|
|
@@ -4920,13 +5554,13 @@ function Select({
|
|
|
4920
5554
|
"aria-labelledby": ariaLabelledBy,
|
|
4921
5555
|
style: { all: "unset", flex: 1, minWidth: 0, display: "flex", alignItems: "center", gap: 8, cursor: "inherit", overflow: "hidden" },
|
|
4922
5556
|
children: [
|
|
4923
|
-
selected && selected.icon ? /* @__PURE__ */ (0,
|
|
4924
|
-
/* @__PURE__ */ (0,
|
|
4925
|
-
multiple && chosen.length > 1 ? /* @__PURE__ */ (0,
|
|
5557
|
+
selected && selected.icon ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-" + selected.icon, style: { flex: "none", color: "var(--text-2)" } }) : null,
|
|
5558
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { title: truncationTitle(boxText), style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", color: (multiple ? chosen.length : selected) ? "var(--text)" : "var(--text-muted)" }, children: boxText }),
|
|
5559
|
+
multiple && chosen.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-mono", style: { flex: "none", fontSize: 11, fontWeight: 700, padding: "1px 6px", borderRadius: 99, background: "var(--brand)", color: "#fff" }, children: chosen.length }) : null
|
|
4926
5560
|
]
|
|
4927
5561
|
}
|
|
4928
5562
|
),
|
|
4929
|
-
clearable && (multiple ? chosen.length > 0 : selected) && !loading ? /* @__PURE__ */ (0,
|
|
5563
|
+
clearable && (multiple ? chosen.length > 0 : selected) && !loading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4930
5564
|
"button",
|
|
4931
5565
|
{
|
|
4932
5566
|
type: "button",
|
|
@@ -4936,12 +5570,12 @@ function Select({
|
|
|
4936
5570
|
fire(multiple ? [] : "");
|
|
4937
5571
|
},
|
|
4938
5572
|
style: { all: "unset", cursor: "pointer", color: "var(--text-muted)", display: "grid", placeItems: "center", padding: 2 },
|
|
4939
|
-
children: /* @__PURE__ */ (0,
|
|
5573
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-x-circle", style: { fontSize: 15 } })
|
|
4940
5574
|
}
|
|
4941
5575
|
) : null,
|
|
4942
|
-
loading ? /* @__PURE__ */ (0,
|
|
5576
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-spinner", style: { color: "var(--text-muted)" }, "aria-label": "Loading options" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-select-caret", onClick: toggle, children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-caret-down", "aria-hidden": "true" }) })
|
|
4943
5577
|
] }),
|
|
4944
|
-
/* @__PURE__ */ (0,
|
|
5578
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4945
5579
|
Popover,
|
|
4946
5580
|
{
|
|
4947
5581
|
open,
|
|
@@ -4954,9 +5588,9 @@ function Select({
|
|
|
4954
5588
|
minWidth: 260,
|
|
4955
5589
|
role: "presentation",
|
|
4956
5590
|
style: { maxWidth: 380 },
|
|
4957
|
-
header: hasSearch ? /* @__PURE__ */ (0,
|
|
4958
|
-
/* @__PURE__ */ (0,
|
|
4959
|
-
/* @__PURE__ */ (0,
|
|
5591
|
+
header: hasSearch ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-pop-search", children: [
|
|
5592
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-magnifying-glass", style: { color: "var(--text-muted)", fontSize: 14 } }),
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4960
5594
|
"input",
|
|
4961
5595
|
{
|
|
4962
5596
|
autoFocus: true,
|
|
@@ -4969,10 +5603,10 @@ function Select({
|
|
|
4969
5603
|
}
|
|
4970
5604
|
}
|
|
4971
5605
|
),
|
|
4972
|
-
q ? /* @__PURE__ */ (0,
|
|
5606
|
+
q ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-body-sm fd-muted", children: visible.length }) : null
|
|
4973
5607
|
] }) : void 0,
|
|
4974
|
-
footer: multiple ? /* @__PURE__ */ (0,
|
|
4975
|
-
/* @__PURE__ */ (0,
|
|
5608
|
+
footer: multiple ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(React34.Fragment, { children: [
|
|
5609
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4976
5610
|
"button",
|
|
4977
5611
|
{
|
|
4978
5612
|
type: "button",
|
|
@@ -4981,13 +5615,13 @@ function Select({
|
|
|
4981
5615
|
children: "Select all"
|
|
4982
5616
|
}
|
|
4983
5617
|
),
|
|
4984
|
-
/* @__PURE__ */ (0,
|
|
4985
|
-
/* @__PURE__ */ (0,
|
|
5618
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { style: { flex: 1 } }),
|
|
5619
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
4986
5620
|
vals.length,
|
|
4987
5621
|
" of ",
|
|
4988
5622
|
opts.length
|
|
4989
5623
|
] }),
|
|
4990
|
-
/* @__PURE__ */ (0,
|
|
5624
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
4991
5625
|
"button",
|
|
4992
5626
|
{
|
|
4993
5627
|
type: "button",
|
|
@@ -4998,13 +5632,13 @@ function Select({
|
|
|
4998
5632
|
}
|
|
4999
5633
|
)
|
|
5000
5634
|
] }) : void 0,
|
|
5001
|
-
children: /* @__PURE__ */ (0,
|
|
5635
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "fd-pop-list", role: "listbox", "aria-multiselectable": multiple || void 0, ref: listRef, children: visible.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-pop-empty", children: [
|
|
5002
5636
|
'Nothing matches "',
|
|
5003
5637
|
q,
|
|
5004
5638
|
'".'
|
|
5005
|
-
] }) : groups.map((grp) => /* @__PURE__ */ (0,
|
|
5006
|
-
grp.g ? /* @__PURE__ */ (0,
|
|
5007
|
-
grp.items.map(({ o, i }) => /* @__PURE__ */ (0,
|
|
5639
|
+
] }) : groups.map((grp) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(React34.Fragment, { children: [
|
|
5640
|
+
grp.g ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "fd-pop-group", children: grp.g }) : null,
|
|
5641
|
+
grp.items.map(({ o, i }) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
5008
5642
|
"button",
|
|
5009
5643
|
{
|
|
5010
5644
|
type: "button",
|
|
@@ -5016,14 +5650,14 @@ function Select({
|
|
|
5016
5650
|
onMouseEnter: () => setActive(i),
|
|
5017
5651
|
onClick: () => pick(o),
|
|
5018
5652
|
children: [
|
|
5019
|
-
multiple ? /* @__PURE__ */ (0,
|
|
5020
|
-
o.icon ? /* @__PURE__ */ (0,
|
|
5021
|
-
/* @__PURE__ */ (0,
|
|
5022
|
-
/* @__PURE__ */ (0,
|
|
5023
|
-
o.description ? /* @__PURE__ */ (0,
|
|
5653
|
+
multiple ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { "aria-hidden": "true", style: { flex: "none", display: "grid", placeItems: "center", width: 16, height: 16, borderRadius: 4, border: "1.5px solid " + (isOn(o.value) ? "var(--brand)" : "var(--border-strong, var(--border))"), background: isOn(o.value) ? "var(--brand)" : "var(--surface)", color: "#fff" }, children: isOn(o.value) ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-check", style: { fontSize: 11 } }) : null }) : null,
|
|
5654
|
+
o.icon ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-opt-icon", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-" + o.icon }) }) : null,
|
|
5655
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { style: { flex: 1, minWidth: 0 }, children: [
|
|
5656
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-opt-label", children: o.label }),
|
|
5657
|
+
o.description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-opt-desc", children: o.description }) : null
|
|
5024
5658
|
] }),
|
|
5025
|
-
o.meta ? /* @__PURE__ */ (0,
|
|
5026
|
-
multiple ? null : /* @__PURE__ */ (0,
|
|
5659
|
+
o.meta ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-opt-meta", children: o.meta }) : null,
|
|
5660
|
+
multiple ? null : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-opt-check", children: o.value === value ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-check" }) : null })
|
|
5027
5661
|
]
|
|
5028
5662
|
},
|
|
5029
5663
|
String(o.value)
|
|
@@ -5031,208 +5665,6 @@ function Select({
|
|
|
5031
5665
|
] }, grp.g || "_")) })
|
|
5032
5666
|
}
|
|
5033
5667
|
),
|
|
5034
|
-
error ? /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "fd-field-error", children: [
|
|
5035
|
-
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
5036
|
-
error
|
|
5037
|
-
] }) : help ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { className: "fd-field-help", children: help }) : null
|
|
5038
|
-
] });
|
|
5039
|
-
}
|
|
5040
|
-
|
|
5041
|
-
// src/components/forms/DatePicker.tsx
|
|
5042
|
-
var React34 = __toESM(require("react"), 1);
|
|
5043
|
-
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
5044
|
-
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
5045
|
-
var DOW = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
5046
|
-
var iso = (d) => d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
|
|
5047
|
-
var parse = (s) => {
|
|
5048
|
-
if (!s) return null;
|
|
5049
|
-
const [y, m, d] = s.split("-").map(Number);
|
|
5050
|
-
return new Date(y, m - 1, d);
|
|
5051
|
-
};
|
|
5052
|
-
var fmt = (s) => {
|
|
5053
|
-
const d = parse(s);
|
|
5054
|
-
return d ? MONTHS[d.getMonth()].slice(0, 3) + " " + d.getDate() + ", " + d.getFullYear() : "";
|
|
5055
|
-
};
|
|
5056
|
-
function Calendar({ value, range = false, onPick, initialMonth, months = 1 }) {
|
|
5057
|
-
const today = /* @__PURE__ */ new Date();
|
|
5058
|
-
const sel = range ? value || {} : { start: value, end: value };
|
|
5059
|
-
const anchor = parse(sel.start) || parse(initialMonth) || today;
|
|
5060
|
-
const [vy, setVy] = React34.useState(anchor.getFullYear());
|
|
5061
|
-
const [vm, setVm] = React34.useState(anchor.getMonth());
|
|
5062
|
-
const [mode2, setMode] = React34.useState("days");
|
|
5063
|
-
const [hover, setHover] = React34.useState(null);
|
|
5064
|
-
const s = parse(sel.start), e = parse(sel.end);
|
|
5065
|
-
const hoverEnd = range && s && !e && hover ? parse(hover) : null;
|
|
5066
|
-
const inRange = (d) => {
|
|
5067
|
-
const lo = s, hi = e || hoverEnd;
|
|
5068
|
-
return lo && hi && d > (lo < hi ? lo : hi) && d < (lo < hi ? hi : lo);
|
|
5069
|
-
};
|
|
5070
|
-
const isEdge = (d) => s && iso(d) === iso(s) || e && iso(d) === iso(e);
|
|
5071
|
-
const clickDay = (d) => {
|
|
5072
|
-
const v = iso(d);
|
|
5073
|
-
if (!range) {
|
|
5074
|
-
onPick(v);
|
|
5075
|
-
return;
|
|
5076
|
-
}
|
|
5077
|
-
if (!sel.start || sel.start && sel.end) onPick({ start: v, end: "" });
|
|
5078
|
-
else {
|
|
5079
|
-
const a = parse(sel.start);
|
|
5080
|
-
onPick(d < a ? { start: v, end: sel.start } : { start: sel.start, end: v });
|
|
5081
|
-
}
|
|
5082
|
-
};
|
|
5083
|
-
const nav = (d) => {
|
|
5084
|
-
let m = vm + d, y = vy;
|
|
5085
|
-
if (m < 0) {
|
|
5086
|
-
m = 11;
|
|
5087
|
-
y--;
|
|
5088
|
-
}
|
|
5089
|
-
if (m > 11) {
|
|
5090
|
-
m = 0;
|
|
5091
|
-
y++;
|
|
5092
|
-
}
|
|
5093
|
-
setVm(m);
|
|
5094
|
-
setVy(y);
|
|
5095
|
-
};
|
|
5096
|
-
const monthGrid = (y, m) => {
|
|
5097
|
-
const startPad = new Date(y, m, 1).getDay();
|
|
5098
|
-
const cells = [];
|
|
5099
|
-
for (let i = 0; i < 42; i++) cells.push(new Date(y, m, i - startPad + 1));
|
|
5100
|
-
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-cal-grid", style: { width: months > 1 ? 252 : "auto", flex: "none" }, onMouseLeave: () => setHover(null), children: [
|
|
5101
|
-
DOW.map((d) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-cal-dow", children: d }, d)),
|
|
5102
|
-
cells.map((d, i) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5103
|
-
"button",
|
|
5104
|
-
{
|
|
5105
|
-
type: "button",
|
|
5106
|
-
className: ["fd-cal-day", d.getMonth() !== m ? "is-out" : "", iso(d) === iso(today) ? "is-today" : "", inRange(d) ? "in-range" : "", isEdge(d) ? "is-edge" : ""].filter(Boolean).join(" "),
|
|
5107
|
-
onClick: () => clickDay(d),
|
|
5108
|
-
onMouseEnter: () => range && setHover(iso(d)),
|
|
5109
|
-
children: d.getDate()
|
|
5110
|
-
},
|
|
5111
|
-
i
|
|
5112
|
-
))
|
|
5113
|
-
] });
|
|
5114
|
-
};
|
|
5115
|
-
const nextY = vm === 11 ? vy + 1 : vy, nextM = (vm + 1) % 12;
|
|
5116
|
-
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-cal", style: { width: months > 1 && mode2 === "days" ? "auto" : void 0 }, children: [
|
|
5117
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-cal-head", children: [
|
|
5118
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Previous", onClick: () => mode2 === "years" ? setVy(vy - 12) : mode2 === "months" ? setVy(vy - 1) : nav(-1), children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-caret-left" }) }),
|
|
5119
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("button", { type: "button", className: "fd-cal-title", onClick: () => setMode(mode2 === "days" ? "months" : mode2 === "months" ? "years" : "days"), children: [
|
|
5120
|
-
mode2 === "days" ? MONTHS[vm] + " " + vy : mode2 === "months" ? vy : vy - 5 + " \u2013 " + (vy + 6),
|
|
5121
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-caret-down", style: { fontSize: 10, marginLeft: 6, color: "var(--text-muted)" } })
|
|
5122
|
-
] }),
|
|
5123
|
-
months > 1 && mode2 === "days" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-cal-title", style: { cursor: "default", background: "none" }, children: MONTHS[nextM] + " " + nextY }) : null,
|
|
5124
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", className: "fd-btn-icon", "aria-label": "Next", onClick: () => mode2 === "years" ? setVy(vy + 12) : mode2 === "months" ? setVy(vy + 1) : nav(1), children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-caret-right" }) })
|
|
5125
|
-
] }),
|
|
5126
|
-
mode2 === "days" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { style: { display: "flex", gap: 18 }, children: [
|
|
5127
|
-
monthGrid(vy, vm),
|
|
5128
|
-
months > 1 ? monthGrid(nextY, nextM) : null
|
|
5129
|
-
] }) : mode2 === "months" ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "fd-cal-grid-months", children: MONTHS.map((m, i) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5130
|
-
"button",
|
|
5131
|
-
{
|
|
5132
|
-
type: "button",
|
|
5133
|
-
className: "fd-cal-cell" + (i === vm && s && s.getFullYear() === vy ? " is-sel" : ""),
|
|
5134
|
-
onClick: () => {
|
|
5135
|
-
setVm(i);
|
|
5136
|
-
setMode("days");
|
|
5137
|
-
},
|
|
5138
|
-
children: m.slice(0, 3)
|
|
5139
|
-
},
|
|
5140
|
-
m
|
|
5141
|
-
)) }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "fd-cal-grid-months", children: Array.from({ length: 12 }, (_, i) => vy - 5 + i).map((y) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5142
|
-
"button",
|
|
5143
|
-
{
|
|
5144
|
-
type: "button",
|
|
5145
|
-
className: "fd-cal-cell" + (y === vy ? " is-sel" : ""),
|
|
5146
|
-
onClick: () => {
|
|
5147
|
-
setVy(y);
|
|
5148
|
-
setMode("months");
|
|
5149
|
-
},
|
|
5150
|
-
children: y
|
|
5151
|
-
},
|
|
5152
|
-
y
|
|
5153
|
-
)) }),
|
|
5154
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "fd-cal-foot", children: [
|
|
5155
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5156
|
-
"button",
|
|
5157
|
-
{
|
|
5158
|
-
type: "button",
|
|
5159
|
-
className: "fd-btn fd-btn-link",
|
|
5160
|
-
style: { fontSize: 12.5 },
|
|
5161
|
-
onClick: () => {
|
|
5162
|
-
setVy(today.getFullYear());
|
|
5163
|
-
setVm(today.getMonth());
|
|
5164
|
-
setMode("days");
|
|
5165
|
-
},
|
|
5166
|
-
children: "Today"
|
|
5167
|
-
}
|
|
5168
|
-
),
|
|
5169
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { style: { flex: 1 } }),
|
|
5170
|
-
range && sel.start ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "fd-body-sm fd-muted", children: [
|
|
5171
|
-
fmt(sel.start),
|
|
5172
|
-
sel.end ? " \u2192 " + fmt(sel.end) : " \u2192 pick an end"
|
|
5173
|
-
] }) : null
|
|
5174
|
-
] })
|
|
5175
|
-
] });
|
|
5176
|
-
}
|
|
5177
|
-
function DatePicker({ label, help, error, required = false, disabled = false, range = false, value, onChange, placeholder, id, className = "", style, ...rest }) {
|
|
5178
|
-
const { fieldId, labelId, ariaLabelledBy } = useTriggerLabelling(label, id);
|
|
5179
|
-
const [open, setOpen] = React34.useState(false);
|
|
5180
|
-
const rootRef = React34.useRef(null);
|
|
5181
|
-
const boxRef = React34.useRef(null);
|
|
5182
|
-
const display = range ? value && value.start ? fmt(value.start) + (value.end ? " \u2192 " + fmt(value.end) : " \u2192 \u2026") : "" : fmt(value);
|
|
5183
|
-
const toggle = () => {
|
|
5184
|
-
if (!disabled) setOpen(!open);
|
|
5185
|
-
};
|
|
5186
|
-
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: ["fd-field", "fd-popfield", open ? "is-open" : "", className].filter(Boolean).join(" "), style, ref: rootRef, children: [
|
|
5187
|
-
label ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(FieldLabel, { id: labelId, required, onClick: toggle, children: label }) : null,
|
|
5188
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: ["fd-input", error ? "fd-input-error" : "", disabled ? "fd-input-disabled" : ""].filter(Boolean).join(" "), style: { cursor: disabled ? "not-allowed" : "pointer" }, onClick: toggle, ref: boxRef, children: [
|
|
5189
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-input-icon", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-calendar-blank", "aria-hidden": "true" }) }),
|
|
5190
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5191
|
-
"button",
|
|
5192
|
-
{
|
|
5193
|
-
type: "button",
|
|
5194
|
-
id: fieldId,
|
|
5195
|
-
"aria-labelledby": ariaLabelledBy,
|
|
5196
|
-
title: truncationTitle(display),
|
|
5197
|
-
disabled,
|
|
5198
|
-
onKeyDown: (e) => {
|
|
5199
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
5200
|
-
e.preventDefault();
|
|
5201
|
-
toggle();
|
|
5202
|
-
}
|
|
5203
|
-
},
|
|
5204
|
-
style: { all: "unset", flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", cursor: "inherit", color: display ? "var(--text)" : "var(--text-muted)" },
|
|
5205
|
-
...rest,
|
|
5206
|
-
children: display || placeholder || (range ? "Pick a date range" : "Pick a date")
|
|
5207
|
-
}
|
|
5208
|
-
),
|
|
5209
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "fd-select-caret", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-caret-down", "aria-hidden": "true" }) })
|
|
5210
|
-
] }),
|
|
5211
|
-
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5212
|
-
Popover,
|
|
5213
|
-
{
|
|
5214
|
-
open,
|
|
5215
|
-
anchorRef: boxRef,
|
|
5216
|
-
triggerRef: rootRef,
|
|
5217
|
-
onClose: () => setOpen(false),
|
|
5218
|
-
placement: "bottom-start",
|
|
5219
|
-
offset: 6,
|
|
5220
|
-
role: "presentation",
|
|
5221
|
-
style: { width: "max-content" },
|
|
5222
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
5223
|
-
Calendar,
|
|
5224
|
-
{
|
|
5225
|
-
range,
|
|
5226
|
-
months: range ? 2 : 1,
|
|
5227
|
-
value,
|
|
5228
|
-
onPick: (v) => {
|
|
5229
|
-
onChange && onChange({ target: { value: v } });
|
|
5230
|
-
if (!range || v.start && v.end) setOpen(false);
|
|
5231
|
-
}
|
|
5232
|
-
}
|
|
5233
|
-
)
|
|
5234
|
-
}
|
|
5235
|
-
),
|
|
5236
5668
|
error ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "fd-field-error", children: [
|
|
5237
5669
|
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("i", { className: "ph ph-warning-circle", "aria-hidden": "true" }),
|
|
5238
5670
|
error
|