@pstrikez/fluent-winui-theme 0.1.2 → 0.2.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/base.css +1 -1
- package/dist/components/ui/confirm-dialog.d.ts +4 -1
- package/dist/components/ui/confirm-flyout.d.ts +14 -0
- package/dist/components/ui/data-table.d.ts +72 -0
- package/dist/components/ui/dialog-shell.d.ts +1 -0
- package/dist/components/ui/file-drop-zone.d.ts +42 -0
- package/dist/components/ui/metric.d.ts +34 -0
- package/dist/components/ui/number-box.d.ts +36 -0
- package/dist/components/ui/outcome-toast.d.ts +9 -1
- package/dist/components/ui/pager.d.ts +23 -0
- package/dist/components/ui/property-list.d.ts +19 -0
- package/dist/components/ui/tab-view.d.ts +25 -0
- package/dist/components/ui/tooltip-icon-button.d.ts +5 -2
- package/dist/components/ui/use-confirm.d.ts +18 -0
- package/dist/i18n/translation.d.ts +46 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +1835 -317
- package/dist/index.js.map +4 -4
- package/dist/winui/controls/dialog.css.d.ts +1 -1
- package/dist/winui/controls/spin-button.css.d.ts +1 -0
- package/dist/winui.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1485,7 +1485,7 @@ var require_prism = __commonJS({
|
|
|
1485
1485
|
import * as fluentNamespace from "@fluentui/react-components";
|
|
1486
1486
|
|
|
1487
1487
|
// src/winui/appearance.ts
|
|
1488
|
-
import { CheckmarkCircleFilled, ChevronDown12Regular, DismissCircleFilled, ErrorCircleFilled, InfoFilled } from "@fluentui/react-icons";
|
|
1488
|
+
import { CheckmarkCircleFilled, ChevronDown12Regular, ChevronUp12Regular, DismissCircleFilled, ErrorCircleFilled, InfoFilled } from "@fluentui/react-icons";
|
|
1489
1489
|
import * as React2 from "react";
|
|
1490
1490
|
|
|
1491
1491
|
// src/winui/wrap.ts
|
|
@@ -1562,6 +1562,16 @@ var withWinuiAppearance = (components) => {
|
|
|
1562
1562
|
...props,
|
|
1563
1563
|
expandIcon: props.expandIcon === void 0 ? { children: React2.createElement(ChevronDown12Regular) } : props.expandIcon
|
|
1564
1564
|
}));
|
|
1565
|
+
const withSpinGlyph = (slot, Glyph) => {
|
|
1566
|
+
if (slot === null) return slot;
|
|
1567
|
+
const slotProps2 = resolveSlotProps(slot);
|
|
1568
|
+
return slotProps2?.children === void 0 ? { ...slotProps2, children: React2.createElement(Glyph) } : slotProps2;
|
|
1569
|
+
};
|
|
1570
|
+
const winuiSpinGlyphs = (component) => wrapFluent(component, (props) => ({
|
|
1571
|
+
...props,
|
|
1572
|
+
incrementButton: withSpinGlyph(props.incrementButton, ChevronUp12Regular),
|
|
1573
|
+
decrementButton: withSpinGlyph(props.decrementButton, ChevronDown12Regular)
|
|
1574
|
+
}));
|
|
1565
1575
|
return {
|
|
1566
1576
|
...components,
|
|
1567
1577
|
AccordionHeader: winuiChevron(components.AccordionHeader),
|
|
@@ -1578,6 +1588,7 @@ var withWinuiAppearance = (components) => {
|
|
|
1578
1588
|
Input: stamp(components.Input, appearance("outline", rootAndPrimary)),
|
|
1579
1589
|
Textarea: stamp(components.Textarea, appearance("outline", rootAndPrimary)),
|
|
1580
1590
|
Select: stamp(components.Select, appearance("outline", rootAndPrimary)),
|
|
1591
|
+
SpinButton: winuiSpinGlyphs(stamp(components.SpinButton, appearance("outline", rootAndPrimary))),
|
|
1581
1592
|
Combobox: stamp(components.Combobox, appearance("outline", rootAndPrimary)),
|
|
1582
1593
|
Dropdown: stamp(components.Dropdown, appearance("outline", rootAndPrimary)),
|
|
1583
1594
|
Card: stamp(components.Card, appearance("filled", rootIsPrimary)),
|
|
@@ -1743,11 +1754,11 @@ var withWinuiDrag = (components) => {
|
|
|
1743
1754
|
const suppressClickRef = React4.useRef(false);
|
|
1744
1755
|
const settleTimerRef = React4.useRef(void 0);
|
|
1745
1756
|
React4.useEffect(() => () => clearTimeout(settleTimerRef.current), []);
|
|
1746
|
-
const end = (gesture,
|
|
1757
|
+
const end = (gesture, toggle2, fromDrag) => {
|
|
1747
1758
|
gestureRef.current = null;
|
|
1748
1759
|
gesture.root.removeAttribute(DRAGGING);
|
|
1749
1760
|
gesture.root.style.removeProperty(DRAG_X);
|
|
1750
|
-
if (
|
|
1761
|
+
if (toggle2) {
|
|
1751
1762
|
if (fromDrag) {
|
|
1752
1763
|
gesture.root.setAttribute(SETTLING, "");
|
|
1753
1764
|
clearTimeout(settleTimerRef.current);
|
|
@@ -5553,7 +5564,30 @@ var en = {
|
|
|
5553
5564
|
"common.discard.discard": "Discard",
|
|
5554
5565
|
"common.copy.action": "Copy",
|
|
5555
5566
|
"common.copy.copied": "Copied",
|
|
5556
|
-
"common.copy.failed": "Copy failed"
|
|
5567
|
+
"common.copy.failed": "Copy failed",
|
|
5568
|
+
"numberBox.increment": "Increase value",
|
|
5569
|
+
"numberBox.decrement": "Decrease value",
|
|
5570
|
+
"fileDropZone.browse": "Browse files",
|
|
5571
|
+
"fileDropZone.dropHint": "Drop files here",
|
|
5572
|
+
"fileDropZone.remove": "Remove file",
|
|
5573
|
+
"pager.label": "Pagination",
|
|
5574
|
+
"pager.first": "First page",
|
|
5575
|
+
"pager.previous": "Previous page",
|
|
5576
|
+
"pager.next": "Next page",
|
|
5577
|
+
"pager.last": "Last page",
|
|
5578
|
+
"pager.page": "Page {n}",
|
|
5579
|
+
"pager.pageSize": "Items per page",
|
|
5580
|
+
"pager.perPage": "{n} / page",
|
|
5581
|
+
"pager.total": "Total {n} items",
|
|
5582
|
+
"dataTable.empty": "No data",
|
|
5583
|
+
"dataTable.loading": "Loading",
|
|
5584
|
+
"dataTable.selectAll": "Select all rows",
|
|
5585
|
+
"dataTable.selectRow": "Select row",
|
|
5586
|
+
"dataTable.expandRow": "Expand row",
|
|
5587
|
+
"dataTable.collapseRow": "Collapse row",
|
|
5588
|
+
"tabView.close": "Close tab",
|
|
5589
|
+
"tabView.scrollBackward": "Scroll tabs left",
|
|
5590
|
+
"tabView.scrollForward": "Scroll tabs right"
|
|
5557
5591
|
};
|
|
5558
5592
|
var zhHans = {
|
|
5559
5593
|
"common.on": "\u5F00",
|
|
@@ -5568,7 +5602,30 @@ var zhHans = {
|
|
|
5568
5602
|
"common.discard.discard": "\u653E\u5F03",
|
|
5569
5603
|
"common.copy.action": "\u590D\u5236",
|
|
5570
5604
|
"common.copy.copied": "\u5DF2\u590D\u5236",
|
|
5571
|
-
"common.copy.failed": "\u590D\u5236\u5931\u8D25"
|
|
5605
|
+
"common.copy.failed": "\u590D\u5236\u5931\u8D25",
|
|
5606
|
+
"numberBox.increment": "\u589E\u5927",
|
|
5607
|
+
"numberBox.decrement": "\u51CF\u5C0F",
|
|
5608
|
+
"fileDropZone.browse": "\u6D4F\u89C8\u6587\u4EF6",
|
|
5609
|
+
"fileDropZone.dropHint": "\u5C06\u6587\u4EF6\u62D6\u653E\u5230\u6B64\u5904",
|
|
5610
|
+
"fileDropZone.remove": "\u79FB\u9664\u6587\u4EF6",
|
|
5611
|
+
"pager.label": "\u5206\u9875",
|
|
5612
|
+
"pager.first": "\u7B2C\u4E00\u9875",
|
|
5613
|
+
"pager.previous": "\u4E0A\u4E00\u9875",
|
|
5614
|
+
"pager.next": "\u4E0B\u4E00\u9875",
|
|
5615
|
+
"pager.last": "\u6700\u540E\u4E00\u9875",
|
|
5616
|
+
"pager.page": "\u7B2C {n} \u9875",
|
|
5617
|
+
"pager.pageSize": "\u6BCF\u9875\u6761\u6570",
|
|
5618
|
+
"pager.perPage": "{n} \u6761/\u9875",
|
|
5619
|
+
"pager.total": "\u5171 {n} \u6761",
|
|
5620
|
+
"dataTable.empty": "\u6682\u65E0\u6570\u636E",
|
|
5621
|
+
"dataTable.loading": "\u52A0\u8F7D\u4E2D",
|
|
5622
|
+
"dataTable.selectAll": "\u9009\u62E9\u5168\u90E8\u884C",
|
|
5623
|
+
"dataTable.selectRow": "\u9009\u62E9\u6B64\u884C",
|
|
5624
|
+
"dataTable.expandRow": "\u5C55\u5F00\u6B64\u884C",
|
|
5625
|
+
"dataTable.collapseRow": "\u6536\u8D77\u6B64\u884C",
|
|
5626
|
+
"tabView.close": "\u5173\u95ED\u6807\u7B7E\u9875",
|
|
5627
|
+
"tabView.scrollBackward": "\u5411\u5DE6\u6EDA\u52A8\u6807\u7B7E\u9875",
|
|
5628
|
+
"tabView.scrollForward": "\u5411\u53F3\u6EDA\u52A8\u6807\u7B7E\u9875"
|
|
5572
5629
|
};
|
|
5573
5630
|
var winuiStringsByLocale = { en, "zh-Hans": zhHans };
|
|
5574
5631
|
var StringsContext = createContext2(en);
|
|
@@ -6917,7 +6974,8 @@ import { jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
|
6917
6974
|
var { Dialog, DialogBody, DialogContent, DialogSurface, mergeClasses: mergeClasses5 } = fluentComponents;
|
|
6918
6975
|
var surfaceWidthClasses = {
|
|
6919
6976
|
standard: "",
|
|
6920
|
-
editor: "fwt-dialog-shell--editor"
|
|
6977
|
+
editor: "fwt-dialog-shell--editor",
|
|
6978
|
+
wide: "fwt-dialog-shell--wide"
|
|
6921
6979
|
};
|
|
6922
6980
|
function DialogShell({ actions, children, onExited, onOpenChange, onSubmit, open, surfaceClassName, title, width = "standard" }) {
|
|
6923
6981
|
return /* @__PURE__ */ jsx12(
|
|
@@ -7028,6 +7086,7 @@ var useStyles5 = makeStyles5({
|
|
|
7028
7086
|
}
|
|
7029
7087
|
}
|
|
7030
7088
|
});
|
|
7089
|
+
var useDangerFillClass = () => useStyles5().danger;
|
|
7031
7090
|
function ConfirmDialog({
|
|
7032
7091
|
actionIntent = "danger",
|
|
7033
7092
|
actionLabel,
|
|
@@ -7078,13 +7137,86 @@ function ConfirmDialog({
|
|
|
7078
7137
|
surfaceClassName: "!w-[min(430px,calc(100vw-48px))]",
|
|
7079
7138
|
title: /* @__PURE__ */ jsx14(DialogTitle, { children: title }),
|
|
7080
7139
|
children: /* @__PURE__ */ jsxs6("div", { className: "grid gap-3 min-w-0", children: [
|
|
7081
|
-
/* @__PURE__ */ jsx14("span", { children: message }),
|
|
7140
|
+
message && /* @__PURE__ */ jsx14("span", { children: message }),
|
|
7082
7141
|
error && /* @__PURE__ */ jsx14(OutcomeMessageBar, { onDismiss: onDismissError, children: error })
|
|
7083
7142
|
] })
|
|
7084
7143
|
}
|
|
7085
7144
|
);
|
|
7086
7145
|
}
|
|
7087
7146
|
|
|
7147
|
+
// src/components/ui/confirm-flyout.tsx
|
|
7148
|
+
import { useCallback as useCallback4, useState as useState5 } from "react";
|
|
7149
|
+
import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
7150
|
+
var { Button: Button5, Popover, PopoverSurface, PopoverTrigger, Spinner, Text, mergeClasses: mergeClasses7 } = fluentComponents;
|
|
7151
|
+
var errorText = (error) => error instanceof Error ? error.message : String(error);
|
|
7152
|
+
function ConfirmFlyout({
|
|
7153
|
+
cancelLabel,
|
|
7154
|
+
children,
|
|
7155
|
+
confirmLabel,
|
|
7156
|
+
disabled = false,
|
|
7157
|
+
intent = "danger",
|
|
7158
|
+
message,
|
|
7159
|
+
onConfirm,
|
|
7160
|
+
positioning,
|
|
7161
|
+
title
|
|
7162
|
+
}) {
|
|
7163
|
+
const { t: t2 } = useTranslation();
|
|
7164
|
+
const dangerFill = useDangerFillClass();
|
|
7165
|
+
const [open, setOpen] = useState5(false);
|
|
7166
|
+
const [busy, setBusy] = useState5(false);
|
|
7167
|
+
const [error, setError] = useState5(null);
|
|
7168
|
+
const changeOpen = useCallback4((next) => {
|
|
7169
|
+
if (busy || next && disabled) return;
|
|
7170
|
+
setError(null);
|
|
7171
|
+
setOpen(next);
|
|
7172
|
+
}, [busy, disabled]);
|
|
7173
|
+
const confirm = async () => {
|
|
7174
|
+
setError(null);
|
|
7175
|
+
setBusy(true);
|
|
7176
|
+
try {
|
|
7177
|
+
await onConfirm();
|
|
7178
|
+
setOpen(false);
|
|
7179
|
+
} catch (caught) {
|
|
7180
|
+
setError(errorText(caught));
|
|
7181
|
+
} finally {
|
|
7182
|
+
setBusy(false);
|
|
7183
|
+
}
|
|
7184
|
+
};
|
|
7185
|
+
return /* @__PURE__ */ jsxs7(
|
|
7186
|
+
Popover,
|
|
7187
|
+
{
|
|
7188
|
+
onOpenChange: (_2, data) => changeOpen(data.open),
|
|
7189
|
+
open: open && !disabled,
|
|
7190
|
+
positioning,
|
|
7191
|
+
trapFocus: true,
|
|
7192
|
+
children: [
|
|
7193
|
+
/* @__PURE__ */ jsx15(PopoverTrigger, { disableButtonEnhancement: true, children }),
|
|
7194
|
+
/* @__PURE__ */ jsx15(PopoverSurface, { "aria-label": title, children: /* @__PURE__ */ jsxs7("div", { className: "grid gap-3 min-w-0 max-w-[min(320px,calc(100vw-48px))]", children: [
|
|
7195
|
+
title && /* @__PURE__ */ jsx15(Text, { weight: "semibold", children: title }),
|
|
7196
|
+
/* @__PURE__ */ jsx15(Text, { children: message }),
|
|
7197
|
+
error && /* @__PURE__ */ jsx15(OutcomeMessageBar, { onDismiss: () => setError(null), children: error }),
|
|
7198
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-2", children: [
|
|
7199
|
+
/* @__PURE__ */ jsx15(
|
|
7200
|
+
Button5,
|
|
7201
|
+
{
|
|
7202
|
+
appearance: "primary",
|
|
7203
|
+
className: mergeClasses7("!whitespace-nowrap", intent === "danger" && dangerFill),
|
|
7204
|
+
disabledFocusable: busy,
|
|
7205
|
+
icon: busy ? /* @__PURE__ */ jsx15(Spinner, { size: "tiny" }) : void 0,
|
|
7206
|
+
onClick: () => {
|
|
7207
|
+
void confirm();
|
|
7208
|
+
},
|
|
7209
|
+
children: confirmLabel
|
|
7210
|
+
}
|
|
7211
|
+
),
|
|
7212
|
+
cancelLabel !== void 0 && /* @__PURE__ */ jsx15(Button5, { className: "!whitespace-nowrap", disabled: busy, onClick: () => changeOpen(false), children: cancelLabel || t2("common.cancel") })
|
|
7213
|
+
] })
|
|
7214
|
+
] }) })
|
|
7215
|
+
]
|
|
7216
|
+
}
|
|
7217
|
+
);
|
|
7218
|
+
}
|
|
7219
|
+
|
|
7088
7220
|
// src/components/ui/danger.ts
|
|
7089
7221
|
var { buttonClassNames, makeStyles: makeStyles6 } = fluentComponents;
|
|
7090
7222
|
var RED = "var(--winui-system-fill-critical) !important";
|
|
@@ -7124,6 +7256,10 @@ var useTextStyles = makeStyles6({
|
|
|
7124
7256
|
});
|
|
7125
7257
|
var useDangerTextClass = () => useTextStyles().danger;
|
|
7126
7258
|
|
|
7259
|
+
// src/components/ui/data-table.tsx
|
|
7260
|
+
import { ChevronDown16Regular, ChevronRight16Regular } from "@fluentui/react-icons";
|
|
7261
|
+
import { useMemo as useMemo3, useState as useState6 } from "react";
|
|
7262
|
+
|
|
7127
7263
|
// src/components/ui/layout.ts
|
|
7128
7264
|
var TIGHT_STACK_CLASS = "grid gap-1";
|
|
7129
7265
|
var HEADER_ROW_CLASS = "flex items-center justify-between min-w-0 max-[900px]:flex-col max-[900px]:items-stretch";
|
|
@@ -7135,19 +7271,6 @@ var SCROLLPORT_FILL_CLASS = "h-full min-h-max";
|
|
|
7135
7271
|
var CONTROL_ROW_CLASS = "!min-h-[34px]";
|
|
7136
7272
|
var CHECKBOX_LIST_CLASS = "gap-x-2 gap-y-1";
|
|
7137
7273
|
|
|
7138
|
-
// src/components/ui/dashboard-page-header.tsx
|
|
7139
|
-
import { jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
7140
|
-
var { Text, mergeClasses: mergeClasses7 } = fluentComponents;
|
|
7141
|
-
function DashboardPageHeader({ actions, className, description, title }) {
|
|
7142
|
-
return /* @__PURE__ */ jsxs7("header", { className: mergeClasses7(HEADER_ROW_CLASS, "gap-[18px]", className), children: [
|
|
7143
|
-
/* @__PURE__ */ jsxs7("div", { className: "grid gap-1.5 min-w-0", children: [
|
|
7144
|
-
/* @__PURE__ */ jsx15(Text, { as: "h1", size: 700, weight: "semibold", className: "m-0", children: title }),
|
|
7145
|
-
description !== void 0 && /* @__PURE__ */ jsx15(Text, { size: 200, className: "text-fui-fg2 max-w-[760px]", children: description })
|
|
7146
|
-
] }),
|
|
7147
|
-
actions !== void 0 && /* @__PURE__ */ jsx15("div", { className: "flex items-center gap-2 flex-none max-[900px]:justify-start", children: actions })
|
|
7148
|
-
] });
|
|
7149
|
-
}
|
|
7150
|
-
|
|
7151
7274
|
// src/components/ui/empty-state.tsx
|
|
7152
7275
|
import { jsx as jsx16, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
7153
7276
|
var { Text: Text2, mergeClasses: mergeClasses8 } = fluentComponents;
|
|
@@ -7168,33 +7291,682 @@ function EmptyStateLine({ children, className }) {
|
|
|
7168
7291
|
return /* @__PURE__ */ jsx16(Text2, { block: true, size: 300, className: mergeClasses8("text-fui-fg2", className), children });
|
|
7169
7292
|
}
|
|
7170
7293
|
|
|
7171
|
-
// src/components/ui/
|
|
7294
|
+
// src/components/ui/pager.tsx
|
|
7295
|
+
import {
|
|
7296
|
+
ChevronLeft12Regular,
|
|
7297
|
+
ChevronRight12Regular,
|
|
7298
|
+
MoreHorizontal16Regular,
|
|
7299
|
+
Next16Regular,
|
|
7300
|
+
Previous16Regular
|
|
7301
|
+
} from "@fluentui/react-icons";
|
|
7172
7302
|
import { jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
7173
|
-
var { Text: Text3 } = fluentComponents;
|
|
7303
|
+
var { Button: Button6, Option: Option2, Text: Text3, Tooltip: Tooltip2, makeStyles: makeStyles7, mergeClasses: mergeClasses9 } = fluentComponents;
|
|
7304
|
+
function pagerPageCount(total, pageSize) {
|
|
7305
|
+
if (!(pageSize > 0) || !(total > 0)) return 1;
|
|
7306
|
+
return Math.ceil(total / pageSize);
|
|
7307
|
+
}
|
|
7308
|
+
function pagerPageWindow(page, pageCount) {
|
|
7309
|
+
if (pageCount < 8) return Array.from({ length: Math.max(pageCount, 0) }, (_2, index) => index + 1);
|
|
7310
|
+
const selectedIndex = page - 1;
|
|
7311
|
+
if (selectedIndex < 4) return [1, 2, 3, 4, 5, "end-ellipsis", pageCount];
|
|
7312
|
+
if (selectedIndex >= pageCount - 4) return [1, "start-ellipsis", pageCount - 4, pageCount - 3, pageCount - 2, pageCount - 1, pageCount];
|
|
7313
|
+
return [1, "start-ellipsis", page - 1, page, page + 1, "end-ellipsis", pageCount];
|
|
7314
|
+
}
|
|
7315
|
+
var clampPage = (page, pageCount) => Math.min(Math.max(Math.trunc(page) || 1, 1), pageCount);
|
|
7316
|
+
var useStyles7 = makeStyles7({
|
|
7317
|
+
navButton: {
|
|
7318
|
+
height: "40px !important",
|
|
7319
|
+
minWidth: "40px !important",
|
|
7320
|
+
padding: "0 !important",
|
|
7321
|
+
width: "40px !important"
|
|
7322
|
+
},
|
|
7323
|
+
numberButton: {
|
|
7324
|
+
height: "20px !important",
|
|
7325
|
+
minHeight: "20px !important",
|
|
7326
|
+
minWidth: "32px !important",
|
|
7327
|
+
paddingBlock: "0 !important",
|
|
7328
|
+
paddingInline: "0 !important"
|
|
7329
|
+
},
|
|
7330
|
+
selected: {
|
|
7331
|
+
position: "relative",
|
|
7332
|
+
"::after": {
|
|
7333
|
+
backgroundColor: "var(--winui-accent-fill-default)",
|
|
7334
|
+
borderRadius: "1px",
|
|
7335
|
+
bottom: "-10px",
|
|
7336
|
+
content: '""',
|
|
7337
|
+
height: "2px",
|
|
7338
|
+
insetInline: 0,
|
|
7339
|
+
position: "absolute",
|
|
7340
|
+
"@media (forced-colors: active)": { backgroundColor: "Highlight" }
|
|
7341
|
+
}
|
|
7342
|
+
},
|
|
7343
|
+
// The glyphs are mirrored for a right-to-left reading order.
|
|
7344
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/PagerControl/PagerControl_themeresources.xaml#L80
|
|
7345
|
+
mirrored: {
|
|
7346
|
+
':where([dir="rtl"]) &': { transform: "scaleX(-1)" }
|
|
7347
|
+
}
|
|
7348
|
+
});
|
|
7349
|
+
function NavigationButton({ className, disabled, icon, label, onClick }) {
|
|
7350
|
+
return /* @__PURE__ */ jsx17(Tooltip2, { content: label, relationship: "label", children: /* @__PURE__ */ jsx17(Button6, { appearance: "subtle", className, disabled, icon, onClick }) });
|
|
7351
|
+
}
|
|
7352
|
+
function Pager({
|
|
7353
|
+
ariaLabel,
|
|
7354
|
+
className,
|
|
7355
|
+
disabled = false,
|
|
7356
|
+
onPageChange,
|
|
7357
|
+
onPageSizeChange,
|
|
7358
|
+
page,
|
|
7359
|
+
pageCount: pageCountProp,
|
|
7360
|
+
pageSize,
|
|
7361
|
+
pageSizeOptions,
|
|
7362
|
+
showTotal = false,
|
|
7363
|
+
total
|
|
7364
|
+
}) {
|
|
7365
|
+
const { t: t2 } = useTranslation();
|
|
7366
|
+
const styles = useStyles7();
|
|
7367
|
+
const pageCount = Math.max(1, Math.trunc(pageCountProp ?? pagerPageCount(total ?? 0, pageSize ?? 1)));
|
|
7368
|
+
const current = clampPage(page, pageCount);
|
|
7369
|
+
const go = (next) => {
|
|
7370
|
+
const target = clampPage(next, pageCount);
|
|
7371
|
+
if (target !== current) onPageChange(target);
|
|
7372
|
+
};
|
|
7373
|
+
const atStart = current <= 1;
|
|
7374
|
+
const atEnd = current >= pageCount;
|
|
7375
|
+
const mirrored = styles.mirrored;
|
|
7376
|
+
const sizes = pageSize !== void 0 && pageSizeOptions && onPageSizeChange ? [.../* @__PURE__ */ new Set([...pageSizeOptions, pageSize])].sort((a2, b2) => a2 - b2) : null;
|
|
7377
|
+
const sizeLabel = (size) => t2("pager.perPage").replace("{n}", String(size));
|
|
7378
|
+
return /* @__PURE__ */ jsxs9("nav", { "aria-label": ariaLabel ?? t2("pager.label"), className: mergeClasses9("flex flex-wrap items-center justify-end gap-x-4 gap-y-1", className), children: [
|
|
7379
|
+
showTotal && total !== void 0 && (typeof showTotal === "function" ? showTotal(total) : /* @__PURE__ */ jsx17(Text3, { className: "text-fui-fg2", size: 300, children: t2("pager.total").replace("{n}", String(total)) })),
|
|
7380
|
+
sizes && pageSize !== void 0 && /* @__PURE__ */ jsx17(
|
|
7381
|
+
Dropdown,
|
|
7382
|
+
{
|
|
7383
|
+
"aria-label": t2("pager.pageSize"),
|
|
7384
|
+
disabled,
|
|
7385
|
+
onOptionSelect: (_2, data) => {
|
|
7386
|
+
const next = Number(data.optionValue);
|
|
7387
|
+
if (next > 0 && next !== pageSize) onPageSizeChange?.(next);
|
|
7388
|
+
},
|
|
7389
|
+
selectedOptions: [String(pageSize)],
|
|
7390
|
+
style: { "--fwt-select-min-width": "112px" },
|
|
7391
|
+
value: sizeLabel(pageSize),
|
|
7392
|
+
children: sizes.map((size) => /* @__PURE__ */ jsx17(Option2, { text: sizeLabel(size), value: String(size), children: sizeLabel(size) }, size))
|
|
7393
|
+
}
|
|
7394
|
+
),
|
|
7395
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center", children: [
|
|
7396
|
+
/* @__PURE__ */ jsx17(NavigationButton, { className: styles.navButton, disabled: disabled || atStart, icon: /* @__PURE__ */ jsx17(Previous16Regular, { className: mirrored }), label: t2("pager.first"), onClick: () => go(1) }),
|
|
7397
|
+
/* @__PURE__ */ jsx17(NavigationButton, { className: styles.navButton, disabled: disabled || atStart, icon: /* @__PURE__ */ jsx17(ChevronLeft12Regular, { className: mirrored }), label: t2("pager.previous"), onClick: () => go(current - 1) }),
|
|
7398
|
+
/* @__PURE__ */ jsx17("div", { className: "flex items-center h-10", style: { gap: 5 }, children: pagerPageWindow(current, pageCount).map((item) => typeof item === "number" ? /* @__PURE__ */ jsx17("span", { className: mergeClasses9("inline-flex", item === current && styles.selected), children: /* @__PURE__ */ jsx17(
|
|
7399
|
+
Button6,
|
|
7400
|
+
{
|
|
7401
|
+
appearance: "subtle",
|
|
7402
|
+
"aria-current": item === current ? "page" : void 0,
|
|
7403
|
+
"aria-label": t2("pager.page").replace("{n}", String(item)),
|
|
7404
|
+
className: styles.numberButton,
|
|
7405
|
+
disabled,
|
|
7406
|
+
onClick: () => go(item),
|
|
7407
|
+
children: item
|
|
7408
|
+
}
|
|
7409
|
+
) }, item) : /* @__PURE__ */ jsx17("span", { "aria-hidden": true, className: "grid place-items-center w-5 text-fui-fg2", children: /* @__PURE__ */ jsx17(MoreHorizontal16Regular, {}) }, item)) }),
|
|
7410
|
+
/* @__PURE__ */ jsx17(NavigationButton, { className: styles.navButton, disabled: disabled || atEnd, icon: /* @__PURE__ */ jsx17(ChevronRight12Regular, { className: mirrored }), label: t2("pager.next"), onClick: () => go(current + 1) }),
|
|
7411
|
+
/* @__PURE__ */ jsx17(NavigationButton, { className: styles.navButton, disabled: disabled || atEnd, icon: /* @__PURE__ */ jsx17(Next16Regular, { className: mirrored }), label: t2("pager.last"), onClick: () => go(pageCount) })
|
|
7412
|
+
] })
|
|
7413
|
+
] });
|
|
7414
|
+
}
|
|
7415
|
+
|
|
7416
|
+
// src/components/ui/table-actions.tsx
|
|
7417
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
7418
|
+
var { TableCell, TableHeaderCell, makeStyles: makeStyles8, mergeClasses: mergeClasses10 } = fluentComponents;
|
|
7419
|
+
var useStyles8 = makeStyles8({
|
|
7420
|
+
trailing: {
|
|
7421
|
+
textAlign: "right",
|
|
7422
|
+
"& .fui-TableHeaderCell__button": { justifyContent: "flex-end" }
|
|
7423
|
+
},
|
|
7424
|
+
centred: {
|
|
7425
|
+
textAlign: "center",
|
|
7426
|
+
"& .fui-TableHeaderCell__button": { justifyContent: "center" }
|
|
7427
|
+
}
|
|
7428
|
+
});
|
|
7429
|
+
function TableTrailingHeader({ className, ...props }) {
|
|
7430
|
+
const styles = useStyles8();
|
|
7431
|
+
return /* @__PURE__ */ jsx18(TableHeaderCell, { ...props, className: mergeClasses10(styles.trailing, className) });
|
|
7432
|
+
}
|
|
7433
|
+
function TableTrailingCell({ className, ...props }) {
|
|
7434
|
+
const styles = useStyles8();
|
|
7435
|
+
return /* @__PURE__ */ jsx18(TableCell, { ...props, className: mergeClasses10(styles.trailing, className) });
|
|
7436
|
+
}
|
|
7437
|
+
function TableCentredHeader({ className, ...props }) {
|
|
7438
|
+
const styles = useStyles8();
|
|
7439
|
+
return /* @__PURE__ */ jsx18(TableHeaderCell, { ...props, className: mergeClasses10(styles.centred, className) });
|
|
7440
|
+
}
|
|
7441
|
+
function TableCentredCell({ className, ...props }) {
|
|
7442
|
+
const styles = useStyles8();
|
|
7443
|
+
return /* @__PURE__ */ jsx18(TableCell, { ...props, className: mergeClasses10(styles.centred, className) });
|
|
7444
|
+
}
|
|
7445
|
+
var stopRowSelection = { onClick: (event) => event.stopPropagation() };
|
|
7446
|
+
var ACTION_GAP = "var(--spacingHorizontalXS)";
|
|
7447
|
+
var ACTION_BUTTON_SIZE = "24px";
|
|
7448
|
+
var TABLE_ACTIONS_WIDTH = `calc(3 * ${ACTION_BUTTON_SIZE} + 2 * ${ACTION_GAP} + var(--spacingHorizontalS) + var(--fwt-panel-inset))`;
|
|
7449
|
+
function TableActions({ children }) {
|
|
7450
|
+
return /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-end", style: { gap: ACTION_GAP }, ...stopRowSelection, children });
|
|
7451
|
+
}
|
|
7452
|
+
|
|
7453
|
+
// src/components/ui/table-columns.tsx
|
|
7454
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
7455
|
+
function TableColumns({ widths }) {
|
|
7456
|
+
return /* @__PURE__ */ jsx19("colgroup", { children: widths.map((width, index) => /* @__PURE__ */ jsx19("col", { style: width === null ? void 0 : { width } }, index)) });
|
|
7457
|
+
}
|
|
7458
|
+
|
|
7459
|
+
// src/components/ui/data-table.tsx
|
|
7460
|
+
import { jsx as jsx20, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
7461
|
+
var {
|
|
7462
|
+
Button: Button7,
|
|
7463
|
+
Spinner: Spinner2,
|
|
7464
|
+
Table,
|
|
7465
|
+
TableBody,
|
|
7466
|
+
TableCell: TableCell2,
|
|
7467
|
+
TableCellLayout,
|
|
7468
|
+
TableHeader,
|
|
7469
|
+
TableHeaderCell: TableHeaderCell2,
|
|
7470
|
+
TableRow,
|
|
7471
|
+
TableSelectionCell,
|
|
7472
|
+
mergeClasses: mergeClasses11
|
|
7473
|
+
} = fluentComponents;
|
|
7474
|
+
var LEADING_COLUMN_WIDTH = "44px";
|
|
7475
|
+
var HEADER_BY_ALIGN = { center: TableCentredHeader, end: TableTrailingHeader, start: TableHeaderCell2 };
|
|
7476
|
+
var CELL_BY_ALIGN = { center: TableCentredCell, end: TableTrailingCell, start: TableCell2 };
|
|
7477
|
+
var toggle = (keys2, key) => keys2.includes(key) ? keys2.filter((candidate) => candidate !== key) : [...keys2, key];
|
|
7478
|
+
function DataTable({
|
|
7479
|
+
ariaLabel,
|
|
7480
|
+
className,
|
|
7481
|
+
columns,
|
|
7482
|
+
defaultSort,
|
|
7483
|
+
empty,
|
|
7484
|
+
expandable,
|
|
7485
|
+
loading = false,
|
|
7486
|
+
minWidth,
|
|
7487
|
+
onRowClick,
|
|
7488
|
+
onSortChange,
|
|
7489
|
+
pagination,
|
|
7490
|
+
rowClassName,
|
|
7491
|
+
rowKey,
|
|
7492
|
+
rows,
|
|
7493
|
+
selection,
|
|
7494
|
+
size = "medium"
|
|
7495
|
+
}) {
|
|
7496
|
+
const { t: t2 } = useTranslation();
|
|
7497
|
+
const [sort, setSort] = useState6(defaultSort ?? null);
|
|
7498
|
+
const [ownPage, setOwnPage] = useState6(1);
|
|
7499
|
+
const [ownPageSize, setOwnPageSize] = useState6(null);
|
|
7500
|
+
const [ownExpanded, setOwnExpanded] = useState6([]);
|
|
7501
|
+
const sortedRows = useMemo3(() => {
|
|
7502
|
+
const column = sort && columns.find((candidate) => candidate.key === sort.key);
|
|
7503
|
+
if (!sort || !column?.sort) return rows;
|
|
7504
|
+
const direction = sort.direction === "ascending" ? 1 : -1;
|
|
7505
|
+
const compare = column.sort;
|
|
7506
|
+
return [...rows].sort((a2, b2) => direction * compare(a2, b2));
|
|
7507
|
+
}, [columns, rows, sort]);
|
|
7508
|
+
const paged = pagination !== void 0 && pagination !== false;
|
|
7509
|
+
const pageSize = !paged ? 0 : pagination.onPageSizeChange ? pagination.pageSize : ownPageSize ?? pagination.pageSize;
|
|
7510
|
+
const pageCount = paged ? Math.max(1, Math.ceil(sortedRows.length / Math.max(pageSize, 1))) : 1;
|
|
7511
|
+
const requestedPage = paged ? pagination.page ?? ownPage : 1;
|
|
7512
|
+
const page = Math.min(Math.max(requestedPage, 1), pageCount);
|
|
7513
|
+
const visibleRows = paged ? sortedRows.slice((page - 1) * pageSize, page * pageSize) : sortedRows;
|
|
7514
|
+
const changePage = (next) => {
|
|
7515
|
+
setOwnPage(next);
|
|
7516
|
+
if (paged) pagination.onPageChange?.(next);
|
|
7517
|
+
};
|
|
7518
|
+
const changePageSize = (next) => {
|
|
7519
|
+
setOwnPageSize(next);
|
|
7520
|
+
setOwnPage(1);
|
|
7521
|
+
if (paged) {
|
|
7522
|
+
pagination.onPageSizeChange?.(next);
|
|
7523
|
+
pagination.onPageChange?.(1);
|
|
7524
|
+
}
|
|
7525
|
+
};
|
|
7526
|
+
const cycleSort = (column) => {
|
|
7527
|
+
const next = sort?.key !== column.key ? { key: column.key, direction: "ascending" } : sort.direction === "ascending" ? { key: column.key, direction: "descending" } : null;
|
|
7528
|
+
setSort(next);
|
|
7529
|
+
onSortChange?.(next);
|
|
7530
|
+
setOwnPage(1);
|
|
7531
|
+
};
|
|
7532
|
+
const selectedKeys = selection?.selectedKeys ?? [];
|
|
7533
|
+
const selectionMode = selection?.mode ?? "multiple";
|
|
7534
|
+
const isSelectable = (row) => selection?.isSelectable?.(row) ?? true;
|
|
7535
|
+
const selectableVisible = visibleRows.filter(isSelectable).map(rowKey);
|
|
7536
|
+
const selectedVisible = selectableVisible.filter((key) => selectedKeys.includes(key));
|
|
7537
|
+
const allChecked = selectedVisible.length === 0 ? false : selectedVisible.length === selectableVisible.length ? true : "mixed";
|
|
7538
|
+
const toggleAll = () => {
|
|
7539
|
+
if (!selection) return;
|
|
7540
|
+
selection.onChange(allChecked === true ? selectedKeys.filter((key) => !selectableVisible.includes(key)) : [...selectedKeys, ...selectableVisible.filter((key) => !selectedKeys.includes(key))]);
|
|
7541
|
+
};
|
|
7542
|
+
const selectRow = (key) => {
|
|
7543
|
+
if (!selection) return;
|
|
7544
|
+
selection.onChange(selectionMode === "single" ? [key] : toggle(selectedKeys, key));
|
|
7545
|
+
};
|
|
7546
|
+
const stop = (event) => event.stopPropagation();
|
|
7547
|
+
const expandedKeys = expandable?.expandedKeys ?? ownExpanded;
|
|
7548
|
+
const toggleExpanded = (key) => {
|
|
7549
|
+
const next = toggle(expandedKeys, key);
|
|
7550
|
+
setOwnExpanded(next);
|
|
7551
|
+
expandable?.onExpandedChange?.(next);
|
|
7552
|
+
};
|
|
7553
|
+
const columnCount = columns.length + (selection ? 1 : 0) + (expandable ? 1 : 0);
|
|
7554
|
+
const widths = [
|
|
7555
|
+
...selection ? [LEADING_COLUMN_WIDTH] : [],
|
|
7556
|
+
...expandable ? [LEADING_COLUMN_WIDTH] : [],
|
|
7557
|
+
...columns.map((column) => column.width ?? null)
|
|
7558
|
+
];
|
|
7559
|
+
const tableStyle = minWidth === void 0 ? void 0 : { minWidth };
|
|
7560
|
+
return /* @__PURE__ */ jsxs10("div", { className: mergeClasses11("min-w-0", className), children: [
|
|
7561
|
+
/* @__PURE__ */ jsxs10("div", { "aria-busy": loading || void 0, className: "relative min-w-0", children: [
|
|
7562
|
+
/* @__PURE__ */ jsx20(ScrollArea, { axes: "horizontal", className: "min-w-0", children: /* @__PURE__ */ jsxs10(Table, { "aria-label": ariaLabel, size, style: tableStyle, children: [
|
|
7563
|
+
/* @__PURE__ */ jsx20(TableColumns, { widths }),
|
|
7564
|
+
/* @__PURE__ */ jsx20(TableHeader, { children: /* @__PURE__ */ jsxs10(TableRow, { children: [
|
|
7565
|
+
selection && (selectionMode === "multiple" ? /* @__PURE__ */ jsx20(
|
|
7566
|
+
TableSelectionCell,
|
|
7567
|
+
{
|
|
7568
|
+
checkboxIndicator: { "aria-label": t2("dataTable.selectAll"), disabled: selectableVisible.length === 0 },
|
|
7569
|
+
checked: allChecked,
|
|
7570
|
+
onClick: selectableVisible.length === 0 ? void 0 : toggleAll
|
|
7571
|
+
}
|
|
7572
|
+
) : /* @__PURE__ */ jsx20(TableHeaderCell2, {})),
|
|
7573
|
+
expandable && /* @__PURE__ */ jsx20(TableHeaderCell2, {}),
|
|
7574
|
+
columns.map((column) => {
|
|
7575
|
+
const Header = HEADER_BY_ALIGN[column.align ?? "start"];
|
|
7576
|
+
const sorted = sort?.key === column.key ? sort.direction : void 0;
|
|
7577
|
+
return /* @__PURE__ */ jsx20(
|
|
7578
|
+
Header,
|
|
7579
|
+
{
|
|
7580
|
+
onClick: column.sort ? () => cycleSort(column) : void 0,
|
|
7581
|
+
sortable: column.sort !== void 0,
|
|
7582
|
+
sortDirection: sorted,
|
|
7583
|
+
children: column.title
|
|
7584
|
+
},
|
|
7585
|
+
column.key
|
|
7586
|
+
);
|
|
7587
|
+
})
|
|
7588
|
+
] }) }),
|
|
7589
|
+
/* @__PURE__ */ jsxs10(TableBody, { children: [
|
|
7590
|
+
visibleRows.length === 0 && /* @__PURE__ */ jsx20(TableRow, { children: /* @__PURE__ */ jsx20(TableCell2, { colSpan: columnCount, children: empty ?? /* @__PURE__ */ jsx20(EmptyStateLine, { className: "py-6 text-center", children: t2("dataTable.empty") }) }) }),
|
|
7591
|
+
visibleRows.flatMap((row, index) => {
|
|
7592
|
+
const key = rowKey(row);
|
|
7593
|
+
const selected = selectedKeys.includes(key);
|
|
7594
|
+
const expanded = expandable !== void 0 && expandedKeys.includes(key);
|
|
7595
|
+
const canExpand = expandable !== void 0 && (expandable.isExpandable?.(row) ?? true);
|
|
7596
|
+
const items = [/* @__PURE__ */ jsxs10(
|
|
7597
|
+
TableRow,
|
|
7598
|
+
{
|
|
7599
|
+
"aria-selected": selection ? selected : void 0,
|
|
7600
|
+
className: mergeClasses11(onRowClick && "cursor-pointer", rowClassName?.(row, index)),
|
|
7601
|
+
onClick: onRowClick ? () => onRowClick(row, index) : void 0,
|
|
7602
|
+
children: [
|
|
7603
|
+
selection && /* @__PURE__ */ jsx20(
|
|
7604
|
+
TableSelectionCell,
|
|
7605
|
+
{
|
|
7606
|
+
checkboxIndicator: { "aria-label": t2("dataTable.selectRow"), disabled: !isSelectable(row) },
|
|
7607
|
+
checked: selected,
|
|
7608
|
+
onClick: (event) => {
|
|
7609
|
+
stop(event);
|
|
7610
|
+
if (isSelectable(row)) selectRow(key);
|
|
7611
|
+
},
|
|
7612
|
+
radioIndicator: { "aria-label": t2("dataTable.selectRow"), disabled: !isSelectable(row) },
|
|
7613
|
+
type: selectionMode === "single" ? "radio" : "checkbox"
|
|
7614
|
+
}
|
|
7615
|
+
),
|
|
7616
|
+
expandable && /* @__PURE__ */ jsx20(TableCell2, { ...stopRowSelection, children: canExpand && /* @__PURE__ */ jsx20(
|
|
7617
|
+
Button7,
|
|
7618
|
+
{
|
|
7619
|
+
appearance: "subtle",
|
|
7620
|
+
"aria-expanded": expanded,
|
|
7621
|
+
"aria-label": t2(expanded ? "dataTable.collapseRow" : "dataTable.expandRow"),
|
|
7622
|
+
icon: expanded ? /* @__PURE__ */ jsx20(ChevronDown16Regular, {}) : /* @__PURE__ */ jsx20(ChevronRight16Regular, {}),
|
|
7623
|
+
onClick: () => toggleExpanded(key),
|
|
7624
|
+
size: "small"
|
|
7625
|
+
}
|
|
7626
|
+
) }),
|
|
7627
|
+
columns.map((column) => {
|
|
7628
|
+
const Cell = CELL_BY_ALIGN[column.align ?? "start"];
|
|
7629
|
+
const content = column.render ? column.render(row, index) : column.dataKey === void 0 ? null : row[column.dataKey];
|
|
7630
|
+
return /* @__PURE__ */ jsx20(Cell, { className: column.ellipsis ? "overflow-hidden" : void 0, children: column.ellipsis ? /* @__PURE__ */ jsx20(TableCellLayout, { title: typeof content === "string" || typeof content === "number" ? String(content) : void 0, truncate: true, children: content }) : content }, column.key);
|
|
7631
|
+
})
|
|
7632
|
+
]
|
|
7633
|
+
},
|
|
7634
|
+
key
|
|
7635
|
+
)];
|
|
7636
|
+
if (expanded && canExpand) {
|
|
7637
|
+
items.push(/* @__PURE__ */ jsx20(TableRow, { children: /* @__PURE__ */ jsx20(TableCell2, { colSpan: columnCount, children: expandable.render(row) }) }, `${key}:expanded`));
|
|
7638
|
+
}
|
|
7639
|
+
return items;
|
|
7640
|
+
})
|
|
7641
|
+
] })
|
|
7642
|
+
] }) }),
|
|
7643
|
+
loading && /* @__PURE__ */ jsx20(
|
|
7644
|
+
"div",
|
|
7645
|
+
{
|
|
7646
|
+
className: "absolute inset-0 grid place-items-center",
|
|
7647
|
+
style: { background: "color-mix(in srgb, var(--colorNeutralBackground1) 60%, transparent)" },
|
|
7648
|
+
children: /* @__PURE__ */ jsx20(Spinner2, { label: t2("dataTable.loading"), size: "small" })
|
|
7649
|
+
}
|
|
7650
|
+
)
|
|
7651
|
+
] }),
|
|
7652
|
+
paged && !(pagination.hideOnSinglePage && pageCount <= 1) && /* @__PURE__ */ jsx20("div", { className: "flex justify-end px-3 py-1", style: { borderTop: "1px solid var(--colorNeutralStroke3)" }, children: /* @__PURE__ */ jsx20(
|
|
7653
|
+
Pager,
|
|
7654
|
+
{
|
|
7655
|
+
onPageChange: changePage,
|
|
7656
|
+
onPageSizeChange: changePageSize,
|
|
7657
|
+
page,
|
|
7658
|
+
pageCount,
|
|
7659
|
+
pageSize,
|
|
7660
|
+
pageSizeOptions: pagination.pageSizeOptions,
|
|
7661
|
+
showTotal: pagination.showTotal,
|
|
7662
|
+
total: sortedRows.length
|
|
7663
|
+
}
|
|
7664
|
+
) })
|
|
7665
|
+
] });
|
|
7666
|
+
}
|
|
7667
|
+
|
|
7668
|
+
// src/components/ui/dashboard-page-header.tsx
|
|
7669
|
+
import { jsx as jsx21, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
7670
|
+
var { Text: Text4, mergeClasses: mergeClasses12 } = fluentComponents;
|
|
7671
|
+
function DashboardPageHeader({ actions, className, description, title }) {
|
|
7672
|
+
return /* @__PURE__ */ jsxs11("header", { className: mergeClasses12(HEADER_ROW_CLASS, "gap-[18px]", className), children: [
|
|
7673
|
+
/* @__PURE__ */ jsxs11("div", { className: "grid gap-1.5 min-w-0", children: [
|
|
7674
|
+
/* @__PURE__ */ jsx21(Text4, { as: "h1", size: 700, weight: "semibold", className: "m-0", children: title }),
|
|
7675
|
+
description !== void 0 && /* @__PURE__ */ jsx21(Text4, { size: 200, className: "text-fui-fg2 max-w-[760px]", children: description })
|
|
7676
|
+
] }),
|
|
7677
|
+
actions !== void 0 && /* @__PURE__ */ jsx21("div", { className: "flex items-center gap-2 flex-none max-[900px]:justify-start", children: actions })
|
|
7678
|
+
] });
|
|
7679
|
+
}
|
|
7680
|
+
|
|
7681
|
+
// src/components/ui/error-shell.tsx
|
|
7682
|
+
import { jsx as jsx22, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
7683
|
+
var { Text: Text5 } = fluentComponents;
|
|
7174
7684
|
function ErrorShell({ action, children, message, title }) {
|
|
7175
|
-
return /* @__PURE__ */
|
|
7176
|
-
/* @__PURE__ */
|
|
7177
|
-
/* @__PURE__ */
|
|
7178
|
-
message !== void 0 && /* @__PURE__ */
|
|
7685
|
+
return /* @__PURE__ */ jsx22(ScrollArea, { axes: "vertical", className: "fwt-error-shell-viewport", contentClassName: "h-full", children: /* @__PURE__ */ jsxs12("main", { className: "fwt-error-shell", children: [
|
|
7686
|
+
/* @__PURE__ */ jsxs12("div", { className: "fwt-error-shell-stack", children: [
|
|
7687
|
+
/* @__PURE__ */ jsx22(Text5, { align: "center", as: "h1", size: 700, weight: "semibold", children: title }),
|
|
7688
|
+
message !== void 0 && /* @__PURE__ */ jsx22(Text5, { align: "center", as: "p", className: "text-fui-fg2", size: 300, children: message })
|
|
7179
7689
|
] }),
|
|
7180
7690
|
children,
|
|
7181
|
-
action !== void 0 && /* @__PURE__ */
|
|
7691
|
+
action !== void 0 && /* @__PURE__ */ jsx22("div", { className: "fwt-error-shell-actions", children: action })
|
|
7182
7692
|
] }) });
|
|
7183
7693
|
}
|
|
7184
7694
|
function ErrorStack({ children }) {
|
|
7185
|
-
return /* @__PURE__ */
|
|
7695
|
+
return /* @__PURE__ */ jsx22(
|
|
7186
7696
|
ScrollArea,
|
|
7187
7697
|
{
|
|
7188
7698
|
axes: "horizontal",
|
|
7189
7699
|
className: "winui-focus-rect-within w-full min-w-0 rounded-[var(--winui-overlay-corner-radius,8px)] border border-solid border-fui-stroke1 bg-fui-bg2 text-left",
|
|
7190
|
-
children: /* @__PURE__ */
|
|
7700
|
+
children: /* @__PURE__ */ jsx22("pre", { className: "m-0 w-max min-w-full p-4 font-mono", children: /* @__PURE__ */ jsx22("code", { children }) })
|
|
7191
7701
|
}
|
|
7192
7702
|
);
|
|
7193
7703
|
}
|
|
7194
7704
|
|
|
7705
|
+
// src/components/ui/file-drop-zone.tsx
|
|
7706
|
+
import { ArrowUploadRegular, DismissRegular as DismissRegular3, DocumentRegular } from "@fluentui/react-icons";
|
|
7707
|
+
import { useId as useId2, useRef as useRef5, useState as useState7 } from "react";
|
|
7708
|
+
import { Fragment as Fragment2, jsx as jsx23, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
7709
|
+
var { Button: Button8, Text: Text6, makeStyles: makeStyles9, mergeClasses: mergeClasses13, shorthands } = fluentComponents;
|
|
7710
|
+
var useStyles9 = makeStyles9({
|
|
7711
|
+
root: {
|
|
7712
|
+
display: "grid",
|
|
7713
|
+
rowGap: "8px",
|
|
7714
|
+
minWidth: 0
|
|
7715
|
+
},
|
|
7716
|
+
zone: {
|
|
7717
|
+
alignItems: "center",
|
|
7718
|
+
backgroundColor: "var(--winui-card-background-fill-default)",
|
|
7719
|
+
...shorthands.border("1px", "dashed", "var(--winui-surface-stroke-default)"),
|
|
7720
|
+
borderRadius: "var(--winui-control-corner-radius)",
|
|
7721
|
+
boxSizing: "border-box",
|
|
7722
|
+
color: "var(--winui-text-fill-primary)",
|
|
7723
|
+
cursor: "pointer",
|
|
7724
|
+
display: "grid",
|
|
7725
|
+
justifyItems: "center",
|
|
7726
|
+
minHeight: "120px",
|
|
7727
|
+
padding: "24px 16px",
|
|
7728
|
+
rowGap: "4px",
|
|
7729
|
+
textAlign: "center",
|
|
7730
|
+
transitionDuration: "var(--winui-control-faster-animation-duration)",
|
|
7731
|
+
transitionProperty: "background-color, border-color",
|
|
7732
|
+
"@media (prefers-reduced-motion: reduce)": { transitionDuration: "0.01ms" },
|
|
7733
|
+
"&:hover": { backgroundColor: "var(--winui-control-fill-secondary)" },
|
|
7734
|
+
"&:active": { backgroundColor: "var(--winui-control-fill-tertiary)" },
|
|
7735
|
+
// The system focus visual, as ./settings-card draws it.
|
|
7736
|
+
"&:focus-visible": {
|
|
7737
|
+
boxShadow: "0 0 0 1px var(--winui-focus-stroke-inner)",
|
|
7738
|
+
outlineColor: "var(--winui-focus-stroke-outer)",
|
|
7739
|
+
outlineOffset: "1px",
|
|
7740
|
+
outlineStyle: "solid",
|
|
7741
|
+
outlineWidth: "2px"
|
|
7742
|
+
}
|
|
7743
|
+
},
|
|
7744
|
+
dragOver: {
|
|
7745
|
+
backgroundColor: "var(--winui-accent-tint-fill-default)",
|
|
7746
|
+
...shorthands.borderColor("var(--winui-accent-base)"),
|
|
7747
|
+
"&:hover": { backgroundColor: "var(--winui-accent-tint-fill-default)" },
|
|
7748
|
+
"&:active": { backgroundColor: "var(--winui-accent-tint-fill-secondary)" }
|
|
7749
|
+
},
|
|
7750
|
+
disabled: {
|
|
7751
|
+
backgroundColor: "var(--winui-control-fill-disabled)",
|
|
7752
|
+
color: "var(--winui-text-fill-disabled)",
|
|
7753
|
+
cursor: "not-allowed",
|
|
7754
|
+
"&:hover": { backgroundColor: "var(--winui-control-fill-disabled)" },
|
|
7755
|
+
"&:active": { backgroundColor: "var(--winui-control-fill-disabled)" }
|
|
7756
|
+
},
|
|
7757
|
+
icon: {
|
|
7758
|
+
color: "var(--winui-text-fill-secondary)",
|
|
7759
|
+
display: "inline-flex",
|
|
7760
|
+
fontSize: "24px",
|
|
7761
|
+
lineHeight: 0,
|
|
7762
|
+
pointerEvents: "none"
|
|
7763
|
+
},
|
|
7764
|
+
iconDragOver: { color: "var(--winui-accent-base)" },
|
|
7765
|
+
list: {
|
|
7766
|
+
display: "grid",
|
|
7767
|
+
listStyleType: "none",
|
|
7768
|
+
margin: 0,
|
|
7769
|
+
padding: 0,
|
|
7770
|
+
rowGap: "4px"
|
|
7771
|
+
},
|
|
7772
|
+
file: {
|
|
7773
|
+
alignItems: "center",
|
|
7774
|
+
backgroundColor: "var(--winui-card-background-fill-default)",
|
|
7775
|
+
...shorthands.border("1px", "solid", "var(--winui-card-stroke-default)"),
|
|
7776
|
+
borderRadius: "var(--winui-control-corner-radius)",
|
|
7777
|
+
columnGap: "8px",
|
|
7778
|
+
display: "flex",
|
|
7779
|
+
minHeight: "40px",
|
|
7780
|
+
paddingBlock: "4px",
|
|
7781
|
+
paddingInlineStart: "12px",
|
|
7782
|
+
paddingInlineEnd: "4px"
|
|
7783
|
+
},
|
|
7784
|
+
fileName: {
|
|
7785
|
+
flexGrow: 1,
|
|
7786
|
+
minWidth: 0,
|
|
7787
|
+
overflow: "hidden",
|
|
7788
|
+
textOverflow: "ellipsis",
|
|
7789
|
+
whiteSpace: "nowrap"
|
|
7790
|
+
}
|
|
7791
|
+
});
|
|
7792
|
+
var BYTE_UNITS = ["B", "KB", "MB", "GB", "TB"];
|
|
7793
|
+
var formatFileSize = (bytes) => {
|
|
7794
|
+
let size = bytes;
|
|
7795
|
+
let unit = 0;
|
|
7796
|
+
while (size >= 1024 && unit < BYTE_UNITS.length - 1) {
|
|
7797
|
+
size /= 1024;
|
|
7798
|
+
unit += 1;
|
|
7799
|
+
}
|
|
7800
|
+
const text = new Intl.NumberFormat(void 0, { maximumFractionDigits: unit === 0 ? 0 : 1 }).format(size);
|
|
7801
|
+
return `${text} ${BYTE_UNITS[unit]}`;
|
|
7802
|
+
};
|
|
7803
|
+
var matchesAccept = (file, accept) => {
|
|
7804
|
+
const tokens3 = accept?.split(",").map((token) => token.trim().toLowerCase()).filter(Boolean) ?? [];
|
|
7805
|
+
if (tokens3.length === 0) return true;
|
|
7806
|
+
const name = file.name.toLowerCase();
|
|
7807
|
+
const type = file.type.toLowerCase();
|
|
7808
|
+
return tokens3.some((token) => {
|
|
7809
|
+
if (token.startsWith(".")) return name.endsWith(token);
|
|
7810
|
+
if (token.endsWith("/*")) return type.startsWith(token.slice(0, -1));
|
|
7811
|
+
return type === token;
|
|
7812
|
+
});
|
|
7813
|
+
};
|
|
7814
|
+
var pickFiles = (files, accept, multiple) => {
|
|
7815
|
+
const accepted = [...files].filter((file) => matchesAccept(file, accept));
|
|
7816
|
+
return multiple ? accepted : accepted.slice(0, 1);
|
|
7817
|
+
};
|
|
7818
|
+
function FileDropZone({
|
|
7819
|
+
accept,
|
|
7820
|
+
className,
|
|
7821
|
+
description,
|
|
7822
|
+
disabled,
|
|
7823
|
+
icon,
|
|
7824
|
+
multiple,
|
|
7825
|
+
onFiles,
|
|
7826
|
+
onRemove,
|
|
7827
|
+
selectedFiles,
|
|
7828
|
+
title
|
|
7829
|
+
}) {
|
|
7830
|
+
const styles = useStyles9();
|
|
7831
|
+
const { t: t2 } = useTranslation();
|
|
7832
|
+
const inputRef = useRef5(null);
|
|
7833
|
+
const depth = useRef5(0);
|
|
7834
|
+
const [dragOver, setDragOver] = useState7(false);
|
|
7835
|
+
const titleId = useId2();
|
|
7836
|
+
const reset = () => {
|
|
7837
|
+
depth.current = 0;
|
|
7838
|
+
setDragOver(false);
|
|
7839
|
+
};
|
|
7840
|
+
const emit = (files) => {
|
|
7841
|
+
const picked = pickFiles(files, accept, multiple);
|
|
7842
|
+
if (picked.length > 0) onFiles(picked);
|
|
7843
|
+
};
|
|
7844
|
+
const open = () => {
|
|
7845
|
+
if (!disabled) inputRef.current?.click();
|
|
7846
|
+
};
|
|
7847
|
+
const handleDragEnter = (event) => {
|
|
7848
|
+
if (disabled) return;
|
|
7849
|
+
event.preventDefault();
|
|
7850
|
+
depth.current += 1;
|
|
7851
|
+
setDragOver(true);
|
|
7852
|
+
};
|
|
7853
|
+
const handleDragOver = (event) => {
|
|
7854
|
+
if (disabled) return;
|
|
7855
|
+
event.preventDefault();
|
|
7856
|
+
event.dataTransfer.dropEffect = "copy";
|
|
7857
|
+
};
|
|
7858
|
+
const handleDragLeave = () => {
|
|
7859
|
+
if (disabled) return;
|
|
7860
|
+
depth.current = Math.max(0, depth.current - 1);
|
|
7861
|
+
if (depth.current === 0) setDragOver(false);
|
|
7862
|
+
};
|
|
7863
|
+
const handleDrop = (event) => {
|
|
7864
|
+
if (disabled) return;
|
|
7865
|
+
event.preventDefault();
|
|
7866
|
+
reset();
|
|
7867
|
+
emit(Array.from(event.dataTransfer.files));
|
|
7868
|
+
};
|
|
7869
|
+
const handleKeyDown = (event) => {
|
|
7870
|
+
if (event.target !== event.currentTarget) return;
|
|
7871
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
7872
|
+
event.preventDefault();
|
|
7873
|
+
open();
|
|
7874
|
+
}
|
|
7875
|
+
};
|
|
7876
|
+
const handleInputChange = (event) => {
|
|
7877
|
+
const files = Array.from(event.target.files ?? []);
|
|
7878
|
+
event.target.value = "";
|
|
7879
|
+
emit(files);
|
|
7880
|
+
};
|
|
7881
|
+
return /* @__PURE__ */ jsxs13("div", { className: mergeClasses13(styles.root, className), children: [
|
|
7882
|
+
/* @__PURE__ */ jsxs13(
|
|
7883
|
+
"div",
|
|
7884
|
+
{
|
|
7885
|
+
"aria-disabled": disabled || void 0,
|
|
7886
|
+
"aria-labelledby": titleId,
|
|
7887
|
+
className: mergeClasses13(styles.zone, dragOver && styles.dragOver, disabled && styles.disabled),
|
|
7888
|
+
"data-drag-over": dragOver || void 0,
|
|
7889
|
+
onClick: open,
|
|
7890
|
+
onDragEnter: handleDragEnter,
|
|
7891
|
+
onDragLeave: handleDragLeave,
|
|
7892
|
+
onDragOver: handleDragOver,
|
|
7893
|
+
onDrop: handleDrop,
|
|
7894
|
+
onKeyDown: handleKeyDown,
|
|
7895
|
+
role: "button",
|
|
7896
|
+
tabIndex: disabled ? -1 : 0,
|
|
7897
|
+
children: [
|
|
7898
|
+
/* @__PURE__ */ jsx23("span", { "aria-hidden": true, className: mergeClasses13(styles.icon, dragOver && styles.iconDragOver), children: icon ?? /* @__PURE__ */ jsx23(ArrowUploadRegular, {}) }),
|
|
7899
|
+
/* @__PURE__ */ jsx23(Text6, { id: titleId, size: 300, weight: "semibold", children: dragOver ? t2("fileDropZone.dropHint") : title }),
|
|
7900
|
+
description !== void 0 && /* @__PURE__ */ jsx23(Text6, { size: 200, className: "text-fui-fg2", children: description })
|
|
7901
|
+
]
|
|
7902
|
+
}
|
|
7903
|
+
),
|
|
7904
|
+
/* @__PURE__ */ jsx23(
|
|
7905
|
+
"input",
|
|
7906
|
+
{
|
|
7907
|
+
accept,
|
|
7908
|
+
disabled,
|
|
7909
|
+
hidden: true,
|
|
7910
|
+
multiple,
|
|
7911
|
+
onChange: handleInputChange,
|
|
7912
|
+
ref: inputRef,
|
|
7913
|
+
tabIndex: -1,
|
|
7914
|
+
type: "file"
|
|
7915
|
+
}
|
|
7916
|
+
),
|
|
7917
|
+
selectedFiles !== void 0 && selectedFiles.length > 0 && /* @__PURE__ */ jsx23("ul", { className: styles.list, children: selectedFiles.map((file, index) => /* @__PURE__ */ jsxs13("li", { className: styles.file, children: [
|
|
7918
|
+
/* @__PURE__ */ jsx23(DocumentRegular, { "aria-hidden": true, className: "text-fui-fg2 shrink-0" }),
|
|
7919
|
+
/* @__PURE__ */ jsx23(Text6, { className: styles.fileName, size: 300, title: file.name, children: file.name }),
|
|
7920
|
+
/* @__PURE__ */ jsx23(Text6, { className: "text-fui-fg2 shrink-0", size: 200, children: formatFileSize(file.size) }),
|
|
7921
|
+
onRemove && /* @__PURE__ */ jsx23(
|
|
7922
|
+
Button8,
|
|
7923
|
+
{
|
|
7924
|
+
appearance: "subtle",
|
|
7925
|
+
"aria-label": `${t2("fileDropZone.remove")}: ${file.name}`,
|
|
7926
|
+
icon: /* @__PURE__ */ jsx23(DismissRegular3, {}),
|
|
7927
|
+
onClick: () => onRemove(file, index),
|
|
7928
|
+
size: "small"
|
|
7929
|
+
}
|
|
7930
|
+
)
|
|
7931
|
+
] }, `${file.name}:${file.size}:${file.lastModified}:${index}`)) })
|
|
7932
|
+
] });
|
|
7933
|
+
}
|
|
7934
|
+
function FilePickerButton({ accept, children, disabled, multiple, onClick, onFiles, ...rest }) {
|
|
7935
|
+
const { t: t2 } = useTranslation();
|
|
7936
|
+
const inputRef = useRef5(null);
|
|
7937
|
+
const buttonProps = {
|
|
7938
|
+
...rest,
|
|
7939
|
+
disabled,
|
|
7940
|
+
onClick: (event) => {
|
|
7941
|
+
onClick?.(event);
|
|
7942
|
+
if (!event.defaultPrevented) inputRef.current?.click();
|
|
7943
|
+
}
|
|
7944
|
+
};
|
|
7945
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
7946
|
+
/* @__PURE__ */ jsx23(Button8, { ...buttonProps, children: children ?? t2("fileDropZone.browse") }),
|
|
7947
|
+
/* @__PURE__ */ jsx23(
|
|
7948
|
+
"input",
|
|
7949
|
+
{
|
|
7950
|
+
accept,
|
|
7951
|
+
disabled,
|
|
7952
|
+
hidden: true,
|
|
7953
|
+
multiple,
|
|
7954
|
+
onChange: (event) => {
|
|
7955
|
+
const files = Array.from(event.target.files ?? []);
|
|
7956
|
+
event.target.value = "";
|
|
7957
|
+
if (files.length > 0) onFiles(files);
|
|
7958
|
+
},
|
|
7959
|
+
ref: inputRef,
|
|
7960
|
+
tabIndex: -1,
|
|
7961
|
+
type: "file"
|
|
7962
|
+
}
|
|
7963
|
+
)
|
|
7964
|
+
] });
|
|
7965
|
+
}
|
|
7966
|
+
|
|
7195
7967
|
// src/components/ui/status-badge.tsx
|
|
7196
|
-
import { jsx as
|
|
7197
|
-
var { Badge, makeStyles:
|
|
7968
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
7969
|
+
var { Badge, makeStyles: makeStyles10, mergeClasses: mergeClasses14 } = fluentComponents;
|
|
7198
7970
|
var TONE_HUES = {
|
|
7199
7971
|
accent: { light: "#0078d4", dark: "#4cc2ff" },
|
|
7200
7972
|
danger: { light: "#c42b1c", dark: "#ff99a4" },
|
|
@@ -7204,7 +7976,7 @@ var TONE_HUES = {
|
|
|
7204
7976
|
};
|
|
7205
7977
|
var CHIP_ROOT_PADDING = "5px";
|
|
7206
7978
|
var LABEL_INSET = `calc(var(--strokeWidthThin) + ${CHIP_ROOT_PADDING} + var(--spacingHorizontalXXS))`;
|
|
7207
|
-
var
|
|
7979
|
+
var useStyles10 = makeStyles10({
|
|
7208
7980
|
root: {
|
|
7209
7981
|
paddingLeft: LABEL_INSET,
|
|
7210
7982
|
paddingRight: LABEL_INSET
|
|
@@ -7212,14 +7984,14 @@ var useStyles7 = makeStyles7({
|
|
|
7212
7984
|
});
|
|
7213
7985
|
function StatusBadge({ children, className, tone }) {
|
|
7214
7986
|
const hue = useBadgeHue(TONE_HUES[tone]);
|
|
7215
|
-
const styles =
|
|
7216
|
-
return /* @__PURE__ */
|
|
7987
|
+
const styles = useStyles10();
|
|
7988
|
+
return /* @__PURE__ */ jsx24(Badge, { appearance: "tint", className: mergeClasses14(styles.root, hue.className, className), size: "large", style: hue.style, children });
|
|
7217
7989
|
}
|
|
7218
7990
|
|
|
7219
7991
|
// src/components/ui/http-badge.tsx
|
|
7220
|
-
import { jsx as
|
|
7221
|
-
var { makeStyles:
|
|
7222
|
-
var
|
|
7992
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
7993
|
+
var { makeStyles: makeStyles11 } = fluentComponents;
|
|
7994
|
+
var useStyles11 = makeStyles11({
|
|
7223
7995
|
root: {
|
|
7224
7996
|
fontFamily: "var(--fontFamilyMonospace)",
|
|
7225
7997
|
minWidth: "48px",
|
|
@@ -7227,34 +7999,34 @@ var useStyles8 = makeStyles8({
|
|
|
7227
7999
|
}
|
|
7228
8000
|
});
|
|
7229
8001
|
function HttpBadge({ children, tone }) {
|
|
7230
|
-
const styles =
|
|
7231
|
-
return /* @__PURE__ */
|
|
8002
|
+
const styles = useStyles11();
|
|
8003
|
+
return /* @__PURE__ */ jsx25(StatusBadge, { className: styles.root, tone, children: /* @__PURE__ */ jsx25("span", { translate: "no", children }) });
|
|
7232
8004
|
}
|
|
7233
8005
|
function HttpMethodBadge({ method }) {
|
|
7234
|
-
return /* @__PURE__ */
|
|
8006
|
+
return /* @__PURE__ */ jsx25(HttpBadge, { tone: method === "GET" ? "accent" : method === "POST" ? "success" : "neutral", children: method });
|
|
7235
8007
|
}
|
|
7236
8008
|
function HttpStatusBadge({ children, severity }) {
|
|
7237
|
-
return /* @__PURE__ */
|
|
8009
|
+
return /* @__PURE__ */ jsx25(HttpBadge, { tone: severity === "error" ? "danger" : severity, children });
|
|
7238
8010
|
}
|
|
7239
8011
|
|
|
7240
8012
|
// src/components/ui/info-label.tsx
|
|
7241
|
-
import { jsx as
|
|
8013
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
7242
8014
|
var { InfoLabel } = fluentComponents;
|
|
7243
|
-
var infoLabelSlot = (label, info) => (_2, slotProps2) => /* @__PURE__ */
|
|
8015
|
+
var infoLabelSlot = (label, info) => (_2, slotProps2) => /* @__PURE__ */ jsx26(InfoLabel, { ...slotProps2, info, children: label });
|
|
7244
8016
|
|
|
7245
8017
|
// src/components/ui/loading-screen.tsx
|
|
7246
|
-
import { jsx as
|
|
7247
|
-
var { Spinner } = fluentComponents;
|
|
8018
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
8019
|
+
var { Spinner: Spinner3 } = fluentComponents;
|
|
7248
8020
|
function AppLoadingScreen({ label }) {
|
|
7249
|
-
return /* @__PURE__ */
|
|
8021
|
+
return /* @__PURE__ */ jsx27("main", { className: "fwt-loading fwt-loading-app", children: /* @__PURE__ */ jsx27(Spinner3, { label }) });
|
|
7250
8022
|
}
|
|
7251
8023
|
function ContentLoadingScreen({ label }) {
|
|
7252
|
-
return /* @__PURE__ */
|
|
8024
|
+
return /* @__PURE__ */ jsx27("div", { className: "fwt-loading", children: /* @__PURE__ */ jsx27(Spinner3, { label }) });
|
|
7253
8025
|
}
|
|
7254
8026
|
|
|
7255
8027
|
// src/components/ui/masked-icon.tsx
|
|
7256
|
-
import { jsx as
|
|
7257
|
-
var { mergeClasses:
|
|
8028
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
8029
|
+
var { mergeClasses: mergeClasses15 } = fluentComponents;
|
|
7258
8030
|
function MaskedIcon({ className, maskSize = "contain", url }) {
|
|
7259
8031
|
const style = {
|
|
7260
8032
|
backgroundColor: "currentColor",
|
|
@@ -7267,13 +8039,96 @@ function MaskedIcon({ className, maskSize = "contain", url }) {
|
|
|
7267
8039
|
maskPosition: "center",
|
|
7268
8040
|
WebkitMaskPosition: "center"
|
|
7269
8041
|
};
|
|
7270
|
-
return /* @__PURE__ */
|
|
8042
|
+
return /* @__PURE__ */ jsx28("span", { "aria-hidden": true, className: mergeClasses15("block flex-none", className), style });
|
|
7271
8043
|
}
|
|
7272
8044
|
|
|
7273
|
-
// src/components/ui/
|
|
7274
|
-
import {
|
|
7275
|
-
|
|
7276
|
-
var
|
|
8045
|
+
// src/components/ui/metric.tsx
|
|
8046
|
+
import { jsx as jsx29, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
8047
|
+
var { makeStyles: makeStyles12, mergeClasses: mergeClasses16 } = fluentComponents;
|
|
8048
|
+
var useStyles12 = makeStyles12({
|
|
8049
|
+
root: {
|
|
8050
|
+
display: "grid",
|
|
8051
|
+
minWidth: 0,
|
|
8052
|
+
rowGap: "4px"
|
|
8053
|
+
},
|
|
8054
|
+
label: {
|
|
8055
|
+
color: "var(--winui-text-fill-secondary)",
|
|
8056
|
+
fontSize: "var(--fontSizeBase200)",
|
|
8057
|
+
lineHeight: "var(--lineHeightBase200)"
|
|
8058
|
+
},
|
|
8059
|
+
value: {
|
|
8060
|
+
alignItems: "baseline",
|
|
8061
|
+
color: "var(--winui-text-fill-primary)",
|
|
8062
|
+
columnGap: "4px",
|
|
8063
|
+
display: "flex",
|
|
8064
|
+
fontVariantNumeric: "tabular-nums",
|
|
8065
|
+
fontWeight: "var(--fontWeightSemibold)",
|
|
8066
|
+
minWidth: 0
|
|
8067
|
+
},
|
|
8068
|
+
title: {
|
|
8069
|
+
fontSize: "var(--fontSizeHero700)",
|
|
8070
|
+
lineHeight: "var(--lineHeightHero700)"
|
|
8071
|
+
},
|
|
8072
|
+
subtitle: {
|
|
8073
|
+
fontSize: "var(--fontSizeBase500)",
|
|
8074
|
+
lineHeight: "var(--lineHeightBase500)"
|
|
8075
|
+
},
|
|
8076
|
+
// A prefix or suffix is a unit or a sign, not part of the figure: one step
|
|
8077
|
+
// down the ramp and the secondary fill, so the figure stays the loudest thing.
|
|
8078
|
+
affix: {
|
|
8079
|
+
color: "var(--winui-text-fill-secondary)",
|
|
8080
|
+
fontSize: "var(--fontSizeBase300)",
|
|
8081
|
+
fontWeight: "var(--fontWeightRegular)",
|
|
8082
|
+
lineHeight: "var(--lineHeightBase300)"
|
|
8083
|
+
},
|
|
8084
|
+
accent: { color: "var(--winui-accent-text-fill-tertiary)" },
|
|
8085
|
+
success: { color: "var(--winui-system-fill-success)" },
|
|
8086
|
+
warning: { color: "var(--winui-system-fill-caution)" },
|
|
8087
|
+
danger: { color: "var(--winui-system-fill-critical)" },
|
|
8088
|
+
grid: {
|
|
8089
|
+
display: "grid",
|
|
8090
|
+
gap: "var(--fwt-metric-gap, 16px)",
|
|
8091
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(min(var(--fwt-metric-min-width, 160px), 100%), 1fr))"
|
|
8092
|
+
}
|
|
8093
|
+
});
|
|
8094
|
+
var formatMetricValue = (value, precision, locale) => typeof value === "number" ? new Intl.NumberFormat(locale, precision === void 0 ? void 0 : { minimumFractionDigits: precision, maximumFractionDigits: precision }).format(value) : value;
|
|
8095
|
+
function Metric({
|
|
8096
|
+
className,
|
|
8097
|
+
formatter,
|
|
8098
|
+
label,
|
|
8099
|
+
locale,
|
|
8100
|
+
precision,
|
|
8101
|
+
prefix,
|
|
8102
|
+
size = "title",
|
|
8103
|
+
suffix,
|
|
8104
|
+
tone = "default",
|
|
8105
|
+
value
|
|
8106
|
+
}) {
|
|
8107
|
+
const styles = useStyles12();
|
|
8108
|
+
const hasValue = value !== null && value !== void 0;
|
|
8109
|
+
const text = hasValue ? formatter ? formatter(value) : formatMetricValue(value, precision, locale) : "\u2014";
|
|
8110
|
+
return /* @__PURE__ */ jsxs14("div", { className: mergeClasses16(styles.root, className), children: [
|
|
8111
|
+
/* @__PURE__ */ jsx29("span", { className: styles.label, children: label }),
|
|
8112
|
+
/* @__PURE__ */ jsxs14("div", { className: mergeClasses16(styles.value, styles[size], tone !== "default" && styles[tone]), children: [
|
|
8113
|
+
prefix !== void 0 && /* @__PURE__ */ jsx29("span", { className: styles.affix, children: prefix }),
|
|
8114
|
+
/* @__PURE__ */ jsx29("span", { children: text }),
|
|
8115
|
+
suffix !== void 0 && /* @__PURE__ */ jsx29("span", { className: styles.affix, children: suffix })
|
|
8116
|
+
] })
|
|
8117
|
+
] });
|
|
8118
|
+
}
|
|
8119
|
+
function MetricGrid({ children, className, gap, minItemWidth }) {
|
|
8120
|
+
const styles = useStyles12();
|
|
8121
|
+
const style = {
|
|
8122
|
+
...minItemWidth !== void 0 && { "--fwt-metric-min-width": typeof minItemWidth === "number" ? `${minItemWidth}px` : minItemWidth },
|
|
8123
|
+
...gap !== void 0 && { "--fwt-metric-gap": typeof gap === "number" ? `${gap}px` : gap }
|
|
8124
|
+
};
|
|
8125
|
+
return /* @__PURE__ */ jsx29("div", { className: mergeClasses16(styles.grid, className), style, children });
|
|
8126
|
+
}
|
|
8127
|
+
|
|
8128
|
+
// src/components/ui/multiselect-combobox.tsx
|
|
8129
|
+
import { useState as useState8 } from "react";
|
|
8130
|
+
import { jsx as jsx30, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
8131
|
+
var { Option: Option3 } = fluentComponents;
|
|
7277
8132
|
var sameValues = (left, right) => left.length === right.length && new Set(right).size === right.length && left.every((entry) => right.includes(entry));
|
|
7278
8133
|
function MultiselectCombobox({
|
|
7279
8134
|
ariaLabel,
|
|
@@ -7290,8 +8145,8 @@ function MultiselectCombobox({
|
|
|
7290
8145
|
renderOption,
|
|
7291
8146
|
value
|
|
7292
8147
|
}) {
|
|
7293
|
-
const [open, setOpen] =
|
|
7294
|
-
const [query, setQuery] =
|
|
8148
|
+
const [open, setOpen] = useState8(false);
|
|
8149
|
+
const [query, setQuery] = useState8("");
|
|
7295
8150
|
const needle = query.trim().toLowerCase();
|
|
7296
8151
|
const optionValues = new Set(options.map((option) => option.value));
|
|
7297
8152
|
const completeOptions = [
|
|
@@ -7304,7 +8159,7 @@ function MultiselectCombobox({
|
|
|
7304
8159
|
if (!sameValues(normalized, value)) onChange(normalized);
|
|
7305
8160
|
setQuery("");
|
|
7306
8161
|
};
|
|
7307
|
-
return /* @__PURE__ */
|
|
8162
|
+
return /* @__PURE__ */ jsxs15(
|
|
7308
8163
|
Combobox,
|
|
7309
8164
|
{
|
|
7310
8165
|
"aria-label": ariaLabel,
|
|
@@ -7328,41 +8183,102 @@ function MultiselectCombobox({
|
|
|
7328
8183
|
selectedOptions: clearLabel && value.length === 0 ? [""] : [...value],
|
|
7329
8184
|
value: open ? query : closedLabel,
|
|
7330
8185
|
children: [
|
|
7331
|
-
clearLabel && needle === "" && /* @__PURE__ */
|
|
7332
|
-
visible.map((option) => /* @__PURE__ */
|
|
8186
|
+
clearLabel && needle === "" && /* @__PURE__ */ jsx30(Option3, { text: clearLabel, value: "", children: clearLabel }),
|
|
8187
|
+
visible.map((option) => /* @__PURE__ */ jsx30(Option3, { text: option.label, value: option.value, children: renderOption ? renderOption(option) : option.label }, option.value))
|
|
7333
8188
|
]
|
|
7334
8189
|
}
|
|
7335
8190
|
);
|
|
7336
8191
|
}
|
|
7337
8192
|
var valuesAsOptions = (values) => values.map((value) => ({ value, label: value }));
|
|
7338
8193
|
|
|
8194
|
+
// src/components/ui/number-box.tsx
|
|
8195
|
+
import { forwardRef as forwardRef4, isValidElement } from "react";
|
|
8196
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
8197
|
+
var { SpinButton } = fluentComponents;
|
|
8198
|
+
var stepPrecision = (step) => {
|
|
8199
|
+
const text = String(step);
|
|
8200
|
+
const exponent = /e-(\d+)$/.exec(text);
|
|
8201
|
+
if (exponent) return Number(exponent[1]);
|
|
8202
|
+
return text.split(".")[1]?.length ?? 0;
|
|
8203
|
+
};
|
|
8204
|
+
var THOUSANDS_GROUPED = /^-?\d{1,3}(,\d{3})+(\.\d+)?$/;
|
|
8205
|
+
var parseNumberText = (text) => {
|
|
8206
|
+
const trimmed = text.trim().replace(/−/g, "-").replace(/\s/g, "");
|
|
8207
|
+
if (trimmed === "") return null;
|
|
8208
|
+
const normalized = THOUSANDS_GROUPED.test(trimmed) ? trimmed.replace(/,/g, "") : /^-?\d*,\d+$/.test(trimmed) ? trimmed.replace(",", ".") : trimmed;
|
|
8209
|
+
const parsed = Number(normalized);
|
|
8210
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
8211
|
+
};
|
|
8212
|
+
var clampNumber = (value, { min, max, precision }) => {
|
|
8213
|
+
let next = value;
|
|
8214
|
+
if (max !== void 0 && next > max) next = max;
|
|
8215
|
+
if (min !== void 0 && next < min) next = min;
|
|
8216
|
+
return precision === void 0 ? next : Number(next.toFixed(Math.min(Math.max(precision, 0), 100)));
|
|
8217
|
+
};
|
|
8218
|
+
var resolveNumberChange = (data, bounds) => {
|
|
8219
|
+
const raw = data.value !== void 0 ? data.value : data.displayValue !== void 0 ? parseNumberText(data.displayValue) : void 0;
|
|
8220
|
+
return typeof raw === "number" ? clampNumber(raw, bounds) : raw;
|
|
8221
|
+
};
|
|
8222
|
+
var labelSlot = (slot, label) => {
|
|
8223
|
+
if (slot === void 0) return { "aria-label": label };
|
|
8224
|
+
if (slot === null || typeof slot !== "object" || isValidElement(slot) || Symbol.iterator in slot) return slot;
|
|
8225
|
+
return { "aria-label": label, ...slot };
|
|
8226
|
+
};
|
|
8227
|
+
var NumberBox = forwardRef4(function NumberBox2({ value, onChange, min, max, step, precision, decrementButton, incrementButton, ...rest }, ref) {
|
|
8228
|
+
const { t: t2 } = useTranslation();
|
|
8229
|
+
const bounds = { min, max, precision: precision ?? stepPrecision(step ?? 1) };
|
|
8230
|
+
const handleChange = (_event, data) => {
|
|
8231
|
+
const next = resolveNumberChange(data, bounds);
|
|
8232
|
+
if (next !== void 0) onChange(next);
|
|
8233
|
+
};
|
|
8234
|
+
return /* @__PURE__ */ jsx31(
|
|
8235
|
+
SpinButton,
|
|
8236
|
+
{
|
|
8237
|
+
...rest,
|
|
8238
|
+
decrementButton: labelSlot(decrementButton, t2("numberBox.decrement")),
|
|
8239
|
+
incrementButton: labelSlot(incrementButton, t2("numberBox.increment")),
|
|
8240
|
+
max,
|
|
8241
|
+
min,
|
|
8242
|
+
onChange: handleChange,
|
|
8243
|
+
precision,
|
|
8244
|
+
ref,
|
|
8245
|
+
step,
|
|
8246
|
+
value
|
|
8247
|
+
}
|
|
8248
|
+
);
|
|
8249
|
+
});
|
|
8250
|
+
|
|
7339
8251
|
// src/components/ui/open-link-label.tsx
|
|
7340
8252
|
import { Open16Regular } from "@fluentui/react-icons";
|
|
7341
|
-
import { jsx as
|
|
8253
|
+
import { jsx as jsx32, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
7342
8254
|
function OpenLinkLabel({ children }) {
|
|
7343
|
-
return /* @__PURE__ */
|
|
8255
|
+
return /* @__PURE__ */ jsxs16("span", { className: "inline-flex items-center gap-1", children: [
|
|
7344
8256
|
children,
|
|
7345
|
-
/* @__PURE__ */
|
|
8257
|
+
/* @__PURE__ */ jsx32(Open16Regular, { "aria-hidden": true, className: "block flex-none" })
|
|
7346
8258
|
] });
|
|
7347
8259
|
}
|
|
7348
8260
|
|
|
7349
8261
|
// src/components/ui/outcome-toast.tsx
|
|
7350
|
-
import { createContext as createContext3, useCallback as
|
|
7351
|
-
import { jsx as
|
|
7352
|
-
var { Spinner:
|
|
8262
|
+
import { createContext as createContext3, useCallback as useCallback5, useContext as useContext3, useId as useId3, useMemo as useMemo4, useRef as useRef6 } from "react";
|
|
8263
|
+
import { jsx as jsx33, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
8264
|
+
var { Spinner: Spinner4, Toast, Toaster, ToastTitle, useToastController } = fluentComponents;
|
|
7353
8265
|
var TOAST_DISMISS_MS = 3e3;
|
|
7354
8266
|
var OutcomeToastContext = createContext3(null);
|
|
8267
|
+
var ToastApiContext = createContext3(null);
|
|
7355
8268
|
function OutcomeToastProvider({ children }) {
|
|
7356
|
-
|
|
7357
|
-
|
|
8269
|
+
return useContext3(OutcomeToastContext) ? children : /* @__PURE__ */ jsx33(ToasterHost, { children });
|
|
8270
|
+
}
|
|
8271
|
+
function ToasterHost({ children }) {
|
|
8272
|
+
const toasterId = useId3();
|
|
8273
|
+
const sequence = useRef6(0);
|
|
7358
8274
|
const { dispatchToast, dismissToast, updateToast } = useToastController(toasterId);
|
|
7359
|
-
const toastFor =
|
|
7360
|
-
const nextToastId =
|
|
7361
|
-
const succeed =
|
|
8275
|
+
const toastFor = useCallback5((toastId, message, pending) => /* @__PURE__ */ jsx33(Toast, { className: "cursor-pointer", onClick: () => dismissToast(toastId), children: /* @__PURE__ */ jsx33(ToastTitle, { media: pending ? /* @__PURE__ */ jsx33(Spinner4, { size: "tiny" }) : void 0, children: message }) }), [dismissToast]);
|
|
8276
|
+
const nextToastId = useCallback5(() => `${toasterId}-${sequence.current++}`, [toasterId]);
|
|
8277
|
+
const succeed = useCallback5((message) => {
|
|
7362
8278
|
const toastId = nextToastId();
|
|
7363
8279
|
dispatchToast(toastFor(toastId, message, false), { intent: "success", toastId, timeout: TOAST_DISMISS_MS });
|
|
7364
8280
|
}, [dispatchToast, nextToastId, toastFor]);
|
|
7365
|
-
const start =
|
|
8281
|
+
const start = useCallback5((pending) => {
|
|
7366
8282
|
const toastId = nextToastId();
|
|
7367
8283
|
dispatchToast(toastFor(toastId, pending, true), { toastId, timeout: -1 });
|
|
7368
8284
|
return {
|
|
@@ -7375,21 +8291,37 @@ function OutcomeToastProvider({ children }) {
|
|
|
7375
8291
|
settle: () => dismissToast(toastId)
|
|
7376
8292
|
};
|
|
7377
8293
|
}, [dismissToast, dispatchToast, nextToastId, toastFor, updateToast]);
|
|
7378
|
-
const value =
|
|
7379
|
-
|
|
7380
|
-
|
|
8294
|
+
const value = useMemo4(() => ({ start, succeed }), [start, succeed]);
|
|
8295
|
+
const notify = useCallback5((intent, text, options) => {
|
|
8296
|
+
const toastId = nextToastId();
|
|
8297
|
+
dispatchToast(toastFor(toastId, text, false), { intent, toastId, timeout: options?.timeout ?? TOAST_DISMISS_MS });
|
|
8298
|
+
return () => dismissToast(toastId);
|
|
8299
|
+
}, [dismissToast, dispatchToast, nextToastId, toastFor]);
|
|
8300
|
+
const api = useMemo4(() => ({
|
|
8301
|
+
success: (text, options) => notify("success", text, options),
|
|
8302
|
+
error: (text, options) => notify("error", text, options),
|
|
8303
|
+
warning: (text, options) => notify("warning", text, options),
|
|
8304
|
+
info: (text, options) => notify("info", text, options)
|
|
8305
|
+
}), [notify]);
|
|
8306
|
+
return /* @__PURE__ */ jsx33(OutcomeToastContext.Provider, { value, children: /* @__PURE__ */ jsxs17(ToastApiContext.Provider, { value: api, children: [
|
|
8307
|
+
/* @__PURE__ */ jsx33(Toaster, { toasterId, position: "top-end" }),
|
|
7381
8308
|
children
|
|
7382
|
-
] });
|
|
8309
|
+
] }) });
|
|
7383
8310
|
}
|
|
7384
8311
|
var useOutcomeToasts = () => {
|
|
7385
8312
|
const value = useContext3(OutcomeToastContext);
|
|
7386
8313
|
if (!value) throw new Error("useOutcomeToasts requires an OutcomeToastProvider above it");
|
|
7387
8314
|
return value;
|
|
7388
8315
|
};
|
|
8316
|
+
var useToast = () => {
|
|
8317
|
+
const value = useContext3(ToastApiContext);
|
|
8318
|
+
if (!value) throw new Error("useToast requires an OutcomeToastProvider above it");
|
|
8319
|
+
return value;
|
|
8320
|
+
};
|
|
7389
8321
|
|
|
7390
8322
|
// src/components/ui/panel.tsx
|
|
7391
|
-
import { jsx as
|
|
7392
|
-
var { Card, mergeClasses:
|
|
8323
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
8324
|
+
var { Card, mergeClasses: mergeClasses17 } = fluentComponents;
|
|
7393
8325
|
var PANEL_INSET_CLASS = "p-[var(--fwt-panel-inset)]";
|
|
7394
8326
|
var PANEL_BAND_CLASS = "px-[var(--fwt-panel-inset)] py-[var(--spacingVerticalSNudge)]";
|
|
7395
8327
|
var PADDING_CLASS = {
|
|
@@ -7397,12 +8329,127 @@ var PADDING_CLASS = {
|
|
|
7397
8329
|
flush: "!p-0"
|
|
7398
8330
|
};
|
|
7399
8331
|
function Panel({ className, padding = "content", ...props }) {
|
|
7400
|
-
return /* @__PURE__ */
|
|
8332
|
+
return /* @__PURE__ */ jsx34(Card, { ...props, className: mergeClasses17(PADDING_CLASS[padding], className) });
|
|
8333
|
+
}
|
|
8334
|
+
|
|
8335
|
+
// src/components/ui/property-list.tsx
|
|
8336
|
+
import { jsx as jsx35, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
8337
|
+
var { makeStyles: makeStyles13, mergeClasses: mergeClasses18, shorthands: shorthands2 } = fluentComponents;
|
|
8338
|
+
var NARROW = "@container fwt-property-list (width < 480px)";
|
|
8339
|
+
var MEDIUM = "@container fwt-property-list (480px <= width < 720px)";
|
|
8340
|
+
var useStyles13 = makeStyles13({
|
|
8341
|
+
container: {
|
|
8342
|
+
containerName: "fwt-property-list",
|
|
8343
|
+
containerType: "inline-size",
|
|
8344
|
+
minWidth: 0
|
|
8345
|
+
},
|
|
8346
|
+
// Cell lines are each cell's own right and bottom edge. The list is pulled
|
|
8347
|
+
// 1px past the frame on those two sides so the last column's and last row's
|
|
8348
|
+
// lines fall under the frame's clip and the frame's own border stands in.
|
|
8349
|
+
frame: {
|
|
8350
|
+
...shorthands2.border("1px", "solid", "var(--winui-divider-stroke-default)"),
|
|
8351
|
+
borderRadius: "var(--winui-control-corner-radius)",
|
|
8352
|
+
overflow: "hidden"
|
|
8353
|
+
},
|
|
8354
|
+
list: {
|
|
8355
|
+
display: "grid",
|
|
8356
|
+
gridTemplateColumns: "repeat(var(--fwt-property-columns, 2), minmax(0, 1fr))",
|
|
8357
|
+
margin: 0,
|
|
8358
|
+
columnGap: "24px",
|
|
8359
|
+
rowGap: "12px",
|
|
8360
|
+
[NARROW]: { gridTemplateColumns: "minmax(0, 1fr)" }
|
|
8361
|
+
},
|
|
8362
|
+
listWrapsToTwo: {
|
|
8363
|
+
[MEDIUM]: { gridTemplateColumns: "repeat(2, minmax(0, 1fr))" }
|
|
8364
|
+
},
|
|
8365
|
+
listBordered: {
|
|
8366
|
+
columnGap: 0,
|
|
8367
|
+
rowGap: 0,
|
|
8368
|
+
marginRight: "-1px",
|
|
8369
|
+
marginBottom: "-1px"
|
|
8370
|
+
},
|
|
8371
|
+
item: {
|
|
8372
|
+
display: "grid",
|
|
8373
|
+
gridColumn: "span var(--fwt-span, 1)",
|
|
8374
|
+
minWidth: 0,
|
|
8375
|
+
rowGap: "2px",
|
|
8376
|
+
[NARROW]: { "&[data-wide]": { gridColumn: "1 / -1" } }
|
|
8377
|
+
},
|
|
8378
|
+
itemWrapsToTwo: {
|
|
8379
|
+
[MEDIUM]: { "&[data-wide]": { gridColumn: "1 / -1" } }
|
|
8380
|
+
},
|
|
8381
|
+
itemBordered: {
|
|
8382
|
+
borderBottom: "1px solid var(--winui-divider-stroke-default)",
|
|
8383
|
+
borderRight: "1px solid var(--winui-divider-stroke-default)",
|
|
8384
|
+
gridTemplateColumns: "var(--fwt-property-label-width, 120px) minmax(0, 1fr)",
|
|
8385
|
+
rowGap: 0
|
|
8386
|
+
},
|
|
8387
|
+
label: {
|
|
8388
|
+
color: "var(--winui-text-fill-secondary)",
|
|
8389
|
+
fontSize: "var(--fontSizeBase200)",
|
|
8390
|
+
lineHeight: "var(--lineHeightBase200)",
|
|
8391
|
+
margin: 0,
|
|
8392
|
+
minWidth: 0
|
|
8393
|
+
},
|
|
8394
|
+
value: {
|
|
8395
|
+
color: "var(--winui-text-fill-primary)",
|
|
8396
|
+
fontSize: "var(--fontSizeBase300)",
|
|
8397
|
+
lineHeight: "var(--lineHeightBase300)",
|
|
8398
|
+
margin: 0,
|
|
8399
|
+
minWidth: 0,
|
|
8400
|
+
overflowWrap: "anywhere"
|
|
8401
|
+
},
|
|
8402
|
+
labelBordered: {
|
|
8403
|
+
backgroundColor: "var(--winui-card-background-fill-secondary)",
|
|
8404
|
+
borderRight: "1px solid var(--winui-divider-stroke-default)",
|
|
8405
|
+
fontSize: "var(--fontSizeBase300)",
|
|
8406
|
+
lineHeight: "var(--lineHeightBase300)",
|
|
8407
|
+
padding: "8px 12px"
|
|
8408
|
+
},
|
|
8409
|
+
valueBordered: {
|
|
8410
|
+
backgroundColor: "var(--winui-card-background-fill-default)",
|
|
8411
|
+
padding: "8px 12px"
|
|
8412
|
+
}
|
|
8413
|
+
});
|
|
8414
|
+
function PropertyList({ bordered, className, columns = 2, items }) {
|
|
8415
|
+
const styles = useStyles13();
|
|
8416
|
+
const columnCount = Math.max(1, Math.floor(columns));
|
|
8417
|
+
const stepsDown = columnCount > 2;
|
|
8418
|
+
const list = /* @__PURE__ */ jsx35(
|
|
8419
|
+
"dl",
|
|
8420
|
+
{
|
|
8421
|
+
className: mergeClasses18(styles.list, stepsDown && styles.listWrapsToTwo, bordered && styles.listBordered),
|
|
8422
|
+
children: items.map((item, index) => {
|
|
8423
|
+
const span = Math.min(Math.max(1, Math.floor(item.span ?? 1)), columnCount);
|
|
8424
|
+
return /* @__PURE__ */ jsxs18(
|
|
8425
|
+
"div",
|
|
8426
|
+
{
|
|
8427
|
+
className: mergeClasses18(styles.item, stepsDown && styles.itemWrapsToTwo, bordered && styles.itemBordered),
|
|
8428
|
+
"data-wide": span > 1 ? "" : void 0,
|
|
8429
|
+
style: { "--fwt-span": span },
|
|
8430
|
+
children: [
|
|
8431
|
+
/* @__PURE__ */ jsx35("dt", { className: mergeClasses18(styles.label, bordered && styles.labelBordered), children: item.label }),
|
|
8432
|
+
/* @__PURE__ */ jsx35("dd", { className: mergeClasses18(styles.value, bordered && styles.valueBordered), children: item.value })
|
|
8433
|
+
]
|
|
8434
|
+
},
|
|
8435
|
+
item.key ?? index
|
|
8436
|
+
);
|
|
8437
|
+
})
|
|
8438
|
+
}
|
|
8439
|
+
);
|
|
8440
|
+
return /* @__PURE__ */ jsx35(
|
|
8441
|
+
"div",
|
|
8442
|
+
{
|
|
8443
|
+
className: mergeClasses18(styles.container, bordered && styles.frame, className),
|
|
8444
|
+
style: { "--fwt-property-columns": columnCount },
|
|
8445
|
+
children: list
|
|
8446
|
+
}
|
|
8447
|
+
);
|
|
7401
8448
|
}
|
|
7402
8449
|
|
|
7403
8450
|
// src/components/ui/progress-ring.tsx
|
|
7404
|
-
import { jsx as
|
|
7405
|
-
var { makeStyles:
|
|
8451
|
+
import { jsx as jsx36, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
8452
|
+
var { makeStyles: makeStyles14, mergeClasses: mergeClasses19 } = fluentComponents;
|
|
7406
8453
|
var DIAMETER = 32;
|
|
7407
8454
|
var STROKE = 4;
|
|
7408
8455
|
var RADIUS = (DIAMETER - STROKE) / 2;
|
|
@@ -7413,7 +8460,7 @@ var TONE_STROKE = {
|
|
|
7413
8460
|
caution: "var(--winui-system-fill-caution)",
|
|
7414
8461
|
critical: "var(--winui-system-fill-critical)"
|
|
7415
8462
|
};
|
|
7416
|
-
var
|
|
8463
|
+
var useStyles14 = makeStyles14({
|
|
7417
8464
|
// A forced-colours palette repaints background and border colours but not an
|
|
7418
8465
|
// SVG stroke, so each ring names its system colour itself: Highlight is what
|
|
7419
8466
|
// HighContrast gives ProgressRingForegroundThemeBrush through
|
|
@@ -7432,19 +8479,19 @@ var useStyles9 = makeStyles9({
|
|
|
7432
8479
|
}
|
|
7433
8480
|
});
|
|
7434
8481
|
function ProgressRing({ className, percent, size = 16, tone }) {
|
|
7435
|
-
const styles =
|
|
8482
|
+
const styles = useStyles14();
|
|
7436
8483
|
const filled = Math.max(0, Math.min(100, percent)) / 100;
|
|
7437
|
-
return /* @__PURE__ */
|
|
8484
|
+
return /* @__PURE__ */ jsxs19(
|
|
7438
8485
|
"svg",
|
|
7439
8486
|
{
|
|
7440
8487
|
"aria-hidden": true,
|
|
7441
|
-
className:
|
|
8488
|
+
className: mergeClasses19("block flex-none", className),
|
|
7442
8489
|
height: size,
|
|
7443
8490
|
style: { transform: "translateY(calc(50% - 0.5cap))" },
|
|
7444
8491
|
viewBox: `0 0 ${DIAMETER} ${DIAMETER}`,
|
|
7445
8492
|
width: size,
|
|
7446
8493
|
children: [
|
|
7447
|
-
/* @__PURE__ */
|
|
8494
|
+
/* @__PURE__ */ jsx36(
|
|
7448
8495
|
"circle",
|
|
7449
8496
|
{
|
|
7450
8497
|
className: styles.track,
|
|
@@ -7456,7 +8503,7 @@ function ProgressRing({ className, percent, size = 16, tone }) {
|
|
|
7456
8503
|
strokeWidth: TRACK_STROKE
|
|
7457
8504
|
}
|
|
7458
8505
|
),
|
|
7459
|
-
/* @__PURE__ */
|
|
8506
|
+
/* @__PURE__ */ jsx36(
|
|
7460
8507
|
"circle",
|
|
7461
8508
|
{
|
|
7462
8509
|
className: styles.arc,
|
|
@@ -7478,9 +8525,9 @@ function ProgressRing({ className, percent, size = 16, tone }) {
|
|
|
7478
8525
|
|
|
7479
8526
|
// src/components/ui/reorder-list.tsx
|
|
7480
8527
|
import { ReOrderDotsVerticalRegular } from "@fluentui/react-icons";
|
|
7481
|
-
import { useEffect as useEffect5, useMemo as
|
|
7482
|
-
import { jsx as
|
|
7483
|
-
var { Button:
|
|
8528
|
+
import { useEffect as useEffect5, useMemo as useMemo5, useRef as useRef7, useState as useState9 } from "react";
|
|
8529
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
8530
|
+
var { Button: Button9, makeStyles: makeStyles15, mergeClasses: mergeClasses20 } = fluentComponents;
|
|
7484
8531
|
var REORDER_OPACITY = 0.8;
|
|
7485
8532
|
var DRAG_RETURN_MS = 200;
|
|
7486
8533
|
var LIST_ATTRIBUTE = "data-reorder-list";
|
|
@@ -7490,7 +8537,7 @@ var EDGE_ATTRIBUTE = "data-reorder-edge";
|
|
|
7490
8537
|
var HANDLE_ATTRIBUTE = "data-reorder-handle";
|
|
7491
8538
|
var DRAG_Y = "--fwt-reorder-drag-y";
|
|
7492
8539
|
var TRACKING_TRANSFORM = { transform: `translateY(var(${DRAG_Y}, 0px))` };
|
|
7493
|
-
var
|
|
8540
|
+
var useStyles15 = makeStyles15({
|
|
7494
8541
|
// A drag that starts on the handle travels over the rows, and without this
|
|
7495
8542
|
// the browser reads that travel as a text selection across them.
|
|
7496
8543
|
list: { [`&[${REORDERING_ATTRIBUTE}]`]: { userSelect: "none" } },
|
|
@@ -7579,11 +8626,11 @@ var siblingHandles = (handle) => {
|
|
|
7579
8626
|
return [...list.querySelectorAll(`[${HANDLE_ATTRIBUTE}]`)].filter((element) => element.closest(`[${LIST_ATTRIBUTE}]`) === list && !element.hasAttribute("disabled"));
|
|
7580
8627
|
};
|
|
7581
8628
|
function useReorderList({ busy = false, disabled = false, length, onDrop, onDropError, onReorder }) {
|
|
7582
|
-
const styles =
|
|
7583
|
-
const gestureRef =
|
|
7584
|
-
const settleRef =
|
|
7585
|
-
const mountedRef =
|
|
7586
|
-
const [preview, setPreview] =
|
|
8629
|
+
const styles = useStyles15();
|
|
8630
|
+
const gestureRef = useRef7(null);
|
|
8631
|
+
const settleRef = useRef7(void 0);
|
|
8632
|
+
const mountedRef = useRef7(true);
|
|
8633
|
+
const [preview, setPreview] = useState9(null);
|
|
7587
8634
|
const locked = busy || disabled || length < 2;
|
|
7588
8635
|
const live = preview !== null && preview.from < length && preview.to < length ? preview : null;
|
|
7589
8636
|
useEffect5(() => {
|
|
@@ -7593,8 +8640,8 @@ function useReorderList({ busy = false, disabled = false, length, onDrop, onDrop
|
|
|
7593
8640
|
clearTimeout(settleRef.current);
|
|
7594
8641
|
};
|
|
7595
8642
|
}, []);
|
|
7596
|
-
const offsets =
|
|
7597
|
-
const ranks =
|
|
8643
|
+
const offsets = useMemo5(() => live && slotOffsets(live.items, live.from, live.to), [live]);
|
|
8644
|
+
const ranks = useMemo5(
|
|
7598
8645
|
() => live && moveItem(Array.from({ length }, (_2, index) => index), live.from, live.to),
|
|
7599
8646
|
[length, live]
|
|
7600
8647
|
);
|
|
@@ -7723,7 +8770,7 @@ function useReorderList({ busy = false, disabled = false, length, onDrop, onDrop
|
|
|
7723
8770
|
return {
|
|
7724
8771
|
[ITEM_ATTRIBUTE]: String(index),
|
|
7725
8772
|
[EDGE_ATTRIBUTE]: !live ? void 0 : rank === 0 ? "first" : rank === length - 1 ? "last" : void 0,
|
|
7726
|
-
className:
|
|
8773
|
+
className: mergeClasses20(
|
|
7727
8774
|
grabbed && styles.lifted,
|
|
7728
8775
|
// The row under the pointer is not travelling toward anything -- it is
|
|
7729
8776
|
// where the pointer put it -- so it wears the drag opacity flat, and
|
|
@@ -7735,20 +8782,20 @@ function useReorderList({ busy = false, disabled = false, length, onDrop, onDrop
|
|
|
7735
8782
|
style: !live ? void 0 : grabbed ? TRACKING_TRANSFORM : { transform: `translateY(${offsets?.get(index) ?? 0}px)` }
|
|
7736
8783
|
};
|
|
7737
8784
|
},
|
|
7738
|
-
listProps: (className) => ({ [LIST_ATTRIBUTE]: "", className:
|
|
8785
|
+
listProps: (className) => ({ [LIST_ATTRIBUTE]: "", className: mergeClasses20(styles.list, className), onKeyDown }),
|
|
7739
8786
|
position
|
|
7740
8787
|
};
|
|
7741
8788
|
}
|
|
7742
8789
|
function ReorderHandle({ label, ...gesture }) {
|
|
7743
|
-
const styles =
|
|
7744
|
-
return /* @__PURE__ */
|
|
7745
|
-
|
|
8790
|
+
const styles = useStyles15();
|
|
8791
|
+
return /* @__PURE__ */ jsx37(
|
|
8792
|
+
Button9,
|
|
7746
8793
|
{
|
|
7747
8794
|
appearance: "subtle",
|
|
7748
8795
|
"aria-keyshortcuts": `${REORDER_CHORD}+ArrowUp ${REORDER_CHORD}+ArrowDown`,
|
|
7749
8796
|
"aria-label": label,
|
|
7750
8797
|
className: styles.handle,
|
|
7751
|
-
icon: /* @__PURE__ */
|
|
8798
|
+
icon: /* @__PURE__ */ jsx37(ReOrderDotsVerticalRegular, {}),
|
|
7752
8799
|
size: "small",
|
|
7753
8800
|
...gesture
|
|
7754
8801
|
}
|
|
@@ -7757,12 +8804,12 @@ function ReorderHandle({ label, ...gesture }) {
|
|
|
7757
8804
|
|
|
7758
8805
|
// src/components/ui/resource-list.tsx
|
|
7759
8806
|
import { AddRegular, ArrowClockwiseRegular } from "@fluentui/react-icons";
|
|
7760
|
-
import { jsx as
|
|
7761
|
-
var { Button:
|
|
8807
|
+
import { jsx as jsx38, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
8808
|
+
var { Button: Button10, Spinner: Spinner5, Tooltip: Tooltip3, makeStyles: makeStyles16, mergeClasses: mergeClasses21 } = fluentComponents;
|
|
7762
8809
|
var DEFAULT_ROW_HEIGHT = "44px";
|
|
7763
8810
|
var ROW_HEIGHT = "--fwt-resource-row-height";
|
|
7764
8811
|
var EDGE_INSET = "var(--fwt-panel-inset)";
|
|
7765
|
-
var
|
|
8812
|
+
var useStyles16 = makeStyles16({
|
|
7766
8813
|
table: {
|
|
7767
8814
|
"& .fui-TableRow": { height: `var(${ROW_HEIGHT})` },
|
|
7768
8815
|
// By type rather than by position: a DataGrid row carries Tabster's focus
|
|
@@ -7795,12 +8842,12 @@ var useStyles11 = makeStyles11({
|
|
|
7795
8842
|
emptyState: { padding: EDGE_INSET }
|
|
7796
8843
|
});
|
|
7797
8844
|
function ResourceListPanel({ className, rowHeight = DEFAULT_ROW_HEIGHT, style, ...props }) {
|
|
7798
|
-
const styles =
|
|
7799
|
-
return /* @__PURE__ */
|
|
8845
|
+
const styles = useStyles16();
|
|
8846
|
+
return /* @__PURE__ */ jsx38(
|
|
7800
8847
|
Panel,
|
|
7801
8848
|
{
|
|
7802
8849
|
...props,
|
|
7803
|
-
className:
|
|
8850
|
+
className: mergeClasses21("grid min-w-0 !gap-0 overflow-hidden", styles.table, className),
|
|
7804
8851
|
padding: "flush",
|
|
7805
8852
|
style: { ...style, [ROW_HEIGHT]: rowHeight }
|
|
7806
8853
|
}
|
|
@@ -7809,12 +8856,12 @@ function ResourceListPanel({ className, rowHeight = DEFAULT_ROW_HEIGHT, style, .
|
|
|
7809
8856
|
function ResourceListActions(props) {
|
|
7810
8857
|
const { appearance, createDisabled = false, createLabel, createTrailingIcon, disabled = false, onRefresh, refreshLabel, refreshing = false } = props;
|
|
7811
8858
|
const busy = disabled || createDisabled || refreshing;
|
|
7812
|
-
const createButton = createLabel !== void 0 && /* @__PURE__ */
|
|
7813
|
-
|
|
8859
|
+
const createButton = createLabel !== void 0 && /* @__PURE__ */ jsxs20(
|
|
8860
|
+
Button10,
|
|
7814
8861
|
{
|
|
7815
8862
|
appearance: "primary",
|
|
7816
8863
|
disabled: busy,
|
|
7817
|
-
icon: /* @__PURE__ */
|
|
8864
|
+
icon: /* @__PURE__ */ jsx38(AddRegular, {}),
|
|
7818
8865
|
onClick: "onCreate" in props ? props.onCreate : void 0,
|
|
7819
8866
|
children: [
|
|
7820
8867
|
createLabel,
|
|
@@ -7822,43 +8869,43 @@ function ResourceListActions(props) {
|
|
|
7822
8869
|
]
|
|
7823
8870
|
}
|
|
7824
8871
|
);
|
|
7825
|
-
return /* @__PURE__ */
|
|
7826
|
-
/* @__PURE__ */
|
|
7827
|
-
|
|
8872
|
+
return /* @__PURE__ */ jsxs20("div", { "aria-busy": refreshing, className: "flex items-center gap-2 flex-none", children: [
|
|
8873
|
+
/* @__PURE__ */ jsx38(Tooltip3, { content: refreshLabel, relationship: "label", children: /* @__PURE__ */ jsx38(
|
|
8874
|
+
Button10,
|
|
7828
8875
|
{
|
|
7829
8876
|
appearance,
|
|
7830
8877
|
"aria-label": refreshLabel,
|
|
7831
8878
|
disabled,
|
|
7832
8879
|
disabledFocusable: refreshing,
|
|
7833
|
-
icon: refreshing ? /* @__PURE__ */
|
|
8880
|
+
icon: refreshing ? /* @__PURE__ */ jsx38(Spinner5, { size: "tiny" }) : /* @__PURE__ */ jsx38(ArrowClockwiseRegular, {}),
|
|
7834
8881
|
onClick: onRefresh
|
|
7835
8882
|
}
|
|
7836
8883
|
) }),
|
|
7837
8884
|
createButton && (props.createTrigger === void 0 ? createButton : props.createTrigger(createButton)),
|
|
7838
|
-
/* @__PURE__ */
|
|
8885
|
+
/* @__PURE__ */ jsx38("span", { "aria-live": "polite", className: "sr-only", children: refreshing ? `${refreshLabel}\u2026` : "" })
|
|
7839
8886
|
] });
|
|
7840
8887
|
}
|
|
7841
8888
|
function ResourceListEmptyState({ children }) {
|
|
7842
|
-
const styles =
|
|
7843
|
-
return /* @__PURE__ */
|
|
8889
|
+
const styles = useStyles16();
|
|
8890
|
+
return /* @__PURE__ */ jsx38(EmptyStateLine, { className: styles.emptyState, children });
|
|
7844
8891
|
}
|
|
7845
8892
|
|
|
7846
8893
|
// src/components/ui/row-title.tsx
|
|
7847
|
-
import { jsx as
|
|
7848
|
-
var { mergeClasses:
|
|
8894
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
8895
|
+
var { mergeClasses: mergeClasses22 } = fluentComponents;
|
|
7849
8896
|
var rowTitleClass = "winui-focus-rect text-fui-fg1 no-underline hover:underline";
|
|
7850
8897
|
function RowTitleButton({ children, onClick, ...trigger }) {
|
|
7851
|
-
return /* @__PURE__ */
|
|
8898
|
+
return /* @__PURE__ */ jsx39("button", { className: mergeClasses22(rowTitleClass, "block bg-transparent border-0 cursor-pointer leading-[var(--lineHeightBase300)] min-w-0 max-w-full truncate p-0 text-fui-base300 text-left"), onClick, type: "button", ...trigger, children });
|
|
7852
8899
|
}
|
|
7853
8900
|
|
|
7854
8901
|
// src/components/ui/secret-input.tsx
|
|
7855
|
-
import { useState as
|
|
7856
|
-
import { jsx as
|
|
8902
|
+
import { useState as useState10 } from "react";
|
|
8903
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
7857
8904
|
function SecretInput({ onChange, revealed = false, value, ...rest }) {
|
|
7858
|
-
const [guardLocked, setGuardLocked] =
|
|
8905
|
+
const [guardLocked, setGuardLocked] = useState10(true);
|
|
7859
8906
|
const hasValue = String(value ?? "").length > 0;
|
|
7860
8907
|
const unlock = () => setGuardLocked(false);
|
|
7861
|
-
return /* @__PURE__ */
|
|
8908
|
+
return /* @__PURE__ */ jsx40(
|
|
7862
8909
|
Input,
|
|
7863
8910
|
{
|
|
7864
8911
|
...rest,
|
|
@@ -7899,12 +8946,12 @@ function SecretInput({ onChange, revealed = false, value, ...rest }) {
|
|
|
7899
8946
|
}
|
|
7900
8947
|
|
|
7901
8948
|
// src/components/ui/section-header.tsx
|
|
7902
|
-
import { jsx as
|
|
7903
|
-
var { InfoButton, Text:
|
|
8949
|
+
import { jsx as jsx41, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
8950
|
+
var { InfoButton, Text: Text7, mergeClasses: mergeClasses23 } = fluentComponents;
|
|
7904
8951
|
var TITLE_SIZE = { 2: 500, 3: 400, 4: 300 };
|
|
7905
8952
|
function SectionHeader({ actions, description, info, level, title, titleId, truncate = false }) {
|
|
7906
|
-
const headingText = /* @__PURE__ */
|
|
7907
|
-
|
|
8953
|
+
const headingText = /* @__PURE__ */ jsx41(
|
|
8954
|
+
Text7,
|
|
7908
8955
|
{
|
|
7909
8956
|
as: `h${level}`,
|
|
7910
8957
|
className: description === void 0 ? "m-0 min-w-0" : "m-0",
|
|
@@ -7916,25 +8963,25 @@ function SectionHeader({ actions, description, info, level, title, titleId, trun
|
|
|
7916
8963
|
children: title
|
|
7917
8964
|
}
|
|
7918
8965
|
);
|
|
7919
|
-
const heading = info === void 0 ? headingText : /* @__PURE__ */
|
|
8966
|
+
const heading = info === void 0 ? headingText : /* @__PURE__ */ jsxs21("div", { className: "inline-flex items-center gap-1 min-w-0", children: [
|
|
7920
8967
|
headingText,
|
|
7921
|
-
/* @__PURE__ */
|
|
8968
|
+
/* @__PURE__ */ jsx41(InfoButton, { info })
|
|
7922
8969
|
] });
|
|
7923
|
-
const block = description === void 0 ? heading : /* @__PURE__ */
|
|
8970
|
+
const block = description === void 0 ? heading : /* @__PURE__ */ jsxs21("div", { className: mergeClasses23(TIGHT_STACK_CLASS, "min-w-0"), children: [
|
|
7924
8971
|
heading,
|
|
7925
|
-
/* @__PURE__ */
|
|
8972
|
+
/* @__PURE__ */ jsx41(Text7, { className: "text-fui-fg2", size: 200, children: description })
|
|
7926
8973
|
] });
|
|
7927
8974
|
if (actions === void 0) return block;
|
|
7928
|
-
return /* @__PURE__ */
|
|
8975
|
+
return /* @__PURE__ */ jsxs21("div", { className: mergeClasses23(HEADER_ROW_CLASS, "gap-3"), children: [
|
|
7929
8976
|
block,
|
|
7930
|
-
/* @__PURE__ */
|
|
8977
|
+
/* @__PURE__ */ jsx41("div", { className: "flex items-center gap-2 flex-none", children: actions })
|
|
7931
8978
|
] });
|
|
7932
8979
|
}
|
|
7933
8980
|
|
|
7934
8981
|
// src/components/ui/settings-card.tsx
|
|
7935
|
-
import { useId as
|
|
7936
|
-
import { Fragment as
|
|
7937
|
-
var { Text:
|
|
8982
|
+
import { useId as useId4, useState as useState11 } from "react";
|
|
8983
|
+
import { Fragment as Fragment3, jsx as jsx42, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
8984
|
+
var { Text: Text8, makeStyles: makeStyles17, mergeClasses: mergeClasses24, shorthands: shorthands3 } = fluentComponents;
|
|
7938
8985
|
var ICON_MARGIN_START = "2px";
|
|
7939
8986
|
var ICON_MARGIN_END = "20px";
|
|
7940
8987
|
var ICON_SIZE = "24px";
|
|
@@ -7944,7 +8991,7 @@ var ICON_COLUMN_VAR = "var(--fwt-settings-icon-column, 0px)";
|
|
|
7944
8991
|
var WRAPPED = "@container fwt-settings-row (width < 476px)";
|
|
7945
8992
|
var WRAPPED_WITH_ICON = "@container fwt-settings-row (286px <= width < 476px)";
|
|
7946
8993
|
var WRAPPED_NO_ICON = "@container fwt-settings-row (width < 286px)";
|
|
7947
|
-
var
|
|
8994
|
+
var useStyles17 = makeStyles17({
|
|
7948
8995
|
// Containment sits one level out of the row so the query measures the same
|
|
7949
8996
|
// box the toolkit's trigger reads (this element carries no padding or
|
|
7950
8997
|
// border), and so the wrapped state can style the row itself -- a container
|
|
@@ -7973,7 +9020,7 @@ var useStyles12 = makeStyles12({
|
|
|
7973
9020
|
borderRightWidth: "1px",
|
|
7974
9021
|
borderBottomWidth: "1px",
|
|
7975
9022
|
borderLeftWidth: "1px",
|
|
7976
|
-
...
|
|
9023
|
+
...shorthands3.borderColor("var(--winui-card-stroke-default)"),
|
|
7977
9024
|
borderRadius: "var(--winui-control-corner-radius)",
|
|
7978
9025
|
boxSizing: "border-box",
|
|
7979
9026
|
color: "var(--winui-text-fill-primary)",
|
|
@@ -8028,7 +9075,7 @@ var useStyles12 = makeStyles12({
|
|
|
8028
9075
|
// would hold its rest fill while the reader is holding it down.
|
|
8029
9076
|
"&:active, &:has(> :active)": {
|
|
8030
9077
|
backgroundColor: "var(--winui-control-fill-tertiary)",
|
|
8031
|
-
...
|
|
9078
|
+
...shorthands3.borderColor("var(--winui-control-stroke-default)")
|
|
8032
9079
|
},
|
|
8033
9080
|
// The system focus visual: a 2px FocusStrokeColorOuter ring with a 1px
|
|
8034
9081
|
// FocusStrokeColorInner ring immediately inside it, around the border box
|
|
@@ -8116,7 +9163,7 @@ var useStyles12 = makeStyles12({
|
|
|
8116
9163
|
expanderHeader: {
|
|
8117
9164
|
position: "relative",
|
|
8118
9165
|
backgroundColor: "var(--winui-card-background-fill-default)",
|
|
8119
|
-
...
|
|
9166
|
+
...shorthands3.borderColor("var(--winui-card-stroke-default)"),
|
|
8120
9167
|
fontFamily: "inherit",
|
|
8121
9168
|
fontSize: "inherit",
|
|
8122
9169
|
paddingInlineEnd: "4px",
|
|
@@ -8166,7 +9213,7 @@ var useStyles12 = makeStyles12({
|
|
|
8166
9213
|
// The row paints the ring; see the interactive style above.
|
|
8167
9214
|
":focus-visible": { outline: "none" },
|
|
8168
9215
|
background: "none",
|
|
8169
|
-
...
|
|
9216
|
+
...shorthands3.borderWidth(0),
|
|
8170
9217
|
cursor: "pointer",
|
|
8171
9218
|
"&:disabled": { cursor: "not-allowed" },
|
|
8172
9219
|
inset: 0,
|
|
@@ -8301,48 +9348,48 @@ var useStyles12 = makeStyles12({
|
|
|
8301
9348
|
readoutDisabled: { color: "var(--winui-text-fill-disabled)" }
|
|
8302
9349
|
});
|
|
8303
9350
|
function CardText({ description, header, icon, id }) {
|
|
8304
|
-
const styles =
|
|
8305
|
-
return /* @__PURE__ */
|
|
8306
|
-
icon !== void 0 && /* @__PURE__ */
|
|
8307
|
-
/* @__PURE__ */
|
|
8308
|
-
/* @__PURE__ */
|
|
8309
|
-
description !== void 0 && /* @__PURE__ */
|
|
9351
|
+
const styles = useStyles17();
|
|
9352
|
+
return /* @__PURE__ */ jsxs22(Fragment3, { children: [
|
|
9353
|
+
icon !== void 0 && /* @__PURE__ */ jsx42("span", { "aria-hidden": true, className: styles.icon, ...{ [ICON_MARKER]: "" }, children: icon }),
|
|
9354
|
+
/* @__PURE__ */ jsxs22("span", { className: styles.text, children: [
|
|
9355
|
+
/* @__PURE__ */ jsx42(Text8, { block: true, id, children: header }),
|
|
9356
|
+
description !== void 0 && /* @__PURE__ */ jsx42(Text8, { block: true, size: 200, className: styles.description, children: description })
|
|
8310
9357
|
] })
|
|
8311
9358
|
] });
|
|
8312
9359
|
}
|
|
8313
9360
|
function SettingsSwitch({ checked, disabled, label, onChange }) {
|
|
8314
|
-
const styles =
|
|
9361
|
+
const styles = useStyles17();
|
|
8315
9362
|
const { t: t2 } = useTranslation();
|
|
8316
|
-
return /* @__PURE__ */
|
|
8317
|
-
/* @__PURE__ */
|
|
8318
|
-
/* @__PURE__ */
|
|
9363
|
+
return /* @__PURE__ */ jsxs22("span", { className: styles.switchRow, children: [
|
|
9364
|
+
/* @__PURE__ */ jsx42(Text8, { className: disabled === true ? styles.readoutDisabled : void 0, children: t2(checked ? "common.on" : "common.off") }),
|
|
9365
|
+
/* @__PURE__ */ jsx42(Switch, { "aria-label": label, checked, disabled, onChange: (_2, data) => onChange(data.checked) })
|
|
8319
9366
|
] });
|
|
8320
9367
|
}
|
|
8321
9368
|
function SettingsCard({ action, description, header, icon }) {
|
|
8322
|
-
const styles =
|
|
8323
|
-
return /* @__PURE__ */
|
|
8324
|
-
/* @__PURE__ */
|
|
8325
|
-
action !== void 0 && /* @__PURE__ */
|
|
9369
|
+
const styles = useStyles17();
|
|
9370
|
+
return /* @__PURE__ */ jsx42("div", { className: styles.row, children: /* @__PURE__ */ jsxs22("div", { className: styles.card, children: [
|
|
9371
|
+
/* @__PURE__ */ jsx42(CardText, { description, header, icon }),
|
|
9372
|
+
action !== void 0 && /* @__PURE__ */ jsx42("span", { className: styles.action, children: action })
|
|
8326
9373
|
] }) });
|
|
8327
9374
|
}
|
|
8328
9375
|
function SettingsExpander({ action, children, defaultOpen = false, description, disclosureDisabled = false, header, icon, revealOn, toggledOn }) {
|
|
8329
|
-
const styles =
|
|
8330
|
-
const [open, setOpen] =
|
|
8331
|
-
const [toggleWas, setToggleWas] =
|
|
9376
|
+
const styles = useStyles17();
|
|
9377
|
+
const [open, setOpen] = useState11(defaultOpen);
|
|
9378
|
+
const [toggleWas, setToggleWas] = useState11(toggledOn);
|
|
8332
9379
|
if (toggledOn !== void 0 && toggledOn !== toggleWas) {
|
|
8333
9380
|
setToggleWas(toggledOn);
|
|
8334
9381
|
setOpen(toggledOn);
|
|
8335
9382
|
}
|
|
8336
|
-
const [revealWas, setRevealWas] =
|
|
9383
|
+
const [revealWas, setRevealWas] = useState11(revealOn);
|
|
8337
9384
|
if (revealOn !== revealWas) {
|
|
8338
9385
|
setRevealWas(revealOn);
|
|
8339
9386
|
if (revealOn === true) setOpen(true);
|
|
8340
9387
|
}
|
|
8341
|
-
const contentId =
|
|
8342
|
-
const headerId =
|
|
8343
|
-
return /* @__PURE__ */
|
|
8344
|
-
/* @__PURE__ */
|
|
8345
|
-
/* @__PURE__ */
|
|
9388
|
+
const contentId = useId4();
|
|
9389
|
+
const headerId = useId4();
|
|
9390
|
+
return /* @__PURE__ */ jsxs22("div", { className: styles.row, children: [
|
|
9391
|
+
/* @__PURE__ */ jsxs22("div", { className: mergeClasses24(styles.card, !disclosureDisabled && styles.interactive, styles.expanderHeader, open && styles.expanderHeaderOpen), children: [
|
|
9392
|
+
/* @__PURE__ */ jsx42(
|
|
8346
9393
|
"button",
|
|
8347
9394
|
{
|
|
8348
9395
|
"aria-controls": contentId,
|
|
@@ -8354,112 +9401,48 @@ function SettingsExpander({ action, children, defaultOpen = false, description,
|
|
|
8354
9401
|
type: "button"
|
|
8355
9402
|
}
|
|
8356
9403
|
),
|
|
8357
|
-
/* @__PURE__ */
|
|
8358
|
-
action !== void 0 && /* @__PURE__ */
|
|
8359
|
-
/* @__PURE__ */
|
|
9404
|
+
/* @__PURE__ */ jsx42(CardText, { description, header, icon, id: headerId }),
|
|
9405
|
+
action !== void 0 && /* @__PURE__ */ jsx42("span", { className: styles.action, children: action }),
|
|
9406
|
+
/* @__PURE__ */ jsx42("span", { "aria-hidden": true, className: styles.chevron, children: /* @__PURE__ */ jsx42("svg", { className: mergeClasses24(styles.chevronGlyph, open && styles.chevronOpen), width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor", children: /* @__PURE__ */ jsx42("path", { d: "M3.15 5.65c.2-.2.5-.2.7 0L8 9.79l4.15-4.14a.5.5 0 0 1 .7.7l-4.5 4.5a.5.5 0 0 1-.7 0l-4.5-4.5a.5.5 0 0 1 0-.7Z" }) }) })
|
|
8360
9407
|
] }),
|
|
8361
|
-
/* @__PURE__ */
|
|
9408
|
+
/* @__PURE__ */ jsx42("div", { className: mergeClasses24(styles.contentFrame, open && styles.contentFrameOpen), children: /* @__PURE__ */ jsx42("div", { className: styles.contentClip, children: /* @__PURE__ */ jsx42("div", { "aria-labelledby": headerId, className: styles.content, id: contentId, inert: !open, role: "group", children }) }) })
|
|
8362
9409
|
] });
|
|
8363
9410
|
}
|
|
8364
9411
|
|
|
8365
9412
|
// src/components/ui/switch-setting.tsx
|
|
8366
|
-
import { jsx as
|
|
9413
|
+
import { jsx as jsx43, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
8367
9414
|
var { InfoButton: InfoButton2 } = fluentComponents;
|
|
8368
9415
|
function SwitchSetting({ checked, description, label, onChange }) {
|
|
8369
|
-
return /* @__PURE__ */
|
|
8370
|
-
/* @__PURE__ */
|
|
8371
|
-
/* @__PURE__ */
|
|
9416
|
+
return /* @__PURE__ */ jsxs23("span", { className: "inline-flex items-center gap-1", children: [
|
|
9417
|
+
/* @__PURE__ */ jsx43(Switch, { checked, label, onChange: (_2, data) => onChange(data.checked) }),
|
|
9418
|
+
/* @__PURE__ */ jsx43(InfoButton2, { info: description })
|
|
8372
9419
|
] });
|
|
8373
9420
|
}
|
|
8374
9421
|
|
|
8375
|
-
// src/components/ui/
|
|
8376
|
-
import {
|
|
8377
|
-
|
|
8378
|
-
var useStyles13 = makeStyles13({
|
|
8379
|
-
trailing: {
|
|
8380
|
-
textAlign: "right",
|
|
8381
|
-
"& .fui-TableHeaderCell__button": { justifyContent: "flex-end" }
|
|
8382
|
-
},
|
|
8383
|
-
centred: {
|
|
8384
|
-
textAlign: "center",
|
|
8385
|
-
"& .fui-TableHeaderCell__button": { justifyContent: "center" }
|
|
8386
|
-
}
|
|
8387
|
-
});
|
|
8388
|
-
function TableTrailingHeader({ className, ...props }) {
|
|
8389
|
-
const styles = useStyles13();
|
|
8390
|
-
return /* @__PURE__ */ jsx35(TableHeaderCell, { ...props, className: mergeClasses18(styles.trailing, className) });
|
|
8391
|
-
}
|
|
8392
|
-
function TableTrailingCell({ className, ...props }) {
|
|
8393
|
-
const styles = useStyles13();
|
|
8394
|
-
return /* @__PURE__ */ jsx35(TableCell, { ...props, className: mergeClasses18(styles.trailing, className) });
|
|
8395
|
-
}
|
|
8396
|
-
function TableCentredHeader({ className, ...props }) {
|
|
8397
|
-
const styles = useStyles13();
|
|
8398
|
-
return /* @__PURE__ */ jsx35(TableHeaderCell, { ...props, className: mergeClasses18(styles.centred, className) });
|
|
8399
|
-
}
|
|
8400
|
-
function TableCentredCell({ className, ...props }) {
|
|
8401
|
-
const styles = useStyles13();
|
|
8402
|
-
return /* @__PURE__ */ jsx35(TableCell, { ...props, className: mergeClasses18(styles.centred, className) });
|
|
8403
|
-
}
|
|
8404
|
-
var stopRowSelection = { onClick: (event) => event.stopPropagation() };
|
|
8405
|
-
var ACTION_GAP = "var(--spacingHorizontalXS)";
|
|
8406
|
-
var ACTION_BUTTON_SIZE = "24px";
|
|
8407
|
-
var TABLE_ACTIONS_WIDTH = `calc(3 * ${ACTION_BUTTON_SIZE} + 2 * ${ACTION_GAP} + var(--spacingHorizontalS) + var(--fwt-panel-inset))`;
|
|
8408
|
-
function TableActions({ children }) {
|
|
8409
|
-
return /* @__PURE__ */ jsx35("div", { className: "flex items-center justify-end", style: { gap: ACTION_GAP }, ...stopRowSelection, children });
|
|
8410
|
-
}
|
|
8411
|
-
|
|
8412
|
-
// src/components/ui/table-columns.tsx
|
|
8413
|
-
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
8414
|
-
function TableColumns({ widths }) {
|
|
8415
|
-
return /* @__PURE__ */ jsx36("colgroup", { children: widths.map((width, index) => /* @__PURE__ */ jsx36("col", { style: width === null ? void 0 : { width } }, index)) });
|
|
8416
|
-
}
|
|
8417
|
-
|
|
8418
|
-
// src/components/ui/tooltip-icon-button.tsx
|
|
8419
|
-
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
8420
|
-
var { Button: Button7, Tooltip: Tooltip3, mergeClasses: mergeClasses19 } = fluentComponents;
|
|
8421
|
-
function TooltipIconButton(props) {
|
|
8422
|
-
return props.to === void 0 ? /* @__PURE__ */ jsx37(IconButton, { ...props }) : /* @__PURE__ */ jsx37(AddressedIconButton, { ...props, to: props.to });
|
|
8423
|
-
}
|
|
8424
|
-
function AddressedIconButton({ to, ...props }) {
|
|
8425
|
-
const address = useRouteAddress(to);
|
|
8426
|
-
return /* @__PURE__ */ jsx37(IconButton, { ...props, ...address });
|
|
8427
|
-
}
|
|
8428
|
-
function IconButton({ className, danger = false, disabled = false, disabledFocusable = false, href, icon, label, onClick }) {
|
|
8429
|
-
const dangerClasses = useDangerActionClasses();
|
|
8430
|
-
const shared = {
|
|
8431
|
-
appearance: "subtle",
|
|
8432
|
-
"aria-label": label,
|
|
8433
|
-
className: mergeClasses19(danger && dangerClasses.button, className),
|
|
8434
|
-
disabled,
|
|
8435
|
-
disabledFocusable,
|
|
8436
|
-
icon,
|
|
8437
|
-
onClick,
|
|
8438
|
-
size: "small"
|
|
8439
|
-
};
|
|
8440
|
-
return /* @__PURE__ */ jsx37(Tooltip3, { content: label, relationship: "label", children: href === void 0 ? /* @__PURE__ */ jsx37(Button7, { ...shared }) : /* @__PURE__ */ jsx37(Button7, { ...shared, as: "a", href }) });
|
|
8441
|
-
}
|
|
9422
|
+
// src/components/ui/tab-view.tsx
|
|
9423
|
+
import { CaretLeft12Filled, CaretRight12Filled, Dismiss12Regular } from "@fluentui/react-icons";
|
|
9424
|
+
import { useCallback as useCallback7, useEffect as useEffect7, useLayoutEffect as useLayoutEffect4, useRef as useRef9, useState as useState13 } from "react";
|
|
8442
9425
|
|
|
8443
9426
|
// src/components/ui/truncation-tooltip.tsx
|
|
8444
|
-
import { useCallback as
|
|
8445
|
-
import { jsx as
|
|
9427
|
+
import { useCallback as useCallback6, useEffect as useEffect6, useRef as useRef8, useState as useState12 } from "react";
|
|
9428
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
8446
9429
|
var { Tooltip: Tooltip4 } = fluentComponents;
|
|
8447
9430
|
var OVERFLOW_TOLERANCE_PX = 1;
|
|
8448
9431
|
var collapseWhitespace = (text) => text.replace(/\s+/gu, " ").trim();
|
|
8449
9432
|
var hidesContent = (node, content) => node.scrollWidth - node.clientWidth > OVERFLOW_TOLERANCE_PX || collapseWhitespace(node.textContent ?? "") !== collapseWhitespace(content);
|
|
8450
9433
|
var useTruncation = (content, relationship) => {
|
|
8451
|
-
const [truncated, setTruncated] =
|
|
8452
|
-
const [visible, setVisible] =
|
|
8453
|
-
const nodeRef =
|
|
8454
|
-
const contentRef =
|
|
8455
|
-
const measure2 =
|
|
9434
|
+
const [truncated, setTruncated] = useState12(false);
|
|
9435
|
+
const [visible, setVisible] = useState12(false);
|
|
9436
|
+
const nodeRef = useRef8(null);
|
|
9437
|
+
const contentRef = useRef8(content);
|
|
9438
|
+
const measure2 = useCallback6(() => {
|
|
8456
9439
|
const node = nodeRef.current;
|
|
8457
9440
|
if (!node) return;
|
|
8458
9441
|
const hides = hidesContent(node, contentRef.current);
|
|
8459
9442
|
setTruncated(hides);
|
|
8460
9443
|
if (!hides) setVisible(false);
|
|
8461
9444
|
}, []);
|
|
8462
|
-
const measureRef =
|
|
9445
|
+
const measureRef = useCallback6((node) => {
|
|
8463
9446
|
nodeRef.current = node;
|
|
8464
9447
|
if (!node) return;
|
|
8465
9448
|
measure2();
|
|
@@ -8498,37 +9481,549 @@ var useTruncation = (content, relationship) => {
|
|
|
8498
9481
|
};
|
|
8499
9482
|
function TruncationTooltip({ children, content, relationship }) {
|
|
8500
9483
|
const { measureRef, tooltipProps } = useTruncation(content, relationship);
|
|
8501
|
-
return /* @__PURE__ */
|
|
9484
|
+
return /* @__PURE__ */ jsx44(Tooltip4, { ...tooltipProps, children: children(measureRef) });
|
|
9485
|
+
}
|
|
9486
|
+
|
|
9487
|
+
// src/components/ui/tab-view.tsx
|
|
9488
|
+
import { jsx as jsx45, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
9489
|
+
var { makeStyles: makeStyles18, mergeClasses: mergeClasses25 } = fluentComponents;
|
|
9490
|
+
var useStyles18 = makeStyles18({
|
|
9491
|
+
// TabViewHeaderPadding: 8px above the tabs.
|
|
9492
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L239
|
|
9493
|
+
// The strip's bottom line is TabViewBorderBrush (CardStrokeColorDefault),
|
|
9494
|
+
// drawn here under the scroller so that the selected tab, which reaches the
|
|
9495
|
+
// strip's last pixel row, paints over it and interrupts it.
|
|
9496
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L36-L37
|
|
9497
|
+
root: {
|
|
9498
|
+
alignItems: "flex-end",
|
|
9499
|
+
display: "flex",
|
|
9500
|
+
maxWidth: "100%",
|
|
9501
|
+
minWidth: 0,
|
|
9502
|
+
paddingTop: "8px",
|
|
9503
|
+
position: "relative",
|
|
9504
|
+
"&::after": {
|
|
9505
|
+
backgroundColor: "var(--winui-card-stroke-default)",
|
|
9506
|
+
bottom: 0,
|
|
9507
|
+
content: '""',
|
|
9508
|
+
height: "1px",
|
|
9509
|
+
left: 0,
|
|
9510
|
+
pointerEvents: "none",
|
|
9511
|
+
position: "absolute",
|
|
9512
|
+
right: 0,
|
|
9513
|
+
zIndex: 0
|
|
9514
|
+
}
|
|
9515
|
+
},
|
|
9516
|
+
scroller: {
|
|
9517
|
+
alignSelf: "stretch",
|
|
9518
|
+
display: "flex",
|
|
9519
|
+
flexGrow: 0,
|
|
9520
|
+
flexShrink: 1,
|
|
9521
|
+
minWidth: 0,
|
|
9522
|
+
overflowX: "auto",
|
|
9523
|
+
overflowY: "hidden",
|
|
9524
|
+
position: "relative",
|
|
9525
|
+
scrollbarWidth: "none",
|
|
9526
|
+
zIndex: 1,
|
|
9527
|
+
"&::-webkit-scrollbar": { display: "none" },
|
|
9528
|
+
"@media (prefers-reduced-motion: no-preference)": { scrollBehavior: "smooth" }
|
|
9529
|
+
},
|
|
9530
|
+
tablist: {
|
|
9531
|
+
alignItems: "flex-end",
|
|
9532
|
+
display: "flex",
|
|
9533
|
+
flexWrap: "nowrap",
|
|
9534
|
+
minWidth: "min-content"
|
|
9535
|
+
},
|
|
9536
|
+
// TabViewItemMinHeight 32, MinWidth 100, MaxWidth 240; the item's own
|
|
9537
|
+
// corners are OverlayCornerRadius on top only (TopCornerRadiusFilterConverter).
|
|
9538
|
+
// Every item holds a 1px border (TabViewItemBorderThickness) so selecting
|
|
9539
|
+
// one, which paints it, moves nothing.
|
|
9540
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L242-L244
|
|
9541
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L296-L297
|
|
9542
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L560-L562
|
|
9543
|
+
item: {
|
|
9544
|
+
alignItems: "stretch",
|
|
9545
|
+
borderBottomWidth: 0,
|
|
9546
|
+
borderLeft: "1px solid transparent",
|
|
9547
|
+
borderRight: "1px solid transparent",
|
|
9548
|
+
borderTop: "1px solid transparent",
|
|
9549
|
+
borderTopLeftRadius: "var(--winui-overlay-corner-radius)",
|
|
9550
|
+
borderTopRightRadius: "var(--winui-overlay-corner-radius)",
|
|
9551
|
+
boxSizing: "border-box",
|
|
9552
|
+
display: "flex",
|
|
9553
|
+
flexGrow: 0,
|
|
9554
|
+
flexShrink: 1,
|
|
9555
|
+
maxWidth: "240px",
|
|
9556
|
+
minHeight: "32px",
|
|
9557
|
+
minWidth: "100px",
|
|
9558
|
+
position: "relative",
|
|
9559
|
+
// TabSeparator: 1px DividerStrokeColorDefault inset 8px top and bottom,
|
|
9560
|
+
// gone under the pointer, on the selected tab and on the tab before it.
|
|
9561
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L553
|
|
9562
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L266
|
|
9563
|
+
"&::after": {
|
|
9564
|
+
backgroundColor: "var(--winui-divider-stroke-default)",
|
|
9565
|
+
bottom: "8px",
|
|
9566
|
+
content: '""',
|
|
9567
|
+
pointerEvents: "none",
|
|
9568
|
+
position: "absolute",
|
|
9569
|
+
right: "-1px",
|
|
9570
|
+
top: "8px",
|
|
9571
|
+
width: "1px"
|
|
9572
|
+
},
|
|
9573
|
+
"&:last-child::after": { display: "none" },
|
|
9574
|
+
"&:hover::after": { opacity: 0 },
|
|
9575
|
+
"&:has(+ [data-selected])::after": { opacity: 0 },
|
|
9576
|
+
"&:hover": { backgroundColor: "var(--winui-subtle-fill-secondary)" },
|
|
9577
|
+
"&:active": { backgroundColor: "var(--winui-subtle-fill-tertiary)" },
|
|
9578
|
+
// The selected tab: TabViewItemHeaderBackgroundSelected, a stroke on top
|
|
9579
|
+
// and sides in CardStrokeColorDefault, no bottom edge. It holds its fill
|
|
9580
|
+
// through the pointer states.
|
|
9581
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L325-L345
|
|
9582
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L72-L80
|
|
9583
|
+
"&[data-selected]": {
|
|
9584
|
+
backgroundColor: "var(--winui-solid-background-fill-tertiary)",
|
|
9585
|
+
borderLeftColor: "var(--winui-card-stroke-default)",
|
|
9586
|
+
borderRightColor: "var(--winui-card-stroke-default)",
|
|
9587
|
+
borderTopColor: "var(--winui-card-stroke-default)",
|
|
9588
|
+
zIndex: 1
|
|
9589
|
+
},
|
|
9590
|
+
"&[data-selected]::after": { opacity: 0 },
|
|
9591
|
+
"&[data-disabled]": { backgroundColor: "transparent" },
|
|
9592
|
+
// WinUI's CloseButtonOverlayMode Auto: the close button shows on the
|
|
9593
|
+
// selected tab and under the pointer, or always where there is no hover.
|
|
9594
|
+
"&:hover [data-tab-close], &:focus-within [data-tab-close]": { opacity: 1, pointerEvents: "auto" },
|
|
9595
|
+
"@media (hover: none)": { "& [data-tab-close]": { opacity: 1, pointerEvents: "auto" } }
|
|
9596
|
+
},
|
|
9597
|
+
// TabViewItemHeaderPaddingWithCloseButton 8,3,4,3 / WithoutCloseButton
|
|
9598
|
+
// 8,3,8,3; the close button's 4px margin supplies the right-hand 4.
|
|
9599
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L253-L254
|
|
9600
|
+
tab: {
|
|
9601
|
+
alignItems: "center",
|
|
9602
|
+
appearance: "none",
|
|
9603
|
+
backgroundColor: "transparent",
|
|
9604
|
+
borderRadius: "inherit",
|
|
9605
|
+
border: "none",
|
|
9606
|
+
// The foreground ramp: rest and pointer-over TextFillColorSecondary,
|
|
9607
|
+
// pressed Tertiary, selected Primary.
|
|
9608
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L12-L21
|
|
9609
|
+
color: "var(--winui-text-fill-secondary)",
|
|
9610
|
+
columnGap: "10px",
|
|
9611
|
+
cursor: "pointer",
|
|
9612
|
+
display: "flex",
|
|
9613
|
+
flexBasis: 0,
|
|
9614
|
+
flexGrow: 1,
|
|
9615
|
+
flexShrink: 1,
|
|
9616
|
+
// TabViewItemHeaderFontSize 12.
|
|
9617
|
+
fontFamily: "inherit",
|
|
9618
|
+
fontSize: "12px",
|
|
9619
|
+
lineHeight: "16px",
|
|
9620
|
+
minWidth: 0,
|
|
9621
|
+
padding: "3px 8px 3px 8px",
|
|
9622
|
+
textAlign: "start",
|
|
9623
|
+
"&:active:not(:disabled)": { color: "var(--winui-text-fill-tertiary)" },
|
|
9624
|
+
'&[aria-selected="true"], &[aria-selected="true"]:active': { color: "var(--winui-text-fill-primary)" },
|
|
9625
|
+
"&:disabled": { color: "var(--winui-text-fill-disabled)", cursor: "not-allowed" },
|
|
9626
|
+
// The system focus visual, as the library's other selectors draw it.
|
|
9627
|
+
"&:focus-visible": {
|
|
9628
|
+
boxShadow: "inset 0 0 0 1px var(--winui-focus-stroke-inner)",
|
|
9629
|
+
outline: "2px solid var(--winui-focus-stroke-outer)",
|
|
9630
|
+
outlineOffset: "-2px"
|
|
9631
|
+
}
|
|
9632
|
+
},
|
|
9633
|
+
tabWithClose: { paddingRight: 0 },
|
|
9634
|
+
// The icon sits in a 16px box with a 10px gap before the label.
|
|
9635
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L246-L247
|
|
9636
|
+
icon: {
|
|
9637
|
+
alignItems: "center",
|
|
9638
|
+
display: "inline-flex",
|
|
9639
|
+
flexShrink: 0,
|
|
9640
|
+
fontSize: "16px",
|
|
9641
|
+
height: "16px",
|
|
9642
|
+
justifyContent: "center",
|
|
9643
|
+
width: "16px"
|
|
9644
|
+
},
|
|
9645
|
+
label: {
|
|
9646
|
+
flexBasis: 0,
|
|
9647
|
+
flexGrow: 1,
|
|
9648
|
+
minWidth: 0,
|
|
9649
|
+
overflow: "hidden",
|
|
9650
|
+
textOverflow: "ellipsis",
|
|
9651
|
+
whiteSpace: "nowrap"
|
|
9652
|
+
},
|
|
9653
|
+
// TabViewItemHeaderCloseButtonWidth 32, Height 24, glyph 12, margin 4,0,0,0,
|
|
9654
|
+
// ControlCornerRadius; the fills are the subtle ramp, the glyph Primary
|
|
9655
|
+
// (Secondary while pressed).
|
|
9656
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L248-L252
|
|
9657
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView.xaml#L172-L187
|
|
9658
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L47-L60
|
|
9659
|
+
close: {
|
|
9660
|
+
alignItems: "center",
|
|
9661
|
+
alignSelf: "center",
|
|
9662
|
+
appearance: "none",
|
|
9663
|
+
backgroundColor: "transparent",
|
|
9664
|
+
borderRadius: "var(--winui-control-corner-radius)",
|
|
9665
|
+
border: "none",
|
|
9666
|
+
color: "var(--winui-text-fill-primary)",
|
|
9667
|
+
cursor: "pointer",
|
|
9668
|
+
display: "inline-flex",
|
|
9669
|
+
flexShrink: 0,
|
|
9670
|
+
fontSize: "12px",
|
|
9671
|
+
height: "24px",
|
|
9672
|
+
justifyContent: "center",
|
|
9673
|
+
margin: "0 4px",
|
|
9674
|
+
opacity: 0,
|
|
9675
|
+
padding: 0,
|
|
9676
|
+
pointerEvents: "none",
|
|
9677
|
+
width: "32px",
|
|
9678
|
+
"&:hover": { backgroundColor: "var(--winui-subtle-fill-secondary)" },
|
|
9679
|
+
"&:active": {
|
|
9680
|
+
backgroundColor: "var(--winui-subtle-fill-tertiary)",
|
|
9681
|
+
color: "var(--winui-text-fill-secondary)"
|
|
9682
|
+
},
|
|
9683
|
+
"&:focus-visible": {
|
|
9684
|
+
boxShadow: "inset 0 0 0 1px var(--winui-focus-stroke-inner)",
|
|
9685
|
+
outline: "2px solid var(--winui-focus-stroke-outer)",
|
|
9686
|
+
outlineOffset: "0",
|
|
9687
|
+
opacity: 1,
|
|
9688
|
+
pointerEvents: "auto"
|
|
9689
|
+
},
|
|
9690
|
+
"&:disabled": { color: "var(--winui-text-fill-disabled)", cursor: "not-allowed" }
|
|
9691
|
+
},
|
|
9692
|
+
closeShown: { opacity: 1, pointerEvents: "auto" },
|
|
9693
|
+
// Scroll buttons: 32x24, glyph 8, ControlCornerRadius, the subtle ramp, with
|
|
9694
|
+
// 8,0,3,3 / 3,0,8,3 container padding.
|
|
9695
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L255-L260
|
|
9696
|
+
// https://github.com/microsoft/microsoft-ui-xaml/blob/188f602b27cdb47572b28c380e9c087b02e1ccee/controls/dev/TabView/TabView_themeresources.xaml#L34-L41
|
|
9697
|
+
scrollButtonBox: {
|
|
9698
|
+
alignSelf: "flex-end",
|
|
9699
|
+
flexShrink: 0,
|
|
9700
|
+
position: "relative",
|
|
9701
|
+
zIndex: 1
|
|
9702
|
+
},
|
|
9703
|
+
scrollBoxLeft: { padding: "0 3px 3px 8px" },
|
|
9704
|
+
scrollBoxRight: { padding: "0 8px 3px 3px" },
|
|
9705
|
+
scrollButton: {
|
|
9706
|
+
alignItems: "center",
|
|
9707
|
+
appearance: "none",
|
|
9708
|
+
backgroundColor: "transparent",
|
|
9709
|
+
borderRadius: "var(--winui-control-corner-radius)",
|
|
9710
|
+
border: "none",
|
|
9711
|
+
color: "var(--winui-text-fill-secondary)",
|
|
9712
|
+
cursor: "pointer",
|
|
9713
|
+
display: "inline-flex",
|
|
9714
|
+
fontSize: "8px",
|
|
9715
|
+
height: "24px",
|
|
9716
|
+
justifyContent: "center",
|
|
9717
|
+
padding: "3px 7px",
|
|
9718
|
+
width: "32px",
|
|
9719
|
+
"&:hover:not(:disabled)": { backgroundColor: "var(--winui-subtle-fill-secondary)" },
|
|
9720
|
+
"&:active:not(:disabled)": { backgroundColor: "var(--winui-subtle-fill-tertiary)" },
|
|
9721
|
+
"&:disabled": { color: "var(--winui-text-fill-disabled)", cursor: "default" },
|
|
9722
|
+
"&:focus-visible": {
|
|
9723
|
+
boxShadow: "inset 0 0 0 1px var(--winui-focus-stroke-inner)",
|
|
9724
|
+
outline: "2px solid var(--winui-focus-stroke-outer)",
|
|
9725
|
+
outlineOffset: "0"
|
|
9726
|
+
}
|
|
9727
|
+
},
|
|
9728
|
+
// TabStripFooter: beside the tabs, after them, on the strip's baseline.
|
|
9729
|
+
footer: {
|
|
9730
|
+
alignItems: "center",
|
|
9731
|
+
alignSelf: "stretch",
|
|
9732
|
+
display: "flex",
|
|
9733
|
+
flexShrink: 0,
|
|
9734
|
+
minHeight: "32px",
|
|
9735
|
+
paddingBottom: "3px",
|
|
9736
|
+
paddingInline: "4px",
|
|
9737
|
+
position: "relative",
|
|
9738
|
+
zIndex: 1
|
|
9739
|
+
}
|
|
9740
|
+
});
|
|
9741
|
+
var SCROLL_STEP_PX = 200;
|
|
9742
|
+
function TabView({ ariaLabel, className, footer, items, onClose, onSelect, selectedValue }) {
|
|
9743
|
+
const styles = useStyles18();
|
|
9744
|
+
const { t: t2 } = useTranslation();
|
|
9745
|
+
const scrollerRef = useRef9(null);
|
|
9746
|
+
const [overflow, setOverflow] = useState13({ backward: false, forward: false, scrollable: false });
|
|
9747
|
+
const enabledValues = items.filter((item) => item.disabled !== true).map((item) => item.value);
|
|
9748
|
+
const tabStop = selectedValue !== null && enabledValues.includes(selectedValue) ? selectedValue : enabledValues[0];
|
|
9749
|
+
const measure2 = useCallback7(() => {
|
|
9750
|
+
const scroller = scrollerRef.current;
|
|
9751
|
+
if (!scroller) return;
|
|
9752
|
+
const scrollable = scroller.scrollWidth - scroller.clientWidth > 1;
|
|
9753
|
+
const backward = scrollable && scroller.scrollLeft > 0;
|
|
9754
|
+
const forward = scrollable && scroller.scrollLeft + scroller.clientWidth < scroller.scrollWidth - 1;
|
|
9755
|
+
setOverflow((previous) => previous.scrollable === scrollable && previous.backward === backward && previous.forward === forward ? previous : { backward, forward, scrollable });
|
|
9756
|
+
}, []);
|
|
9757
|
+
useLayoutEffect4(() => {
|
|
9758
|
+
measure2();
|
|
9759
|
+
const scroller = scrollerRef.current;
|
|
9760
|
+
if (!scroller || typeof ResizeObserver === "undefined") return;
|
|
9761
|
+
const observer = new ResizeObserver(measure2);
|
|
9762
|
+
observer.observe(scroller);
|
|
9763
|
+
const list = scroller.firstElementChild;
|
|
9764
|
+
if (list) observer.observe(list);
|
|
9765
|
+
return () => observer.disconnect();
|
|
9766
|
+
}, [measure2, items]);
|
|
9767
|
+
useEffect7(() => {
|
|
9768
|
+
const selected = scrollerRef.current?.querySelector('[role="tab"][aria-selected="true"]');
|
|
9769
|
+
selected?.scrollIntoView?.({ block: "nearest", inline: "nearest" });
|
|
9770
|
+
}, [selectedValue]);
|
|
9771
|
+
const scrollBy = (direction) => scrollerRef.current?.scrollBy?.({ left: direction * SCROLL_STEP_PX });
|
|
9772
|
+
const closeIfClosable = (value) => {
|
|
9773
|
+
const item = items.find((candidate) => candidate.value === value);
|
|
9774
|
+
if (item?.closable !== true || item.disabled === true) return false;
|
|
9775
|
+
onClose?.(value);
|
|
9776
|
+
return true;
|
|
9777
|
+
};
|
|
9778
|
+
const handleKeyDown = (event) => {
|
|
9779
|
+
const target = event.target;
|
|
9780
|
+
const owner = target.closest("[data-tab-value]");
|
|
9781
|
+
if (!owner) return;
|
|
9782
|
+
const value = owner.dataset.tabValue;
|
|
9783
|
+
if (event.key === "F4" && event.ctrlKey || event.key === "Delete") {
|
|
9784
|
+
if (closeIfClosable(value)) event.preventDefault();
|
|
9785
|
+
return;
|
|
9786
|
+
}
|
|
9787
|
+
if (!target.matches('[role="tab"]') || enabledValues.length === 0) return;
|
|
9788
|
+
const current = enabledValues.indexOf(value);
|
|
9789
|
+
let next;
|
|
9790
|
+
switch (event.key) {
|
|
9791
|
+
case "ArrowRight":
|
|
9792
|
+
next = enabledValues[(current + 1) % enabledValues.length];
|
|
9793
|
+
break;
|
|
9794
|
+
case "ArrowLeft":
|
|
9795
|
+
next = enabledValues[(current - 1 + enabledValues.length) % enabledValues.length];
|
|
9796
|
+
break;
|
|
9797
|
+
case "Home":
|
|
9798
|
+
next = enabledValues[0];
|
|
9799
|
+
break;
|
|
9800
|
+
case "End":
|
|
9801
|
+
next = enabledValues[enabledValues.length - 1];
|
|
9802
|
+
break;
|
|
9803
|
+
default:
|
|
9804
|
+
return;
|
|
9805
|
+
}
|
|
9806
|
+
event.preventDefault();
|
|
9807
|
+
const nextTab = event.currentTarget.querySelector(`[data-tab-value="${CSS.escape(next)}"] [role="tab"]`);
|
|
9808
|
+
nextTab?.focus();
|
|
9809
|
+
if (next !== selectedValue) onSelect(next);
|
|
9810
|
+
};
|
|
9811
|
+
return /* @__PURE__ */ jsxs24("div", { className: mergeClasses25(styles.root, className), children: [
|
|
9812
|
+
overflow.scrollable ? /* @__PURE__ */ jsx45("div", { className: mergeClasses25(styles.scrollButtonBox, styles.scrollBoxLeft), children: /* @__PURE__ */ jsx45(
|
|
9813
|
+
"button",
|
|
9814
|
+
{
|
|
9815
|
+
"aria-label": t2("tabView.scrollBackward"),
|
|
9816
|
+
className: styles.scrollButton,
|
|
9817
|
+
disabled: !overflow.backward,
|
|
9818
|
+
onClick: () => scrollBy(-1),
|
|
9819
|
+
tabIndex: -1,
|
|
9820
|
+
type: "button",
|
|
9821
|
+
children: /* @__PURE__ */ jsx45(CaretLeft12Filled, { fontSize: 8 })
|
|
9822
|
+
}
|
|
9823
|
+
) }) : null,
|
|
9824
|
+
/* @__PURE__ */ jsx45("div", { className: styles.scroller, onScroll: measure2, ref: scrollerRef, children: /* @__PURE__ */ jsx45("div", { "aria-label": ariaLabel, "aria-orientation": "horizontal", className: styles.tablist, onKeyDown: handleKeyDown, role: "tablist", children: items.map((item) => {
|
|
9825
|
+
const selected = item.value === selectedValue;
|
|
9826
|
+
const disabled = item.disabled === true;
|
|
9827
|
+
const closable = item.closable === true;
|
|
9828
|
+
const closeLabel = item.closeLabel ?? t2("tabView.close");
|
|
9829
|
+
return /* @__PURE__ */ jsxs24(
|
|
9830
|
+
"div",
|
|
9831
|
+
{
|
|
9832
|
+
className: styles.item,
|
|
9833
|
+
"data-disabled": disabled ? "" : void 0,
|
|
9834
|
+
"data-selected": selected ? "" : void 0,
|
|
9835
|
+
"data-tab-value": item.value,
|
|
9836
|
+
onAuxClick: (event) => {
|
|
9837
|
+
if (event.button !== 1 || !closable) return;
|
|
9838
|
+
event.preventDefault();
|
|
9839
|
+
closeIfClosable(item.value);
|
|
9840
|
+
},
|
|
9841
|
+
onMouseDown: (event) => {
|
|
9842
|
+
if (event.button === 1) event.preventDefault();
|
|
9843
|
+
},
|
|
9844
|
+
role: "presentation",
|
|
9845
|
+
children: [
|
|
9846
|
+
/* @__PURE__ */ jsxs24(
|
|
9847
|
+
"button",
|
|
9848
|
+
{
|
|
9849
|
+
"aria-selected": selected,
|
|
9850
|
+
className: mergeClasses25(styles.tab, closable && styles.tabWithClose),
|
|
9851
|
+
disabled,
|
|
9852
|
+
onClick: () => {
|
|
9853
|
+
if (!selected) onSelect(item.value);
|
|
9854
|
+
},
|
|
9855
|
+
role: "tab",
|
|
9856
|
+
tabIndex: item.value === tabStop ? 0 : -1,
|
|
9857
|
+
type: "button",
|
|
9858
|
+
children: [
|
|
9859
|
+
item.icon === void 0 ? null : /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: styles.icon, children: item.icon }),
|
|
9860
|
+
typeof item.header === "string" ? /* @__PURE__ */ jsx45(TruncationTooltip, { content: item.header, relationship: "description", children: (measureRef) => /* @__PURE__ */ jsx45("span", { className: styles.label, ref: measureRef, children: item.header }) }) : /* @__PURE__ */ jsx45("span", { className: styles.label, children: item.header })
|
|
9861
|
+
]
|
|
9862
|
+
}
|
|
9863
|
+
),
|
|
9864
|
+
closable ? /* @__PURE__ */ jsx45(
|
|
9865
|
+
"button",
|
|
9866
|
+
{
|
|
9867
|
+
"aria-label": closeLabel,
|
|
9868
|
+
className: mergeClasses25(styles.close, selected && styles.closeShown),
|
|
9869
|
+
"data-tab-close": "",
|
|
9870
|
+
disabled,
|
|
9871
|
+
onClick: () => closeIfClosable(item.value),
|
|
9872
|
+
tabIndex: -1,
|
|
9873
|
+
type: "button",
|
|
9874
|
+
children: /* @__PURE__ */ jsx45(Dismiss12Regular, { fontSize: 12 })
|
|
9875
|
+
}
|
|
9876
|
+
) : null
|
|
9877
|
+
]
|
|
9878
|
+
},
|
|
9879
|
+
item.value
|
|
9880
|
+
);
|
|
9881
|
+
}) }) }),
|
|
9882
|
+
overflow.scrollable ? /* @__PURE__ */ jsx45("div", { className: mergeClasses25(styles.scrollButtonBox, styles.scrollBoxRight), children: /* @__PURE__ */ jsx45(
|
|
9883
|
+
"button",
|
|
9884
|
+
{
|
|
9885
|
+
"aria-label": t2("tabView.scrollForward"),
|
|
9886
|
+
className: styles.scrollButton,
|
|
9887
|
+
disabled: !overflow.forward,
|
|
9888
|
+
onClick: () => scrollBy(1),
|
|
9889
|
+
tabIndex: -1,
|
|
9890
|
+
type: "button",
|
|
9891
|
+
children: /* @__PURE__ */ jsx45(CaretRight12Filled, { fontSize: 8 })
|
|
9892
|
+
}
|
|
9893
|
+
) }) : null,
|
|
9894
|
+
footer === void 0 ? null : /* @__PURE__ */ jsx45("div", { className: styles.footer, children: footer })
|
|
9895
|
+
] });
|
|
8502
9896
|
}
|
|
8503
9897
|
|
|
9898
|
+
// src/components/ui/tooltip-icon-button.tsx
|
|
9899
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
9900
|
+
var { Button: Button11, Tooltip: Tooltip5, mergeClasses: mergeClasses26 } = fluentComponents;
|
|
9901
|
+
function TooltipIconButton(props) {
|
|
9902
|
+
return props.to === void 0 ? /* @__PURE__ */ jsx46(IconButton, { ...props }) : /* @__PURE__ */ jsx46(AddressedIconButton, { ...props, to: props.to });
|
|
9903
|
+
}
|
|
9904
|
+
function AddressedIconButton({ to, ...props }) {
|
|
9905
|
+
const address = useRouteAddress(to);
|
|
9906
|
+
return /* @__PURE__ */ jsx46(IconButton, { ...props, ...address });
|
|
9907
|
+
}
|
|
9908
|
+
function IconButton({ className, danger = false, disabled = false, disabledFocusable = false, href, icon, label, onClick, ...trigger }) {
|
|
9909
|
+
const dangerClasses = useDangerActionClasses();
|
|
9910
|
+
const shared = {
|
|
9911
|
+
...trigger,
|
|
9912
|
+
appearance: "subtle",
|
|
9913
|
+
"aria-label": label,
|
|
9914
|
+
className: mergeClasses26(danger && dangerClasses.button, className),
|
|
9915
|
+
disabled,
|
|
9916
|
+
disabledFocusable,
|
|
9917
|
+
icon,
|
|
9918
|
+
onClick,
|
|
9919
|
+
size: "small"
|
|
9920
|
+
};
|
|
9921
|
+
return /* @__PURE__ */ jsx46(Tooltip5, { content: label, relationship: "label", children: href === void 0 ? /* @__PURE__ */ jsx46(Button11, { ...shared }) : /* @__PURE__ */ jsx46(Button11, { ...shared, as: "a", href }) });
|
|
9922
|
+
}
|
|
9923
|
+
|
|
9924
|
+
// src/components/ui/use-confirm.tsx
|
|
9925
|
+
import { createContext as createContext4, useCallback as useCallback8, useContext as useContext4, useRef as useRef10, useState as useState14 } from "react";
|
|
9926
|
+
import { jsx as jsx47, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
9927
|
+
var ConfirmContext = createContext4(null);
|
|
9928
|
+
var errorText2 = (error) => error instanceof Error ? error.message : String(error);
|
|
9929
|
+
function ConfirmDialogProvider({ children }) {
|
|
9930
|
+
const nextId = useRef10(0);
|
|
9931
|
+
const [queue, setQueue] = useState14([]);
|
|
9932
|
+
const [open, setOpen] = useState14(true);
|
|
9933
|
+
const [busy, setBusy] = useState14(false);
|
|
9934
|
+
const [error, setError] = useState14(null);
|
|
9935
|
+
const head = queue[0];
|
|
9936
|
+
const confirm = useCallback8((options) => new Promise((resolve) => {
|
|
9937
|
+
setQueue((current) => [...current, { id: nextId.current++, options, resolve }]);
|
|
9938
|
+
}), []);
|
|
9939
|
+
const finish = (confirmed) => {
|
|
9940
|
+
if (!open) return;
|
|
9941
|
+
head?.resolve(confirmed);
|
|
9942
|
+
setOpen(false);
|
|
9943
|
+
};
|
|
9944
|
+
const accept = async () => {
|
|
9945
|
+
if (!head) return;
|
|
9946
|
+
const { onConfirm } = head.options;
|
|
9947
|
+
if (!onConfirm) {
|
|
9948
|
+
finish(true);
|
|
9949
|
+
return;
|
|
9950
|
+
}
|
|
9951
|
+
setError(null);
|
|
9952
|
+
setBusy(true);
|
|
9953
|
+
try {
|
|
9954
|
+
await onConfirm();
|
|
9955
|
+
setBusy(false);
|
|
9956
|
+
finish(true);
|
|
9957
|
+
} catch (caught) {
|
|
9958
|
+
setBusy(false);
|
|
9959
|
+
setError(errorText2(caught));
|
|
9960
|
+
}
|
|
9961
|
+
};
|
|
9962
|
+
const advance = () => {
|
|
9963
|
+
setQueue((current) => current.slice(1));
|
|
9964
|
+
setError(null);
|
|
9965
|
+
setOpen(true);
|
|
9966
|
+
};
|
|
9967
|
+
return /* @__PURE__ */ jsxs25(ConfirmContext.Provider, { value: confirm, children: [
|
|
9968
|
+
children,
|
|
9969
|
+
head && /* @__PURE__ */ jsx47(
|
|
9970
|
+
ConfirmDialog,
|
|
9971
|
+
{
|
|
9972
|
+
actionIntent: head.options.intent,
|
|
9973
|
+
actionLabel: head.options.actionLabel,
|
|
9974
|
+
busy,
|
|
9975
|
+
cancelLabel: head.options.cancelLabel,
|
|
9976
|
+
error,
|
|
9977
|
+
message: head.options.message,
|
|
9978
|
+
onConfirm: () => {
|
|
9979
|
+
void accept();
|
|
9980
|
+
},
|
|
9981
|
+
onDismissError: () => setError(null),
|
|
9982
|
+
onExited: advance,
|
|
9983
|
+
onOpenChange: (next) => {
|
|
9984
|
+
if (!next) finish(false);
|
|
9985
|
+
},
|
|
9986
|
+
open,
|
|
9987
|
+
title: head.options.title
|
|
9988
|
+
},
|
|
9989
|
+
head.id
|
|
9990
|
+
)
|
|
9991
|
+
] });
|
|
9992
|
+
}
|
|
9993
|
+
var useConfirm = () => {
|
|
9994
|
+
const value = useContext4(ConfirmContext);
|
|
9995
|
+
if (!value) throw new Error("useConfirm requires a ConfirmDialogProvider above it");
|
|
9996
|
+
return value;
|
|
9997
|
+
};
|
|
9998
|
+
|
|
8504
9999
|
// src/components/ui/use-dialog-invocation.ts
|
|
8505
|
-
import { useCallback as
|
|
10000
|
+
import { useCallback as useCallback9, useMemo as useMemo6, useRef as useRef11, useState as useState15 } from "react";
|
|
8506
10001
|
var useDialogInvocation = () => {
|
|
8507
|
-
const nextKey =
|
|
8508
|
-
const [invocation, setInvocation] =
|
|
8509
|
-
const [isOpen, setIsOpen] =
|
|
8510
|
-
const open =
|
|
10002
|
+
const nextKey = useRef11(0);
|
|
10003
|
+
const [invocation, setInvocation] = useState15(null);
|
|
10004
|
+
const [isOpen, setIsOpen] = useState15(false);
|
|
10005
|
+
const open = useCallback9((value) => {
|
|
8511
10006
|
setInvocation({ key: nextKey.current++, value });
|
|
8512
10007
|
setIsOpen(true);
|
|
8513
10008
|
}, []);
|
|
8514
|
-
const close =
|
|
8515
|
-
return
|
|
10009
|
+
const close = useCallback9(() => setIsOpen(false), []);
|
|
10010
|
+
return useMemo6(() => ({ close, invocation, isOpen, open }), [close, invocation, isOpen, open]);
|
|
8516
10011
|
};
|
|
8517
10012
|
|
|
8518
10013
|
// src/components/ui/use-discard-guard.tsx
|
|
8519
|
-
import { useCallback as
|
|
8520
|
-
import { jsx as
|
|
10014
|
+
import { useCallback as useCallback10, useRef as useRef12, useState as useState16 } from "react";
|
|
10015
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
8521
10016
|
var useDiscardGuard = ({ onClose, values }) => {
|
|
8522
10017
|
const { t: t2 } = useTranslation();
|
|
8523
10018
|
const prompt = useDialogInvocation();
|
|
8524
|
-
const discarding =
|
|
8525
|
-
const [openedWith] =
|
|
10019
|
+
const discarding = useRef12(false);
|
|
10020
|
+
const [openedWith] = useState16(() => JSON.stringify(values));
|
|
8526
10021
|
const dirty = JSON.stringify(values) !== openedWith;
|
|
8527
|
-
const requestClose =
|
|
10022
|
+
const requestClose = useCallback10(() => {
|
|
8528
10023
|
if (dirty) prompt.open();
|
|
8529
10024
|
else onClose();
|
|
8530
10025
|
}, [dirty, onClose, prompt]);
|
|
8531
|
-
const discardConfirmation = prompt.invocation && /* @__PURE__ */
|
|
10026
|
+
const discardConfirmation = prompt.invocation && /* @__PURE__ */ jsx48(
|
|
8532
10027
|
ConfirmDialog,
|
|
8533
10028
|
{
|
|
8534
10029
|
actionLabel: t2("common.discard.discard"),
|
|
@@ -8556,13 +10051,13 @@ var useDiscardGuard = ({ onClose, values }) => {
|
|
|
8556
10051
|
|
|
8557
10052
|
// src/shell/app-shell.tsx
|
|
8558
10053
|
import { NavigationRegular } from "@fluentui/react-icons";
|
|
8559
|
-
import { useLayoutEffect as
|
|
10054
|
+
import { useLayoutEffect as useLayoutEffect5, useRef as useRef13, useState as useState18 } from "react";
|
|
8560
10055
|
|
|
8561
10056
|
// src/shell/page-frames.tsx
|
|
8562
|
-
import { useState as
|
|
10057
|
+
import { useState as useState17 } from "react";
|
|
8563
10058
|
var usePageFrames = (page, pageKey) => {
|
|
8564
|
-
const [current, setCurrent] =
|
|
8565
|
-
const [leaving, setLeaving] =
|
|
10059
|
+
const [current, setCurrent] = useState17({ id: 0, key: pageKey, node: page });
|
|
10060
|
+
const [leaving, setLeaving] = useState17(null);
|
|
8566
10061
|
if (current.key !== pageKey) {
|
|
8567
10062
|
setLeaving({ id: current.id, node: current.node });
|
|
8568
10063
|
setCurrent({ id: current.id + 1, key: pageKey, node: page });
|
|
@@ -8578,14 +10073,14 @@ var usePageFrames = (page, pageKey) => {
|
|
|
8578
10073
|
var pageFrameClassName = (frame) => frame.leaving ? "fwt-page-leaving" : frame.id > 0 ? "fwt-page-entering" : "";
|
|
8579
10074
|
|
|
8580
10075
|
// src/shell/app-shell.tsx
|
|
8581
|
-
import { jsx as
|
|
8582
|
-
var { Button:
|
|
10076
|
+
import { jsx as jsx49, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
10077
|
+
var { Button: Button12, DrawerBody, OverlayDrawer } = fluentComponents;
|
|
8583
10078
|
var MAIN_ID = "fwt-main";
|
|
8584
10079
|
function AppShell({ children, labels, narrowHeader, narrowHeaderActions, navigation, pageKey, workspace = false }) {
|
|
8585
|
-
const [navigationOpen, setNavigationOpen] =
|
|
8586
|
-
const firstFrameRef =
|
|
8587
|
-
const entranceStarted =
|
|
8588
|
-
|
|
10080
|
+
const [navigationOpen, setNavigationOpen] = useState18(false);
|
|
10081
|
+
const firstFrameRef = useRef13(null);
|
|
10082
|
+
const entranceStarted = useRef13(false);
|
|
10083
|
+
useLayoutEffect5(() => {
|
|
8589
10084
|
if (entranceStarted.current) return;
|
|
8590
10085
|
if (prefersReducedMotion()) return;
|
|
8591
10086
|
const frame = firstFrameRef.current;
|
|
@@ -8597,19 +10092,19 @@ function AppShell({ children, labels, narrowHeader, narrowHeaderActions, navigat
|
|
|
8597
10092
|
{ duration: PAGE_ENTER_MS, easing: PAGE_ENTER_EASING, fill: "forwards" }
|
|
8598
10093
|
);
|
|
8599
10094
|
}, []);
|
|
8600
|
-
const page = /* @__PURE__ */
|
|
10095
|
+
const page = /* @__PURE__ */ jsx49(
|
|
8601
10096
|
ScrollArea,
|
|
8602
10097
|
{
|
|
8603
10098
|
axes: "vertical",
|
|
8604
10099
|
className: "h-full min-h-0",
|
|
8605
10100
|
contentClassName: workspace ? "h-full" : "min-h-full",
|
|
8606
10101
|
noTabIndex: true,
|
|
8607
|
-
children: /* @__PURE__ */
|
|
10102
|
+
children: /* @__PURE__ */ jsx49("div", { className: `${workspace ? SCROLLPORT_FILL_CLASS : ""} p-[22px_var(--fwt-page-inset)_var(--fwt-page-inset)] max-[680px]:p-4`, children })
|
|
8608
10103
|
}
|
|
8609
10104
|
);
|
|
8610
10105
|
const frames = usePageFrames(page, pageKey);
|
|
8611
|
-
return /* @__PURE__ */
|
|
8612
|
-
/* @__PURE__ */
|
|
10106
|
+
return /* @__PURE__ */ jsxs26(OutcomeToastProvider, { children: [
|
|
10107
|
+
/* @__PURE__ */ jsx49(
|
|
8613
10108
|
"a",
|
|
8614
10109
|
{
|
|
8615
10110
|
className: "fixed left-3 top-3 z-[100000] -translate-y-20 rounded-md bg-fui-bg1 px-3 py-2 text-fui-fg1 shadow-lg focus:translate-y-0",
|
|
@@ -8617,22 +10112,22 @@ function AppShell({ children, labels, narrowHeader, narrowHeaderActions, navigat
|
|
|
8617
10112
|
children: labels.skipToContent
|
|
8618
10113
|
}
|
|
8619
10114
|
),
|
|
8620
|
-
/* @__PURE__ */
|
|
8621
|
-
/* @__PURE__ */
|
|
8622
|
-
/* @__PURE__ */
|
|
8623
|
-
/* @__PURE__ */
|
|
8624
|
-
|
|
10115
|
+
/* @__PURE__ */ jsxs26("div", { className: "grid grid-cols-[clamp(240px,18vw,290px)_minmax(0,1fr)] grid-rows-[minmax(0,1fr)] h-[100dvh] min-h-0 max-[900px]:grid-cols-1 max-[900px]:grid-rows-[58px_minmax(0,1fr)]", children: [
|
|
10116
|
+
/* @__PURE__ */ jsx49("div", { className: "min-h-0 max-[900px]:hidden", children: navigation({}) }),
|
|
10117
|
+
/* @__PURE__ */ jsxs26("header", { className: "hidden max-[900px]:flex items-center gap-3 border-b border-b-solid border-fui-divider px-4", children: [
|
|
10118
|
+
/* @__PURE__ */ jsx49(
|
|
10119
|
+
Button12,
|
|
8625
10120
|
{
|
|
8626
10121
|
appearance: "subtle",
|
|
8627
10122
|
"aria-label": labels.openNavigation,
|
|
8628
|
-
icon: /* @__PURE__ */
|
|
10123
|
+
icon: /* @__PURE__ */ jsx49(NavigationRegular, {}),
|
|
8629
10124
|
onClick: () => setNavigationOpen(true)
|
|
8630
10125
|
}
|
|
8631
10126
|
),
|
|
8632
10127
|
narrowHeader,
|
|
8633
|
-
narrowHeaderActions !== void 0 && /* @__PURE__ */
|
|
10128
|
+
narrowHeaderActions !== void 0 && /* @__PURE__ */ jsx49("div", { className: "ml-auto flex items-center gap-2", children: narrowHeaderActions })
|
|
8634
10129
|
] }),
|
|
8635
|
-
/* @__PURE__ */
|
|
10130
|
+
/* @__PURE__ */ jsx49("div", { className: "grid grid-cols-[minmax(0,1fr)] grid-rows-[minmax(0,1fr)] min-h-0", children: frames.map((frame) => /* @__PURE__ */ jsx49(
|
|
8636
10131
|
"div",
|
|
8637
10132
|
{
|
|
8638
10133
|
"aria-hidden": frame.leaving || void 0,
|
|
@@ -8648,7 +10143,7 @@ function AppShell({ children, labels, narrowHeader, narrowHeaderActions, navigat
|
|
|
8648
10143
|
frame.id
|
|
8649
10144
|
)) })
|
|
8650
10145
|
] }),
|
|
8651
|
-
/* @__PURE__ */
|
|
10146
|
+
/* @__PURE__ */ jsx49(
|
|
8652
10147
|
OverlayDrawer,
|
|
8653
10148
|
{
|
|
8654
10149
|
"aria-label": labels.navigation,
|
|
@@ -8656,33 +10151,33 @@ function AppShell({ children, labels, narrowHeader, narrowHeaderActions, navigat
|
|
|
8656
10151
|
onOpenChange: (_2, data) => setNavigationOpen(data.open),
|
|
8657
10152
|
open: navigationOpen,
|
|
8658
10153
|
position: "start",
|
|
8659
|
-
children: /* @__PURE__ */
|
|
10154
|
+
children: /* @__PURE__ */ jsx49(DrawerBody, { className: "!p-0", children: navigation({ onNavigate: () => setNavigationOpen(false) }) })
|
|
8660
10155
|
}
|
|
8661
10156
|
)
|
|
8662
10157
|
] });
|
|
8663
10158
|
}
|
|
8664
10159
|
|
|
8665
10160
|
// src/shell/gradient-background.tsx
|
|
8666
|
-
import { jsx as
|
|
10161
|
+
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
8667
10162
|
function GradientBackground({ children }) {
|
|
8668
|
-
return /* @__PURE__ */
|
|
10163
|
+
return /* @__PURE__ */ jsx50("div", { className: "fwt-gradient-background", children });
|
|
8669
10164
|
}
|
|
8670
10165
|
|
|
8671
10166
|
// src/shell/navigation-pane.tsx
|
|
8672
|
-
import { DismissRegular as
|
|
8673
|
-
import { useRef as
|
|
8674
|
-
import { jsx as
|
|
10167
|
+
import { DismissRegular as DismissRegular4 } from "@fluentui/react-icons";
|
|
10168
|
+
import { useRef as useRef14 } from "react";
|
|
10169
|
+
import { jsx as jsx51, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
8675
10170
|
var {
|
|
8676
|
-
Button:
|
|
10171
|
+
Button: Button13,
|
|
8677
10172
|
NavDrawer,
|
|
8678
10173
|
NavDrawerBody,
|
|
8679
10174
|
NavDrawerFooter,
|
|
8680
10175
|
NavDrawerHeader,
|
|
8681
10176
|
NavItem,
|
|
8682
10177
|
NavSectionHeader,
|
|
8683
|
-
makeStyles:
|
|
10178
|
+
makeStyles: makeStyles19
|
|
8684
10179
|
} = fluentComponents;
|
|
8685
|
-
var
|
|
10180
|
+
var useStyles19 = makeStyles19({
|
|
8686
10181
|
// 36px is a floor rather than a fixed height, so a two-line label lengthens
|
|
8687
10182
|
// the row instead of being cut. The left-pane template's 40px icon column
|
|
8688
10183
|
// plus the presenter's 4 puts the label at 44; Fluent's icon slot is 20px
|
|
@@ -8704,14 +10199,14 @@ var useStyles14 = makeStyles14({
|
|
|
8704
10199
|
});
|
|
8705
10200
|
var NAV_INDICATOR_INSET = 0;
|
|
8706
10201
|
function PaneLink({ item, onNavigate, pending, href }) {
|
|
8707
|
-
const styles =
|
|
10202
|
+
const styles = useStyles19();
|
|
8708
10203
|
const address = useRouteAddress(href);
|
|
8709
10204
|
const handleClick = (event) => {
|
|
8710
10205
|
const followsInThisView = event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey;
|
|
8711
10206
|
address.onClick(event);
|
|
8712
10207
|
if (followsInThisView) onNavigate?.();
|
|
8713
10208
|
};
|
|
8714
|
-
return /* @__PURE__ */
|
|
10209
|
+
return /* @__PURE__ */ jsx51(
|
|
8715
10210
|
NavItem,
|
|
8716
10211
|
{
|
|
8717
10212
|
as: "a",
|
|
@@ -8727,11 +10222,11 @@ function PaneLink({ item, onNavigate, pending, href }) {
|
|
|
8727
10222
|
);
|
|
8728
10223
|
}
|
|
8729
10224
|
function PaneItem({ item, onNavigate, pendingValue }) {
|
|
8730
|
-
const styles =
|
|
10225
|
+
const styles = useStyles19();
|
|
8731
10226
|
if (item.href !== void 0) {
|
|
8732
|
-
return /* @__PURE__ */
|
|
10227
|
+
return /* @__PURE__ */ jsx51(PaneLink, { href: item.href, item, onNavigate, pending: pendingValue === item.value });
|
|
8733
10228
|
}
|
|
8734
|
-
return /* @__PURE__ */
|
|
10229
|
+
return /* @__PURE__ */ jsx51(NavItem, { className: styles.item, "data-nav-value": item.value, icon: item.icon, value: item.value, children: item.label });
|
|
8735
10230
|
}
|
|
8736
10231
|
function NavigationPane({
|
|
8737
10232
|
closeLabel = "Close navigation",
|
|
@@ -8744,10 +10239,10 @@ function NavigationPane({
|
|
|
8744
10239
|
pendingValue,
|
|
8745
10240
|
selectedValue
|
|
8746
10241
|
}) {
|
|
8747
|
-
const bodyRef =
|
|
8748
|
-
const footerRef =
|
|
10242
|
+
const bodyRef = useRef14(null);
|
|
10243
|
+
const footerRef = useRef14(null);
|
|
8749
10244
|
const allItems = [...groups.flatMap((group) => group.items), ...footerItems];
|
|
8750
|
-
return /* @__PURE__ */
|
|
10245
|
+
return /* @__PURE__ */ jsxs27(
|
|
8751
10246
|
NavDrawer,
|
|
8752
10247
|
{
|
|
8753
10248
|
"aria-label": label,
|
|
@@ -8762,21 +10257,21 @@ function NavigationPane({
|
|
|
8762
10257
|
surfaceMotion: null,
|
|
8763
10258
|
type: "inline",
|
|
8764
10259
|
children: [
|
|
8765
|
-
/* @__PURE__ */
|
|
10260
|
+
/* @__PURE__ */ jsx51(NavDrawerHeader, { className: "!bg-transparent !px-5 !py-4", children: /* @__PURE__ */ jsxs27("div", { className: "flex items-center min-h-10", children: [
|
|
8766
10261
|
header,
|
|
8767
|
-
!onNavigate && headerActions !== void 0 && /* @__PURE__ */
|
|
8768
|
-
onNavigate && /* @__PURE__ */
|
|
10262
|
+
!onNavigate && headerActions !== void 0 && /* @__PURE__ */ jsx51("div", { className: "ml-auto flex items-center gap-2", children: headerActions }),
|
|
10263
|
+
onNavigate && /* @__PURE__ */ jsx51(Button13, { appearance: "subtle", "aria-label": closeLabel, className: "!ml-auto", icon: /* @__PURE__ */ jsx51(DismissRegular4, {}), onClick: onNavigate })
|
|
8769
10264
|
] }) }),
|
|
8770
|
-
/* @__PURE__ */
|
|
8771
|
-
/* @__PURE__ */
|
|
8772
|
-
groups.map((group, groupIndex) => group.items.length === 0 ? null : /* @__PURE__ */
|
|
8773
|
-
group.label !== void 0 && /* @__PURE__ */
|
|
8774
|
-
/* @__PURE__ */
|
|
10265
|
+
/* @__PURE__ */ jsx51(NavDrawerBody, { className: "!bg-transparent overflow-hidden !p-0", children: /* @__PURE__ */ jsx51(ScrollArea, { axes: "vertical", className: "h-full min-h-0", contentClassName: "px-[10px]", noTabIndex: true, children: /* @__PURE__ */ jsxs27("div", { className: "relative", ref: bodyRef, children: [
|
|
10266
|
+
/* @__PURE__ */ jsx51(NavSelectionIndicator, { containerRef: bodyRef, inset: NAV_INDICATOR_INSET, otherListIs: "below", selectedValue }),
|
|
10267
|
+
groups.map((group, groupIndex) => group.items.length === 0 ? null : /* @__PURE__ */ jsxs27("div", { children: [
|
|
10268
|
+
group.label !== void 0 && /* @__PURE__ */ jsx51(NavSectionHeader, { children: group.label }),
|
|
10269
|
+
/* @__PURE__ */ jsx51("div", { className: "grid gap-1", children: group.items.map((item) => /* @__PURE__ */ jsx51(PaneItem, { item, onNavigate, pendingValue }, item.value)) })
|
|
8775
10270
|
] }, groupIndex))
|
|
8776
10271
|
] }) }) }),
|
|
8777
|
-
footerItems.length > 0 && /* @__PURE__ */
|
|
8778
|
-
/* @__PURE__ */
|
|
8779
|
-
footerItems.map((item) => /* @__PURE__ */
|
|
10272
|
+
footerItems.length > 0 && /* @__PURE__ */ jsx51(NavDrawerFooter, { className: "!bg-transparent !gap-y-1 !px-[10px] !py-3", children: /* @__PURE__ */ jsxs27("div", { className: "grid gap-y-1 relative w-full", ref: footerRef, children: [
|
|
10273
|
+
/* @__PURE__ */ jsx51(NavSelectionIndicator, { containerRef: footerRef, inset: NAV_INDICATOR_INSET, otherListIs: "above", selectedValue }),
|
|
10274
|
+
footerItems.map((item) => /* @__PURE__ */ jsx51(PaneItem, { item, onNavigate, pendingValue }, item.value))
|
|
8780
10275
|
] }) })
|
|
8781
10276
|
]
|
|
8782
10277
|
}
|
|
@@ -8784,9 +10279,9 @@ function NavigationPane({
|
|
|
8784
10279
|
}
|
|
8785
10280
|
|
|
8786
10281
|
// src/shell/navigation-progress.tsx
|
|
8787
|
-
import { jsx as
|
|
10282
|
+
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
8788
10283
|
function NavigationProgress({ active }) {
|
|
8789
|
-
return /* @__PURE__ */
|
|
10284
|
+
return /* @__PURE__ */ jsx52("div", { "aria-hidden": "true", className: "fwt-navigation-progress", "data-active": active });
|
|
8790
10285
|
}
|
|
8791
10286
|
export {
|
|
8792
10287
|
AppLoadingScreen,
|
|
@@ -8807,8 +10302,11 @@ export {
|
|
|
8807
10302
|
CodeBlock,
|
|
8808
10303
|
Combobox,
|
|
8809
10304
|
ConfirmDialog,
|
|
10305
|
+
ConfirmDialogProvider,
|
|
10306
|
+
ConfirmFlyout,
|
|
8810
10307
|
ContentLoadingScreen,
|
|
8811
10308
|
DashboardPageHeader,
|
|
10309
|
+
DataTable,
|
|
8812
10310
|
DialogShell,
|
|
8813
10311
|
Dropdown,
|
|
8814
10312
|
EXPAND_ANIMATION_MS,
|
|
@@ -8816,6 +10314,8 @@ export {
|
|
|
8816
10314
|
EmptyStateLine,
|
|
8817
10315
|
ErrorShell,
|
|
8818
10316
|
ErrorStack,
|
|
10317
|
+
FileDropZone,
|
|
10318
|
+
FilePickerButton,
|
|
8819
10319
|
GradientBackground,
|
|
8820
10320
|
HEADER_ROW_CLASS,
|
|
8821
10321
|
HttpMethodBadge,
|
|
@@ -8827,10 +10327,13 @@ export {
|
|
|
8827
10327
|
Input,
|
|
8828
10328
|
LISTBOX_POSITIONING,
|
|
8829
10329
|
MaskedIcon,
|
|
10330
|
+
Metric,
|
|
10331
|
+
MetricGrid,
|
|
8830
10332
|
MultiselectCombobox,
|
|
8831
10333
|
NavSelectionIndicator,
|
|
8832
10334
|
NavigationPane,
|
|
8833
10335
|
NavigationProgress,
|
|
10336
|
+
NumberBox,
|
|
8834
10337
|
OpenLinkLabel,
|
|
8835
10338
|
OutcomeMessageBar,
|
|
8836
10339
|
OutcomeToastProvider,
|
|
@@ -8853,8 +10356,10 @@ export {
|
|
|
8853
10356
|
POPUP_SLIDE_EASING,
|
|
8854
10357
|
POPUP_SLIDE_MS,
|
|
8855
10358
|
POP_IN_OFFSET_PX,
|
|
10359
|
+
Pager,
|
|
8856
10360
|
Panel,
|
|
8857
10361
|
ProgressRing,
|
|
10362
|
+
PropertyList,
|
|
8858
10363
|
REPOSITION_ANIMATION_MS,
|
|
8859
10364
|
REPOSITION_DELETE_DELAY_MS,
|
|
8860
10365
|
REPOSITION_EASING,
|
|
@@ -8879,6 +10384,7 @@ export {
|
|
|
8879
10384
|
THEME_MODE_ATTRIBUTE,
|
|
8880
10385
|
TIGHT_STACK_CLASS,
|
|
8881
10386
|
TWO_COLUMN_FORM_CLASS,
|
|
10387
|
+
TabView,
|
|
8882
10388
|
TableActions,
|
|
8883
10389
|
TableCentredCell,
|
|
8884
10390
|
TableCentredHeader,
|
|
@@ -8892,21 +10398,32 @@ export {
|
|
|
8892
10398
|
WinuiStringsProvider,
|
|
8893
10399
|
applyThemeMode,
|
|
8894
10400
|
baseFontStack,
|
|
10401
|
+
clampNumber,
|
|
8895
10402
|
copyOutcomeIcon,
|
|
8896
10403
|
copyToClipboard,
|
|
8897
10404
|
fluentComponents,
|
|
10405
|
+
formatFileSize,
|
|
10406
|
+
formatMetricValue,
|
|
8898
10407
|
infoLabelSlot,
|
|
10408
|
+
matchesAccept,
|
|
8899
10409
|
monospaceStack,
|
|
8900
10410
|
moveItem,
|
|
8901
10411
|
pageFrameClassName,
|
|
10412
|
+
pagerPageCount,
|
|
10413
|
+
pagerPageWindow,
|
|
10414
|
+
parseNumberText,
|
|
8902
10415
|
progressIndeterminateCss,
|
|
8903
10416
|
refuseToggle,
|
|
10417
|
+
resolveNumberChange,
|
|
8904
10418
|
resolveThemeMode,
|
|
10419
|
+
stepPrecision,
|
|
8905
10420
|
stopRowSelection,
|
|
8906
10421
|
useBadgeHue,
|
|
10422
|
+
useConfirm,
|
|
8907
10423
|
useCopyLabel,
|
|
8908
10424
|
useCopyToClipboard,
|
|
8909
10425
|
useDangerActionClasses,
|
|
10426
|
+
useDangerFillClass,
|
|
8910
10427
|
useDangerTextClass,
|
|
8911
10428
|
useDialogInvocation,
|
|
8912
10429
|
useDiscardGuard,
|
|
@@ -8915,6 +10432,7 @@ export {
|
|
|
8915
10432
|
useReorderList,
|
|
8916
10433
|
useRouteAddress,
|
|
8917
10434
|
useScrollAreaHost,
|
|
10435
|
+
useToast,
|
|
8918
10436
|
useTruncation,
|
|
8919
10437
|
useWinuiTheme,
|
|
8920
10438
|
valuesAsOptions,
|