@hxdhxd/harmony-flow-ui 0.2.0 → 0.3.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/README.md +19 -5
- package/dist/index.cjs +1349 -840
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +449 -40
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +103 -3
- package/dist/index.d.ts +103 -3
- package/dist/index.js +1319 -817
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -32,7 +32,9 @@ __export(index_exports, {
|
|
|
32
32
|
AvailabilityGrid: () => AvailabilityGrid,
|
|
33
33
|
Avatar: () => Avatar,
|
|
34
34
|
AvatarGroup: () => AvatarGroup,
|
|
35
|
+
BackToTop: () => BackToTop,
|
|
35
36
|
Badge: () => Badge,
|
|
37
|
+
BottomNavigation: () => BottomNavigation,
|
|
36
38
|
Breadcrumb: () => Breadcrumb,
|
|
37
39
|
Button: () => Button,
|
|
38
40
|
ButtonGroup: () => ButtonGroup,
|
|
@@ -81,6 +83,7 @@ __export(index_exports, {
|
|
|
81
83
|
GanttChart: () => GanttChart,
|
|
82
84
|
Grid: () => Grid,
|
|
83
85
|
Hero: () => Hero,
|
|
86
|
+
HierarchicalSidebar: () => HierarchicalSidebar,
|
|
84
87
|
HoldToConfirm: () => HoldToConfirm,
|
|
85
88
|
HotspotGuide: () => HotspotGuide,
|
|
86
89
|
Icon: () => Icon,
|
|
@@ -97,11 +100,13 @@ __export(index_exports, {
|
|
|
97
100
|
LoadMore: () => LoadMore,
|
|
98
101
|
LoadingDots: () => LoadingDots,
|
|
99
102
|
LoadingOverlay: () => LoadingOverlay,
|
|
103
|
+
LongPageNavigation: () => LongPageNavigation,
|
|
100
104
|
MarkdownContent: () => MarkdownContent,
|
|
101
105
|
Masonry: () => Masonry,
|
|
102
106
|
MegaMenu: () => MegaMenu,
|
|
103
107
|
MemberPicker: () => MemberPicker,
|
|
104
108
|
MentionInput: () => MentionInput,
|
|
109
|
+
MobileContentNavigation: () => MobileContentNavigation,
|
|
105
110
|
MobileNavigation: () => MobileNavigation,
|
|
106
111
|
Modal: () => Modal,
|
|
107
112
|
ModelSelector: () => ModelSelector,
|
|
@@ -123,6 +128,7 @@ __export(index_exports, {
|
|
|
123
128
|
ProgressBar: () => ProgressBar,
|
|
124
129
|
ProgressRing: () => ProgressRing,
|
|
125
130
|
PromptSuggestions: () => PromptSuggestions,
|
|
131
|
+
PullToRefresh: () => PullToRefresh,
|
|
126
132
|
QueryBuilder: () => QueryBuilder,
|
|
127
133
|
Radio: () => Radio,
|
|
128
134
|
RadioGroup: () => RadioGroup,
|
|
@@ -158,6 +164,7 @@ __export(index_exports, {
|
|
|
158
164
|
Table: () => Table,
|
|
159
165
|
Tabs: () => Tabs,
|
|
160
166
|
Tag: () => Tag,
|
|
167
|
+
TaskProgress: () => TaskProgress,
|
|
161
168
|
Textarea: () => Textarea,
|
|
162
169
|
ThemeProvider: () => ThemeProvider,
|
|
163
170
|
TimePicker: () => TimePicker,
|
|
@@ -2633,30 +2640,307 @@ function MobileNavigation({ brand, items, mode = "drawer", activeKey, open, onOp
|
|
|
2633
2640
|
// src/navigation/Scrollspy.tsx
|
|
2634
2641
|
var import_react34 = require("react");
|
|
2635
2642
|
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
2636
|
-
function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%", className = "", ...props }) {
|
|
2643
|
+
function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%", target, className = "", ...props }) {
|
|
2637
2644
|
const [observedKey, setObservedKey] = (0, import_react34.useState)(items[0]?.key);
|
|
2638
2645
|
const currentKey = activeKey ?? observedKey;
|
|
2639
2646
|
(0, import_react34.useEffect)(() => {
|
|
2640
|
-
|
|
2641
|
-
const
|
|
2647
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2648
|
+
const Observer = view.IntersectionObserver;
|
|
2649
|
+
if (activeKey !== void 0 || target === null || !Observer) return;
|
|
2650
|
+
const observer = new Observer((entries) => {
|
|
2642
2651
|
const visible = entries.find((entry) => entry.isIntersecting);
|
|
2643
2652
|
if (visible?.target.id) setObservedKey(visible.target.id);
|
|
2644
|
-
}, { rootMargin });
|
|
2653
|
+
}, { root: target ?? null, rootMargin });
|
|
2645
2654
|
items.forEach((item) => {
|
|
2646
|
-
const section = document.getElementById(item.key);
|
|
2647
|
-
if (section) observer.observe(section);
|
|
2655
|
+
const section = target ? [...target.querySelectorAll("[id]")].find((element) => element.id === item.key) : view.document.getElementById(item.key);
|
|
2656
|
+
if (section && (!target || target.contains(section))) observer.observe(section);
|
|
2648
2657
|
});
|
|
2649
2658
|
return () => observer.disconnect();
|
|
2650
|
-
}, [activeKey, items, rootMargin]);
|
|
2659
|
+
}, [activeKey, items, rootMargin, target]);
|
|
2651
2660
|
return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("nav", { className: `hf-scrollspy ${className}`.trim(), "aria-label": "\u9875\u5185\u5BFC\u822A", ...props, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("a", { href: item.href ?? `#${item.key}`, "aria-current": currentKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) });
|
|
2652
2661
|
}
|
|
2653
2662
|
|
|
2654
|
-
// src/navigation/
|
|
2663
|
+
// src/navigation/BackToTop.tsx
|
|
2655
2664
|
var import_react35 = require("react");
|
|
2656
2665
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
2657
|
-
function
|
|
2658
|
-
const [
|
|
2666
|
+
function BackToTop({ target, threshold = 320, behavior = "smooth", label = "\u8FD4\u56DE\u9876\u90E8", onActivate, className = "", ...props }) {
|
|
2667
|
+
const [visible, setVisible] = (0, import_react35.useState)(false);
|
|
2659
2668
|
(0, import_react35.useEffect)(() => {
|
|
2669
|
+
if (target === null) {
|
|
2670
|
+
setVisible(false);
|
|
2671
|
+
return;
|
|
2672
|
+
}
|
|
2673
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2674
|
+
const source = target ?? view;
|
|
2675
|
+
const measure = () => setVisible((target?.scrollTop ?? view.scrollY) >= threshold);
|
|
2676
|
+
measure();
|
|
2677
|
+
source.addEventListener("scroll", measure, { passive: true });
|
|
2678
|
+
return () => source.removeEventListener("scroll", measure);
|
|
2679
|
+
}, [target, threshold]);
|
|
2680
|
+
const handleActivate = () => {
|
|
2681
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2682
|
+
const reduceMotion = view.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
2683
|
+
const resolvedBehavior = reduceMotion ? "auto" : behavior;
|
|
2684
|
+
if (target) target.scrollTo({ top: 0, behavior: resolvedBehavior });
|
|
2685
|
+
else view.scrollTo({ top: 0, behavior: resolvedBehavior });
|
|
2686
|
+
onActivate?.();
|
|
2687
|
+
};
|
|
2688
|
+
if (!visible) return null;
|
|
2689
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("button", { ...props, type: "button", className: `hf-back-to-top hf-back-to-top--visible ${className}`.trim(), onClick: handleActivate, children: [
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { "aria-hidden": "true", children: "\u2191" }),
|
|
2691
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: label })
|
|
2692
|
+
] });
|
|
2693
|
+
}
|
|
2694
|
+
|
|
2695
|
+
// src/navigation/HierarchicalSidebar.tsx
|
|
2696
|
+
var import_react36 = require("react");
|
|
2697
|
+
|
|
2698
|
+
// src/navigation/navigationTree.ts
|
|
2699
|
+
function flattenNavigationItems(items) {
|
|
2700
|
+
return items.flatMap((item) => [item, ...flattenNavigationItems(item.children ?? [])]);
|
|
2701
|
+
}
|
|
2702
|
+
function getNavigationAncestorKeys(items, activeKey) {
|
|
2703
|
+
if (!activeKey) return [];
|
|
2704
|
+
for (const item of items) {
|
|
2705
|
+
if (item.key === activeKey) return [];
|
|
2706
|
+
const childPath = getNavigationAncestorKeys(item.children ?? [], activeKey);
|
|
2707
|
+
if (childPath.length || item.children?.some((child) => child.key === activeKey)) return [item.key, ...childPath];
|
|
2708
|
+
}
|
|
2709
|
+
return [];
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
// src/navigation/HierarchicalSidebar.tsx
|
|
2713
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
2714
|
+
function HierarchicalSidebar({ items, title = "\u5185\u5BB9\u5BFC\u822A", activeKey, onItemSelect, expandedKeys, defaultExpandedKeys = [], onExpandedChange, className = "", ...props }) {
|
|
2715
|
+
const [internalExpanded, setInternalExpanded] = (0, import_react36.useState)(() => /* @__PURE__ */ new Set([...defaultExpandedKeys, ...getNavigationAncestorKeys(items, activeKey)]));
|
|
2716
|
+
const activeAncestorKeys = (0, import_react36.useMemo)(() => getNavigationAncestorKeys(items, activeKey), [activeKey, items]);
|
|
2717
|
+
const activeAncestorSignature = activeAncestorKeys.join("\0");
|
|
2718
|
+
const expanded = new Set(expandedKeys ?? internalExpanded);
|
|
2719
|
+
(0, import_react36.useEffect)(() => {
|
|
2720
|
+
if (expandedKeys !== void 0) return;
|
|
2721
|
+
setInternalExpanded((current) => {
|
|
2722
|
+
const next = new Set(current);
|
|
2723
|
+
activeAncestorKeys.forEach((key) => next.add(key));
|
|
2724
|
+
return next;
|
|
2725
|
+
});
|
|
2726
|
+
}, [activeAncestorSignature, expandedKeys]);
|
|
2727
|
+
const toggle = (key) => {
|
|
2728
|
+
const next = new Set(expandedKeys ?? internalExpanded);
|
|
2729
|
+
if (next.has(key)) next.delete(key);
|
|
2730
|
+
else next.add(key);
|
|
2731
|
+
if (expandedKeys === void 0) setInternalExpanded(next);
|
|
2732
|
+
onExpandedChange?.([...next]);
|
|
2733
|
+
};
|
|
2734
|
+
const renderItems = (nodes, level = 0) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { className: "hf-hierarchical-sidebar__list", "data-level": level, children: nodes.map((item) => {
|
|
2735
|
+
const hasChildren = Boolean(item.children?.length);
|
|
2736
|
+
const isExpanded = expanded.has(item.key);
|
|
2737
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("li", { children: [
|
|
2738
|
+
hasChildren ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("button", { type: "button", className: "hf-hierarchical-sidebar__group", "aria-expanded": isExpanded, onClick: () => toggle(item.key), children: [
|
|
2739
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item.icon }),
|
|
2740
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item.label }),
|
|
2741
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "aria-hidden": "true", className: "hf-hierarchical-sidebar__chevron", children: "\u203A" })
|
|
2742
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("a", { href: item.href ?? `#${item.key}`, "aria-current": activeKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: [
|
|
2743
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { "aria-hidden": "true", children: item.icon }),
|
|
2744
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: item.label })
|
|
2745
|
+
] }),
|
|
2746
|
+
hasChildren && isExpanded && renderItems(item.children ?? [], level + 1)
|
|
2747
|
+
] }, item.key);
|
|
2748
|
+
}) });
|
|
2749
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("aside", { className: `hf-hierarchical-sidebar ${className}`.trim(), ...props, children: [
|
|
2750
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "hf-hierarchical-sidebar__title", children: title }),
|
|
2751
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("nav", { "aria-label": "\u5C42\u7EA7\u4FA7\u680F", children: renderItems(items) })
|
|
2752
|
+
] });
|
|
2753
|
+
}
|
|
2754
|
+
|
|
2755
|
+
// src/navigation/useReadingPosition.ts
|
|
2756
|
+
var import_react37 = require("react");
|
|
2757
|
+
function useReadingPosition(target) {
|
|
2758
|
+
const [snapshot, setSnapshot] = (0, import_react37.useState)({ target, value: 0 });
|
|
2759
|
+
(0, import_react37.useEffect)(() => {
|
|
2760
|
+
if (target === null) return;
|
|
2761
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2762
|
+
const root = target ?? view.document.documentElement;
|
|
2763
|
+
const events = target ?? view;
|
|
2764
|
+
let frame = 0;
|
|
2765
|
+
let disposed = false;
|
|
2766
|
+
const measure = () => {
|
|
2767
|
+
frame = 0;
|
|
2768
|
+
if (disposed) return;
|
|
2769
|
+
const viewport = target ? root.clientHeight : view.innerHeight;
|
|
2770
|
+
const height = target ? root.scrollHeight : Math.max(root.scrollHeight, view.document.body?.scrollHeight ?? 0);
|
|
2771
|
+
const offset = target ? root.scrollTop : view.scrollY;
|
|
2772
|
+
const range = Math.max(0, height - viewport);
|
|
2773
|
+
const value = range === 0 ? 100 : Math.round(Math.min(1, Math.max(0, offset / range)) * 100);
|
|
2774
|
+
setSnapshot((previous) => previous.target === target && previous.value === value ? previous : { target, value });
|
|
2775
|
+
};
|
|
2776
|
+
const schedule = () => {
|
|
2777
|
+
if (!disposed && !frame) frame = view.requestAnimationFrame(measure);
|
|
2778
|
+
};
|
|
2779
|
+
const resize = new ResizeObserver(schedule);
|
|
2780
|
+
const observeContent = () => {
|
|
2781
|
+
resize.disconnect();
|
|
2782
|
+
resize.observe(root);
|
|
2783
|
+
for (const child of root.children) resize.observe(child);
|
|
2784
|
+
if (!target && view.document.body) {
|
|
2785
|
+
resize.observe(view.document.body);
|
|
2786
|
+
for (const child of view.document.body.children) resize.observe(child);
|
|
2787
|
+
}
|
|
2788
|
+
schedule();
|
|
2789
|
+
};
|
|
2790
|
+
const mutations = new MutationObserver(observeContent);
|
|
2791
|
+
mutations.observe(root, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
2792
|
+
events.addEventListener("scroll", schedule, { passive: true });
|
|
2793
|
+
view.addEventListener("resize", schedule);
|
|
2794
|
+
root.addEventListener("load", schedule, true);
|
|
2795
|
+
observeContent();
|
|
2796
|
+
return () => {
|
|
2797
|
+
disposed = true;
|
|
2798
|
+
view.cancelAnimationFrame(frame);
|
|
2799
|
+
resize.disconnect();
|
|
2800
|
+
mutations.disconnect();
|
|
2801
|
+
events.removeEventListener("scroll", schedule);
|
|
2802
|
+
view.removeEventListener("resize", schedule);
|
|
2803
|
+
root.removeEventListener("load", schedule, true);
|
|
2804
|
+
};
|
|
2805
|
+
}, [target]);
|
|
2806
|
+
return target === null || snapshot.target !== target ? 0 : snapshot.value;
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
// src/navigation/ReadingProgress.tsx
|
|
2810
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
2811
|
+
function ReadingProgress({ target, label = "\u9605\u8BFB\u8FDB\u5EA6", showValue = true, className = "" }) {
|
|
2812
|
+
const value = useReadingPosition(target);
|
|
2813
|
+
const name = label.trim() || "\u9605\u8BFB\u8FDB\u5EA6";
|
|
2814
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: `hf-reading-progress ${className}`.trim(), children: [
|
|
2815
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "hf-reading-progress__caption", "aria-hidden": "true", children: [
|
|
2816
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: name }),
|
|
2817
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("span", { children: [
|
|
2818
|
+
value,
|
|
2819
|
+
"%"
|
|
2820
|
+
] })
|
|
2821
|
+
] }),
|
|
2822
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
|
|
2823
|
+
"div",
|
|
2824
|
+
{
|
|
2825
|
+
className: "hf-reading-progress__track",
|
|
2826
|
+
role: "progressbar",
|
|
2827
|
+
"aria-label": name,
|
|
2828
|
+
"aria-valuemin": 0,
|
|
2829
|
+
"aria-valuemax": 100,
|
|
2830
|
+
"aria-valuenow": value,
|
|
2831
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { className: "hf-reading-progress__fill", style: { width: `${value}%` } })
|
|
2832
|
+
}
|
|
2833
|
+
)
|
|
2834
|
+
] });
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
// src/navigation/LongPageNavigation.tsx
|
|
2838
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
2839
|
+
function LongPageNavigation({ items, target, title = "\u672C\u9875\u5185\u5BB9", progressLabel = "\u9605\u8BFB\u8FDB\u5EA6", rootMargin, backToTopThreshold = 320, showProgress = true, activeKey, onItemSelect, className = "", ...props }) {
|
|
2840
|
+
const flattenedItems = flattenNavigationItems(items);
|
|
2841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("aside", { className: `hf-long-page-navigation ${className}`.trim(), ...props, children: [
|
|
2842
|
+
showProgress && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(ReadingProgress, { target, label: progressLabel }),
|
|
2843
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "hf-long-page-navigation__title", children: title }),
|
|
2844
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Scrollspy, { items: flattenedItems, target, rootMargin, activeKey, onItemSelect }),
|
|
2845
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(BackToTop, { target, threshold: backToTopThreshold })
|
|
2846
|
+
] });
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
// src/navigation/BottomNavigation.tsx
|
|
2850
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
2851
|
+
function BottomNavigation({ items, label = "\u5E95\u90E8\u5BFC\u822A", activeKey, onItemSelect, className = "", ...props }) {
|
|
2852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("nav", { className: `hf-bottom-navigation ${className}`.trim(), "aria-label": label, ...props, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("a", { href: item.href ?? `#${item.key}`, "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: [
|
|
2853
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "hf-bottom-navigation__icon", "aria-hidden": "true", children: item.icon }),
|
|
2854
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { children: item.label })
|
|
2855
|
+
] }, item.key)) });
|
|
2856
|
+
}
|
|
2857
|
+
|
|
2858
|
+
// src/navigation/PullToRefresh.tsx
|
|
2859
|
+
var import_react38 = require("react");
|
|
2860
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
2861
|
+
function PullToRefresh({ children, onRefresh, threshold = 72, disabled = false, label = "\u5237\u65B0\u5185\u5BB9", onRefreshError, className = "", onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }) {
|
|
2862
|
+
const rootRef = (0, import_react38.useRef)(null);
|
|
2863
|
+
const gestureRef = (0, import_react38.useRef)(null);
|
|
2864
|
+
const [distance, setDistance] = (0, import_react38.useState)(0);
|
|
2865
|
+
const [refreshing, setRefreshing] = (0, import_react38.useState)(false);
|
|
2866
|
+
const refreshingRef = (0, import_react38.useRef)(false);
|
|
2867
|
+
const runRefresh = async () => {
|
|
2868
|
+
if (disabled || refreshingRef.current) return;
|
|
2869
|
+
refreshingRef.current = true;
|
|
2870
|
+
setRefreshing(true);
|
|
2871
|
+
try {
|
|
2872
|
+
await onRefresh();
|
|
2873
|
+
} catch (error) {
|
|
2874
|
+
onRefreshError?.(error);
|
|
2875
|
+
} finally {
|
|
2876
|
+
refreshingRef.current = false;
|
|
2877
|
+
setRefreshing(false);
|
|
2878
|
+
}
|
|
2879
|
+
};
|
|
2880
|
+
const start = (event) => {
|
|
2881
|
+
if (disabled || refreshingRef.current || event.isPrimary === false || rootRef.current?.scrollTop !== 0 || event.target.closest('button, a, input, select, textarea, summary, label, video, audio, [contenteditable], [role="button"], [role="slider"]')) return;
|
|
2882
|
+
gestureRef.current = { pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, tracking: false };
|
|
2883
|
+
};
|
|
2884
|
+
const move = (event) => {
|
|
2885
|
+
const gesture = gestureRef.current;
|
|
2886
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
2887
|
+
const dx = event.clientX - gesture.startX;
|
|
2888
|
+
const dy = event.clientY - gesture.startY;
|
|
2889
|
+
if (!gesture.tracking && (dy <= 8 || Math.abs(dx) >= dy)) {
|
|
2890
|
+
if (Math.abs(dx) > 8 || dy < 0) gestureRef.current = null;
|
|
2891
|
+
return;
|
|
2892
|
+
}
|
|
2893
|
+
gesture.tracking = true;
|
|
2894
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2895
|
+
setDistance(Math.min(threshold * 1.35, dy * 0.55));
|
|
2896
|
+
};
|
|
2897
|
+
const finish = async (event) => {
|
|
2898
|
+
const gesture = gestureRef.current;
|
|
2899
|
+
gestureRef.current = null;
|
|
2900
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
2901
|
+
const shouldRefresh = distance >= threshold;
|
|
2902
|
+
setDistance(0);
|
|
2903
|
+
if (!shouldRefresh) return;
|
|
2904
|
+
await runRefresh();
|
|
2905
|
+
};
|
|
2906
|
+
const refresh = async () => {
|
|
2907
|
+
await runRefresh();
|
|
2908
|
+
};
|
|
2909
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { ...props, ref: rootRef, className: `hf-pull-to-refresh${distance > 0 ? " hf-pull-to-refresh--dragging" : ""} ${className}`.trim(), onPointerDown: (event) => {
|
|
2910
|
+
start(event);
|
|
2911
|
+
onPointerDown?.(event);
|
|
2912
|
+
}, onPointerMove: (event) => {
|
|
2913
|
+
move(event);
|
|
2914
|
+
onPointerMove?.(event);
|
|
2915
|
+
}, onPointerUp: (event) => {
|
|
2916
|
+
void finish(event);
|
|
2917
|
+
onPointerUp?.(event);
|
|
2918
|
+
}, onPointerCancel: (event) => {
|
|
2919
|
+
gestureRef.current = null;
|
|
2920
|
+
setDistance(0);
|
|
2921
|
+
onPointerCancel?.(event);
|
|
2922
|
+
}, children: [
|
|
2923
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "hf-pull-to-refresh__indicator", style: { "--hf-pull-distance": `${distance}px` }, "aria-live": "polite", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { type: "button", onClick: () => void refresh(), disabled: disabled || refreshing, children: refreshing ? "\u6B63\u5728\u5237\u65B0\u2026" : distance >= threshold ? "\u677E\u5F00\u5237\u65B0" : label }) }),
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "hf-pull-to-refresh__content", style: { transform: `translateY(${distance}px)` }, children })
|
|
2925
|
+
] });
|
|
2926
|
+
}
|
|
2927
|
+
|
|
2928
|
+
// src/navigation/MobileContentNavigation.tsx
|
|
2929
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
2930
|
+
function MobileContentNavigation({ items, children, onRefresh, refreshThreshold, navigationLabel, activeKey, onItemSelect, className = "", ...props }) {
|
|
2931
|
+
const content = onRefresh ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(PullToRefresh, { onRefresh, threshold: refreshThreshold, children }) : children;
|
|
2932
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: `hf-mobile-content-navigation${onRefresh ? " hf-mobile-content-navigation--refreshable" : ""} ${className}`.trim(), ...props, children: [
|
|
2933
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "hf-mobile-content-navigation__body", children: content }),
|
|
2934
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(BottomNavigation, { items, label: navigationLabel, activeKey, onItemSelect })
|
|
2935
|
+
] });
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
// src/navigation/ShrinkNav.tsx
|
|
2939
|
+
var import_react39 = require("react");
|
|
2940
|
+
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
2941
|
+
function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSelect, className = "", ...props }) {
|
|
2942
|
+
const [compact, setCompact] = (0, import_react39.useState)(false);
|
|
2943
|
+
(0, import_react39.useEffect)(() => {
|
|
2660
2944
|
let frame = 0;
|
|
2661
2945
|
const update = () => {
|
|
2662
2946
|
cancelAnimationFrame(frame);
|
|
@@ -2669,18 +2953,18 @@ function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSele
|
|
|
2669
2953
|
window.removeEventListener("scroll", update);
|
|
2670
2954
|
};
|
|
2671
2955
|
}, [threshold]);
|
|
2672
|
-
return /* @__PURE__ */ (0,
|
|
2673
|
-
/* @__PURE__ */ (0,
|
|
2674
|
-
/* @__PURE__ */ (0,
|
|
2956
|
+
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("nav", { className: `hf-shrink-nav ${compact ? "hf-shrink-nav--compact" : ""} ${className}`.trim(), "aria-label": "\u6EDA\u52A8\u5BFC\u822A", ...props, children: [
|
|
2957
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "hf-shrink-nav__brand", children: brand }),
|
|
2958
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "hf-shrink-nav__items", children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) }),
|
|
2675
2959
|
action
|
|
2676
2960
|
] });
|
|
2677
2961
|
}
|
|
2678
2962
|
|
|
2679
2963
|
// src/navigation/Tabs.tsx
|
|
2680
|
-
var
|
|
2681
|
-
var
|
|
2964
|
+
var import_react40 = require("react");
|
|
2965
|
+
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
2682
2966
|
function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\u6807\u7B7E" }) {
|
|
2683
|
-
const id = (0,
|
|
2967
|
+
const id = (0, import_react40.useId)();
|
|
2684
2968
|
const active = items.find((item) => item.key === value) ?? items[0];
|
|
2685
2969
|
const onKeyDown = (event) => {
|
|
2686
2970
|
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
@@ -2691,43 +2975,43 @@ function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\
|
|
|
2691
2975
|
const next = enabled[(current + offset + enabled.length) % enabled.length];
|
|
2692
2976
|
if (next) onChange(next.key);
|
|
2693
2977
|
};
|
|
2694
|
-
return /* @__PURE__ */ (0,
|
|
2695
|
-
/* @__PURE__ */ (0,
|
|
2978
|
+
return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: `hf-tabs hf-tabs--${variant}`, children: [
|
|
2979
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { role: "tablist", "aria-label": label, onKeyDown, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("button", { type: "button", role: "tab", id: `${id}-${item.key}`, "aria-controls": `${id}-${item.key}-panel`, "aria-selected": item.key === value, tabIndex: item.key === value ? 0 : -1, disabled: item.disabled, onClick: () => onChange(item.key), children: [
|
|
2696
2980
|
item.icon,
|
|
2697
|
-
/* @__PURE__ */ (0,
|
|
2698
|
-
item.badge && /* @__PURE__ */ (0,
|
|
2981
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { children: item.label }),
|
|
2982
|
+
item.badge && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("small", { children: item.badge })
|
|
2699
2983
|
] }, item.key)) }),
|
|
2700
|
-
active && /* @__PURE__ */ (0,
|
|
2984
|
+
active && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { role: "tabpanel", id: `${id}-${active.key}-panel`, "aria-labelledby": `${id}-${active.key}`, tabIndex: 0, children: active.content })
|
|
2701
2985
|
] });
|
|
2702
2986
|
}
|
|
2703
2987
|
|
|
2704
2988
|
// src/navigation/Steps.tsx
|
|
2705
|
-
var
|
|
2989
|
+
var import_jsx_runtime50 = require("react/jsx-runtime");
|
|
2706
2990
|
function Steps({ items, current, onChange, orientation = "horizontal" }) {
|
|
2707
2991
|
const currentIndex = Math.max(0, items.findIndex((item) => item.key === current));
|
|
2708
|
-
return /* @__PURE__ */ (0,
|
|
2992
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("ol", { className: `hf-steps hf-steps--${orientation}`, children: items.map((item, index) => {
|
|
2709
2993
|
const state = index < currentIndex ? "complete" : index === currentIndex ? "current" : "upcoming";
|
|
2710
|
-
return /* @__PURE__ */ (0,
|
|
2711
|
-
/* @__PURE__ */ (0,
|
|
2712
|
-
/* @__PURE__ */ (0,
|
|
2713
|
-
/* @__PURE__ */ (0,
|
|
2714
|
-
item.optional && /* @__PURE__ */ (0,
|
|
2715
|
-
item.description && /* @__PURE__ */ (0,
|
|
2994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("li", { className: `is-${state}`, "aria-current": state === "current" ? "step" : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("button", { type: "button", disabled: item.disabled || !onChange, onClick: () => onChange?.(item.key), children: [
|
|
2995
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { children: state === "complete" ? "\u2713" : index + 1 }),
|
|
2996
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("span", { children: [
|
|
2997
|
+
/* @__PURE__ */ (0, import_jsx_runtime50.jsx)("strong", { children: item.title }),
|
|
2998
|
+
item.optional && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("small", { children: "\u53EF\u9009" }),
|
|
2999
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("small", { children: item.description })
|
|
2716
3000
|
] })
|
|
2717
3001
|
] }) }, item.key);
|
|
2718
3002
|
}) });
|
|
2719
3003
|
}
|
|
2720
3004
|
|
|
2721
3005
|
// src/navigation/CommandPalette.tsx
|
|
2722
|
-
var
|
|
3006
|
+
var import_react41 = require("react");
|
|
2723
3007
|
var import_react_dom4 = require("react-dom");
|
|
2724
|
-
var
|
|
3008
|
+
var import_jsx_runtime51 = require("react/jsx-runtime");
|
|
2725
3009
|
function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u8F93\u5165\u547D\u4EE4\u6216\u641C\u7D22\u2026" }) {
|
|
2726
|
-
const [query, setQuery] = (0,
|
|
2727
|
-
const [active, setActive] = (0,
|
|
2728
|
-
const enabled = (0,
|
|
3010
|
+
const [query, setQuery] = (0, import_react41.useState)("");
|
|
3011
|
+
const [active, setActive] = (0, import_react41.useState)(0);
|
|
3012
|
+
const enabled = (0, import_react41.useMemo)(() => items.filter((item) => !item.disabled && `${item.label} ${item.description ?? ""} ${item.group ?? ""}`.toLowerCase().includes(query.toLowerCase())), [items, query]);
|
|
2729
3013
|
const dialogRef = useDismissibleLayer(open, () => onOpenChange(false), true);
|
|
2730
|
-
(0,
|
|
3014
|
+
(0, import_react41.useEffect)(() => {
|
|
2731
3015
|
if (!open) {
|
|
2732
3016
|
setQuery("");
|
|
2733
3017
|
setActive(0);
|
|
@@ -2751,39 +3035,39 @@ function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u
|
|
|
2751
3035
|
}
|
|
2752
3036
|
};
|
|
2753
3037
|
if (!open) return null;
|
|
2754
|
-
return (0, import_react_dom4.createPortal)(/* @__PURE__ */ (0,
|
|
2755
|
-
/* @__PURE__ */ (0,
|
|
2756
|
-
/* @__PURE__ */ (0,
|
|
2757
|
-
/* @__PURE__ */ (0,
|
|
3038
|
+
return (0, import_react_dom4.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "hf-command-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onOpenChange(false), children: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { ref: dialogRef, tabIndex: -1, className: "hf-command", role: "dialog", "aria-modal": "true", "aria-label": "\u547D\u4EE4\u9762\u677F", children: [
|
|
3039
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "hf-command__search", children: [
|
|
3040
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { "aria-hidden": "true", children: "\u2315" }),
|
|
3041
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("input", { autoFocus: true, role: "combobox", "aria-expanded": "true", "aria-controls": "hf-command-list", value: query, placeholder, onChange: (event) => {
|
|
2758
3042
|
setQuery(event.target.value);
|
|
2759
3043
|
setActive(0);
|
|
2760
3044
|
}, onKeyDown: keydown }),
|
|
2761
|
-
/* @__PURE__ */ (0,
|
|
3045
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("kbd", { children: "Esc" })
|
|
2762
3046
|
] }),
|
|
2763
|
-
/* @__PURE__ */ (0,
|
|
2764
|
-
enabled.map((item, index) => /* @__PURE__ */ (0,
|
|
3047
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { id: "hf-command-list", className: "hf-command__list", role: "listbox", children: [
|
|
3048
|
+
enabled.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("button", { type: "button", role: "option", "aria-selected": index === active, onPointerMove: () => setActive(index), onClick: () => {
|
|
2765
3049
|
onSelect(item.key);
|
|
2766
3050
|
onOpenChange(false);
|
|
2767
3051
|
}, children: [
|
|
2768
3052
|
item.icon,
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
2771
|
-
item.description && /* @__PURE__ */ (0,
|
|
3053
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("span", { children: [
|
|
3054
|
+
/* @__PURE__ */ (0, import_jsx_runtime51.jsx)("strong", { children: item.label }),
|
|
3055
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("small", { children: item.description })
|
|
2772
3056
|
] }),
|
|
2773
|
-
item.shortcut && /* @__PURE__ */ (0,
|
|
3057
|
+
item.shortcut && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("kbd", { children: item.shortcut })
|
|
2774
3058
|
] }, item.key)),
|
|
2775
|
-
!enabled.length && /* @__PURE__ */ (0,
|
|
3059
|
+
!enabled.length && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "hf-command__empty", children: "\u6CA1\u6709\u5339\u914D\u547D\u4EE4" })
|
|
2776
3060
|
] })
|
|
2777
3061
|
] }) }), document.body);
|
|
2778
3062
|
}
|
|
2779
3063
|
|
|
2780
3064
|
// src/layout/Layout.tsx
|
|
2781
|
-
var
|
|
3065
|
+
var import_jsx_runtime52 = require("react/jsx-runtime");
|
|
2782
3066
|
function Container({ size = "lg", padding = 24, className = "", style, ...props }) {
|
|
2783
|
-
return /* @__PURE__ */ (0,
|
|
3067
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: `hf-container hf-container--${size} ${className}`.trim(), style: { "--hf-container-padding": `${padding}px`, ...style }, ...props });
|
|
2784
3068
|
}
|
|
2785
3069
|
function Stack({ direction = "column", gap = 12, align, justify, wrap = false, className = "", style, ...props }) {
|
|
2786
|
-
return /* @__PURE__ */ (0,
|
|
3070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: `hf-stack hf-stack--${direction} ${className}`.trim(), style: { "--hf-stack-gap": `${gap}px`, alignItems: align, justifyContent: justify, flexWrap: wrap ? "wrap" : void 0, ...style }, ...props });
|
|
2787
3071
|
}
|
|
2788
3072
|
function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "", style, ...props }) {
|
|
2789
3073
|
const gridStyle = {
|
|
@@ -2791,7 +3075,7 @@ function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "",
|
|
|
2791
3075
|
"--hf-grid-gap": `${gap}px`,
|
|
2792
3076
|
...style
|
|
2793
3077
|
};
|
|
2794
|
-
return /* @__PURE__ */ (0,
|
|
3078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: `hf-grid ${className}`.trim(), style: gridStyle, ...props });
|
|
2795
3079
|
}
|
|
2796
3080
|
function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", style, children, ...props }) {
|
|
2797
3081
|
const masonryStyle = {
|
|
@@ -2800,120 +3084,120 @@ function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", styl
|
|
|
2800
3084
|
"--hf-masonry-gap": `${gap}px`,
|
|
2801
3085
|
...style
|
|
2802
3086
|
};
|
|
2803
|
-
return /* @__PURE__ */ (0,
|
|
3087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: `hf-masonry ${className}`.trim(), style: masonryStyle, ...props, children });
|
|
2804
3088
|
}
|
|
2805
3089
|
function PageLayout({ variant = "single", sidebar, header, sidebarWidth = 280, className = "", style, children, ...props }) {
|
|
2806
3090
|
const layoutStyle = { "--hf-layout-sidebar": `${sidebarWidth}px`, ...style };
|
|
2807
|
-
return /* @__PURE__ */ (0,
|
|
2808
|
-
header && /* @__PURE__ */ (0,
|
|
2809
|
-
sidebar && /* @__PURE__ */ (0,
|
|
2810
|
-
/* @__PURE__ */ (0,
|
|
3091
|
+
return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: `hf-page-layout hf-page-layout--${variant} ${className}`.trim(), style: layoutStyle, ...props, children: [
|
|
3092
|
+
header && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("header", { className: "hf-page-layout__header", children: header }),
|
|
3093
|
+
sidebar && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("aside", { className: "hf-page-layout__sidebar", children: sidebar }),
|
|
3094
|
+
/* @__PURE__ */ (0, import_jsx_runtime52.jsx)("main", { className: "hf-page-layout__main", children })
|
|
2811
3095
|
] });
|
|
2812
3096
|
}
|
|
2813
3097
|
|
|
2814
3098
|
// src/layout/Skeleton.tsx
|
|
2815
|
-
var
|
|
3099
|
+
var import_jsx_runtime53 = require("react/jsx-runtime");
|
|
2816
3100
|
function Skeleton({ width = "100%", height = 16, radius, circle, animated = true, className = "", style, ...props }) {
|
|
2817
3101
|
const value = (input) => typeof input === "number" ? `${input}px` : input;
|
|
2818
|
-
return /* @__PURE__ */ (0,
|
|
3102
|
+
return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { "aria-hidden": "true", className: `hf-skeleton ${animated ? "is-animated" : ""} ${circle ? "is-circle" : ""} ${className}`.trim(), style: { width: value(width), height: value(height), borderRadius: radius ? value(radius) : void 0, ...style }, ...props });
|
|
2819
3103
|
}
|
|
2820
3104
|
|
|
2821
3105
|
// src/feedback/Loading.tsx
|
|
2822
|
-
var
|
|
3106
|
+
var import_jsx_runtime54 = require("react/jsx-runtime");
|
|
2823
3107
|
function Spinner({ label = "\u6B63\u5728\u52A0\u8F7D", size = 20, className = "" }) {
|
|
2824
|
-
return /* @__PURE__ */ (0,
|
|
3108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: `hf-loading-spinner ${className}`.trim(), role: "status", "aria-label": label, style: { "--hf-loading-size": `${size}px` } });
|
|
2825
3109
|
}
|
|
2826
3110
|
function LoadingDots({ label = "\u6B63\u5728\u52A0\u8F7D" }) {
|
|
2827
|
-
return /* @__PURE__ */ (0,
|
|
2828
|
-
/* @__PURE__ */ (0,
|
|
2829
|
-
/* @__PURE__ */ (0,
|
|
2830
|
-
/* @__PURE__ */ (0,
|
|
3111
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("span", { className: "hf-loading-dots", role: "status", "aria-label": label, children: [
|
|
3112
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", {}),
|
|
3113
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", {}),
|
|
3114
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", {})
|
|
2831
3115
|
] });
|
|
2832
3116
|
}
|
|
2833
3117
|
function ProgressBar({ value, label, indeterminate = false, className = "" }) {
|
|
2834
3118
|
const percent = Math.min(100, Math.max(0, value ?? 0));
|
|
2835
|
-
return /* @__PURE__ */ (0,
|
|
2836
|
-
label && /* @__PURE__ */ (0,
|
|
2837
|
-
/* @__PURE__ */ (0,
|
|
2838
|
-
!indeterminate && /* @__PURE__ */ (0,
|
|
3119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: `hf-progress ${indeterminate ? "is-indeterminate" : ""} ${className}`.trim(), children: [
|
|
3120
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "hf-progress__label", children: [
|
|
3121
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: label }),
|
|
3122
|
+
!indeterminate && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("strong", { children: [
|
|
2839
3123
|
percent,
|
|
2840
3124
|
"%"
|
|
2841
3125
|
] })
|
|
2842
3126
|
] }),
|
|
2843
|
-
/* @__PURE__ */ (0,
|
|
3127
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": indeterminate ? void 0 : percent, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("i", { style: { "--hf-progress": `${percent}%` } }) })
|
|
2844
3128
|
] });
|
|
2845
3129
|
}
|
|
2846
3130
|
function ProgressRing({ value, size = 72, label }) {
|
|
2847
3131
|
const percent = Math.min(100, Math.max(0, value));
|
|
2848
|
-
return /* @__PURE__ */ (0,
|
|
3132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "hf-progress-ring", role: "progressbar", "aria-label": label, "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": percent, style: { "--hf-ring-value": `${percent * 3.6}deg`, "--hf-ring-size": `${size}px` }, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("strong", { children: [
|
|
2849
3133
|
percent,
|
|
2850
3134
|
"%"
|
|
2851
3135
|
] }) });
|
|
2852
3136
|
}
|
|
2853
3137
|
function LoadingOverlay({ active = true, label = "\u6B63\u5728\u51C6\u5907\u5185\u5BB9", className = "", children, ...props }) {
|
|
2854
|
-
return /* @__PURE__ */ (0,
|
|
3138
|
+
return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: `hf-loading-overlay ${className}`.trim(), "aria-busy": active, ...props, children: [
|
|
2855
3139
|
children,
|
|
2856
|
-
active && /* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
/* @__PURE__ */ (0,
|
|
3140
|
+
active && /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: "hf-loading-overlay__veil", role: "status", children: [
|
|
3141
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Spinner, { label, size: 28 }),
|
|
3142
|
+
/* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children: label })
|
|
2859
3143
|
] })
|
|
2860
3144
|
] });
|
|
2861
3145
|
}
|
|
2862
3146
|
|
|
2863
3147
|
// src/forms/MultiSelect.tsx
|
|
2864
|
-
var
|
|
2865
|
-
var
|
|
3148
|
+
var import_react42 = require("react");
|
|
3149
|
+
var import_jsx_runtime55 = require("react/jsx-runtime");
|
|
2866
3150
|
function MultiSelect({ label, options, value, onChange, placeholder = "\u8BF7\u9009\u62E9", max, hint, disabled }) {
|
|
2867
|
-
const [open, setOpen] = (0,
|
|
3151
|
+
const [open, setOpen] = (0, import_react42.useState)(false);
|
|
2868
3152
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
2869
|
-
const listId = (0,
|
|
3153
|
+
const listId = (0, import_react42.useId)();
|
|
2870
3154
|
const toggle = (next) => {
|
|
2871
3155
|
const selected = value.includes(next);
|
|
2872
3156
|
if (!selected && max && value.length >= max) return;
|
|
2873
3157
|
onChange(selected ? value.filter((item) => item !== next) : [...value, next]);
|
|
2874
3158
|
};
|
|
2875
|
-
return /* @__PURE__ */ (0,
|
|
2876
|
-
label && /* @__PURE__ */ (0,
|
|
2877
|
-
/* @__PURE__ */ (0,
|
|
3159
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "hf-field hf-multiselect", ref: rootRef, children: [
|
|
3160
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3161
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "hf-multiselect__trigger", role: "combobox", tabIndex: disabled ? -1 : 0, "aria-disabled": disabled, "aria-expanded": open, "aria-controls": listId, onClick: () => !disabled && setOpen(!open), onKeyDown: (event) => {
|
|
2878
3162
|
if (!disabled && (event.key === "Enter" || event.key === " ")) {
|
|
2879
3163
|
event.preventDefault();
|
|
2880
3164
|
setOpen(!open);
|
|
2881
3165
|
}
|
|
2882
3166
|
}, children: [
|
|
2883
|
-
/* @__PURE__ */ (0,
|
|
3167
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { children: value.length ? value.map((item) => {
|
|
2884
3168
|
const option = options.find((candidate) => candidate.value === item);
|
|
2885
|
-
return /* @__PURE__ */ (0,
|
|
3169
|
+
return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("i", { children: [
|
|
2886
3170
|
option?.label,
|
|
2887
|
-
/* @__PURE__ */ (0,
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("button", { type: "button", "aria-label": `\u79FB\u9664 ${String(option?.label)}`, onClick: (event) => {
|
|
2888
3172
|
event.stopPropagation();
|
|
2889
3173
|
toggle(item);
|
|
2890
|
-
}, children: /* @__PURE__ */ (0,
|
|
3174
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Icon, { name: "close", size: 13 }) })
|
|
2891
3175
|
] }, item);
|
|
2892
|
-
}) : /* @__PURE__ */ (0,
|
|
2893
|
-
/* @__PURE__ */ (0,
|
|
3176
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("em", { children: placeholder }) }),
|
|
3177
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Icon, { name: "chevron-down", size: 16, className: "hf-multiselect__chevron" })
|
|
2894
3178
|
] }),
|
|
2895
|
-
open && /* @__PURE__ */ (0,
|
|
2896
|
-
/* @__PURE__ */ (0,
|
|
2897
|
-
/* @__PURE__ */ (0,
|
|
3179
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { id: listId, className: "hf-multiselect__menu", role: "listbox", "aria-multiselectable": "true", children: options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("button", { type: "button", role: "option", "aria-selected": value.includes(option.value), disabled: option.disabled, onClick: () => toggle(option.value), children: [
|
|
3180
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { children: option.label }),
|
|
3181
|
+
/* @__PURE__ */ (0, import_jsx_runtime55.jsx)("i", { children: value.includes(option.value) ? "\u2713" : "" })
|
|
2898
3182
|
] }, option.value)) }),
|
|
2899
|
-
hint && /* @__PURE__ */ (0,
|
|
3183
|
+
hint && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "hf-field__hint", children: hint })
|
|
2900
3184
|
] });
|
|
2901
3185
|
}
|
|
2902
3186
|
|
|
2903
3187
|
// src/forms/ChoiceGroup.tsx
|
|
2904
|
-
var
|
|
2905
|
-
var
|
|
3188
|
+
var import_react43 = require("react");
|
|
3189
|
+
var import_jsx_runtime56 = require("react/jsx-runtime");
|
|
2906
3190
|
function ChoiceGroup({ label, options, value, defaultValue, onChange, type = "radio", direction = "column", disabled, name }) {
|
|
2907
|
-
const id = (0,
|
|
3191
|
+
const id = (0, import_react43.useId)();
|
|
2908
3192
|
const groupName = name ?? id;
|
|
2909
3193
|
const values = Array.isArray(value) ? value : value ? [value] : void 0;
|
|
2910
3194
|
const defaults = Array.isArray(defaultValue) ? defaultValue : defaultValue ? [defaultValue] : [];
|
|
2911
|
-
return /* @__PURE__ */ (0,
|
|
2912
|
-
label && /* @__PURE__ */ (0,
|
|
3195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("fieldset", { className: `hf-choice-group hf-choice-group--${direction}`, disabled, children: [
|
|
3196
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("legend", { children: label }),
|
|
2913
3197
|
options.map((option) => {
|
|
2914
3198
|
const checked = values?.includes(option.value);
|
|
2915
|
-
return /* @__PURE__ */ (0,
|
|
2916
|
-
/* @__PURE__ */ (0,
|
|
3199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("label", { className: "hf-choice", children: [
|
|
3200
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("input", { type, name: type === "radio" ? groupName : `${groupName}-${option.value}`, value: option.value, checked, defaultChecked: values ? void 0 : defaults.includes(option.value), disabled: option.disabled, onChange: (event) => {
|
|
2917
3201
|
if (type === "radio") onChange?.(option.value);
|
|
2918
3202
|
else {
|
|
2919
3203
|
const next = new Set(values ?? defaults);
|
|
@@ -2921,37 +3205,37 @@ function ChoiceGroup({ label, options, value, defaultValue, onChange, type = "ra
|
|
|
2921
3205
|
onChange?.([...next]);
|
|
2922
3206
|
}
|
|
2923
3207
|
} }),
|
|
2924
|
-
/* @__PURE__ */ (0,
|
|
2925
|
-
/* @__PURE__ */ (0,
|
|
2926
|
-
/* @__PURE__ */ (0,
|
|
2927
|
-
option.description && /* @__PURE__ */ (0,
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "hf-choice__control", "aria-hidden": "true" }),
|
|
3209
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "hf-choice__copy", children: [
|
|
3210
|
+
/* @__PURE__ */ (0, import_jsx_runtime56.jsx)("strong", { children: option.label }),
|
|
3211
|
+
option.description && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("small", { children: option.description })
|
|
2928
3212
|
] })
|
|
2929
3213
|
] }, option.value);
|
|
2930
3214
|
})
|
|
2931
3215
|
] });
|
|
2932
3216
|
}
|
|
2933
3217
|
function RadioGroup(props) {
|
|
2934
|
-
return /* @__PURE__ */ (0,
|
|
3218
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ChoiceGroup, { ...props, type: "radio", onChange: (next) => props.onChange?.(next) });
|
|
2935
3219
|
}
|
|
2936
3220
|
function CheckboxGroup(props) {
|
|
2937
|
-
return /* @__PURE__ */ (0,
|
|
3221
|
+
return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ChoiceGroup, { ...props, type: "checkbox", onChange: (next) => props.onChange?.(next) });
|
|
2938
3222
|
}
|
|
2939
3223
|
|
|
2940
3224
|
// src/forms/ValidatedInput.tsx
|
|
2941
|
-
var
|
|
2942
|
-
var
|
|
3225
|
+
var import_react44 = require("react");
|
|
3226
|
+
var import_jsx_runtime57 = require("react/jsx-runtime");
|
|
2943
3227
|
function validateValue(value, rules) {
|
|
2944
3228
|
return rules.find((rule) => !rule.validate(value))?.message;
|
|
2945
3229
|
}
|
|
2946
3230
|
function ValidatedInput({ value, rules, validateOn = "blur", onChange, onValidityChange, ...props }) {
|
|
2947
|
-
const [touched, setTouched] = (0,
|
|
3231
|
+
const [touched, setTouched] = (0, import_react44.useState)(false);
|
|
2948
3232
|
const error = touched ? validateValue(value, rules) : void 0;
|
|
2949
3233
|
const update = (next) => {
|
|
2950
3234
|
onChange(next);
|
|
2951
3235
|
if (validateOn === "change") setTouched(true);
|
|
2952
3236
|
onValidityChange?.(!validateValue(next, rules));
|
|
2953
3237
|
};
|
|
2954
|
-
return /* @__PURE__ */ (0,
|
|
3238
|
+
return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(Input, { ...props, value, error, onChange: (event) => update(event.target.value), onBlur: () => setTouched(true) });
|
|
2955
3239
|
}
|
|
2956
3240
|
function validateForm(event) {
|
|
2957
3241
|
if (!event.currentTarget.checkValidity()) {
|
|
@@ -2963,26 +3247,26 @@ function validateForm(event) {
|
|
|
2963
3247
|
}
|
|
2964
3248
|
|
|
2965
3249
|
// src/forms/Textarea.tsx
|
|
2966
|
-
var
|
|
2967
|
-
var
|
|
2968
|
-
var Textarea = (0,
|
|
2969
|
-
const generated = (0,
|
|
3250
|
+
var import_react45 = require("react");
|
|
3251
|
+
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
3252
|
+
var Textarea = (0, import_react45.forwardRef)(function Textarea2({ label, hint, error, resize = "vertical", id, className = "", ...props }, ref) {
|
|
3253
|
+
const generated = (0, import_react45.useId)();
|
|
2970
3254
|
const fieldId = id ?? generated;
|
|
2971
3255
|
const message = error ?? hint;
|
|
2972
3256
|
const messageId = message ? `${fieldId}-message` : void 0;
|
|
2973
|
-
return /* @__PURE__ */ (0,
|
|
2974
|
-
label && /* @__PURE__ */ (0,
|
|
2975
|
-
/* @__PURE__ */ (0,
|
|
2976
|
-
message && /* @__PURE__ */ (0,
|
|
3257
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { className: "hf-field", htmlFor: fieldId, children: [
|
|
3258
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3259
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("textarea", { ref, id: fieldId, className: `hf-textarea hf-textarea--${resize}${error ? " hf-textarea--error" : ""} ${className}`, "aria-invalid": error ? true : void 0, "aria-describedby": messageId, ...props }),
|
|
3260
|
+
message && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { id: messageId, className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: message })
|
|
2977
3261
|
] });
|
|
2978
3262
|
});
|
|
2979
3263
|
|
|
2980
3264
|
// src/forms/Choice.tsx
|
|
2981
|
-
var
|
|
2982
|
-
var
|
|
2983
|
-
var Checkbox = (0,
|
|
2984
|
-
const local = (0,
|
|
2985
|
-
(0,
|
|
3265
|
+
var import_react46 = require("react");
|
|
3266
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
3267
|
+
var Checkbox = (0, import_react46.forwardRef)(function Checkbox2({ label, description, indeterminate, className = "", ...props }, forwardedRef) {
|
|
3268
|
+
const local = (0, import_react46.useRef)(null);
|
|
3269
|
+
(0, import_react46.useEffect)(() => {
|
|
2986
3270
|
if (local.current) local.current.indeterminate = Boolean(indeterminate);
|
|
2987
3271
|
}, [indeterminate]);
|
|
2988
3272
|
const setRef = (node) => {
|
|
@@ -2990,76 +3274,76 @@ var Checkbox = (0, import_react42.forwardRef)(function Checkbox2({ label, descri
|
|
|
2990
3274
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2991
3275
|
else if (forwardedRef) forwardedRef.current = node;
|
|
2992
3276
|
};
|
|
2993
|
-
return /* @__PURE__ */ (0,
|
|
2994
|
-
/* @__PURE__ */ (0,
|
|
2995
|
-
/* @__PURE__ */ (0,
|
|
2996
|
-
/* @__PURE__ */ (0,
|
|
2997
|
-
/* @__PURE__ */ (0,
|
|
2998
|
-
description && /* @__PURE__ */ (0,
|
|
3277
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { className: `hf-choice-control ${className}`, children: [
|
|
3278
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { ref: setRef, type: "checkbox", ...props }),
|
|
3279
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "hf-choice-control__mark", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(IconCheck, {}) }),
|
|
3280
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { children: [
|
|
3281
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { children: label }),
|
|
3282
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("small", { children: description })
|
|
2999
3283
|
] })
|
|
3000
3284
|
] });
|
|
3001
3285
|
});
|
|
3002
|
-
var Radio = (0,
|
|
3003
|
-
return /* @__PURE__ */ (0,
|
|
3004
|
-
/* @__PURE__ */ (0,
|
|
3005
|
-
/* @__PURE__ */ (0,
|
|
3006
|
-
/* @__PURE__ */ (0,
|
|
3007
|
-
/* @__PURE__ */ (0,
|
|
3008
|
-
description && /* @__PURE__ */ (0,
|
|
3286
|
+
var Radio = (0, import_react46.forwardRef)(function Radio2({ label, description, className = "", ...props }, ref) {
|
|
3287
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { className: `hf-choice-control hf-choice-control--radio ${className}`, children: [
|
|
3288
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { ref, type: "radio", ...props }),
|
|
3289
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "hf-choice-control__mark", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("i", {}) }),
|
|
3290
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { children: [
|
|
3291
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { children: label }),
|
|
3292
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("small", { children: description })
|
|
3009
3293
|
] })
|
|
3010
3294
|
] });
|
|
3011
3295
|
});
|
|
3012
3296
|
function IconCheck() {
|
|
3013
|
-
return /* @__PURE__ */ (0,
|
|
3297
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("path", { d: "m3.5 8 3 3 6-6" }) });
|
|
3014
3298
|
}
|
|
3015
3299
|
|
|
3016
3300
|
// src/forms/Advanced.tsx
|
|
3017
|
-
var
|
|
3018
|
-
var
|
|
3301
|
+
var import_react47 = require("react");
|
|
3302
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
3019
3303
|
var iso = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
3020
3304
|
function Calendar({ value, onChange, min, max, className = "" }) {
|
|
3021
3305
|
const initial = value ? /* @__PURE__ */ new Date(`${value}T00:00:00`) : /* @__PURE__ */ new Date();
|
|
3022
|
-
const [view, setView] = (0,
|
|
3306
|
+
const [view, setView] = (0, import_react47.useState)(new Date(initial.getFullYear(), initial.getMonth(), 1));
|
|
3023
3307
|
const first = view.getDay();
|
|
3024
3308
|
const days = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
|
|
3025
3309
|
const cells = Array.from(
|
|
3026
3310
|
{ length: Math.ceil((first + days) / 7) * 7 },
|
|
3027
3311
|
(_, index) => index - first + 1
|
|
3028
3312
|
);
|
|
3029
|
-
return /* @__PURE__ */ (0,
|
|
3030
|
-
/* @__PURE__ */ (0,
|
|
3031
|
-
/* @__PURE__ */ (0,
|
|
3313
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: `hf-calendar ${className}`, children: [
|
|
3314
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("header", { children: [
|
|
3315
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3032
3316
|
"button",
|
|
3033
3317
|
{
|
|
3034
3318
|
type: "button",
|
|
3035
3319
|
"aria-label": "\u4E0A\u4E2A\u6708",
|
|
3036
3320
|
onClick: () => setView(new Date(view.getFullYear(), view.getMonth() - 1, 1)),
|
|
3037
|
-
children: /* @__PURE__ */ (0,
|
|
3321
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "chevron-down", className: "hf-calendar__prev" })
|
|
3038
3322
|
}
|
|
3039
3323
|
),
|
|
3040
|
-
/* @__PURE__ */ (0,
|
|
3324
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("strong", { children: [
|
|
3041
3325
|
view.getFullYear(),
|
|
3042
3326
|
" \u5E74 ",
|
|
3043
3327
|
view.getMonth() + 1,
|
|
3044
3328
|
" \u6708"
|
|
3045
3329
|
] }),
|
|
3046
|
-
/* @__PURE__ */ (0,
|
|
3330
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3047
3331
|
"button",
|
|
3048
3332
|
{
|
|
3049
3333
|
type: "button",
|
|
3050
3334
|
"aria-label": "\u4E0B\u4E2A\u6708",
|
|
3051
3335
|
onClick: () => setView(new Date(view.getFullYear(), view.getMonth() + 1, 1)),
|
|
3052
|
-
children: /* @__PURE__ */ (0,
|
|
3336
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "chevron-down", className: "hf-calendar__next" })
|
|
3053
3337
|
}
|
|
3054
3338
|
)
|
|
3055
3339
|
] }),
|
|
3056
|
-
/* @__PURE__ */ (0,
|
|
3057
|
-
/* @__PURE__ */ (0,
|
|
3058
|
-
if (day2 < 1 || day2 > days) return /* @__PURE__ */ (0,
|
|
3340
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "hf-calendar__week", children: "\u65E5\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D".split("").map((day2) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: day2 }, day2)) }),
|
|
3341
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "hf-calendar__days", children: cells.map((day2, index) => {
|
|
3342
|
+
if (day2 < 1 || day2 > days) return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", {}, index);
|
|
3059
3343
|
const date = iso(new Date(view.getFullYear(), view.getMonth(), day2));
|
|
3060
3344
|
const disabled = Boolean(min && date < min || max && date > max);
|
|
3061
3345
|
const stateClass = date === value ? "is-selected" : date === iso(/* @__PURE__ */ new Date()) ? "is-today" : "";
|
|
3062
|
-
return /* @__PURE__ */ (0,
|
|
3346
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3063
3347
|
"button",
|
|
3064
3348
|
{
|
|
3065
3349
|
type: "button",
|
|
@@ -3083,13 +3367,13 @@ function DatePicker({
|
|
|
3083
3367
|
max,
|
|
3084
3368
|
error
|
|
3085
3369
|
}) {
|
|
3086
|
-
const [open, setOpen] = (0,
|
|
3370
|
+
const [open, setOpen] = (0, import_react47.useState)(false);
|
|
3087
3371
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), {
|
|
3088
3372
|
autoFocus: false
|
|
3089
3373
|
});
|
|
3090
|
-
return /* @__PURE__ */ (0,
|
|
3091
|
-
label && /* @__PURE__ */ (0,
|
|
3092
|
-
/* @__PURE__ */ (0,
|
|
3374
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { ref: rootRef, className: "hf-field hf-date-picker", children: [
|
|
3375
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3376
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
3093
3377
|
"button",
|
|
3094
3378
|
{
|
|
3095
3379
|
type: "button",
|
|
@@ -3097,12 +3381,12 @@ function DatePicker({
|
|
|
3097
3381
|
"aria-expanded": open,
|
|
3098
3382
|
onClick: () => setOpen(!open),
|
|
3099
3383
|
children: [
|
|
3100
|
-
/* @__PURE__ */ (0,
|
|
3101
|
-
/* @__PURE__ */ (0,
|
|
3384
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: value ? "" : "is-placeholder", children: value || placeholder }),
|
|
3385
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "chevron-down", size: 16 })
|
|
3102
3386
|
]
|
|
3103
3387
|
}
|
|
3104
3388
|
),
|
|
3105
|
-
open && /* @__PURE__ */ (0,
|
|
3389
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "hf-date-picker__panel", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3106
3390
|
Calendar,
|
|
3107
3391
|
{
|
|
3108
3392
|
value,
|
|
@@ -3114,11 +3398,11 @@ function DatePicker({
|
|
|
3114
3398
|
}
|
|
3115
3399
|
}
|
|
3116
3400
|
) }),
|
|
3117
|
-
error && /* @__PURE__ */ (0,
|
|
3401
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "hf-field__hint hf-field__hint--error", children: error })
|
|
3118
3402
|
] });
|
|
3119
3403
|
}
|
|
3120
3404
|
function TimePicker({ label, value, onChange, step = 30 }) {
|
|
3121
|
-
const [open, setOpen] = (0,
|
|
3405
|
+
const [open, setOpen] = (0, import_react47.useState)(false);
|
|
3122
3406
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), {
|
|
3123
3407
|
autoFocus: false
|
|
3124
3408
|
});
|
|
@@ -3126,9 +3410,9 @@ function TimePicker({ label, value, onChange, step = 30 }) {
|
|
|
3126
3410
|
const minutes = index * step;
|
|
3127
3411
|
return `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}`;
|
|
3128
3412
|
});
|
|
3129
|
-
return /* @__PURE__ */ (0,
|
|
3130
|
-
label && /* @__PURE__ */ (0,
|
|
3131
|
-
/* @__PURE__ */ (0,
|
|
3413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { ref: rootRef, className: "hf-field hf-time-picker", children: [
|
|
3414
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3415
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
|
|
3132
3416
|
"button",
|
|
3133
3417
|
{
|
|
3134
3418
|
type: "button",
|
|
@@ -3136,12 +3420,12 @@ function TimePicker({ label, value, onChange, step = 30 }) {
|
|
|
3136
3420
|
"aria-expanded": open,
|
|
3137
3421
|
onClick: () => setOpen(!open),
|
|
3138
3422
|
children: [
|
|
3139
|
-
/* @__PURE__ */ (0,
|
|
3140
|
-
/* @__PURE__ */ (0,
|
|
3423
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: value ? "" : "is-placeholder", children: value || "\u9009\u62E9\u65F6\u95F4" }),
|
|
3424
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "chevron-down", size: 16 })
|
|
3141
3425
|
]
|
|
3142
3426
|
}
|
|
3143
3427
|
),
|
|
3144
|
-
open && /* @__PURE__ */ (0,
|
|
3428
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "hf-time-picker__panel", role: "listbox", children: times.map((time) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3145
3429
|
"button",
|
|
3146
3430
|
{
|
|
3147
3431
|
type: "button",
|
|
@@ -3168,12 +3452,12 @@ function Slider({
|
|
|
3168
3452
|
...props
|
|
3169
3453
|
}) {
|
|
3170
3454
|
const percent = (value - Number(min)) / (Number(max) - Number(min)) * 100;
|
|
3171
|
-
return /* @__PURE__ */ (0,
|
|
3172
|
-
/* @__PURE__ */ (0,
|
|
3455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("label", { className: "hf-slider", children: [
|
|
3456
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { children: [
|
|
3173
3457
|
label,
|
|
3174
|
-
showValue && /* @__PURE__ */ (0,
|
|
3458
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("strong", { children: value })
|
|
3175
3459
|
] }),
|
|
3176
|
-
/* @__PURE__ */ (0,
|
|
3460
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3177
3461
|
"input",
|
|
3178
3462
|
{
|
|
3179
3463
|
type: "range",
|
|
@@ -3190,9 +3474,9 @@ function Slider({
|
|
|
3190
3474
|
}
|
|
3191
3475
|
|
|
3192
3476
|
// src/forms/Form.tsx
|
|
3193
|
-
var
|
|
3194
|
-
var
|
|
3195
|
-
var FormContext = (0,
|
|
3477
|
+
var import_react48 = require("react");
|
|
3478
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
3479
|
+
var FormContext = (0, import_react48.createContext)({});
|
|
3196
3480
|
function Form({
|
|
3197
3481
|
layout = "vertical",
|
|
3198
3482
|
disabled,
|
|
@@ -3200,13 +3484,13 @@ function Form({
|
|
|
3200
3484
|
children,
|
|
3201
3485
|
...props
|
|
3202
3486
|
}) {
|
|
3203
|
-
return /* @__PURE__ */ (0,
|
|
3487
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(FormContext.Provider, { value: { disabled }, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
3204
3488
|
"form",
|
|
3205
3489
|
{
|
|
3206
3490
|
className: `hf-form hf-form--${layout} ${className}`.trim(),
|
|
3207
3491
|
"aria-disabled": disabled || void 0,
|
|
3208
3492
|
...props,
|
|
3209
|
-
children: /* @__PURE__ */ (0,
|
|
3493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("fieldset", { className: "hf-form__fieldset", disabled, children })
|
|
3210
3494
|
}
|
|
3211
3495
|
) });
|
|
3212
3496
|
}
|
|
@@ -3219,21 +3503,21 @@ function FormItem({
|
|
|
3219
3503
|
className = "",
|
|
3220
3504
|
...props
|
|
3221
3505
|
}) {
|
|
3222
|
-
const { disabled } = (0,
|
|
3223
|
-
return /* @__PURE__ */ (0,
|
|
3506
|
+
const { disabled } = (0, import_react48.useContext)(FormContext);
|
|
3507
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(
|
|
3224
3508
|
"div",
|
|
3225
3509
|
{
|
|
3226
3510
|
className: `hf-form-item${error ? " is-error" : ""} ${className}`.trim(),
|
|
3227
3511
|
"aria-disabled": disabled || void 0,
|
|
3228
3512
|
...props,
|
|
3229
3513
|
children: [
|
|
3230
|
-
label && /* @__PURE__ */ (0,
|
|
3514
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "hf-form-item__label", children: [
|
|
3231
3515
|
label,
|
|
3232
|
-
required && /* @__PURE__ */ (0,
|
|
3516
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { "aria-hidden": "true", children: "*" })
|
|
3233
3517
|
] }),
|
|
3234
|
-
/* @__PURE__ */ (0,
|
|
3518
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
|
|
3235
3519
|
children,
|
|
3236
|
-
(error || hint) && /* @__PURE__ */ (0,
|
|
3520
|
+
(error || hint) && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("small", { className: error ? "is-error" : "", children: error || hint })
|
|
3237
3521
|
] })
|
|
3238
3522
|
]
|
|
3239
3523
|
}
|
|
@@ -3241,8 +3525,8 @@ function FormItem({
|
|
|
3241
3525
|
}
|
|
3242
3526
|
|
|
3243
3527
|
// src/forms/Upload.tsx
|
|
3244
|
-
var
|
|
3245
|
-
var
|
|
3528
|
+
var import_react49 = require("react");
|
|
3529
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
3246
3530
|
function formatFileSize(bytes) {
|
|
3247
3531
|
if (bytes >= 1024 * 1024) {
|
|
3248
3532
|
const megabytes = bytes / (1024 * 1024);
|
|
@@ -3301,10 +3585,10 @@ function Upload({
|
|
|
3301
3585
|
hint,
|
|
3302
3586
|
disabled
|
|
3303
3587
|
}) {
|
|
3304
|
-
const id = (0,
|
|
3305
|
-
const ref = (0,
|
|
3306
|
-
const [dragging, setDragging] = (0,
|
|
3307
|
-
const [rejections, setRejections] = (0,
|
|
3588
|
+
const id = (0, import_react49.useId)();
|
|
3589
|
+
const ref = (0, import_react49.useRef)(null);
|
|
3590
|
+
const [dragging, setDragging] = (0, import_react49.useState)(false);
|
|
3591
|
+
const [rejections, setRejections] = (0, import_react49.useState)([]);
|
|
3308
3592
|
const takeFiles = (list) => {
|
|
3309
3593
|
const result = validateUploadFiles(Array.from(list ?? []), {
|
|
3310
3594
|
accept,
|
|
@@ -3315,8 +3599,8 @@ function Upload({
|
|
|
3315
3599
|
onFiles(result.accepted);
|
|
3316
3600
|
if (result.rejected.length) onReject?.(result.rejected);
|
|
3317
3601
|
};
|
|
3318
|
-
return /* @__PURE__ */ (0,
|
|
3319
|
-
/* @__PURE__ */ (0,
|
|
3602
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "hf-upload", children: [
|
|
3603
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
|
|
3320
3604
|
"input",
|
|
3321
3605
|
{
|
|
3322
3606
|
ref,
|
|
@@ -3328,7 +3612,7 @@ function Upload({
|
|
|
3328
3612
|
onChange: (event) => takeFiles(event.target.files)
|
|
3329
3613
|
}
|
|
3330
3614
|
),
|
|
3331
|
-
/* @__PURE__ */ (0,
|
|
3615
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
3332
3616
|
"button",
|
|
3333
3617
|
{
|
|
3334
3618
|
type: "button",
|
|
@@ -3346,32 +3630,32 @@ function Upload({
|
|
|
3346
3630
|
if (!disabled) takeFiles(event.dataTransfer.files);
|
|
3347
3631
|
},
|
|
3348
3632
|
children: [
|
|
3349
|
-
/* @__PURE__ */ (0,
|
|
3350
|
-
/* @__PURE__ */ (0,
|
|
3351
|
-
/* @__PURE__ */ (0,
|
|
3633
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { name: "inbox", size: 24 }),
|
|
3634
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("strong", { children: label }),
|
|
3635
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: "\u62D6\u653E\u5230\u8FD9\u91CC\uFF0C\u6216\u70B9\u51FB\u9009\u62E9" })
|
|
3352
3636
|
]
|
|
3353
3637
|
}
|
|
3354
3638
|
),
|
|
3355
|
-
rejections.length > 0 && /* @__PURE__ */ (0,
|
|
3639
|
+
rejections.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "hf-upload__errors", role: "alert", children: rejections.map(({ file, reason, message }, index) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { children: [
|
|
3356
3640
|
file.name,
|
|
3357
3641
|
"\uFF1A",
|
|
3358
3642
|
message
|
|
3359
3643
|
] }, `${file.name}-${reason}-${index}`)) }),
|
|
3360
|
-
hint && /* @__PURE__ */ (0,
|
|
3644
|
+
hint && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("small", { children: hint })
|
|
3361
3645
|
] });
|
|
3362
3646
|
}
|
|
3363
3647
|
|
|
3364
3648
|
// src/forms/Combobox.tsx
|
|
3365
|
-
var
|
|
3366
|
-
var
|
|
3649
|
+
var import_react50 = require("react");
|
|
3650
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
3367
3651
|
function Combobox({ label, options, value = "", onChange, placeholder = "\u641C\u7D22\u6216\u9009\u62E9", hint, error, disabled, emptyText = "\u6CA1\u6709\u5339\u914D\u9879" }) {
|
|
3368
|
-
const id = (0,
|
|
3369
|
-
const [open, setOpen] = (0,
|
|
3652
|
+
const id = (0, import_react50.useId)();
|
|
3653
|
+
const [open, setOpen] = (0, import_react50.useState)(false);
|
|
3370
3654
|
const root = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
3371
|
-
const [query, setQuery] = (0,
|
|
3372
|
-
const [active, setActive] = (0,
|
|
3655
|
+
const [query, setQuery] = (0, import_react50.useState)("");
|
|
3656
|
+
const [active, setActive] = (0, import_react50.useState)(0);
|
|
3373
3657
|
const selected = options.find((item) => item.value === value);
|
|
3374
|
-
const filtered = (0,
|
|
3658
|
+
const filtered = (0, import_react50.useMemo)(() => options.filter((item) => `${typeof item.label === "string" ? item.label : item.value} ${item.keywords ?? ""}`.toLowerCase().includes(query.toLowerCase())), [options, query]);
|
|
3375
3659
|
const choose = (next) => {
|
|
3376
3660
|
onChange(next);
|
|
3377
3661
|
setQuery("");
|
|
@@ -3388,51 +3672,51 @@ function Combobox({ label, options, value = "", onChange, placeholder = "\u641C\
|
|
|
3388
3672
|
if (option && !option.disabled) choose(option.value);
|
|
3389
3673
|
} else if (event.key === "Escape") setOpen(false);
|
|
3390
3674
|
};
|
|
3391
|
-
return /* @__PURE__ */ (0,
|
|
3392
|
-
label && /* @__PURE__ */ (0,
|
|
3393
|
-
/* @__PURE__ */ (0,
|
|
3394
|
-
/* @__PURE__ */ (0,
|
|
3675
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "hf-field hf-combobox", ref: root, children: [
|
|
3676
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("label", { className: "hf-field__label", htmlFor: id, children: label }),
|
|
3677
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: `hf-combobox__control${open ? " is-open" : ""}${error ? " is-error" : ""}`, children: [
|
|
3678
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("input", { id, role: "combobox", "aria-expanded": open, "aria-controls": `${id}-listbox`, "aria-autocomplete": "list", "aria-invalid": Boolean(error), disabled, placeholder: selected && !open ? String(selected.label) : placeholder, value: open ? query : selected ? String(selected.label) : "", onFocus: () => setOpen(true), onChange: (event) => {
|
|
3395
3679
|
setQuery(event.target.value);
|
|
3396
3680
|
setActive(0);
|
|
3397
3681
|
setOpen(true);
|
|
3398
3682
|
}, onKeyDown }),
|
|
3399
|
-
/* @__PURE__ */ (0,
|
|
3683
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", "aria-label": open ? "\u5173\u95ED\u9009\u9879" : "\u6253\u5F00\u9009\u9879", disabled, onClick: () => setOpen((current) => !current), children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Icon, { name: "chevron-down", size: 16 }) })
|
|
3400
3684
|
] }),
|
|
3401
|
-
open && /* @__PURE__ */ (0,
|
|
3402
|
-
/* @__PURE__ */ (0,
|
|
3403
|
-
option.value === value && /* @__PURE__ */ (0,
|
|
3404
|
-
] }, option.value)) : /* @__PURE__ */ (0,
|
|
3405
|
-
(error || hint) && /* @__PURE__ */ (0,
|
|
3685
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { id: `${id}-listbox`, className: "hf-combobox__menu", role: "listbox", children: filtered.length ? filtered.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("button", { type: "button", role: "option", "aria-selected": option.value === value, disabled: option.disabled, className: index === active ? "is-active" : "", onPointerMove: () => setActive(index), onClick: () => choose(option.value), children: [
|
|
3686
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: option.label }),
|
|
3687
|
+
option.value === value && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { "aria-hidden": "true", children: "\u2713" })
|
|
3688
|
+
] }, option.value)) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "hf-combobox__empty", children: emptyText }) }),
|
|
3689
|
+
(error || hint) && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: error ?? hint })
|
|
3406
3690
|
] });
|
|
3407
3691
|
}
|
|
3408
3692
|
|
|
3409
3693
|
// src/forms/NumberInput.tsx
|
|
3410
|
-
var
|
|
3411
|
-
var
|
|
3694
|
+
var import_react51 = require("react");
|
|
3695
|
+
var import_jsx_runtime64 = require("react/jsx-runtime");
|
|
3412
3696
|
function NumberInput({ label, value, onChange, min, max, step = 1, prefix, suffix, hint, error, disabled }) {
|
|
3413
|
-
const id = (0,
|
|
3414
|
-
const
|
|
3415
|
-
return /* @__PURE__ */ (0,
|
|
3416
|
-
label && /* @__PURE__ */ (0,
|
|
3417
|
-
/* @__PURE__ */ (0,
|
|
3418
|
-
prefix && /* @__PURE__ */ (0,
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3697
|
+
const id = (0, import_react51.useId)();
|
|
3698
|
+
const clamp2 = (next) => Math.min(max ?? Infinity, Math.max(min ?? -Infinity, next));
|
|
3699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "hf-field hf-number-input", children: [
|
|
3700
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("label", { className: "hf-field__label", htmlFor: id, children: label }),
|
|
3701
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: `hf-number-input__control${error ? " is-error" : ""}`, children: [
|
|
3702
|
+
prefix && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { children: prefix }),
|
|
3703
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("input", { id, type: "number", value, min, max, step, disabled, "aria-invalid": Boolean(error), onChange: (event) => {
|
|
3420
3704
|
const next = event.currentTarget.valueAsNumber;
|
|
3421
|
-
if (!Number.isNaN(next)) onChange(
|
|
3705
|
+
if (!Number.isNaN(next)) onChange(clamp2(next));
|
|
3422
3706
|
} }),
|
|
3423
|
-
/* @__PURE__ */ (0,
|
|
3424
|
-
/* @__PURE__ */ (0,
|
|
3425
|
-
/* @__PURE__ */ (0,
|
|
3707
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { children: [
|
|
3708
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", disabled: disabled || max !== void 0 && value >= max, "aria-label": "\u589E\u52A0", onClick: () => onChange(clamp2(value + step)), children: "\uFF0B" }),
|
|
3709
|
+
/* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", disabled: disabled || min !== void 0 && value <= min, "aria-label": "\u51CF\u5C11", onClick: () => onChange(clamp2(value - step)), children: "\u2212" })
|
|
3426
3710
|
] }),
|
|
3427
|
-
suffix && /* @__PURE__ */ (0,
|
|
3711
|
+
suffix && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { children: suffix })
|
|
3428
3712
|
] }),
|
|
3429
|
-
(error || hint) && /* @__PURE__ */ (0,
|
|
3713
|
+
(error || hint) && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: error ?? hint })
|
|
3430
3714
|
] });
|
|
3431
3715
|
}
|
|
3432
3716
|
|
|
3433
3717
|
// src/forms/NextBatch.tsx
|
|
3434
|
-
var
|
|
3435
|
-
var
|
|
3718
|
+
var import_react52 = require("react");
|
|
3719
|
+
var import_jsx_runtime65 = require("react/jsx-runtime");
|
|
3436
3720
|
function Cascader({ options, value = [], onChange, label }) {
|
|
3437
3721
|
const levels = [options];
|
|
3438
3722
|
let current = options;
|
|
@@ -3442,44 +3726,44 @@ function Cascader({ options, value = [], onChange, label }) {
|
|
|
3442
3726
|
levels.push(next);
|
|
3443
3727
|
current = next;
|
|
3444
3728
|
}
|
|
3445
|
-
return /* @__PURE__ */ (0,
|
|
3446
|
-
label && /* @__PURE__ */ (0,
|
|
3447
|
-
/* @__PURE__ */ (0,
|
|
3729
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "hf-field hf-cascader", children: [
|
|
3730
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3731
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { children: levels.map((items, level) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Select, { "aria-label": `\u7B2C ${level + 1} \u7EA7`, className: "hf-cascader__level", value: value[level] ?? "", placeholder: "\u8BF7\u9009\u62E9", options: items.map((item) => ({ label: item.label, value: item.value, disabled: item.disabled })), onChange: (event) => onChange([...value.slice(0, level), event.target.value]) }, level)) })
|
|
3448
3732
|
] });
|
|
3449
3733
|
}
|
|
3450
3734
|
function TreeSelect({ options, value, onChange, label, placeholder = "\u9009\u62E9\u8282\u70B9" }) {
|
|
3451
|
-
const [open, setOpen] = (0,
|
|
3735
|
+
const [open, setOpen] = (0, import_react52.useState)(false);
|
|
3452
3736
|
const flatten = (nodes, depth = 0) => nodes.flatMap((node) => [{ node, depth }, ...flatten(node.children ?? [], depth + 1)]);
|
|
3453
3737
|
const all = flatten(options);
|
|
3454
|
-
return /* @__PURE__ */ (0,
|
|
3455
|
-
label && /* @__PURE__ */ (0,
|
|
3456
|
-
/* @__PURE__ */ (0,
|
|
3457
|
-
/* @__PURE__ */ (0,
|
|
3458
|
-
/* @__PURE__ */ (0,
|
|
3738
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "hf-field hf-tree-select", children: [
|
|
3739
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3740
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("button", { type: "button", className: "hf-picker-trigger", "aria-expanded": open, onClick: () => setOpen(!open), children: [
|
|
3741
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: all.find((item) => item.node.key === value)?.node.label ?? placeholder }),
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Icon, { className: "hf-picker-trigger__chevron", name: "chevron-down", size: 16 })
|
|
3459
3743
|
] }),
|
|
3460
|
-
open && /* @__PURE__ */ (0,
|
|
3744
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { role: "listbox", children: all.map(({ node, depth }) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", role: "option", "aria-selected": node.key === value, disabled: node.disabled, style: { paddingLeft: 12 + depth * 18 }, onClick: () => {
|
|
3461
3745
|
onChange(node.key);
|
|
3462
3746
|
setOpen(false);
|
|
3463
3747
|
}, children: node.label }, node.key)) })
|
|
3464
3748
|
] });
|
|
3465
3749
|
}
|
|
3466
3750
|
function Transfer({ items, value, onChange, titles = ["\u53EF\u9009\u9879", "\u5DF2\u9009\u62E9"] }) {
|
|
3467
|
-
const [marked, setMarked] = (0,
|
|
3468
|
-
const pane = (selected) => /* @__PURE__ */ (0,
|
|
3469
|
-
/* @__PURE__ */ (0,
|
|
3470
|
-
items.filter((item) => value.includes(item.key) === selected).map((item) => /* @__PURE__ */ (0,
|
|
3471
|
-
/* @__PURE__ */ (0,
|
|
3751
|
+
const [marked, setMarked] = (0, import_react52.useState)([]);
|
|
3752
|
+
const pane = (selected) => /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("section", { children: [
|
|
3753
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("strong", { children: titles[selected ? 1 : 0] }),
|
|
3754
|
+
items.filter((item) => value.includes(item.key) === selected).map((item) => /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("label", { children: [
|
|
3755
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("input", { type: "checkbox", disabled: item.disabled, checked: marked.includes(item.key), onChange: () => setMarked((keys) => keys.includes(item.key) ? keys.filter((key) => key !== item.key) : [...keys, item.key]) }),
|
|
3472
3756
|
item.label
|
|
3473
3757
|
] }, item.key))
|
|
3474
3758
|
] });
|
|
3475
|
-
return /* @__PURE__ */ (0,
|
|
3759
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "hf-transfer", children: [
|
|
3476
3760
|
pane(false),
|
|
3477
|
-
/* @__PURE__ */ (0,
|
|
3478
|
-
/* @__PURE__ */ (0,
|
|
3761
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { children: [
|
|
3762
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", "aria-label": "\u79FB\u81F3\u5DF2\u9009\u62E9", onClick: () => {
|
|
3479
3763
|
onChange([.../* @__PURE__ */ new Set([...value, ...marked])]);
|
|
3480
3764
|
setMarked([]);
|
|
3481
3765
|
}, children: "\u2192" }),
|
|
3482
|
-
/* @__PURE__ */ (0,
|
|
3766
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", "aria-label": "\u79FB\u56DE\u53EF\u9009\u9879", onClick: () => {
|
|
3483
3767
|
onChange(value.filter((key) => !marked.includes(key)));
|
|
3484
3768
|
setMarked([]);
|
|
3485
3769
|
}, children: "\u2190" })
|
|
@@ -3488,108 +3772,108 @@ function Transfer({ items, value, onChange, titles = ["\u53EF\u9009\u9879", "\u5
|
|
|
3488
3772
|
] });
|
|
3489
3773
|
}
|
|
3490
3774
|
function DateRangePicker({ label, value, onChange, min, max }) {
|
|
3491
|
-
return /* @__PURE__ */ (0,
|
|
3492
|
-
label && /* @__PURE__ */ (0,
|
|
3493
|
-
/* @__PURE__ */ (0,
|
|
3494
|
-
/* @__PURE__ */ (0,
|
|
3495
|
-
/* @__PURE__ */ (0,
|
|
3496
|
-
/* @__PURE__ */ (0,
|
|
3775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "hf-field hf-date-range", children: [
|
|
3776
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "hf-field__label", children: label }),
|
|
3777
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { children: [
|
|
3778
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("input", { "aria-label": "\u5F00\u59CB\u65E5\u671F", type: "date", value: value[0], min, max: value[1] || max, onChange: (event) => onChange([event.target.value, value[1]]) }),
|
|
3779
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { children: "\u81F3" }),
|
|
3780
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("input", { "aria-label": "\u7ED3\u675F\u65E5\u671F", type: "date", value: value[1], min: value[0] || min, max, onChange: (event) => onChange([value[0], event.target.value]) })
|
|
3497
3781
|
] })
|
|
3498
3782
|
] });
|
|
3499
3783
|
}
|
|
3500
3784
|
function SearchInput({ onSearch, loading, clearable = true, ...props }) {
|
|
3501
|
-
const [value, setValue] = (0,
|
|
3502
|
-
return /* @__PURE__ */ (0,
|
|
3785
|
+
const [value, setValue] = (0, import_react52.useState)(String(props.defaultValue ?? props.value ?? ""));
|
|
3786
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("form", { className: "hf-search-input", role: "search", onSubmit: (event) => {
|
|
3503
3787
|
event.preventDefault();
|
|
3504
3788
|
onSearch(value);
|
|
3505
3789
|
}, children: [
|
|
3506
|
-
/* @__PURE__ */ (0,
|
|
3507
|
-
/* @__PURE__ */ (0,
|
|
3790
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { "aria-hidden": "true", children: "\u2315" }),
|
|
3791
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("input", { ...props, value, onChange: (event) => {
|
|
3508
3792
|
setValue(event.target.value);
|
|
3509
3793
|
props.onChange?.(event);
|
|
3510
3794
|
} }),
|
|
3511
|
-
clearable && value && /* @__PURE__ */ (0,
|
|
3512
|
-
/* @__PURE__ */ (0,
|
|
3795
|
+
clearable && value && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", "aria-label": "\u6E05\u9664\u641C\u7D22", onClick: () => setValue(""), children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Icon, { name: "close", size: 14 }) }),
|
|
3796
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "submit", disabled: loading, children: loading ? "\u641C\u7D22\u4E2D" : "\u641C\u7D22" })
|
|
3513
3797
|
] });
|
|
3514
3798
|
}
|
|
3515
3799
|
|
|
3516
3800
|
// src/feedback/Drawer.tsx
|
|
3517
|
-
var
|
|
3801
|
+
var import_react53 = require("react");
|
|
3518
3802
|
var import_react_dom5 = require("react-dom");
|
|
3519
|
-
var
|
|
3803
|
+
var import_jsx_runtime66 = require("react/jsx-runtime");
|
|
3520
3804
|
function Drawer({ open, title, children, onClose, footer, side = "right", size = "md" }) {
|
|
3521
|
-
const titleId = (0,
|
|
3805
|
+
const titleId = (0, import_react53.useId)();
|
|
3522
3806
|
const drawerRef = useDismissibleLayer(open, onClose, true);
|
|
3523
3807
|
if (!open) return null;
|
|
3524
|
-
return (0, import_react_dom5.createPortal)(/* @__PURE__ */ (0,
|
|
3525
|
-
/* @__PURE__ */ (0,
|
|
3526
|
-
/* @__PURE__ */ (0,
|
|
3527
|
-
/* @__PURE__ */ (0,
|
|
3808
|
+
return (0, import_react_dom5.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "hf-drawer-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { ref: drawerRef, className: `hf-drawer hf-drawer--${side} hf-drawer--${size}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [
|
|
3809
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("header", { children: [
|
|
3810
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("h2", { id: titleId, children: title }),
|
|
3811
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Button, { variant: "quiet", size: "sm", iconOnly: true, leadingIcon: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Icon, { name: "close", size: 16 }), onClick: onClose, "aria-label": "\u5173\u95ED\u62BD\u5C49" })
|
|
3528
3812
|
] }),
|
|
3529
|
-
/* @__PURE__ */ (0,
|
|
3530
|
-
footer && /* @__PURE__ */ (0,
|
|
3813
|
+
/* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "hf-drawer__body", children }),
|
|
3814
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("footer", { children: footer })
|
|
3531
3815
|
] }) }), document.body);
|
|
3532
3816
|
}
|
|
3533
3817
|
|
|
3534
3818
|
// src/feedback/Popover.tsx
|
|
3535
|
-
var
|
|
3536
|
-
var
|
|
3819
|
+
var import_react54 = require("react");
|
|
3820
|
+
var import_jsx_runtime67 = require("react/jsx-runtime");
|
|
3537
3821
|
function Popover({ trigger, children, open, defaultOpen = false, onOpenChange, placement = "bottom", label = "\u66F4\u591A\u5185\u5BB9" }) {
|
|
3538
|
-
const [innerOpen, setInnerOpen] = (0,
|
|
3822
|
+
const [innerOpen, setInnerOpen] = (0, import_react54.useState)(defaultOpen);
|
|
3539
3823
|
const controlled = open !== void 0;
|
|
3540
3824
|
const visible = controlled ? open : innerOpen;
|
|
3541
|
-
const contentId = (0,
|
|
3825
|
+
const contentId = (0, import_react54.useId)();
|
|
3542
3826
|
const update = (next) => {
|
|
3543
3827
|
if (!controlled) setInnerOpen(next);
|
|
3544
3828
|
onOpenChange?.(next);
|
|
3545
3829
|
};
|
|
3546
3830
|
const rootRef = useDismissibleLayer(visible, () => update(false));
|
|
3547
3831
|
const triggerProps = { "aria-expanded": visible, "aria-controls": visible ? contentId : void 0, "aria-haspopup": "dialog", onClick: () => update(!visible) };
|
|
3548
|
-
return /* @__PURE__ */ (0,
|
|
3549
|
-
(0,
|
|
3550
|
-
visible && /* @__PURE__ */ (0,
|
|
3832
|
+
return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("span", { className: "hf-popover", ref: rootRef, children: [
|
|
3833
|
+
(0, import_react54.isValidElement)(trigger) && (0, import_react54.cloneElement)(trigger, triggerProps),
|
|
3834
|
+
visible && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { id: contentId, role: "dialog", "aria-label": label, className: `hf-popover__content hf-popover__content--${placement}`, children })
|
|
3551
3835
|
] });
|
|
3552
3836
|
}
|
|
3553
3837
|
|
|
3554
3838
|
// src/feedback/Status.tsx
|
|
3555
|
-
var
|
|
3556
|
-
var
|
|
3839
|
+
var import_react55 = require("react");
|
|
3840
|
+
var import_jsx_runtime68 = require("react/jsx-runtime");
|
|
3557
3841
|
function Tooltip({ content, children, placement = "top" }) {
|
|
3558
|
-
const [open, setOpen] = (0,
|
|
3559
|
-
const id = (0,
|
|
3560
|
-
const trigger = (0,
|
|
3561
|
-
return /* @__PURE__ */ (0,
|
|
3842
|
+
const [open, setOpen] = (0, import_react55.useState)(false);
|
|
3843
|
+
const id = (0, import_react55.useId)();
|
|
3844
|
+
const trigger = (0, import_react55.cloneElement)(children, { "aria-describedby": open ? id : void 0 });
|
|
3845
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { className: "hf-tooltip", onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false), onFocus: () => setOpen(true), onBlur: () => setOpen(false), children: [
|
|
3562
3846
|
trigger,
|
|
3563
|
-
open && /* @__PURE__ */ (0,
|
|
3847
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { id, role: "tooltip", className: `hf-tooltip__bubble hf-tooltip__bubble--${placement}`, children: content })
|
|
3564
3848
|
] });
|
|
3565
3849
|
}
|
|
3566
3850
|
function Alert({ tone = "info", title, children, onClose, action }) {
|
|
3567
3851
|
const icon = { info: "info", success: "check", warning: "warning", danger: "error" };
|
|
3568
|
-
return /* @__PURE__ */ (0,
|
|
3569
|
-
/* @__PURE__ */ (0,
|
|
3570
|
-
/* @__PURE__ */ (0,
|
|
3571
|
-
/* @__PURE__ */ (0,
|
|
3572
|
-
children && /* @__PURE__ */ (0,
|
|
3573
|
-
action && /* @__PURE__ */ (0,
|
|
3852
|
+
return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: `hf-alert hf-alert--${tone}`, role: tone === "danger" ? "alert" : "status", children: [
|
|
3853
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Icon, { name: icon[tone] }),
|
|
3854
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { children: [
|
|
3855
|
+
/* @__PURE__ */ (0, import_jsx_runtime68.jsx)("strong", { children: title }),
|
|
3856
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { children }),
|
|
3857
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "hf-alert__action", children: action })
|
|
3574
3858
|
] }),
|
|
3575
|
-
onClose && /* @__PURE__ */ (0,
|
|
3859
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("button", { type: "button", onClick: onClose, "aria-label": "\u5173\u95ED\u63D0\u793A", children: /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Icon, { name: "close", size: 16 }) })
|
|
3576
3860
|
] });
|
|
3577
3861
|
}
|
|
3578
3862
|
|
|
3579
3863
|
// src/feedback/Essentials.tsx
|
|
3580
|
-
var
|
|
3581
|
-
var
|
|
3864
|
+
var import_react56 = require("react");
|
|
3865
|
+
var import_jsx_runtime69 = require("react/jsx-runtime");
|
|
3582
3866
|
function Popconfirm({ trigger, title, description, confirmText = "\u786E\u8BA4", cancelText = "\u53D6\u6D88", tone = "primary", onConfirm }) {
|
|
3583
|
-
const [open, setOpen] = (0,
|
|
3867
|
+
const [open, setOpen] = (0, import_react56.useState)(false);
|
|
3584
3868
|
const root = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
3585
|
-
return /* @__PURE__ */ (0,
|
|
3586
|
-
(0,
|
|
3587
|
-
open && /* @__PURE__ */ (0,
|
|
3588
|
-
/* @__PURE__ */ (0,
|
|
3589
|
-
description && /* @__PURE__ */ (0,
|
|
3590
|
-
/* @__PURE__ */ (0,
|
|
3591
|
-
/* @__PURE__ */ (0,
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
3869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { className: "hf-popconfirm", ref: root, children: [
|
|
3870
|
+
(0, import_react56.isValidElement)(trigger) && (0, import_react56.cloneElement)(trigger, { onClick: () => setOpen(true), "aria-expanded": open }),
|
|
3871
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { role: "alertdialog", "aria-modal": "false", className: "hf-popconfirm__panel", children: [
|
|
3872
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("strong", { children: title }),
|
|
3873
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("p", { children: description }),
|
|
3874
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { children: [
|
|
3875
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Button, { size: "sm", variant: "quiet", onClick: () => setOpen(false), children: cancelText }),
|
|
3876
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Button, { size: "sm", variant: tone === "danger" ? "danger" : "primary", onClick: () => {
|
|
3593
3877
|
onConfirm();
|
|
3594
3878
|
setOpen(false);
|
|
3595
3879
|
}, children: confirmText })
|
|
@@ -3599,82 +3883,82 @@ function Popconfirm({ trigger, title, description, confirmText = "\u786E\u8BA4",
|
|
|
3599
3883
|
}
|
|
3600
3884
|
function Notification({ title, children, tone = "info", time, unread, action, onClose }) {
|
|
3601
3885
|
const icons = { info: "info", success: "check", warning: "warning", danger: "error" };
|
|
3602
|
-
return /* @__PURE__ */ (0,
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3604
|
-
/* @__PURE__ */ (0,
|
|
3605
|
-
/* @__PURE__ */ (0,
|
|
3606
|
-
/* @__PURE__ */ (0,
|
|
3607
|
-
time && /* @__PURE__ */ (0,
|
|
3886
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("article", { className: `hf-notification hf-notification--${tone}${unread ? " is-unread" : ""}`, children: [
|
|
3887
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "hf-notification__icon", children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Icon, { name: icons[tone], size: 18 }) }),
|
|
3888
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { children: [
|
|
3889
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("header", { children: [
|
|
3890
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("strong", { children: title }),
|
|
3891
|
+
time && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("time", { children: time })
|
|
3608
3892
|
] }),
|
|
3609
|
-
children && /* @__PURE__ */ (0,
|
|
3610
|
-
action && /* @__PURE__ */ (0,
|
|
3893
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("p", { children }),
|
|
3894
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "hf-notification__action", children: action })
|
|
3611
3895
|
] }),
|
|
3612
|
-
onClose && /* @__PURE__ */ (0,
|
|
3896
|
+
onClose && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("button", { type: "button", "aria-label": "\u5173\u95ED\u901A\u77E5", onClick: onClose, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Icon, { name: "close", size: 15 }) })
|
|
3613
3897
|
] });
|
|
3614
3898
|
}
|
|
3615
3899
|
function Result({ status = "info", title, description, actions, extra }) {
|
|
3616
3900
|
const icon = status === "success" ? "\u2713" : status === "error" ? "\xD7" : status === "warning" ? "!" : status === "info" ? "i" : status;
|
|
3617
|
-
return /* @__PURE__ */ (0,
|
|
3618
|
-
/* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
3620
|
-
description && /* @__PURE__ */ (0,
|
|
3621
|
-
actions && /* @__PURE__ */ (0,
|
|
3622
|
-
extra && /* @__PURE__ */ (0,
|
|
3901
|
+
return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("section", { className: `hf-result hf-result--${status}`, children: [
|
|
3902
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "hf-result__icon", "aria-hidden": "true", children: icon }),
|
|
3903
|
+
/* @__PURE__ */ (0, import_jsx_runtime69.jsx)("h2", { children: title }),
|
|
3904
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("p", { children: description }),
|
|
3905
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "hf-result__actions", children: actions }),
|
|
3906
|
+
extra && /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "hf-result__extra", children: extra })
|
|
3623
3907
|
] });
|
|
3624
3908
|
}
|
|
3625
3909
|
|
|
3626
3910
|
// src/data-display/DataDisplay.tsx
|
|
3627
|
-
var
|
|
3911
|
+
var import_jsx_runtime70 = require("react/jsx-runtime");
|
|
3628
3912
|
function StatisticCard({ label, value, trend, icon, tone = "blue", className = "", ...props }) {
|
|
3629
|
-
return /* @__PURE__ */ (0,
|
|
3630
|
-
/* @__PURE__ */ (0,
|
|
3631
|
-
/* @__PURE__ */ (0,
|
|
3632
|
-
icon && /* @__PURE__ */ (0,
|
|
3913
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("article", { className: `hf-stat hf-stat--${tone} ${className}`.trim(), ...props, children: [
|
|
3914
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "hf-stat__top", children: [
|
|
3915
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { children: label }),
|
|
3916
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", { children: icon })
|
|
3633
3917
|
] }),
|
|
3634
|
-
/* @__PURE__ */ (0,
|
|
3635
|
-
trend && /* @__PURE__ */ (0,
|
|
3636
|
-
/* @__PURE__ */ (0,
|
|
3918
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("strong", { children: value }),
|
|
3919
|
+
trend && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("small", { children: trend }),
|
|
3920
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "hf-stat__glow", "aria-hidden": "true" })
|
|
3637
3921
|
] });
|
|
3638
3922
|
}
|
|
3639
3923
|
var Stat = StatisticCard;
|
|
3640
3924
|
function Progress({ value, max = 100, label, showValue = true, size = "md", tone = "primary", className = "", ...props }) {
|
|
3641
3925
|
const percent = Math.min(100, Math.max(0, max ? value / max * 100 : 0));
|
|
3642
|
-
return /* @__PURE__ */ (0,
|
|
3643
|
-
(label || showValue) && /* @__PURE__ */ (0,
|
|
3644
|
-
/* @__PURE__ */ (0,
|
|
3645
|
-
showValue && /* @__PURE__ */ (0,
|
|
3926
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: `hf-progress hf-progress--${size} hf-progress--${tone} ${className}`.trim(), ...props, children: [
|
|
3927
|
+
(label || showValue) && /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "hf-progress__meta", children: [
|
|
3928
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { children: label }),
|
|
3929
|
+
showValue && /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("strong", { children: [
|
|
3646
3930
|
Math.round(percent),
|
|
3647
3931
|
"%"
|
|
3648
3932
|
] })
|
|
3649
3933
|
] }),
|
|
3650
|
-
/* @__PURE__ */ (0,
|
|
3934
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": max, "aria-valuenow": value, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { style: { "--hf-progress": `${percent}%` } }) })
|
|
3651
3935
|
] });
|
|
3652
3936
|
}
|
|
3653
3937
|
function CircularProgress({ value, max = 100, label, size = 92, thickness = 8, className = "", ...props }) {
|
|
3654
3938
|
const percent = Math.min(100, Math.max(0, max ? value / max * 100 : 0));
|
|
3655
|
-
return /* @__PURE__ */ (0,
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
3939
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("div", { className: `hf-circular-progress ${className}`.trim(), style: { "--hf-circle": `${percent * 3.6}deg`, "--hf-circle-size": `${size}px`, "--hf-circle-thickness": `${thickness}px` }, role: "progressbar", "aria-valuemin": 0, "aria-valuemax": max, "aria-valuenow": value, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { children: [
|
|
3940
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("strong", { children: [
|
|
3657
3941
|
Math.round(percent),
|
|
3658
3942
|
"%"
|
|
3659
3943
|
] }),
|
|
3660
|
-
label && /* @__PURE__ */ (0,
|
|
3944
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("small", { children: label })
|
|
3661
3945
|
] }) });
|
|
3662
3946
|
}
|
|
3663
3947
|
function StepProgress({ steps, current, className = "", ...props }) {
|
|
3664
|
-
return /* @__PURE__ */ (0,
|
|
3665
|
-
/* @__PURE__ */ (0,
|
|
3666
|
-
/* @__PURE__ */ (0,
|
|
3948
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("ol", { className: `hf-step-progress ${className}`.trim(), ...props, children: steps.map((step, index) => /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("li", { className: index < current ? "is-complete" : index === current ? "is-current" : "", children: [
|
|
3949
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { children: index < current ? "\u2713" : index + 1 }),
|
|
3950
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("small", { children: step })
|
|
3667
3951
|
] }, index)) });
|
|
3668
3952
|
}
|
|
3669
3953
|
function ActivityIndicator({ variant = "spinner", label = "\u6B63\u5728\u52A0\u8F7D", size = "md", className = "", ...props }) {
|
|
3670
|
-
return /* @__PURE__ */ (0,
|
|
3671
|
-
variant === "dots" && /* @__PURE__ */ (0,
|
|
3672
|
-
/* @__PURE__ */ (0,
|
|
3673
|
-
/* @__PURE__ */ (0,
|
|
3674
|
-
/* @__PURE__ */ (0,
|
|
3954
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("span", { className: `hf-activity hf-activity--${variant} hf-activity--${size} ${className}`.trim(), role: "status", "aria-label": label, ...props, children: [
|
|
3955
|
+
variant === "dots" && /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
|
|
3956
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", {}),
|
|
3957
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", {}),
|
|
3958
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", {})
|
|
3675
3959
|
] }),
|
|
3676
|
-
variant === "wave" && Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ (0,
|
|
3677
|
-
variant === "radar" && /* @__PURE__ */ (0,
|
|
3960
|
+
variant === "wave" && Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", {}, index)),
|
|
3961
|
+
variant === "radar" && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("i", {})
|
|
3678
3962
|
] });
|
|
3679
3963
|
}
|
|
3680
3964
|
function Sparkline({ data, width = 160, height = 48, label = "\u8D8B\u52BF\u56FE", filled = true, ...props }) {
|
|
@@ -3683,27 +3967,27 @@ function Sparkline({ data, width = 160, height = 48, label = "\u8D8B\u52BF\u56FE
|
|
|
3683
3967
|
const range = max - min || 1;
|
|
3684
3968
|
const points = data.map((value, index) => `${data.length === 1 ? width / 2 : index / (data.length - 1) * width},${height - ((value - min) / range * (height - 8) + 4)}`).join(" ");
|
|
3685
3969
|
const area = `0,${height} ${points} ${width},${height}`;
|
|
3686
|
-
return /* @__PURE__ */ (0,
|
|
3687
|
-
filled && /* @__PURE__ */ (0,
|
|
3688
|
-
/* @__PURE__ */ (0,
|
|
3970
|
+
return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("svg", { className: "hf-sparkline", viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": label, ...props, children: [
|
|
3971
|
+
filled && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("polygon", { points: area, className: "hf-sparkline__area" }),
|
|
3972
|
+
/* @__PURE__ */ (0, import_jsx_runtime70.jsx)("polyline", { points, className: "hf-sparkline__line" })
|
|
3689
3973
|
] });
|
|
3690
3974
|
}
|
|
3691
3975
|
|
|
3692
3976
|
// src/data-display/Collections.tsx
|
|
3693
|
-
var
|
|
3977
|
+
var import_jsx_runtime71 = require("react/jsx-runtime");
|
|
3694
3978
|
function Table({ columns, data, rowKey, caption, empty = "\u6682\u65E0\u6570\u636E", striped, onRowClick, className = "", ...props }) {
|
|
3695
3979
|
const keyOf = (item, index) => typeof rowKey === "function" ? rowKey(item, index) : String(item[rowKey]);
|
|
3696
|
-
return /* @__PURE__ */ (0,
|
|
3697
|
-
caption && /* @__PURE__ */ (0,
|
|
3698
|
-
/* @__PURE__ */ (0,
|
|
3699
|
-
/* @__PURE__ */ (0,
|
|
3700
|
-
data.map((item, index) => /* @__PURE__ */ (0,
|
|
3980
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: `hf-table-wrap ${className}`, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("table", { className: `hf-table${striped ? " hf-table--striped" : ""}`, children: [
|
|
3981
|
+
caption && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("caption", { children: caption }),
|
|
3982
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("tr", { children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("th", { style: { textAlign: column.align, width: column.width }, children: column.header }, column.key)) }) }),
|
|
3983
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("tbody", { children: [
|
|
3984
|
+
data.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("tr", { className: onRowClick ? "is-clickable" : "", onClick: () => onRowClick?.(item, index), tabIndex: onRowClick ? 0 : void 0, onKeyDown: (event) => {
|
|
3701
3985
|
if (onRowClick && (event.key === "Enter" || event.key === " ")) {
|
|
3702
3986
|
event.preventDefault();
|
|
3703
3987
|
onRowClick(item, index);
|
|
3704
3988
|
}
|
|
3705
|
-
}, children: columns.map((column) => /* @__PURE__ */ (0,
|
|
3706
|
-
!data.length && /* @__PURE__ */ (0,
|
|
3989
|
+
}, children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("td", { style: { textAlign: column.align }, children: column.render ? column.render(item, index) : String(item[column.key] ?? "") }, column.key)) }, keyOf(item, index))),
|
|
3990
|
+
!data.length && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("td", { className: "hf-table__empty", colSpan: columns.length, children: empty }) })
|
|
3707
3991
|
] })
|
|
3708
3992
|
] }) });
|
|
3709
3993
|
}
|
|
@@ -3716,71 +4000,71 @@ function Pagination({ page, total, pageSize = 10, siblingCount = 1, onChange, cl
|
|
|
3716
4000
|
if (index && value - visible[index - 1] > 1) parts.push("ellipsis");
|
|
3717
4001
|
parts.push(value);
|
|
3718
4002
|
});
|
|
3719
|
-
return /* @__PURE__ */ (0,
|
|
3720
|
-
/* @__PURE__ */ (0,
|
|
3721
|
-
parts.map((part, index) => part === "ellipsis" ? /* @__PURE__ */ (0,
|
|
3722
|
-
/* @__PURE__ */ (0,
|
|
4003
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("nav", { className: `hf-pagination ${className}`, "aria-label": "\u5206\u9875", ...props, children: [
|
|
4004
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { disabled: current === 1, onClick: () => onChange(current - 1), "aria-label": "\u4E0A\u4E00\u9875", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Icon, { name: "chevron-down", size: 16, className: "hf-pagination__prev" }) }),
|
|
4005
|
+
parts.map((part, index) => part === "ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { "aria-hidden": "true", children: "\u2026" }, `e-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { className: part === current ? "is-active" : "", "aria-current": part === current ? "page" : void 0, onClick: () => onChange(part), children: part }, part)),
|
|
4006
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { disabled: current === count, onClick: () => onChange(current + 1), "aria-label": "\u4E0B\u4E00\u9875", children: /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(Icon, { name: "chevron-down", size: 16, className: "hf-pagination__next" }) })
|
|
3723
4007
|
] });
|
|
3724
4008
|
}
|
|
3725
4009
|
function List({ items, divided = true, className = "", ...props }) {
|
|
3726
|
-
return /* @__PURE__ */ (0,
|
|
3727
|
-
item.leading && /* @__PURE__ */ (0,
|
|
3728
|
-
/* @__PURE__ */ (0,
|
|
3729
|
-
/* @__PURE__ */ (0,
|
|
3730
|
-
item.description && /* @__PURE__ */ (0,
|
|
4010
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("ul", { className: `hf-list${divided ? " hf-list--divided" : ""} ${className}`, ...props, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("li", { children: [
|
|
4011
|
+
item.leading && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "hf-list__leading", children: item.leading }),
|
|
4012
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { children: [
|
|
4013
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("strong", { children: item.title }),
|
|
4014
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("small", { children: item.description })
|
|
3731
4015
|
] }),
|
|
3732
|
-
item.trailing && /* @__PURE__ */ (0,
|
|
4016
|
+
item.trailing && /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { className: "hf-list__trailing", children: item.trailing })
|
|
3733
4017
|
] }, item.key)) });
|
|
3734
4018
|
}
|
|
3735
4019
|
function Descriptions({ items, columns = 2, bordered, className = "", ...props }) {
|
|
3736
|
-
return /* @__PURE__ */ (0,
|
|
3737
|
-
/* @__PURE__ */ (0,
|
|
3738
|
-
/* @__PURE__ */ (0,
|
|
4020
|
+
return /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("dl", { className: `hf-descriptions hf-descriptions--${columns}${bordered ? " hf-descriptions--bordered" : ""} ${className}`, ...props, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { style: { gridColumn: `span ${Math.min(item.span ?? 1, columns)}` }, children: [
|
|
4021
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("dt", { children: item.label }),
|
|
4022
|
+
/* @__PURE__ */ (0, import_jsx_runtime71.jsx)("dd", { children: item.value })
|
|
3739
4023
|
] }, item.key)) });
|
|
3740
4024
|
}
|
|
3741
4025
|
|
|
3742
4026
|
// src/data-display/Insight.tsx
|
|
3743
|
-
var
|
|
4027
|
+
var import_jsx_runtime72 = require("react/jsx-runtime");
|
|
3744
4028
|
function Timeline({ items, label = "\u65F6\u95F4\u8F74" }) {
|
|
3745
|
-
return /* @__PURE__ */ (0,
|
|
3746
|
-
/* @__PURE__ */ (0,
|
|
3747
|
-
/* @__PURE__ */ (0,
|
|
3748
|
-
/* @__PURE__ */ (0,
|
|
3749
|
-
item.description && /* @__PURE__ */ (0,
|
|
4029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("ol", { className: "hf-timeline", "aria-label": label, children: items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("li", { className: `hf-timeline--${item.status ?? "upcoming"}`, children: [
|
|
4030
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("i", { "aria-hidden": "true" }),
|
|
4031
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("div", { children: [
|
|
4032
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("strong", { children: item.title }),
|
|
4033
|
+
item.description && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("p", { children: item.description })
|
|
3750
4034
|
] }),
|
|
3751
|
-
item.time && /* @__PURE__ */ (0,
|
|
4035
|
+
item.time && /* @__PURE__ */ (0, import_jsx_runtime72.jsx)("time", { children: item.time })
|
|
3752
4036
|
] }, item.key)) });
|
|
3753
4037
|
}
|
|
3754
4038
|
function InsightBoard({ summary, trend, detail, heading, filters }) {
|
|
3755
|
-
return /* @__PURE__ */ (0,
|
|
3756
|
-
(heading || filters) && /* @__PURE__ */ (0,
|
|
3757
|
-
/* @__PURE__ */ (0,
|
|
4039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("section", { className: "hf-insight-board", children: [
|
|
4040
|
+
(heading || filters) && /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)("header", { children: [
|
|
4041
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { children: heading }),
|
|
3758
4042
|
filters
|
|
3759
4043
|
] }),
|
|
3760
|
-
/* @__PURE__ */ (0,
|
|
3761
|
-
/* @__PURE__ */ (0,
|
|
3762
|
-
/* @__PURE__ */ (0,
|
|
4044
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "hf-insight-board__summary", "aria-label": "\u6838\u5FC3\u7ED3\u679C", children: summary }),
|
|
4045
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "hf-insight-board__trend", "aria-label": "\u53D8\u5316\u8D8B\u52BF", children: trend }),
|
|
4046
|
+
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)("div", { className: "hf-insight-board__detail", "aria-label": "\u660E\u7EC6\u4E0E\u539F\u56E0", children: detail })
|
|
3763
4047
|
] });
|
|
3764
4048
|
}
|
|
3765
4049
|
|
|
3766
4050
|
// src/data-display/EmptyState.tsx
|
|
3767
|
-
var
|
|
4051
|
+
var import_jsx_runtime73 = require("react/jsx-runtime");
|
|
3768
4052
|
function EmptyState({ icon = "inbox", title, description, action, size = "md" }) {
|
|
3769
|
-
return /* @__PURE__ */ (0,
|
|
3770
|
-
/* @__PURE__ */ (0,
|
|
3771
|
-
/* @__PURE__ */ (0,
|
|
3772
|
-
description && /* @__PURE__ */ (0,
|
|
3773
|
-
action && /* @__PURE__ */ (0,
|
|
4053
|
+
return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: `hf-empty hf-empty--${size}`, children: [
|
|
4054
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "hf-empty__icon", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Icon, { name: icon, size: size === "sm" ? 22 : 28 }) }),
|
|
4055
|
+
/* @__PURE__ */ (0, import_jsx_runtime73.jsx)("strong", { children: title }),
|
|
4056
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { children: description }),
|
|
4057
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { children: action })
|
|
3774
4058
|
] });
|
|
3775
4059
|
}
|
|
3776
4060
|
|
|
3777
4061
|
// src/data-display/DataGrid.tsx
|
|
3778
|
-
var
|
|
3779
|
-
var
|
|
4062
|
+
var import_react57 = require("react");
|
|
4063
|
+
var import_jsx_runtime74 = require("react/jsx-runtime");
|
|
3780
4064
|
function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange, empty = "\u6682\u65E0\u6570\u636E", caption }) {
|
|
3781
|
-
const [sort, setSort] = (0,
|
|
4065
|
+
const [sort, setSort] = (0, import_react57.useState)();
|
|
3782
4066
|
const keyOf = (item) => typeof rowKey === "function" ? rowKey(item) : String(item[rowKey]);
|
|
3783
|
-
const rows = (0,
|
|
4067
|
+
const rows = (0, import_react57.useMemo)(() => {
|
|
3784
4068
|
if (!sort) return [...data];
|
|
3785
4069
|
const column = columns.find((item) => item.key === sort.key);
|
|
3786
4070
|
if (!column) return [...data];
|
|
@@ -3793,7 +4077,7 @@ function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange,
|
|
|
3793
4077
|
}, [columns, data, sort]);
|
|
3794
4078
|
const all = data.length > 0 && data.every((item) => selectedKeys.includes(keyOf(item)));
|
|
3795
4079
|
const changeAll = () => onSelectionChange?.(all ? [] : data.map(keyOf));
|
|
3796
|
-
return /* @__PURE__ */ (0,
|
|
4080
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "hf-data-grid", onKeyDown: (event) => {
|
|
3797
4081
|
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
3798
4082
|
const controls = [...event.currentTarget.querySelectorAll("button,input")];
|
|
3799
4083
|
const current = controls.indexOf(event.target);
|
|
@@ -3801,95 +4085,258 @@ function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange,
|
|
|
3801
4085
|
event.preventDefault();
|
|
3802
4086
|
const direction = event.key === "ArrowLeft" || event.key === "ArrowUp" ? -1 : 1;
|
|
3803
4087
|
controls[(current + direction + controls.length) % controls.length]?.focus();
|
|
3804
|
-
}, children: /* @__PURE__ */ (0,
|
|
3805
|
-
caption && /* @__PURE__ */ (0,
|
|
3806
|
-
/* @__PURE__ */ (0,
|
|
3807
|
-
onSelectionChange && /* @__PURE__ */ (0,
|
|
3808
|
-
columns.map((column) => /* @__PURE__ */ (0,
|
|
4088
|
+
}, children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("table", { children: [
|
|
4089
|
+
caption && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("caption", { children: caption }),
|
|
4090
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("tr", { children: [
|
|
4091
|
+
onSelectionChange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("th", { className: "hf-data-grid__check", children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("input", { type: "checkbox", "aria-label": "\u9009\u62E9\u5168\u90E8", checked: all, onChange: changeAll }) }),
|
|
4092
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("th", { style: { width: column.width }, children: column.sortable ? /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("button", { type: "button", onClick: () => setSort((current) => ({ key: column.key, direction: current?.key === column.key && current.direction === "asc" ? "desc" : "asc" })), children: [
|
|
3809
4093
|
column.header,
|
|
3810
|
-
/* @__PURE__ */ (0,
|
|
4094
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { "aria-hidden": "true", children: sort?.key === column.key ? sort.direction === "asc" ? "\u2191" : "\u2193" : "\u2195" })
|
|
3811
4095
|
] }) : column.header }, column.key))
|
|
3812
4096
|
] }) }),
|
|
3813
|
-
/* @__PURE__ */ (0,
|
|
4097
|
+
/* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("tbody", { children: [
|
|
3814
4098
|
rows.map((item) => {
|
|
3815
4099
|
const key = keyOf(item);
|
|
3816
|
-
return /* @__PURE__ */ (0,
|
|
3817
|
-
onSelectionChange && /* @__PURE__ */ (0,
|
|
3818
|
-
columns.map((column) => /* @__PURE__ */ (0,
|
|
4100
|
+
return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("tr", { className: selectedKeys.includes(key) ? "is-selected" : "", children: [
|
|
4101
|
+
onSelectionChange && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("input", { type: "checkbox", "aria-label": `\u9009\u62E9\u884C ${key}`, checked: selectedKeys.includes(key), onChange: () => onSelectionChange(selectedKeys.includes(key) ? selectedKeys.filter((item2) => item2 !== key) : [...selectedKeys, key]) }) }),
|
|
4102
|
+
columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("td", { children: column.render ? column.render(item) : String(item[column.key] ?? "") }, column.key))
|
|
3819
4103
|
] }, key);
|
|
3820
4104
|
}),
|
|
3821
|
-
!rows.length && /* @__PURE__ */ (0,
|
|
4105
|
+
!rows.length && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("td", { className: "hf-data-grid__empty", colSpan: columns.length + (onSelectionChange ? 1 : 0), children: empty }) })
|
|
3822
4106
|
] })
|
|
3823
4107
|
] }) });
|
|
3824
4108
|
}
|
|
3825
4109
|
|
|
3826
4110
|
// src/data-display/Tree.tsx
|
|
3827
|
-
var
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
4111
|
+
var import_react59 = require("react");
|
|
4112
|
+
|
|
4113
|
+
// src/data-display/TreeFileIcon.tsx
|
|
4114
|
+
var import_jsx_runtime75 = require("react/jsx-runtime");
|
|
4115
|
+
function TreeFileIcon({ folder, open }) {
|
|
4116
|
+
return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
|
|
4117
|
+
"svg",
|
|
4118
|
+
{
|
|
4119
|
+
width: "18",
|
|
4120
|
+
height: "18",
|
|
4121
|
+
viewBox: "0 0 24 24",
|
|
4122
|
+
fill: "none",
|
|
4123
|
+
stroke: "currentColor",
|
|
4124
|
+
strokeWidth: "1.6",
|
|
4125
|
+
strokeLinecap: "round",
|
|
4126
|
+
strokeLinejoin: "round",
|
|
4127
|
+
"aria-hidden": "true",
|
|
4128
|
+
children: folder ? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
|
|
4129
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { d: "M3 18V6a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v2" }),
|
|
4130
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { d: open ? "M3 18 6 11h16l-3 9H5a2 2 0 0 1-2-2Z" : "M3 10h18v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z" })
|
|
4131
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
|
|
4132
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { d: "M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8Z M14 3v5h5" }),
|
|
4133
|
+
/* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { d: "M9 12h6M9 16h4" })
|
|
4134
|
+
] })
|
|
4135
|
+
}
|
|
4136
|
+
);
|
|
4137
|
+
}
|
|
4138
|
+
|
|
4139
|
+
// src/data-display/useTreeState.ts
|
|
4140
|
+
var import_react58 = require("react");
|
|
4141
|
+
function visibleNodes(nodes, expanded, parent) {
|
|
4142
|
+
const result = [];
|
|
4143
|
+
for (const node of nodes) {
|
|
4144
|
+
result.push({ node, parent });
|
|
4145
|
+
if (node.children && expanded.has(node.key)) result.push(...visibleNodes(node.children, expanded, node.key));
|
|
4146
|
+
}
|
|
4147
|
+
return result;
|
|
4148
|
+
}
|
|
4149
|
+
function useTreeState({ nodes, selectedKey, onSelect, defaultExpandedKeys = [], expandedKeys, onExpand }) {
|
|
4150
|
+
const [internalExpanded, setExpanded] = (0, import_react58.useState)([...defaultExpandedKeys]);
|
|
4151
|
+
const [focusedKey, setFocusedKey] = (0, import_react58.useState)();
|
|
4152
|
+
const elements = (0, import_react58.useRef)(/* @__PURE__ */ new Map());
|
|
4153
|
+
const expanded = new Set(expandedKeys ?? internalExpanded);
|
|
4154
|
+
const visible = visibleNodes(nodes, expanded);
|
|
4155
|
+
const enabled = visible.filter(({ node }) => !node.disabled);
|
|
4156
|
+
const activeKey = enabled.find(({ node }) => node.key === focusedKey)?.node.key ?? enabled.find(({ node }) => node.key === selectedKey)?.node.key ?? enabled[0]?.node.key;
|
|
4157
|
+
function focus(key) {
|
|
4158
|
+
if (key === void 0) return;
|
|
4159
|
+
setFocusedKey(key);
|
|
4160
|
+
elements.current.get(key)?.focus();
|
|
4161
|
+
}
|
|
4162
|
+
function toggle(node) {
|
|
4163
|
+
if (node.disabled || !node.children?.length) return;
|
|
4164
|
+
const next = new Set(expanded);
|
|
4165
|
+
if (next.has(node.key)) next.delete(node.key);
|
|
4166
|
+
else next.add(node.key);
|
|
4167
|
+
if (expandedKeys === void 0) setExpanded([...next]);
|
|
4168
|
+
onExpand?.([...next]);
|
|
4169
|
+
}
|
|
4170
|
+
function onKeyDown(event, node) {
|
|
4171
|
+
if (event.target !== event.currentTarget || node.disabled) return;
|
|
4172
|
+
const index = enabled.findIndex((item) => item.node.key === node.key);
|
|
3833
4173
|
const branch = Boolean(node.children?.length);
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
4174
|
+
const open = expanded.has(node.key);
|
|
4175
|
+
const actions = {
|
|
4176
|
+
ArrowDown: () => focus(enabled[Math.min(index + 1, enabled.length - 1)]?.node.key),
|
|
4177
|
+
ArrowUp: () => focus(enabled[Math.max(index - 1, 0)]?.node.key),
|
|
4178
|
+
Home: () => focus(enabled[0]?.node.key),
|
|
4179
|
+
End: () => focus(enabled.at(-1)?.node.key),
|
|
4180
|
+
ArrowRight: () => {
|
|
4181
|
+
if (branch && !open) toggle(node);
|
|
4182
|
+
else if (branch) focus(node.children?.find((child) => !child.disabled)?.key);
|
|
4183
|
+
},
|
|
4184
|
+
ArrowLeft: () => {
|
|
4185
|
+
if (branch && open) toggle(node);
|
|
4186
|
+
else {
|
|
4187
|
+
let parent = visible.find((item) => item.node.key === node.key)?.parent;
|
|
4188
|
+
while (parent !== void 0 && visible.find((item) => item.node.key === parent)?.node.disabled) {
|
|
4189
|
+
parent = visible.find((item) => item.node.key === parent)?.parent;
|
|
4190
|
+
}
|
|
4191
|
+
focus(parent);
|
|
4192
|
+
}
|
|
4193
|
+
},
|
|
4194
|
+
Enter: () => onSelect?.(node.key),
|
|
4195
|
+
" ": () => onSelect?.(node.key)
|
|
4196
|
+
};
|
|
4197
|
+
const action = actions[event.key];
|
|
4198
|
+
if (action) {
|
|
3848
4199
|
event.preventDefault();
|
|
3849
|
-
|
|
3850
|
-
|
|
4200
|
+
event.stopPropagation();
|
|
4201
|
+
action();
|
|
3851
4202
|
}
|
|
3852
|
-
}
|
|
4203
|
+
}
|
|
4204
|
+
return { elements, expanded, activeKey, focus, toggle, onKeyDown, setFocusedKey };
|
|
4205
|
+
}
|
|
4206
|
+
|
|
4207
|
+
// src/data-display/Tree.tsx
|
|
4208
|
+
var import_jsx_runtime76 = require("react/jsx-runtime");
|
|
4209
|
+
function Tree({
|
|
4210
|
+
nodes,
|
|
4211
|
+
selectedKey,
|
|
4212
|
+
onSelect,
|
|
4213
|
+
defaultExpandedKeys = [],
|
|
4214
|
+
expandedKeys,
|
|
4215
|
+
onExpand,
|
|
4216
|
+
label = "\u6811\u5F62\u5217\u8868",
|
|
4217
|
+
showIcon = false,
|
|
4218
|
+
showLine = true,
|
|
4219
|
+
emptyText = "\u6682\u65E0\u5185\u5BB9"
|
|
4220
|
+
}) {
|
|
4221
|
+
const id = (0, import_react59.useId)();
|
|
4222
|
+
const { elements, expanded, activeKey, focus, toggle, onKeyDown, setFocusedKey } = useTreeState({
|
|
4223
|
+
nodes,
|
|
4224
|
+
selectedKey,
|
|
4225
|
+
onSelect,
|
|
4226
|
+
defaultExpandedKeys,
|
|
4227
|
+
expandedKeys,
|
|
4228
|
+
onExpand
|
|
4229
|
+
});
|
|
4230
|
+
function render(items, level) {
|
|
4231
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("ul", { role: level ? "group" : "tree", "aria-label": level ? void 0 : label, children: items.map((node) => {
|
|
4232
|
+
const open = expanded.has(node.key);
|
|
4233
|
+
const branch = Boolean(node.children?.length);
|
|
4234
|
+
const folder = node.children !== void 0;
|
|
4235
|
+
const labelId = `${id}-${encodeURIComponent(node.key)}`;
|
|
4236
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
4237
|
+
"li",
|
|
4238
|
+
{
|
|
4239
|
+
role: "treeitem",
|
|
4240
|
+
"aria-labelledby": labelId,
|
|
4241
|
+
"aria-level": level + 1,
|
|
4242
|
+
"aria-expanded": branch ? open : void 0,
|
|
4243
|
+
"aria-selected": node.key === selectedKey,
|
|
4244
|
+
"aria-disabled": node.disabled || void 0,
|
|
4245
|
+
tabIndex: !node.disabled && node.key === activeKey ? 0 : -1,
|
|
4246
|
+
ref: (element) => {
|
|
4247
|
+
if (element) elements.current.set(node.key, element);
|
|
4248
|
+
else elements.current.delete(node.key);
|
|
4249
|
+
},
|
|
4250
|
+
onFocus: (event) => {
|
|
4251
|
+
if (event.target === event.currentTarget) setFocusedKey(node.key);
|
|
4252
|
+
},
|
|
4253
|
+
onKeyDown: (event) => onKeyDown(event, node),
|
|
4254
|
+
children: [
|
|
4255
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
|
|
4256
|
+
"div",
|
|
4257
|
+
{
|
|
4258
|
+
className: `hf-tree__row${node.key === selectedKey ? " is-selected" : ""}`,
|
|
4259
|
+
style: { "--hf-tree-depth": level },
|
|
4260
|
+
onClick: () => {
|
|
4261
|
+
if (!node.disabled) {
|
|
4262
|
+
focus(node.key);
|
|
4263
|
+
onSelect?.(node.key);
|
|
4264
|
+
}
|
|
4265
|
+
},
|
|
4266
|
+
children: [
|
|
4267
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "hf-tree__guides", "aria-hidden": "true", children: Array.from({ length: level }, (_, depth) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("i", {}, depth)) }),
|
|
4268
|
+
branch ? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
|
|
4269
|
+
"button",
|
|
4270
|
+
{
|
|
4271
|
+
type: "button",
|
|
4272
|
+
className: "hf-tree__toggle",
|
|
4273
|
+
tabIndex: -1,
|
|
4274
|
+
disabled: node.disabled,
|
|
4275
|
+
"aria-label": `${open ? "\u6536\u8D77" : "\u5C55\u5F00"}${typeof node.label === "string" ? node.label : "\u8282\u70B9"}`,
|
|
4276
|
+
onClick: (event) => {
|
|
4277
|
+
event.stopPropagation();
|
|
4278
|
+
focus(node.key);
|
|
4279
|
+
toggle(node);
|
|
4280
|
+
},
|
|
4281
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(Icon, { name: "chevron-down", size: 14, className: open ? "is-open" : "" })
|
|
4282
|
+
}
|
|
4283
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "hf-tree__spacer", "aria-hidden": "true" }),
|
|
4284
|
+
(node.icon != null || showIcon) && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: `hf-tree__icon${folder ? " is-folder" : ""}`, "aria-hidden": "true", children: node.icon ?? /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(TreeFileIcon, { folder, open }) }),
|
|
4285
|
+
/* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { id: labelId, className: "hf-tree__label", title: typeof node.label === "string" ? node.label : void 0, children: node.label })
|
|
4286
|
+
]
|
|
4287
|
+
}
|
|
4288
|
+
),
|
|
4289
|
+
branch && open && render(node.children, level + 1)
|
|
4290
|
+
]
|
|
4291
|
+
},
|
|
4292
|
+
node.key
|
|
4293
|
+
);
|
|
4294
|
+
}) });
|
|
4295
|
+
}
|
|
4296
|
+
return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: `hf-tree${showLine ? " hf-tree--lines" : ""}`, children: [
|
|
4297
|
+
render(nodes, 0),
|
|
4298
|
+
!nodes.length && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "hf-tree__empty", role: "status", children: emptyText })
|
|
4299
|
+
] });
|
|
3853
4300
|
}
|
|
3854
4301
|
|
|
3855
4302
|
// src/layout/AuthLayout.tsx
|
|
3856
|
-
var
|
|
4303
|
+
var import_jsx_runtime77 = require("react/jsx-runtime");
|
|
3857
4304
|
function AuthLayout({ children, brand, aside, footer, variant = "card", backgroundImage, currentStep = 1, steps = 1 }) {
|
|
3858
4305
|
const style = backgroundImage ? { "--hf-auth-image": `url("${backgroundImage}")` } : void 0;
|
|
3859
|
-
return /* @__PURE__ */ (0,
|
|
3860
|
-
brand && /* @__PURE__ */ (0,
|
|
3861
|
-
aside && /* @__PURE__ */ (0,
|
|
3862
|
-
/* @__PURE__ */ (0,
|
|
3863
|
-
variant === "step" && /* @__PURE__ */ (0,
|
|
3864
|
-
/* @__PURE__ */ (0,
|
|
3865
|
-
footer && /* @__PURE__ */ (0,
|
|
4306
|
+
return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("section", { className: `hf-auth hf-auth--${variant}`, style, children: [
|
|
4307
|
+
brand && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("header", { className: "hf-auth__brand", children: brand }),
|
|
4308
|
+
aside && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("aside", { className: "hf-auth__aside", children: aside }),
|
|
4309
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("main", { className: "hf-auth__main", children: [
|
|
4310
|
+
variant === "step" && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "hf-auth__steps", "aria-label": `\u7B2C ${currentStep} \u6B65\uFF0C\u5171 ${steps} \u6B65`, children: Array.from({ length: steps }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: index < currentStep ? "is-active" : "" }, index)) }),
|
|
4311
|
+
/* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "hf-auth__card", children }),
|
|
4312
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("footer", { children: footer })
|
|
3866
4313
|
] })
|
|
3867
4314
|
] });
|
|
3868
4315
|
}
|
|
3869
4316
|
|
|
3870
4317
|
// src/layout/Hero.tsx
|
|
3871
|
-
var
|
|
4318
|
+
var import_jsx_runtime78 = require("react/jsx-runtime");
|
|
3872
4319
|
function Hero({ eyebrow, title, description, primaryAction, secondaryAction, visual, proof, align = "left", kind = "product" }) {
|
|
3873
|
-
return /* @__PURE__ */ (0,
|
|
3874
|
-
/* @__PURE__ */ (0,
|
|
3875
|
-
eyebrow && /* @__PURE__ */ (0,
|
|
3876
|
-
/* @__PURE__ */ (0,
|
|
3877
|
-
description && /* @__PURE__ */ (0,
|
|
3878
|
-
(primaryAction || secondaryAction) && /* @__PURE__ */ (0,
|
|
4320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("section", { className: `hf-hero hf-hero--${align} hf-hero--${kind}`, children: [
|
|
4321
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "hf-hero__content", children: [
|
|
4322
|
+
eyebrow && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "hf-hero__eyebrow", children: eyebrow }),
|
|
4323
|
+
/* @__PURE__ */ (0, import_jsx_runtime78.jsx)("h1", { children: title }),
|
|
4324
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { children: description }),
|
|
4325
|
+
(primaryAction || secondaryAction) && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "hf-hero__actions", children: [
|
|
3879
4326
|
primaryAction,
|
|
3880
4327
|
secondaryAction
|
|
3881
4328
|
] }),
|
|
3882
|
-
proof && /* @__PURE__ */ (0,
|
|
4329
|
+
proof && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "hf-hero__proof", children: proof })
|
|
3883
4330
|
] }),
|
|
3884
|
-
visual && /* @__PURE__ */ (0,
|
|
4331
|
+
visual && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "hf-hero__visual", children: visual })
|
|
3885
4332
|
] });
|
|
3886
4333
|
}
|
|
3887
4334
|
|
|
3888
4335
|
// src/layout/ResizablePanel.tsx
|
|
3889
|
-
var
|
|
3890
|
-
var
|
|
4336
|
+
var import_react60 = require("react");
|
|
4337
|
+
var import_jsx_runtime79 = require("react/jsx-runtime");
|
|
3891
4338
|
function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, maxSize = 80, direction = "horizontal", onResize }) {
|
|
3892
|
-
const [size, setSize] = (0,
|
|
4339
|
+
const [size, setSize] = (0, import_react60.useState)(defaultSize);
|
|
3893
4340
|
const start = (event) => {
|
|
3894
4341
|
const root = event.currentTarget.parentElement;
|
|
3895
4342
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -3907,9 +4354,9 @@ function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, ma
|
|
|
3907
4354
|
document.addEventListener("pointermove", move);
|
|
3908
4355
|
document.addEventListener("pointerup", end);
|
|
3909
4356
|
};
|
|
3910
|
-
return /* @__PURE__ */ (0,
|
|
3911
|
-
/* @__PURE__ */ (0,
|
|
3912
|
-
/* @__PURE__ */ (0,
|
|
4357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: `hf-resizable hf-resizable--${direction}`, children: [
|
|
4358
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { style: { flexBasis: `${size}%` }, children: primary }),
|
|
4359
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { className: "hf-resizable__handle", role: "separator", "aria-orientation": direction, "aria-valuemin": minSize, "aria-valuemax": maxSize, "aria-valuenow": Math.round(size), tabIndex: 0, onPointerDown: start, onKeyDown: (event) => {
|
|
3913
4360
|
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
3914
4361
|
event.preventDefault();
|
|
3915
4362
|
const grow = event.key === "ArrowRight" || event.key === "ArrowDown";
|
|
@@ -3917,61 +4364,61 @@ function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, ma
|
|
|
3917
4364
|
setSize(value);
|
|
3918
4365
|
onResize?.(value);
|
|
3919
4366
|
} }),
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
4367
|
+
/* @__PURE__ */ (0, import_jsx_runtime79.jsx)("div", { children: secondary })
|
|
3921
4368
|
] });
|
|
3922
4369
|
}
|
|
3923
4370
|
|
|
3924
4371
|
// src/feedback/NotificationCenter.tsx
|
|
3925
|
-
var
|
|
4372
|
+
var import_jsx_runtime80 = require("react/jsx-runtime");
|
|
3926
4373
|
function NotificationCenter({ items, onRead, onDismiss, onReadAll, empty = "\u6682\u65E0\u901A\u77E5", title = "\u901A\u77E5\u4E2D\u5FC3" }) {
|
|
3927
4374
|
const unread = items.filter((item) => item.unread).length;
|
|
3928
|
-
return /* @__PURE__ */ (0,
|
|
3929
|
-
/* @__PURE__ */ (0,
|
|
3930
|
-
/* @__PURE__ */ (0,
|
|
3931
|
-
/* @__PURE__ */ (0,
|
|
3932
|
-
unread > 0 && /* @__PURE__ */ (0,
|
|
4375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("section", { className: "hf-notification-center", children: [
|
|
4376
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("header", { children: [
|
|
4377
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { children: [
|
|
4378
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("strong", { children: title }),
|
|
4379
|
+
unread > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { children: unread })
|
|
3933
4380
|
] }),
|
|
3934
|
-
unread > 0 && onReadAll && /* @__PURE__ */ (0,
|
|
4381
|
+
unread > 0 && onReadAll && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", { type: "button", onClick: onReadAll, children: "\u5168\u90E8\u5DF2\u8BFB" })
|
|
3935
4382
|
] }),
|
|
3936
|
-
/* @__PURE__ */ (0,
|
|
4383
|
+
/* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { children: items.length ? items.map(({ key, content, ...item }) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { onClick: () => item.unread && onRead?.(key), children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(Notification, { ...item, onClose: onDismiss ? () => onDismiss(key) : void 0, children: content }) }, key)) : /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("p", { className: "hf-notification-center__empty", children: empty }) })
|
|
3937
4384
|
] });
|
|
3938
4385
|
}
|
|
3939
4386
|
|
|
3940
4387
|
// src/data-display/VirtualList.tsx
|
|
3941
|
-
var
|
|
3942
|
-
var
|
|
4388
|
+
var import_react61 = require("react");
|
|
4389
|
+
var import_jsx_runtime81 = require("react/jsx-runtime");
|
|
3943
4390
|
function VirtualList({ items, itemHeight, height, renderItem, itemKey, overscan = 3, label = "\u865A\u62DF\u5217\u8868" }) {
|
|
3944
|
-
const [scrollTop, setScrollTop] = (0,
|
|
4391
|
+
const [scrollTop, setScrollTop] = (0, import_react61.useState)(0);
|
|
3945
4392
|
const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
|
|
3946
4393
|
const end = Math.min(items.length, Math.ceil((scrollTop + height) / itemHeight) + overscan);
|
|
3947
|
-
return /* @__PURE__ */ (0,
|
|
4394
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "hf-virtual-list", role: "list", "aria-label": label, style: { height }, onScroll: (event) => setScrollTop(event.currentTarget.scrollTop), children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { style: { height: items.length * itemHeight, position: "relative" }, children: items.slice(start, end).map((item, offset) => {
|
|
3948
4395
|
const index = start + offset;
|
|
3949
|
-
return /* @__PURE__ */ (0,
|
|
4396
|
+
return /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { role: "listitem", style: { height: itemHeight, left: 0, position: "absolute", right: 0, top: index * itemHeight }, children: renderItem(item, index) }, itemKey(item, index));
|
|
3950
4397
|
}) }) });
|
|
3951
4398
|
}
|
|
3952
4399
|
|
|
3953
4400
|
// src/data-display/DeveloperView.tsx
|
|
3954
|
-
var
|
|
3955
|
-
var
|
|
4401
|
+
var import_react62 = require("react");
|
|
4402
|
+
var import_jsx_runtime82 = require("react/jsx-runtime");
|
|
3956
4403
|
function JsonNode({ name, value, depth, defaultExpanded, maxDepth }) {
|
|
3957
4404
|
const complex = value !== null && typeof value === "object";
|
|
3958
|
-
const [open, setOpen] = (0,
|
|
3959
|
-
if (!complex) return /* @__PURE__ */ (0,
|
|
3960
|
-
/* @__PURE__ */ (0,
|
|
3961
|
-
/* @__PURE__ */ (0,
|
|
4405
|
+
const [open, setOpen] = (0, import_react62.useState)(defaultExpanded && depth < maxDepth);
|
|
4406
|
+
if (!complex) return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "hf-json-viewer__row", children: [
|
|
4407
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: name !== void 0 && `${name}: ` }),
|
|
4408
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("code", { className: `is-${value === null ? "null" : typeof value}`, children: value === null ? "null" : JSON.stringify(value) })
|
|
3962
4409
|
] });
|
|
3963
4410
|
const entries = Object.entries(value);
|
|
3964
|
-
return /* @__PURE__ */ (0,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
3967
|
-
/* @__PURE__ */ (0,
|
|
3968
|
-
/* @__PURE__ */ (0,
|
|
4411
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "hf-json-viewer__node", children: [
|
|
4412
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("button", { type: "button", "aria-expanded": open, onClick: () => setOpen(!open), children: [
|
|
4413
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: open ? "\u2304" : "\u203A" }),
|
|
4414
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("strong", { children: name ?? (Array.isArray(value) ? "Array" : "Object") }),
|
|
4415
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("small", { children: Array.isArray(value) ? `[${entries.length}]` : `{${entries.length}}` })
|
|
3969
4416
|
] }),
|
|
3970
|
-
open && /* @__PURE__ */ (0,
|
|
4417
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { children: entries.map(([key, item]) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(JsonNode, { name: key, value: item, depth: depth + 1, defaultExpanded, maxDepth }, key)) })
|
|
3971
4418
|
] });
|
|
3972
4419
|
}
|
|
3973
4420
|
function JsonViewer({ data, name, defaultExpanded = true, maxDepth = 2 }) {
|
|
3974
|
-
return /* @__PURE__ */ (0,
|
|
4421
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "hf-json-viewer", role: "tree", "aria-label": name ?? "JSON \u67E5\u770B\u5668", children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(JsonNode, { name, value: data, depth: 0, defaultExpanded, maxDepth }) });
|
|
3975
4422
|
}
|
|
3976
4423
|
function compareLines(before, after) {
|
|
3977
4424
|
const a = before.split("\n"), b = after.split("\n"), matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
|
|
@@ -3990,28 +4437,28 @@ function compareLines(before, after) {
|
|
|
3990
4437
|
return rows;
|
|
3991
4438
|
}
|
|
3992
4439
|
function DiffCell({ number, marker, children }) {
|
|
3993
|
-
return /* @__PURE__ */ (0,
|
|
3994
|
-
/* @__PURE__ */ (0,
|
|
3995
|
-
/* @__PURE__ */ (0,
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
4440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "hf-diff-viewer__cell", children: [
|
|
4441
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: number ?? "" }),
|
|
4442
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("i", { children: marker }),
|
|
4443
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("code", { children: children ?? "" })
|
|
3997
4444
|
] });
|
|
3998
4445
|
}
|
|
3999
4446
|
function DiffViewer({ before, after, beforeLabel = "\u4FEE\u6539\u524D", afterLabel = "\u4FEE\u6539\u540E", mode = "split" }) {
|
|
4000
4447
|
const rows = compareLines(before, after);
|
|
4001
|
-
return /* @__PURE__ */ (0,
|
|
4002
|
-
/* @__PURE__ */ (0,
|
|
4003
|
-
/* @__PURE__ */ (0,
|
|
4004
|
-
mode === "split" && /* @__PURE__ */ (0,
|
|
4448
|
+
return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: `hf-diff-viewer hf-diff-viewer--${mode}`, children: [
|
|
4449
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("header", { children: [
|
|
4450
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("strong", { children: beforeLabel }),
|
|
4451
|
+
mode === "split" && /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("strong", { children: afterLabel })
|
|
4005
4452
|
] }),
|
|
4006
|
-
/* @__PURE__ */ (0,
|
|
4007
|
-
/* @__PURE__ */ (0,
|
|
4008
|
-
/* @__PURE__ */ (0,
|
|
4009
|
-
] }, index) : /* @__PURE__ */ (0,
|
|
4453
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { children: rows.map((row, index) => mode === "split" ? /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: `is-${row.kind}`, children: [
|
|
4454
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DiffCell, { number: row.leftNo, marker: row.kind === "remove" ? "\u2212" : " ", children: row.left }),
|
|
4455
|
+
/* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DiffCell, { number: row.rightNo, marker: row.kind === "add" ? "+" : " ", children: row.right })
|
|
4456
|
+
] }, index) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: `is-${row.kind}`, children: /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(DiffCell, { number: row.leftNo ?? row.rightNo, marker: row.kind === "add" ? "+" : row.kind === "remove" ? "\u2212" : " ", children: row.kind === "add" ? row.right : row.left }) }, index)) })
|
|
4010
4457
|
] });
|
|
4011
4458
|
}
|
|
4012
4459
|
|
|
4013
4460
|
// src/forms/QueryBuilder.tsx
|
|
4014
|
-
var
|
|
4461
|
+
var import_jsx_runtime83 = require("react/jsx-runtime");
|
|
4015
4462
|
var defaultOperators = [{ value: "equals", label: "\u7B49\u4E8E" }, { value: "notEquals", label: "\u4E0D\u7B49\u4E8E" }, { value: "contains", label: "\u5305\u542B" }];
|
|
4016
4463
|
function QueryBuilder({ fields, rules, onChange, conjunction = "and", onConjunctionChange, disabled }) {
|
|
4017
4464
|
const update = (id, patch) => onChange(rules.map((rule) => rule.id === id ? { ...rule, ...patch } : rule));
|
|
@@ -4021,39 +4468,39 @@ function QueryBuilder({ fields, rules, onChange, conjunction = "and", onConjunct
|
|
|
4021
4468
|
const operator = (field.operators ?? defaultOperators)[0]?.value ?? "equals";
|
|
4022
4469
|
onChange([...rules, { id: `rule-${Date.now()}`, field: field.key, operator, value: "" }]);
|
|
4023
4470
|
};
|
|
4024
|
-
return /* @__PURE__ */ (0,
|
|
4025
|
-
/* @__PURE__ */ (0,
|
|
4026
|
-
/* @__PURE__ */ (0,
|
|
4027
|
-
/* @__PURE__ */ (0,
|
|
4471
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "hf-query-builder", children: [
|
|
4472
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("header", { children: [
|
|
4473
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("strong", { children: "\u6EE1\u8DB3" }),
|
|
4474
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Select, { className: "hf-query-builder__select", "aria-label": "\u6761\u4EF6\u5173\u7CFB", value: conjunction, disabled, options: [{ value: "and", label: "\u5168\u90E8\u6761\u4EF6" }, { value: "or", label: "\u4EFB\u4E00\u6761\u4EF6" }], onChange: (event) => onConjunctionChange?.(event.target.value) })
|
|
4028
4475
|
] }),
|
|
4029
|
-
/* @__PURE__ */ (0,
|
|
4476
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { children: rules.map((rule, index) => {
|
|
4030
4477
|
const field = fields.find((item) => item.key === rule.field) ?? fields[0];
|
|
4031
4478
|
const operators = field?.operators ?? defaultOperators;
|
|
4032
|
-
return /* @__PURE__ */ (0,
|
|
4033
|
-
/* @__PURE__ */ (0,
|
|
4034
|
-
/* @__PURE__ */ (0,
|
|
4479
|
+
return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "hf-query-builder__rule", children: [
|
|
4480
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { children: index + 1 }),
|
|
4481
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Select, { className: "hf-query-builder__select", "aria-label": `\u6761\u4EF6 ${index + 1} \u5B57\u6BB5`, value: rule.field, disabled, options: fields.map((item) => ({ value: item.key, label: item.label })), onChange: (event) => {
|
|
4035
4482
|
const next = fields.find((item) => item.key === event.target.value);
|
|
4036
4483
|
update(rule.id, { field: next.key, operator: (next.operators ?? defaultOperators)[0]?.value ?? "equals", value: "" });
|
|
4037
4484
|
} }),
|
|
4038
|
-
/* @__PURE__ */ (0,
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4040
|
-
/* @__PURE__ */ (0,
|
|
4485
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Select, { className: "hf-query-builder__select", "aria-label": `\u6761\u4EF6 ${index + 1} \u8FD0\u7B97\u7B26`, value: rule.operator, disabled, options: operators, onChange: (event) => update(rule.id, { operator: event.target.value }) }),
|
|
4486
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("input", { "aria-label": `\u6761\u4EF6 ${index + 1} \u503C`, type: field?.type ?? "text", value: rule.value, disabled, onChange: (event) => update(rule.id, { value: event.target.value }) }),
|
|
4487
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("button", { type: "button", "aria-label": `\u5220\u9664\u6761\u4EF6 ${index + 1}`, disabled, onClick: () => onChange(rules.filter((item) => item.id !== rule.id)), children: /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(Icon, { name: "close", size: 15 }) })
|
|
4041
4488
|
] }, rule.id);
|
|
4042
4489
|
}) }),
|
|
4043
|
-
/* @__PURE__ */ (0,
|
|
4490
|
+
/* @__PURE__ */ (0, import_jsx_runtime83.jsx)("button", { type: "button", className: "hf-query-builder__add", disabled: disabled || !fields.length, onClick: add, children: "\uFF0B \u6DFB\u52A0\u6761\u4EF6" })
|
|
4044
4491
|
] });
|
|
4045
4492
|
}
|
|
4046
4493
|
|
|
4047
4494
|
// src/data-display/WorkflowViews.tsx
|
|
4048
|
-
var
|
|
4495
|
+
var import_react64 = require("react");
|
|
4049
4496
|
|
|
4050
4497
|
// src/data-display/useKanbanMove.ts
|
|
4051
|
-
var
|
|
4498
|
+
var import_react63 = require("react");
|
|
4052
4499
|
function useKanbanMove({ columns, onMove }) {
|
|
4053
|
-
const root = (0,
|
|
4054
|
-
const session = (0,
|
|
4055
|
-
const [target, setTarget] = (0,
|
|
4056
|
-
const [announcement, setAnnouncement] = (0,
|
|
4500
|
+
const root = (0, import_react63.useRef)(null);
|
|
4501
|
+
const session = (0, import_react63.useRef)(null);
|
|
4502
|
+
const [target, setTarget] = (0, import_react63.useState)(null);
|
|
4503
|
+
const [announcement, setAnnouncement] = (0, import_react63.useState)("");
|
|
4057
4504
|
const snapshot = JSON.stringify(columns.map((column) => [column.id, column.cards.map((card) => card.id)]));
|
|
4058
4505
|
function cancel() {
|
|
4059
4506
|
if (session.current) setAnnouncement("\u5DF2\u53D6\u6D88\u79FB\u52A8\uFF0C\u672A\u63D0\u4EA4\u66F4\u6539");
|
|
@@ -4117,13 +4564,13 @@ function useKanbanMove({ columns, onMove }) {
|
|
|
4117
4564
|
}
|
|
4118
4565
|
|
|
4119
4566
|
// src/data-display/KanbanBoardView.tsx
|
|
4120
|
-
var
|
|
4567
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
4121
4568
|
function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
4122
4569
|
const drag = useKanbanMove({ columns, onMove });
|
|
4123
|
-
if (!columns.length) return /* @__PURE__ */ (0,
|
|
4124
|
-
return /* @__PURE__ */ (0,
|
|
4125
|
-
onMove && /* @__PURE__ */ (0,
|
|
4126
|
-
/* @__PURE__ */ (0,
|
|
4570
|
+
if (!columns.length) return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "hf-kanban-board__empty", children: empty });
|
|
4571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "hf-kanban-enhanced", children: [
|
|
4572
|
+
onMove && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { className: "hf-kanban-enhanced__hint", children: "\u62D6\u52A8\u624B\u67C4\u8DE8\u5217\u79FB\u52A8\uFF0C\u4E5F\u53EF\u9009\u62E9\u76EE\u6807\u5217\u3002Escape \u53D6\u6D88\u62D6\u52A8\u3002" }),
|
|
4573
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
4127
4574
|
"div",
|
|
4128
4575
|
{
|
|
4129
4576
|
ref: drag.root,
|
|
@@ -4135,7 +4582,7 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4135
4582
|
onKeyDown: (event) => {
|
|
4136
4583
|
if (event.key === "Escape") drag.cancel();
|
|
4137
4584
|
},
|
|
4138
|
-
children: columns.map((column) => /* @__PURE__ */ (0,
|
|
4585
|
+
children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
4139
4586
|
"section",
|
|
4140
4587
|
{
|
|
4141
4588
|
"data-hf-kanban-column": column.id,
|
|
@@ -4150,18 +4597,18 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4150
4597
|
drag.drop(column.id);
|
|
4151
4598
|
},
|
|
4152
4599
|
children: [
|
|
4153
|
-
/* @__PURE__ */ (0,
|
|
4154
|
-
/* @__PURE__ */ (0,
|
|
4155
|
-
/* @__PURE__ */ (0,
|
|
4600
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("header", { children: [
|
|
4601
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("strong", { children: column.title }),
|
|
4602
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("span", { children: [
|
|
4156
4603
|
column.cards.length,
|
|
4157
4604
|
column.limit ? ` / ${column.limit}` : ""
|
|
4158
4605
|
] })
|
|
4159
4606
|
] }),
|
|
4160
|
-
/* @__PURE__ */ (0,
|
|
4607
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { children: [
|
|
4161
4608
|
column.cards.map((card, index) => {
|
|
4162
4609
|
const label = typeof card.title === "string" ? card.title : `\u5361\u7247${index + 1}`;
|
|
4163
|
-
return /* @__PURE__ */ (0,
|
|
4164
|
-
/* @__PURE__ */ (0,
|
|
4610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "hf-kanban-enhanced__item", "data-card-id": card.id, children: [
|
|
4611
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
4165
4612
|
"button",
|
|
4166
4613
|
{
|
|
4167
4614
|
type: "button",
|
|
@@ -4179,15 +4626,15 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4179
4626
|
onDragEnd: drag.cancel,
|
|
4180
4627
|
onClick: () => onCardClick?.(card.id, column.id),
|
|
4181
4628
|
children: [
|
|
4182
|
-
/* @__PURE__ */ (0,
|
|
4183
|
-
card.description && /* @__PURE__ */ (0,
|
|
4184
|
-
card.tags?.length ? /* @__PURE__ */ (0,
|
|
4185
|
-
card.meta && /* @__PURE__ */ (0,
|
|
4629
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("strong", { children: card.title }),
|
|
4630
|
+
card.description && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { children: card.description }),
|
|
4631
|
+
card.tags?.length ? /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: card.tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("i", { children: tag }, tag)) }) : null,
|
|
4632
|
+
card.meta && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("small", { children: card.meta })
|
|
4186
4633
|
]
|
|
4187
4634
|
}
|
|
4188
4635
|
),
|
|
4189
|
-
onMove && /* @__PURE__ */ (0,
|
|
4190
|
-
/* @__PURE__ */ (0,
|
|
4636
|
+
onMove && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "hf-kanban-enhanced__controls", children: [
|
|
4637
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
4191
4638
|
"button",
|
|
4192
4639
|
{
|
|
4193
4640
|
type: "button",
|
|
@@ -4201,17 +4648,17 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4201
4648
|
children: "\u2194"
|
|
4202
4649
|
}
|
|
4203
4650
|
),
|
|
4204
|
-
/* @__PURE__ */ (0,
|
|
4651
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("select", { "aria-label": `\u79FB\u52A8${label}\u5230`, value: "", onChange: (event) => {
|
|
4205
4652
|
drag.cancel();
|
|
4206
4653
|
drag.request(card.id, column.id, event.target.value);
|
|
4207
4654
|
}, children: [
|
|
4208
|
-
/* @__PURE__ */ (0,
|
|
4209
|
-
columns.filter((candidate) => candidate.id !== column.id).map((candidate, destinationIndex) => /* @__PURE__ */ (0,
|
|
4655
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("option", { value: "", disabled: true, children: "\u79FB\u52A8\u5230\u2026" }),
|
|
4656
|
+
columns.filter((candidate) => candidate.id !== column.id).map((candidate, destinationIndex) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("option", { value: candidate.id, children: typeof candidate.title === "string" ? candidate.title : `\u76EE\u6807\u5217${destinationIndex + 1}` }, candidate.id))
|
|
4210
4657
|
] })
|
|
4211
4658
|
] })
|
|
4212
4659
|
] }, card.id);
|
|
4213
4660
|
}),
|
|
4214
|
-
!column.cards.length && /* @__PURE__ */ (0,
|
|
4661
|
+
!column.cards.length && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("p", { className: "hf-kanban-enhanced__empty", children: [
|
|
4215
4662
|
"\u6682\u65E0\u5361\u7247",
|
|
4216
4663
|
onMove ? "\uFF0C\u53EF\u62D6\u5165\u6B64\u5217" : ""
|
|
4217
4664
|
] })
|
|
@@ -4222,59 +4669,59 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4222
4669
|
))
|
|
4223
4670
|
}
|
|
4224
4671
|
),
|
|
4225
|
-
/* @__PURE__ */ (0,
|
|
4672
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "hf-sr-only", role: "status", children: drag.announcement })
|
|
4226
4673
|
] });
|
|
4227
4674
|
}
|
|
4228
4675
|
|
|
4229
4676
|
// src/data-display/WorkflowViews.tsx
|
|
4230
|
-
var
|
|
4677
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
4231
4678
|
function FlowCanvas({ nodes, edges, width = 900, height = 420, selectedId, onSelect, empty = "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) {
|
|
4232
4679
|
const map = new Map(nodes.map((node) => [node.id, node]));
|
|
4233
|
-
if (!nodes.length) return /* @__PURE__ */ (0,
|
|
4234
|
-
return /* @__PURE__ */ (0,
|
|
4235
|
-
/* @__PURE__ */ (0,
|
|
4680
|
+
if (!nodes.length) return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-flow-canvas hf-flow-canvas__empty", children: empty });
|
|
4681
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-flow-canvas", role: "group", "aria-label": "\u6D41\u7A0B\u753B\u5E03", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { style: { width, height }, children: [
|
|
4682
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("svg", { viewBox: `0 0 ${width} ${height}`, "aria-hidden": "true", children: edges.map((edge, index) => {
|
|
4236
4683
|
const from = map.get(edge.from), to = map.get(edge.to);
|
|
4237
4684
|
if (!from || !to) return null;
|
|
4238
4685
|
const x1 = from.x + 82, y1 = from.y + 28, x2 = to.x, y2 = to.y + 28, bend = Math.max(30, Math.abs(x2 - x1) / 2);
|
|
4239
|
-
return /* @__PURE__ */ (0,
|
|
4240
|
-
/* @__PURE__ */ (0,
|
|
4241
|
-
/* @__PURE__ */ (0,
|
|
4242
|
-
edge.label && /* @__PURE__ */ (0,
|
|
4686
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("g", { children: [
|
|
4687
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("path", { d: `M${x1} ${y1} C${x1 + bend} ${y1},${x2 - bend} ${y2},${x2} ${y2}` }),
|
|
4688
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("circle", { cx: x2, cy: y2, r: "3" }),
|
|
4689
|
+
edge.label && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("text", { x: (x1 + x2) / 2, y: (y1 + y2) / 2 - 8, children: edge.label })
|
|
4243
4690
|
] }, edge.id ?? index);
|
|
4244
4691
|
}) }),
|
|
4245
|
-
nodes.map((node) => /* @__PURE__ */ (0,
|
|
4246
|
-
/* @__PURE__ */ (0,
|
|
4247
|
-
node.description && /* @__PURE__ */ (0,
|
|
4692
|
+
nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("button", { type: "button", className: `hf-flow-canvas__node is-${node.status ?? "default"}${selectedId === node.id ? " is-selected" : ""}`, style: { left: node.x, top: node.y }, "aria-pressed": selectedId === node.id, onClick: () => onSelect?.(node.id), children: [
|
|
4693
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: node.label }),
|
|
4694
|
+
node.description && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("small", { children: node.description })
|
|
4248
4695
|
] }, node.id))
|
|
4249
4696
|
] }) });
|
|
4250
4697
|
}
|
|
4251
4698
|
function KanbanBoard({ columns, onMove, onCardClick, empty = "\u6682\u65E0\u770B\u677F\u5217" }) {
|
|
4252
|
-
return /* @__PURE__ */ (0,
|
|
4699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(KanbanBoardView, { columns, onMove, onCardClick, empty });
|
|
4253
4700
|
}
|
|
4254
4701
|
var day = 864e5;
|
|
4255
4702
|
var toTime = (value) => new Date(value).setHours(0, 0, 0, 0);
|
|
4256
4703
|
function GanttChart({ tasks, start, end, onTaskClick, empty = "\u6682\u65E0\u6392\u671F\u4EFB\u52A1" }) {
|
|
4257
|
-
const range = (0,
|
|
4704
|
+
const range = (0, import_react64.useMemo)(() => {
|
|
4258
4705
|
const starts = tasks.map((task) => toTime(task.start)), ends = tasks.map((task) => toTime(task.end));
|
|
4259
4706
|
const from = start ? toTime(start) : Math.min(...starts), to = end ? toTime(end) : Math.max(...ends);
|
|
4260
4707
|
return { from, days: Math.max(1, Math.round((to - from) / day) + 1) };
|
|
4261
4708
|
}, [tasks, start, end]);
|
|
4262
|
-
if (!tasks.length) return /* @__PURE__ */ (0,
|
|
4263
|
-
return /* @__PURE__ */ (0,
|
|
4264
|
-
/* @__PURE__ */ (0,
|
|
4265
|
-
/* @__PURE__ */ (0,
|
|
4266
|
-
/* @__PURE__ */ (0,
|
|
4709
|
+
if (!tasks.length) return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-gantt-chart__empty", children: empty });
|
|
4710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "hf-gantt-chart", children: [
|
|
4711
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("header", { children: [
|
|
4712
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: "\u4EFB\u52A1" }),
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { children: Array.from({ length: Math.min(range.days, 31) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: new Date(range.from + index * day).getDate() }, index)) })
|
|
4267
4714
|
] }),
|
|
4268
4715
|
tasks.map((task) => {
|
|
4269
4716
|
const offset = Math.max(0, (toTime(task.start) - range.from) / day), length = Math.max(1, (toTime(task.end) - toTime(task.start)) / day + 1);
|
|
4270
|
-
return /* @__PURE__ */ (0,
|
|
4271
|
-
/* @__PURE__ */ (0,
|
|
4272
|
-
/* @__PURE__ */ (0,
|
|
4273
|
-
task.group && /* @__PURE__ */ (0,
|
|
4717
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "hf-gantt-chart__row", children: [
|
|
4718
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
|
|
4719
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: task.label }),
|
|
4720
|
+
task.group && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("small", { children: task.group })
|
|
4274
4721
|
] }),
|
|
4275
|
-
/* @__PURE__ */ (0,
|
|
4276
|
-
/* @__PURE__ */ (0,
|
|
4277
|
-
/* @__PURE__ */ (0,
|
|
4722
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("button", { type: "button", style: { left: `${offset / range.days * 100}%`, width: `${length / range.days * 100}%`, "--hf-gantt-color": task.color }, onClick: () => onTaskClick?.(task.id), children: [
|
|
4723
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("i", { style: { width: `${Math.max(0, Math.min(100, task.progress ?? 0))}%` } }),
|
|
4724
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
|
|
4278
4725
|
task.progress ?? 0,
|
|
4279
4726
|
"%"
|
|
4280
4727
|
] })
|
|
@@ -4284,23 +4731,23 @@ function GanttChart({ tasks, start, end, onTaskClick, empty = "\u6682\u65E0\u639
|
|
|
4284
4731
|
] });
|
|
4285
4732
|
}
|
|
4286
4733
|
function ChartContainer({ title, description, actions, legend, children, height = 320, loading, empty, emptyContent = "\u6682\u65E0\u56FE\u8868\u6570\u636E" }) {
|
|
4287
|
-
return /* @__PURE__ */ (0,
|
|
4288
|
-
/* @__PURE__ */ (0,
|
|
4289
|
-
/* @__PURE__ */ (0,
|
|
4290
|
-
title && /* @__PURE__ */ (0,
|
|
4291
|
-
description && /* @__PURE__ */ (0,
|
|
4734
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("section", { className: "hf-chart-container", children: [
|
|
4735
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("header", { children: [
|
|
4736
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { children: [
|
|
4737
|
+
title && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: title }),
|
|
4738
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { children: description })
|
|
4292
4739
|
] }),
|
|
4293
4740
|
actions
|
|
4294
4741
|
] }),
|
|
4295
|
-
legend?.length ? /* @__PURE__ */ (0,
|
|
4296
|
-
/* @__PURE__ */ (0,
|
|
4742
|
+
legend?.length ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-chart-container__legend", children: legend.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
|
|
4743
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("i", { style: { background: item.color } }),
|
|
4297
4744
|
item.label,
|
|
4298
|
-
item.value && /* @__PURE__ */ (0,
|
|
4745
|
+
item.value && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: item.value })
|
|
4299
4746
|
] }, index)) }) : null,
|
|
4300
|
-
/* @__PURE__ */ (0,
|
|
4301
|
-
/* @__PURE__ */ (0,
|
|
4747
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-chart-container__body", style: { height }, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "hf-chart-container__state", children: [
|
|
4748
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "hf-spinner" }),
|
|
4302
4749
|
"\u6B63\u5728\u52A0\u8F7D\u56FE\u8868"
|
|
4303
|
-
] }) : empty ? /* @__PURE__ */ (0,
|
|
4750
|
+
] }) : empty ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-chart-container__state", children: emptyContent }) : children })
|
|
4304
4751
|
] });
|
|
4305
4752
|
}
|
|
4306
4753
|
function PivotTable({ data, row, column, values, rowLabel = "\u9879\u76EE", showTotals = true, empty = "\u6682\u65E0\u900F\u89C6\u6570\u636E" }) {
|
|
@@ -4310,60 +4757,60 @@ function PivotTable({ data, row, column, values, rowLabel = "\u9879\u76EE", show
|
|
|
4310
4757
|
const sum = items.reduce((total, item) => total + metric.value(item), 0);
|
|
4311
4758
|
return metric.aggregate === "average" ? items.length ? sum / items.length : 0 : sum;
|
|
4312
4759
|
};
|
|
4313
|
-
if (!data.length || !values.length) return /* @__PURE__ */ (0,
|
|
4314
|
-
return /* @__PURE__ */ (0,
|
|
4315
|
-
/* @__PURE__ */ (0,
|
|
4316
|
-
/* @__PURE__ */ (0,
|
|
4317
|
-
/* @__PURE__ */ (0,
|
|
4318
|
-
columns.map((item) => /* @__PURE__ */ (0,
|
|
4319
|
-
showTotals && /* @__PURE__ */ (0,
|
|
4760
|
+
if (!data.length || !values.length) return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-pivot-table__empty", children: empty });
|
|
4761
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "hf-pivot-table", children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("table", { children: [
|
|
4762
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("thead", { children: [
|
|
4763
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("tr", { children: [
|
|
4764
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("th", { rowSpan: 2, children: rowLabel }),
|
|
4765
|
+
columns.map((item) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("th", { colSpan: values.length, children: item }, item)),
|
|
4766
|
+
showTotals && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("th", { colSpan: values.length, children: "\u5408\u8BA1" })
|
|
4320
4767
|
] }),
|
|
4321
|
-
/* @__PURE__ */ (0,
|
|
4768
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("tr", { children: [...columns, ...showTotals ? ["__total"] : []].flatMap((col) => values.map((metric) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("th", { children: metric.label }, `${col}-${metric.key}`))) })
|
|
4322
4769
|
] }),
|
|
4323
|
-
/* @__PURE__ */ (0,
|
|
4324
|
-
/* @__PURE__ */ (0,
|
|
4770
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("tbody", { children: rows.map((rowName) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("tr", { children: [
|
|
4771
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("th", { children: rowName }),
|
|
4325
4772
|
[...columns, ...showTotals ? ["__total"] : []].flatMap((columnName) => values.map((metric) => {
|
|
4326
4773
|
const items = data.filter((item) => row(item) === rowName && (columnName === "__total" || column(item) === columnName));
|
|
4327
4774
|
const result = calculate(items, metric);
|
|
4328
|
-
return /* @__PURE__ */ (0,
|
|
4775
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("td", { children: metric.format?.(result) ?? result }, `${columnName}-${metric.key}`);
|
|
4329
4776
|
}))
|
|
4330
4777
|
] }, rowName)) })
|
|
4331
4778
|
] }) });
|
|
4332
4779
|
}
|
|
4333
4780
|
|
|
4334
4781
|
// src/forms/FilterBuilder.tsx
|
|
4335
|
-
var
|
|
4782
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
4336
4783
|
function FilterBuilder({ fields, value, onChange, disabled, addLabel = "\u6DFB\u52A0\u7B5B\u9009" }) {
|
|
4337
4784
|
const add = () => {
|
|
4338
4785
|
const field = fields.find((item) => !value.some((filter) => filter.field === item.key)) ?? fields[0];
|
|
4339
4786
|
if (field) onChange([...value, { id: `filter-${Date.now()}`, field: field.key, value: "" }]);
|
|
4340
4787
|
};
|
|
4341
4788
|
const update = (id, patch) => onChange(value.map((item) => item.id === id ? { ...item, ...patch } : item));
|
|
4342
|
-
return /* @__PURE__ */ (0,
|
|
4343
|
-
/* @__PURE__ */ (0,
|
|
4789
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "hf-filter-builder", role: "group", "aria-label": "\u7B5B\u9009\u6761\u4EF6", children: [
|
|
4790
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { children: value.map((filter, index) => {
|
|
4344
4791
|
const field = fields.find((item) => item.key === filter.field) ?? fields[0];
|
|
4345
|
-
return /* @__PURE__ */ (0,
|
|
4346
|
-
/* @__PURE__ */ (0,
|
|
4347
|
-
field?.options ? /* @__PURE__ */ (0,
|
|
4348
|
-
/* @__PURE__ */ (0,
|
|
4792
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "hf-filter-builder__item", children: [
|
|
4793
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Select, { className: "hf-filter-builder__select", "aria-label": `\u7B5B\u9009 ${index + 1} \u5B57\u6BB5`, value: filter.field, disabled, options: fields.map((item) => ({ value: item.key, label: item.label })), onChange: (event) => update(filter.id, { field: event.target.value, value: "" }) }),
|
|
4794
|
+
field?.options ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Select, { className: "hf-filter-builder__select", "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, value: filter.value, placeholder: "\u8BF7\u9009\u62E9", disabled, options: field.options, onChange: (event) => update(filter.id, { value: event.target.value }) }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("input", { "aria-label": `\u7B5B\u9009 ${index + 1} \u503C`, type: field?.type ?? "text", value: filter.value, disabled, onChange: (event) => update(filter.id, { value: event.target.value }) }),
|
|
4795
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", "aria-label": `\u5220\u9664\u7B5B\u9009 ${index + 1}`, disabled, onClick: () => onChange(value.filter((item) => item.id !== filter.id)), children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)(Icon, { name: "close", size: 15 }) })
|
|
4349
4796
|
] }, filter.id);
|
|
4350
4797
|
}) }),
|
|
4351
|
-
/* @__PURE__ */ (0,
|
|
4798
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("button", { type: "button", className: "hf-filter-builder__add", disabled: disabled || !fields.length, onClick: add, children: [
|
|
4352
4799
|
"\uFF0B ",
|
|
4353
4800
|
addLabel
|
|
4354
4801
|
] }),
|
|
4355
|
-
value.length > 0 && /* @__PURE__ */ (0,
|
|
4802
|
+
value.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "hf-filter-builder__clear", disabled, onClick: () => onChange([]), children: "\u6E05\u7A7A" })
|
|
4356
4803
|
] });
|
|
4357
4804
|
}
|
|
4358
4805
|
|
|
4359
4806
|
// src/data-display/ZoomableChart.tsx
|
|
4360
|
-
var
|
|
4361
|
-
var
|
|
4807
|
+
var import_react65 = require("react");
|
|
4808
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
4362
4809
|
function normalizeWindow(value, length) {
|
|
4363
4810
|
const last = Math.max(0, length - 1);
|
|
4364
|
-
const
|
|
4365
|
-
let start =
|
|
4366
|
-
let end =
|
|
4811
|
+
const clamp2 = (number, fallback) => Number.isFinite(number) ? Math.max(0, Math.min(last, Math.round(number))) : fallback;
|
|
4812
|
+
let start = clamp2(value[0], 0);
|
|
4813
|
+
let end = clamp2(value[1], last);
|
|
4367
4814
|
if (start > end) [start, end] = [end, start];
|
|
4368
4815
|
if (start === end && length > 1) {
|
|
4369
4816
|
if (end < last) end++;
|
|
@@ -4381,9 +4828,9 @@ function ZoomableChart({
|
|
|
4381
4828
|
disabled = false,
|
|
4382
4829
|
className = ""
|
|
4383
4830
|
}) {
|
|
4384
|
-
const [internal, setInternal] = (0,
|
|
4831
|
+
const [internal, setInternal] = (0, import_react65.useState)(defaultWindow);
|
|
4385
4832
|
const [start, end] = normalizeWindow(controlled ?? internal ?? [0, points.length - 1], points.length);
|
|
4386
|
-
const visible = (0,
|
|
4833
|
+
const visible = (0, import_react65.useMemo)(() => points.slice(start, end + 1), [points, start, end]);
|
|
4387
4834
|
const count = end - start + 1;
|
|
4388
4835
|
function update(next) {
|
|
4389
4836
|
if (disabled) return;
|
|
@@ -4401,13 +4848,13 @@ function ZoomableChart({
|
|
|
4401
4848
|
const left = Math.max(0, Math.min(points.length - count, start + direction * Math.max(1, Math.floor(count / 2))));
|
|
4402
4849
|
update([left, left + count - 1]);
|
|
4403
4850
|
}
|
|
4404
|
-
return /* @__PURE__ */ (0,
|
|
4405
|
-
/* @__PURE__ */ (0,
|
|
4406
|
-
/* @__PURE__ */ (0,
|
|
4407
|
-
/* @__PURE__ */ (0,
|
|
4408
|
-
/* @__PURE__ */ (0,
|
|
4409
|
-
/* @__PURE__ */ (0,
|
|
4410
|
-
/* @__PURE__ */ (0,
|
|
4851
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: `hf-zoomable-chart ${className}`, children: [
|
|
4852
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "hf-zoomable-chart__controls", role: "group", "aria-label": `${label}\u89C6\u7A97\u64CD\u4F5C`, children: [
|
|
4853
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || count <= 2, onClick: () => resize(0.5), children: "\u653E\u5927" }),
|
|
4854
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || count >= points.length, onClick: () => resize(2), children: "\u7F29\u5C0F" }),
|
|
4855
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || start === 0, onClick: () => pan(-1), children: "\u5411\u524D\u5E73\u79FB" }),
|
|
4856
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || end >= points.length - 1, onClick: () => pan(1), children: "\u5411\u540E\u5E73\u79FB" }),
|
|
4857
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
4411
4858
|
Button,
|
|
4412
4859
|
{
|
|
4413
4860
|
type: "button",
|
|
@@ -4419,8 +4866,8 @@ function ZoomableChart({
|
|
|
4419
4866
|
}
|
|
4420
4867
|
)
|
|
4421
4868
|
] }),
|
|
4422
|
-
/* @__PURE__ */ (0,
|
|
4423
|
-
points.length > 1 && /* @__PURE__ */ (0,
|
|
4869
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)(ChartCrosshair, { points: visible, label, formatValue, disabled }),
|
|
4870
|
+
points.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
4424
4871
|
RangeBrush,
|
|
4425
4872
|
{
|
|
4426
4873
|
label: "\u53EF\u89C1\u6570\u636E\u8303\u56F4",
|
|
@@ -4432,22 +4879,22 @@ function ZoomableChart({
|
|
|
4432
4879
|
formatValue: (index) => points[index]?.label ?? String(index)
|
|
4433
4880
|
}
|
|
4434
4881
|
),
|
|
4435
|
-
/* @__PURE__ */ (0,
|
|
4882
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "hf-zoomable-chart__summary", role: "status", children: points.length ? `\u663E\u793A\u7B2C${start + 1}\u2014${end + 1}\u70B9\uFF0C\u5171${points.length}\u70B9` : "\u6CA1\u6709\u53EF\u7F29\u653E\u7684\u6570\u636E" })
|
|
4436
4883
|
] });
|
|
4437
4884
|
}
|
|
4438
4885
|
|
|
4439
4886
|
// src/feedback/HoldToConfirm.tsx
|
|
4440
|
-
var
|
|
4887
|
+
var import_react68 = require("react");
|
|
4441
4888
|
|
|
4442
4889
|
// src/feedback/useHoldConfirmation.ts
|
|
4443
|
-
var
|
|
4890
|
+
var import_react66 = require("react");
|
|
4444
4891
|
function useHoldConfirmation(options) {
|
|
4445
|
-
const latest = (0,
|
|
4892
|
+
const latest = (0, import_react66.useRef)(options);
|
|
4446
4893
|
latest.current = options;
|
|
4447
|
-
const session = (0,
|
|
4448
|
-
const frame = (0,
|
|
4449
|
-
const [progress, setProgress] = (0,
|
|
4450
|
-
const [message, setMessage] = (0,
|
|
4894
|
+
const session = (0, import_react66.useRef)(null);
|
|
4895
|
+
const frame = (0, import_react66.useRef)(void 0);
|
|
4896
|
+
const [progress, setProgress] = (0, import_react66.useState)(0);
|
|
4897
|
+
const [message, setMessage] = (0, import_react66.useState)("");
|
|
4451
4898
|
function stopFrame() {
|
|
4452
4899
|
if (frame.current !== void 0) cancelAnimationFrame(frame.current);
|
|
4453
4900
|
frame.current = void 0;
|
|
@@ -4493,10 +4940,10 @@ function useHoldConfirmation(options) {
|
|
|
4493
4940
|
function release(source) {
|
|
4494
4941
|
if (session.current?.source === source) cancel();
|
|
4495
4942
|
}
|
|
4496
|
-
(0,
|
|
4943
|
+
(0, import_react66.useEffect)(() => {
|
|
4497
4944
|
cancel();
|
|
4498
4945
|
}, [options.actionKey, options.duration, options.blocked]);
|
|
4499
|
-
(0,
|
|
4946
|
+
(0, import_react66.useEffect)(() => {
|
|
4500
4947
|
const hide = () => {
|
|
4501
4948
|
if (document.hidden) cancel();
|
|
4502
4949
|
};
|
|
@@ -4518,15 +4965,15 @@ function useHoldConfirmation(options) {
|
|
|
4518
4965
|
}
|
|
4519
4966
|
|
|
4520
4967
|
// src/feedback/ConfirmationAlternative.tsx
|
|
4521
|
-
var
|
|
4522
|
-
var
|
|
4968
|
+
var import_react67 = require("react");
|
|
4969
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
4523
4970
|
function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
4524
|
-
const [open, setOpen] = (0,
|
|
4525
|
-
const [requested, setRequested] = (0,
|
|
4526
|
-
const requestedRef = (0,
|
|
4527
|
-
const trigger = (0,
|
|
4528
|
-
const confirm = (0,
|
|
4529
|
-
const id = (0,
|
|
4971
|
+
const [open, setOpen] = (0, import_react67.useState)(false);
|
|
4972
|
+
const [requested, setRequested] = (0, import_react67.useState)(false);
|
|
4973
|
+
const requestedRef = (0, import_react67.useRef)(false);
|
|
4974
|
+
const trigger = (0, import_react67.useRef)(null);
|
|
4975
|
+
const confirm = (0, import_react67.useRef)(null);
|
|
4976
|
+
const id = (0, import_react67.useId)();
|
|
4530
4977
|
function close() {
|
|
4531
4978
|
setOpen(false);
|
|
4532
4979
|
trigger.current?.focus();
|
|
@@ -4547,11 +4994,11 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4547
4994
|
setRequested(true);
|
|
4548
4995
|
onConfirm();
|
|
4549
4996
|
}
|
|
4550
|
-
(0,
|
|
4997
|
+
(0, import_react67.useEffect)(() => {
|
|
4551
4998
|
if (open) confirm.current?.focus();
|
|
4552
4999
|
}, [open]);
|
|
4553
|
-
return /* @__PURE__ */ (0,
|
|
4554
|
-
/* @__PURE__ */ (0,
|
|
5000
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { children: [
|
|
5001
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(
|
|
4555
5002
|
Button,
|
|
4556
5003
|
{
|
|
4557
5004
|
type: "button",
|
|
@@ -4565,7 +5012,7 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4565
5012
|
children: "\u5206\u6B65\u786E\u8BA4\uFF08\u65E0\u9700\u957F\u6309\uFF09"
|
|
4566
5013
|
}
|
|
4567
5014
|
),
|
|
4568
|
-
open && /* @__PURE__ */ (0,
|
|
5015
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)(
|
|
4569
5016
|
"div",
|
|
4570
5017
|
{
|
|
4571
5018
|
id,
|
|
@@ -4576,16 +5023,16 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4576
5023
|
if (event.key === "Escape") close();
|
|
4577
5024
|
},
|
|
4578
5025
|
children: [
|
|
4579
|
-
/* @__PURE__ */ (0,
|
|
5026
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("p", { children: [
|
|
4580
5027
|
"\u786E\u8BA4\u6267\u884C\u201C",
|
|
4581
5028
|
label,
|
|
4582
5029
|
"\u201D\uFF1F"
|
|
4583
5030
|
] }),
|
|
4584
|
-
/* @__PURE__ */ (0,
|
|
4585
|
-
/* @__PURE__ */ (0,
|
|
4586
|
-
/* @__PURE__ */ (0,
|
|
5031
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "hf-confirm-actions", children: [
|
|
5032
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, { type: "button", variant: "outline", onClick: close, children: "\u53D6\u6D88" }),
|
|
5033
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)(Button, { type: "button", ref: confirm, disabled: blocked || requested, onClick: request, children: "\u786E\u8BA4\u6267\u884C" })
|
|
4587
5034
|
] }),
|
|
4588
|
-
requested && /* @__PURE__ */ (0,
|
|
5035
|
+
requested && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("p", { className: "hf-confirm-hint", role: "status", children: "\u5DF2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u8BF7\u7B49\u5F85\u64CD\u4F5C\u7ED3\u679C" })
|
|
4589
5036
|
]
|
|
4590
5037
|
}
|
|
4591
5038
|
)
|
|
@@ -4593,7 +5040,7 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4593
5040
|
}
|
|
4594
5041
|
|
|
4595
5042
|
// src/feedback/HoldToConfirm.tsx
|
|
4596
|
-
var
|
|
5043
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
4597
5044
|
function HoldToConfirm({
|
|
4598
5045
|
actionKey,
|
|
4599
5046
|
label,
|
|
@@ -4607,14 +5054,14 @@ function HoldToConfirm({
|
|
|
4607
5054
|
const milliseconds = Number.isFinite(duration) ? Math.max(500, Math.min(1e4, duration)) : 1500;
|
|
4608
5055
|
const blocked = disabled || loading;
|
|
4609
5056
|
const hold = useHoldConfirmation({ actionKey, duration: milliseconds, blocked, onConfirm });
|
|
4610
|
-
const hintId = (0,
|
|
4611
|
-
return /* @__PURE__ */ (0,
|
|
4612
|
-
/* @__PURE__ */ (0,
|
|
5057
|
+
const hintId = (0, import_react68.useId)();
|
|
5058
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: `hf-hold-confirm ${className}`, children: [
|
|
5059
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("p", { id: hintId, className: "hf-confirm-hint", children: [
|
|
4613
5060
|
"\u6309\u4F4F",
|
|
4614
5061
|
milliseconds / 1e3,
|
|
4615
5062
|
"\u79D2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u63D0\u524D\u677E\u5F00\u53EF\u53D6\u6D88\u3002"
|
|
4616
5063
|
] }),
|
|
4617
|
-
/* @__PURE__ */ (0,
|
|
5064
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
4618
5065
|
Button,
|
|
4619
5066
|
{
|
|
4620
5067
|
type: "button",
|
|
@@ -4651,8 +5098,8 @@ function HoldToConfirm({
|
|
|
4651
5098
|
children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : label
|
|
4652
5099
|
}
|
|
4653
5100
|
),
|
|
4654
|
-
/* @__PURE__ */ (0,
|
|
4655
|
-
/* @__PURE__ */ (0,
|
|
5101
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { className: "hf-hold-confirm__track", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { style: { width: `${hold.progress * 100}%` } }) }),
|
|
5102
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
4656
5103
|
ConfirmationAlternative,
|
|
4657
5104
|
{
|
|
4658
5105
|
label,
|
|
@@ -4662,16 +5109,16 @@ function HoldToConfirm({
|
|
|
4662
5109
|
},
|
|
4663
5110
|
JSON.stringify([actionKey, milliseconds, blocked])
|
|
4664
5111
|
),
|
|
4665
|
-
/* @__PURE__ */ (0,
|
|
4666
|
-
error && /* @__PURE__ */ (0,
|
|
5112
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "hf-confirm-hint", role: "status", children: hold.message }),
|
|
5113
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "hf-confirm-error hf-tone--danger", role: "alert", children: error })
|
|
4667
5114
|
] });
|
|
4668
5115
|
}
|
|
4669
5116
|
|
|
4670
5117
|
// src/feedback/TypedConfirm.tsx
|
|
4671
|
-
var
|
|
4672
|
-
var
|
|
5118
|
+
var import_react69 = require("react");
|
|
5119
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
4673
5120
|
function TypedConfirm(props) {
|
|
4674
|
-
return /* @__PURE__ */ (0,
|
|
5121
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(TypedConfirmFields, { ...props }, JSON.stringify([props.actionKey, props.confirmationText]));
|
|
4675
5122
|
}
|
|
4676
5123
|
function TypedConfirmFields({
|
|
4677
5124
|
confirmationText,
|
|
@@ -4684,12 +5131,12 @@ function TypedConfirmFields({
|
|
|
4684
5131
|
error,
|
|
4685
5132
|
className = ""
|
|
4686
5133
|
}) {
|
|
4687
|
-
const [value, setValue] = (0,
|
|
4688
|
-
const [composing, setComposing] = (0,
|
|
4689
|
-
const [requested, setRequested] = (0,
|
|
4690
|
-
const composingRef = (0,
|
|
4691
|
-
const valueRef = (0,
|
|
4692
|
-
const titleId = (0,
|
|
5134
|
+
const [value, setValue] = (0, import_react69.useState)("");
|
|
5135
|
+
const [composing, setComposing] = (0, import_react69.useState)(false);
|
|
5136
|
+
const [requested, setRequested] = (0, import_react69.useState)(false);
|
|
5137
|
+
const composingRef = (0, import_react69.useRef)(false);
|
|
5138
|
+
const valueRef = (0, import_react69.useRef)("");
|
|
5139
|
+
const titleId = (0, import_react69.useId)();
|
|
4693
5140
|
const validTarget = confirmationText.trim().length > 0 && !/[\r\n]/.test(confirmationText);
|
|
4694
5141
|
const blocked = disabled || loading;
|
|
4695
5142
|
const matches = validTarget && value === confirmationText && !composing;
|
|
@@ -4700,15 +5147,15 @@ function TypedConfirmFields({
|
|
|
4700
5147
|
setRequested(true);
|
|
4701
5148
|
onConfirm();
|
|
4702
5149
|
}
|
|
4703
|
-
return /* @__PURE__ */ (0,
|
|
4704
|
-
/* @__PURE__ */ (0,
|
|
4705
|
-
description && /* @__PURE__ */ (0,
|
|
4706
|
-
validTarget ? /* @__PURE__ */ (0,
|
|
5150
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: `hf-typed-confirm ${className}`, "aria-labelledby": titleId, children: [
|
|
5151
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("h3", { id: titleId, children: label }),
|
|
5152
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { children: description }),
|
|
5153
|
+
validTarget ? /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("p", { children: [
|
|
4707
5154
|
"\u8F93\u5165 ",
|
|
4708
|
-
/* @__PURE__ */ (0,
|
|
5155
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("code", { children: confirmationText }),
|
|
4709
5156
|
" \u4EE5\u786E\u8BA4\uFF0C\u9700\u5B8C\u5168\u4E00\u81F4\u3002"
|
|
4710
|
-
] }) : /* @__PURE__ */ (0,
|
|
4711
|
-
/* @__PURE__ */ (0,
|
|
5157
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { role: "alert", className: "hf-confirm-error hf-tone--danger", children: "\u786E\u8BA4\u6587\u5B57\u4E0D\u80FD\u4E3A\u7A7A\u6216\u5305\u542B\u6362\u884C\uFF0C\u8BF7\u914D\u7F6E\u6709\u6548\u7684\u5355\u884C\u5185\u5BB9\u3002" }),
|
|
5158
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(
|
|
4712
5159
|
Input,
|
|
4713
5160
|
{
|
|
4714
5161
|
label: "\u786E\u8BA4\u6587\u5B57",
|
|
@@ -4738,21 +5185,21 @@ function TypedConfirmFields({
|
|
|
4738
5185
|
}
|
|
4739
5186
|
}
|
|
4740
5187
|
),
|
|
4741
|
-
/* @__PURE__ */ (0,
|
|
4742
|
-
/* @__PURE__ */ (0,
|
|
4743
|
-
error && /* @__PURE__ */ (0,
|
|
5188
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)(Button, { type: "button", disabled: blocked || !matches, onClick: confirm, children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : confirmLabel }),
|
|
5189
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "hf-confirm-hint", role: "status", children: requested ? "\u5DF2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u8BF7\u7B49\u5F85\u64CD\u4F5C\u7ED3\u679C" : matches ? "\u6587\u5B57\u5DF2\u5339\u914D\uFF0C\u53EF\u4EE5\u786E\u8BA4" : "" }),
|
|
5190
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "hf-confirm-error hf-tone--danger", role: "alert", children: error })
|
|
4744
5191
|
] });
|
|
4745
5192
|
}
|
|
4746
5193
|
|
|
4747
5194
|
// src/data-display/SwipeActions.tsx
|
|
4748
|
-
var
|
|
5195
|
+
var import_react71 = require("react");
|
|
4749
5196
|
|
|
4750
5197
|
// src/data-display/useSwipeReveal.ts
|
|
4751
|
-
var
|
|
5198
|
+
var import_react70 = require("react");
|
|
4752
5199
|
function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
4753
|
-
const session = (0,
|
|
4754
|
-
const [offset, setOffset] = (0,
|
|
4755
|
-
const cleanup = (0,
|
|
5200
|
+
const session = (0, import_react70.useRef)(null);
|
|
5201
|
+
const [offset, setOffset] = (0, import_react70.useState)(null);
|
|
5202
|
+
const cleanup = (0, import_react70.useRef)(null);
|
|
4756
5203
|
function cancel() {
|
|
4757
5204
|
cleanup.current?.();
|
|
4758
5205
|
cleanup.current = null;
|
|
@@ -4798,7 +5245,7 @@ function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
|
4798
5245
|
if (!disabled && current.open === open && Math.abs(current.delta) >= 40) onChange(current.delta < 0);
|
|
4799
5246
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
4800
5247
|
}
|
|
4801
|
-
(0,
|
|
5248
|
+
(0, import_react70.useEffect)(() => () => {
|
|
4802
5249
|
cleanup.current?.();
|
|
4803
5250
|
session.current = null;
|
|
4804
5251
|
}, []);
|
|
@@ -4806,10 +5253,10 @@ function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
|
4806
5253
|
}
|
|
4807
5254
|
|
|
4808
5255
|
// src/data-display/SwipeActions.tsx
|
|
4809
|
-
var
|
|
5256
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
4810
5257
|
function SwipeActions(props) {
|
|
4811
5258
|
const identity = JSON.stringify([props.actionKey, props.disabled, props.actions.map(({ id, label, disabled, tone }) => [id, label, disabled, tone])]);
|
|
4812
|
-
return /* @__PURE__ */ (0,
|
|
5259
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(SwipeActionsRow, { ...props }, identity);
|
|
4813
5260
|
}
|
|
4814
5261
|
function SwipeActionsRow({
|
|
4815
5262
|
label,
|
|
@@ -4821,10 +5268,10 @@ function SwipeActionsRow({
|
|
|
4821
5268
|
disabled = false,
|
|
4822
5269
|
className = ""
|
|
4823
5270
|
}) {
|
|
4824
|
-
const [internal, setInternal] = (0,
|
|
4825
|
-
const trigger = (0,
|
|
4826
|
-
const tools = (0,
|
|
4827
|
-
const id = (0,
|
|
5271
|
+
const [internal, setInternal] = (0, import_react71.useState)(defaultOpen);
|
|
5272
|
+
const trigger = (0, import_react71.useRef)(null);
|
|
5273
|
+
const tools = (0, import_react71.useRef)(null);
|
|
5274
|
+
const id = (0, import_react71.useId)();
|
|
4828
5275
|
const valid = actions.length > 0 && actions.every((item) => item.id.trim() && item.label.trim()) && new Set(actions.map((item) => item.id)).size === actions.length;
|
|
4829
5276
|
const blocked = disabled || !valid;
|
|
4830
5277
|
const open = !blocked && (controlled ?? internal);
|
|
@@ -4834,7 +5281,7 @@ function SwipeActionsRow({
|
|
|
4834
5281
|
onOpenChange?.(next);
|
|
4835
5282
|
}
|
|
4836
5283
|
const swipe = useSwipeReveal({ open, disabled: blocked, width: 144, onChange: request });
|
|
4837
|
-
(0,
|
|
5284
|
+
(0, import_react71.useEffect)(() => {
|
|
4838
5285
|
if (!open) return;
|
|
4839
5286
|
const frame = requestAnimationFrame(() => {
|
|
4840
5287
|
if (document.activeElement === trigger.current) tools.current?.querySelector("button:not(:disabled)")?.focus();
|
|
@@ -4851,10 +5298,10 @@ function SwipeActionsRow({
|
|
|
4851
5298
|
close();
|
|
4852
5299
|
action.onAction();
|
|
4853
5300
|
}
|
|
4854
|
-
return /* @__PURE__ */ (0,
|
|
5301
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: `hf-swipe-actions ${className}`, onKeyDown: (event) => {
|
|
4855
5302
|
if (event.key === "Escape") close();
|
|
4856
5303
|
}, children: [
|
|
4857
|
-
/* @__PURE__ */ (0,
|
|
5304
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
4858
5305
|
"div",
|
|
4859
5306
|
{
|
|
4860
5307
|
className: "hf-swipe-actions__viewport",
|
|
@@ -4870,7 +5317,7 @@ function SwipeActionsRow({
|
|
|
4870
5317
|
if (!event.currentTarget.contains(event.relatedTarget)) swipe.cancel();
|
|
4871
5318
|
},
|
|
4872
5319
|
children: [
|
|
4873
|
-
open && /* @__PURE__ */ (0,
|
|
5320
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { id, ref: tools, className: "hf-swipe-actions__tools", children: actions.map((action, index) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
4874
5321
|
Button,
|
|
4875
5322
|
{
|
|
4876
5323
|
type: "button",
|
|
@@ -4882,7 +5329,7 @@ function SwipeActionsRow({
|
|
|
4882
5329
|
},
|
|
4883
5330
|
index
|
|
4884
5331
|
)) }),
|
|
4885
|
-
/* @__PURE__ */ (0,
|
|
5332
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
4886
5333
|
"div",
|
|
4887
5334
|
{
|
|
4888
5335
|
className: "hf-swipe-actions__content",
|
|
@@ -4895,7 +5342,7 @@ function SwipeActionsRow({
|
|
|
4895
5342
|
]
|
|
4896
5343
|
}
|
|
4897
5344
|
),
|
|
4898
|
-
/* @__PURE__ */ (0,
|
|
5345
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)(
|
|
4899
5346
|
Button,
|
|
4900
5347
|
{
|
|
4901
5348
|
type: "button",
|
|
@@ -4916,16 +5363,16 @@ function SwipeActionsRow({
|
|
|
4916
5363
|
]
|
|
4917
5364
|
}
|
|
4918
5365
|
),
|
|
4919
|
-
!valid && /* @__PURE__ */ (0,
|
|
5366
|
+
!valid && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "hf-row-hint", children: actions.length ? "\u64CD\u4F5C\u6807\u8BC6\u548C\u540D\u79F0\u5FC5\u987B\u975E\u7A7A\uFF0C\u4E14\u6807\u8BC6\u4E0D\u80FD\u91CD\u590D\u3002" : "\u6682\u65E0\u53EF\u7528\u64CD\u4F5C" })
|
|
4920
5367
|
] });
|
|
4921
5368
|
}
|
|
4922
5369
|
|
|
4923
5370
|
// src/feedback/ChecklistConfirm.tsx
|
|
4924
|
-
var
|
|
4925
|
-
var
|
|
5371
|
+
var import_react72 = require("react");
|
|
5372
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
4926
5373
|
function ChecklistConfirm(props) {
|
|
4927
5374
|
const identity = JSON.stringify([props.actionKey, props.items.map(({ id, label, description }) => [id, label, description])]);
|
|
4928
|
-
return /* @__PURE__ */ (0,
|
|
5375
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(ChecklistConfirmFields, { ...props }, identity);
|
|
4929
5376
|
}
|
|
4930
5377
|
function ChecklistConfirmFields({
|
|
4931
5378
|
title,
|
|
@@ -4937,11 +5384,11 @@ function ChecklistConfirmFields({
|
|
|
4937
5384
|
error,
|
|
4938
5385
|
className = ""
|
|
4939
5386
|
}) {
|
|
4940
|
-
const [checked, setChecked] = (0,
|
|
4941
|
-
const [requested, setRequested] = (0,
|
|
4942
|
-
const lock = (0,
|
|
4943
|
-
const first = (0,
|
|
4944
|
-
const titleId = (0,
|
|
5387
|
+
const [checked, setChecked] = (0, import_react72.useState)(/* @__PURE__ */ new Set());
|
|
5388
|
+
const [requested, setRequested] = (0, import_react72.useState)(false);
|
|
5389
|
+
const lock = (0, import_react72.useRef)(false);
|
|
5390
|
+
const first = (0, import_react72.useRef)(null);
|
|
5391
|
+
const titleId = (0, import_react72.useId)();
|
|
4945
5392
|
const valid = items.length > 0 && items.every((item) => item.id.trim() && item.label.trim()) && new Set(items.map((item) => item.id)).size === items.length;
|
|
4946
5393
|
const blocked = disabled || loading || !valid;
|
|
4947
5394
|
const allChecked = valid && items.every((item) => checked.has(item.id));
|
|
@@ -4964,10 +5411,10 @@ function ChecklistConfirmFields({
|
|
|
4964
5411
|
first.current?.focus();
|
|
4965
5412
|
onConfirm();
|
|
4966
5413
|
}
|
|
4967
|
-
return /* @__PURE__ */ (0,
|
|
4968
|
-
/* @__PURE__ */ (0,
|
|
4969
|
-
!valid && /* @__PURE__ */ (0,
|
|
4970
|
-
/* @__PURE__ */ (0,
|
|
5414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("section", { className: `hf-checklist-confirm ${className}`, "aria-labelledby": titleId, children: [
|
|
5415
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("h3", { id: titleId, children: title }),
|
|
5416
|
+
!valid && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { role: "alert", className: "hf-tone--danger hf-row-error", children: items.length ? "\u786E\u8BA4\u9879\u6807\u8BC6\u548C\u540D\u79F0\u5FC5\u987B\u975E\u7A7A\uFF0C\u4E14\u6807\u8BC6\u4E0D\u80FD\u91CD\u590D\u3002" : "\u6682\u65E0\u786E\u8BA4\u9879\uFF0C\u4E0D\u80FD\u63D0\u4EA4\u3002" }),
|
|
5417
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("div", { className: "hf-checklist-confirm__items", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
4971
5418
|
Checkbox,
|
|
4972
5419
|
{
|
|
4973
5420
|
ref: index === 0 ? first : void 0,
|
|
@@ -4979,22 +5426,22 @@ function ChecklistConfirmFields({
|
|
|
4979
5426
|
},
|
|
4980
5427
|
index
|
|
4981
5428
|
)) }),
|
|
4982
|
-
/* @__PURE__ */ (0,
|
|
4983
|
-
/* @__PURE__ */ (0,
|
|
4984
|
-
error && /* @__PURE__ */ (0,
|
|
5429
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { className: "hf-row-hint", role: "status", children: requested ? "\u5DF2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u8BF7\u7B49\u5F85\u64CD\u4F5C\u7ED3\u679C" : `\u5DF2\u786E\u8BA4 ${checked.size} / ${items.length} \u9879` }),
|
|
5430
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(Button, { type: "button", disabled: blocked || !allChecked, onClick: confirm, children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : confirmLabel }),
|
|
5431
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("p", { role: "alert", className: "hf-tone--danger hf-row-error", children: error })
|
|
4985
5432
|
] });
|
|
4986
5433
|
}
|
|
4987
5434
|
|
|
4988
5435
|
// src/feedback/UndoNotice.tsx
|
|
4989
|
-
var
|
|
5436
|
+
var import_react75 = require("react");
|
|
4990
5437
|
|
|
4991
5438
|
// src/feedback/useUndoDeadline.ts
|
|
4992
|
-
var
|
|
5439
|
+
var import_react73 = require("react");
|
|
4993
5440
|
function useUndoDeadline(expiresAt, active) {
|
|
4994
|
-
const [now, setNow] = (0,
|
|
5441
|
+
const [now, setNow] = (0, import_react73.useState)(() => Date.now());
|
|
4995
5442
|
const valid = expiresAt === void 0 || Number.isFinite(expiresAt);
|
|
4996
5443
|
const expired = expiresAt !== void 0 && valid && expiresAt <= Math.max(now, Date.now());
|
|
4997
|
-
(0,
|
|
5444
|
+
(0, import_react73.useEffect)(() => {
|
|
4998
5445
|
if (!active || !valid || expiresAt === void 0 || expired) return;
|
|
4999
5446
|
const update = () => setNow(Date.now());
|
|
5000
5447
|
const timer = window.setTimeout(update, Math.min(1e3, Math.max(1, expiresAt - Date.now())));
|
|
@@ -5009,12 +5456,12 @@ function useUndoDeadline(expiresAt, active) {
|
|
|
5009
5456
|
}
|
|
5010
5457
|
|
|
5011
5458
|
// src/feedback/useUndoRequest.ts
|
|
5012
|
-
var
|
|
5459
|
+
var import_react74 = require("react");
|
|
5013
5460
|
function useUndoRequest(onUndo) {
|
|
5014
|
-
const [phase, setPhase] = (0,
|
|
5015
|
-
const currentPhase = (0,
|
|
5016
|
-
const request = (0,
|
|
5017
|
-
(0,
|
|
5461
|
+
const [phase, setPhase] = (0, import_react74.useState)("ready");
|
|
5462
|
+
const currentPhase = (0, import_react74.useRef)("ready");
|
|
5463
|
+
const request = (0, import_react74.useRef)(null);
|
|
5464
|
+
(0, import_react74.useEffect)(() => () => request.current?.abort(), []);
|
|
5018
5465
|
async function undo() {
|
|
5019
5466
|
if (currentPhase.current === "pending" || currentPhase.current === "undone") return;
|
|
5020
5467
|
const controller = new AbortController();
|
|
@@ -5038,9 +5485,9 @@ function useUndoRequest(onUndo) {
|
|
|
5038
5485
|
}
|
|
5039
5486
|
|
|
5040
5487
|
// src/feedback/UndoNotice.tsx
|
|
5041
|
-
var
|
|
5488
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
5042
5489
|
function UndoNotice(props) {
|
|
5043
|
-
return /* @__PURE__ */ (0,
|
|
5490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(UndoNoticeSession, { ...props }, props.operationKey);
|
|
5044
5491
|
}
|
|
5045
5492
|
function UndoNoticeSession({
|
|
5046
5493
|
operationKey,
|
|
@@ -5055,8 +5502,8 @@ function UndoNoticeSession({
|
|
|
5055
5502
|
}) {
|
|
5056
5503
|
const { phase, undo } = useUndoRequest(onUndo);
|
|
5057
5504
|
const deadline = useUndoDeadline(expiresAt, phase === "ready" || phase === "failed");
|
|
5058
|
-
const messageId = (0,
|
|
5059
|
-
const statusId = (0,
|
|
5505
|
+
const messageId = (0, import_react75.useId)();
|
|
5506
|
+
const statusId = (0, import_react75.useId)();
|
|
5060
5507
|
const valid = deadline.valid && !!operationKey.trim() && !!message.trim() && !!undoLabel.trim();
|
|
5061
5508
|
const pending = phase === "pending";
|
|
5062
5509
|
const undone = phase === "undone";
|
|
@@ -5066,18 +5513,18 @@ function UndoNoticeSession({
|
|
|
5066
5513
|
if (blocked || expiresAt !== void 0 && Date.now() >= expiresAt) return;
|
|
5067
5514
|
void undo();
|
|
5068
5515
|
}
|
|
5069
|
-
return /* @__PURE__ */ (0,
|
|
5070
|
-
/* @__PURE__ */ (0,
|
|
5071
|
-
/* @__PURE__ */ (0,
|
|
5072
|
-
/* @__PURE__ */ (0,
|
|
5073
|
-
phase === "failed" && /* @__PURE__ */ (0,
|
|
5074
|
-
valid && !pending && !undone && !deadline.expired && deadline.remaining !== void 0 && /* @__PURE__ */ (0,
|
|
5516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("section", { className: `hf-undo-notice ${className}`.trim(), "aria-labelledby": messageId, children: [
|
|
5517
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "hf-undo-notice__content", children: [
|
|
5518
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { id: messageId, className: "hf-undo-notice__message", children: message }),
|
|
5519
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { id: statusId, role: "status", "aria-atomic": "true", className: "hf-undo-notice__status", children: status }),
|
|
5520
|
+
phase === "failed" && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)("p", { role: "alert", className: "hf-undo-notice__error hf-tone--danger", children: errorMessage.trim() || "\u64A4\u9500\u5931\u8D25\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" }),
|
|
5521
|
+
valid && !pending && !undone && !deadline.expired && deadline.remaining !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("p", { className: "hf-undo-notice__deadline", "aria-live": "off", children: [
|
|
5075
5522
|
"\u5269\u4F59 ",
|
|
5076
5523
|
deadline.remaining,
|
|
5077
5524
|
" \u79D2"
|
|
5078
5525
|
] })
|
|
5079
5526
|
] }),
|
|
5080
|
-
/* @__PURE__ */ (0,
|
|
5527
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
5081
5528
|
Button,
|
|
5082
5529
|
{
|
|
5083
5530
|
type: "button",
|
|
@@ -5092,93 +5539,11 @@ function UndoNoticeSession({
|
|
|
5092
5539
|
] });
|
|
5093
5540
|
}
|
|
5094
5541
|
|
|
5095
|
-
// src/navigation/useReadingPosition.ts
|
|
5096
|
-
var import_react71 = require("react");
|
|
5097
|
-
function useReadingPosition(target) {
|
|
5098
|
-
const [snapshot, setSnapshot] = (0, import_react71.useState)({ target, value: 0 });
|
|
5099
|
-
(0, import_react71.useEffect)(() => {
|
|
5100
|
-
if (target === null) return;
|
|
5101
|
-
const view = target?.ownerDocument.defaultView ?? window;
|
|
5102
|
-
const root = target ?? view.document.documentElement;
|
|
5103
|
-
const events = target ?? view;
|
|
5104
|
-
let frame = 0;
|
|
5105
|
-
let disposed = false;
|
|
5106
|
-
const measure = () => {
|
|
5107
|
-
frame = 0;
|
|
5108
|
-
if (disposed) return;
|
|
5109
|
-
const viewport = target ? root.clientHeight : view.innerHeight;
|
|
5110
|
-
const height = target ? root.scrollHeight : Math.max(root.scrollHeight, view.document.body?.scrollHeight ?? 0);
|
|
5111
|
-
const offset = target ? root.scrollTop : view.scrollY;
|
|
5112
|
-
const range = Math.max(0, height - viewport);
|
|
5113
|
-
const value = range === 0 ? 100 : Math.round(Math.min(1, Math.max(0, offset / range)) * 100);
|
|
5114
|
-
setSnapshot((previous) => previous.target === target && previous.value === value ? previous : { target, value });
|
|
5115
|
-
};
|
|
5116
|
-
const schedule = () => {
|
|
5117
|
-
if (!disposed && !frame) frame = view.requestAnimationFrame(measure);
|
|
5118
|
-
};
|
|
5119
|
-
const resize = new ResizeObserver(schedule);
|
|
5120
|
-
const observeContent = () => {
|
|
5121
|
-
resize.disconnect();
|
|
5122
|
-
resize.observe(root);
|
|
5123
|
-
for (const child of root.children) resize.observe(child);
|
|
5124
|
-
if (!target && view.document.body) {
|
|
5125
|
-
resize.observe(view.document.body);
|
|
5126
|
-
for (const child of view.document.body.children) resize.observe(child);
|
|
5127
|
-
}
|
|
5128
|
-
schedule();
|
|
5129
|
-
};
|
|
5130
|
-
const mutations = new MutationObserver(observeContent);
|
|
5131
|
-
mutations.observe(root, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
5132
|
-
events.addEventListener("scroll", schedule, { passive: true });
|
|
5133
|
-
view.addEventListener("resize", schedule);
|
|
5134
|
-
root.addEventListener("load", schedule, true);
|
|
5135
|
-
observeContent();
|
|
5136
|
-
return () => {
|
|
5137
|
-
disposed = true;
|
|
5138
|
-
view.cancelAnimationFrame(frame);
|
|
5139
|
-
resize.disconnect();
|
|
5140
|
-
mutations.disconnect();
|
|
5141
|
-
events.removeEventListener("scroll", schedule);
|
|
5142
|
-
view.removeEventListener("resize", schedule);
|
|
5143
|
-
root.removeEventListener("load", schedule, true);
|
|
5144
|
-
};
|
|
5145
|
-
}, [target]);
|
|
5146
|
-
return target === null || snapshot.target !== target ? 0 : snapshot.value;
|
|
5147
|
-
}
|
|
5148
|
-
|
|
5149
|
-
// src/navigation/ReadingProgress.tsx
|
|
5150
|
-
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
5151
|
-
function ReadingProgress({ target, label = "\u9605\u8BFB\u8FDB\u5EA6", showValue = true, className = "" }) {
|
|
5152
|
-
const value = useReadingPosition(target);
|
|
5153
|
-
const name = label.trim() || "\u9605\u8BFB\u8FDB\u5EA6";
|
|
5154
|
-
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: `hf-reading-progress ${className}`.trim(), children: [
|
|
5155
|
-
showValue && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "hf-reading-progress__caption", "aria-hidden": "true", children: [
|
|
5156
|
-
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { children: name }),
|
|
5157
|
-
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("span", { children: [
|
|
5158
|
-
value,
|
|
5159
|
-
"%"
|
|
5160
|
-
] })
|
|
5161
|
-
] }),
|
|
5162
|
-
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)(
|
|
5163
|
-
"div",
|
|
5164
|
-
{
|
|
5165
|
-
className: "hf-reading-progress__track",
|
|
5166
|
-
role: "progressbar",
|
|
5167
|
-
"aria-label": name,
|
|
5168
|
-
"aria-valuemin": 0,
|
|
5169
|
-
"aria-valuemax": 100,
|
|
5170
|
-
"aria-valuenow": value,
|
|
5171
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "hf-reading-progress__fill", style: { width: `${value}%` } })
|
|
5172
|
-
}
|
|
5173
|
-
)
|
|
5174
|
-
] });
|
|
5175
|
-
}
|
|
5176
|
-
|
|
5177
5542
|
// src/data-display/LoadMore.tsx
|
|
5178
|
-
var
|
|
5179
|
-
var
|
|
5543
|
+
var import_react76 = require("react");
|
|
5544
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
5180
5545
|
function LoadMore(props) {
|
|
5181
|
-
return /* @__PURE__ */ (0,
|
|
5546
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsx)(LoadMoreControl, { ...props }, props.resetKey);
|
|
5182
5547
|
}
|
|
5183
5548
|
function LoadMoreControl({
|
|
5184
5549
|
onLoad,
|
|
@@ -5189,12 +5554,12 @@ function LoadMoreControl({
|
|
|
5189
5554
|
className = "",
|
|
5190
5555
|
trigger = 0
|
|
5191
5556
|
}) {
|
|
5192
|
-
const [phase, setPhase] = (0,
|
|
5193
|
-
const request = (0,
|
|
5194
|
-
const alive = (0,
|
|
5195
|
-
const latest = (0,
|
|
5557
|
+
const [phase, setPhase] = (0, import_react76.useState)("idle");
|
|
5558
|
+
const request = (0, import_react76.useRef)(null);
|
|
5559
|
+
const alive = (0, import_react76.useRef)(true);
|
|
5560
|
+
const latest = (0, import_react76.useRef)({ onLoad, hasMore, disabled });
|
|
5196
5561
|
latest.current = { onLoad, hasMore, disabled };
|
|
5197
|
-
(0,
|
|
5562
|
+
(0, import_react76.useEffect)(() => {
|
|
5198
5563
|
alive.current = true;
|
|
5199
5564
|
return () => {
|
|
5200
5565
|
alive.current = false;
|
|
@@ -5215,32 +5580,32 @@ function LoadMoreControl({
|
|
|
5215
5580
|
if (request.current === controller) request.current = null;
|
|
5216
5581
|
}
|
|
5217
5582
|
}
|
|
5218
|
-
const seen = (0,
|
|
5219
|
-
(0,
|
|
5583
|
+
const seen = (0, import_react76.useRef)(0);
|
|
5584
|
+
(0, import_react76.useEffect)(() => {
|
|
5220
5585
|
if (trigger === seen.current) return;
|
|
5221
5586
|
seen.current = trigger;
|
|
5222
5587
|
if (phase !== "error") void load();
|
|
5223
5588
|
}, [trigger]);
|
|
5224
5589
|
const blocked = disabled || !hasMore || phase === "pending";
|
|
5225
|
-
return /* @__PURE__ */ (0,
|
|
5226
|
-
/* @__PURE__ */ (0,
|
|
5227
|
-
phase === "error" && hasMore && /* @__PURE__ */ (0,
|
|
5228
|
-
/* @__PURE__ */ (0,
|
|
5590
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: `hf-content-loading ${className}`.trim(), "aria-busy": phase === "pending", children: [
|
|
5591
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { role: "status", "aria-atomic": "true", children: phase === "pending" ? "\u6B63\u5728\u52A0\u8F7D\u2026" : !hasMore ? "\u6CA1\u6709\u66F4\u591A\u5185\u5BB9\u4E86" : phase === "success" ? "\u5185\u5BB9\u5DF2\u52A0\u8F7D" : "" }),
|
|
5592
|
+
phase === "error" && hasMore && /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { role: "alert", className: "hf-tone--danger", children: errorMessage.trim() || "\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002" }),
|
|
5593
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)(Button, { type: "button", variant: "outline", "aria-disabled": blocked, onClick: () => {
|
|
5229
5594
|
if (!blocked) void load();
|
|
5230
5595
|
}, children: phase === "pending" ? "\u6B63\u5728\u52A0\u8F7D" : phase === "error" && hasMore ? "\u91CD\u8BD5\u52A0\u8F7D" : !hasMore ? "\u5DF2\u5168\u90E8\u52A0\u8F7D" : label.trim() || "\u52A0\u8F7D\u66F4\u591A" })
|
|
5231
5596
|
] });
|
|
5232
5597
|
}
|
|
5233
5598
|
|
|
5234
5599
|
// src/data-display/InfiniteScroll.tsx
|
|
5235
|
-
var
|
|
5236
|
-
var
|
|
5600
|
+
var import_react77 = require("react");
|
|
5601
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
5237
5602
|
function InfiniteScroll(props) {
|
|
5238
|
-
return /* @__PURE__ */ (0,
|
|
5603
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsx)(InfiniteScrollSession, { ...props }, props.resetKey);
|
|
5239
5604
|
}
|
|
5240
5605
|
function InfiniteScrollSession({ children, root, rootMargin = "0px", ...props }) {
|
|
5241
|
-
const sentinel = (0,
|
|
5242
|
-
const [trigger, setTrigger] = (0,
|
|
5243
|
-
(0,
|
|
5606
|
+
const sentinel = (0, import_react77.useRef)(null);
|
|
5607
|
+
const [trigger, setTrigger] = (0, import_react77.useState)(0);
|
|
5608
|
+
(0, import_react77.useEffect)(() => {
|
|
5244
5609
|
if (!sentinel.current || root === null || props.disabled || !props.hasMore || typeof IntersectionObserver === "undefined") return;
|
|
5245
5610
|
let inside = false;
|
|
5246
5611
|
let observer;
|
|
@@ -5256,16 +5621,16 @@ function InfiniteScrollSession({ children, root, rootMargin = "0px", ...props })
|
|
|
5256
5621
|
observer.observe(sentinel.current);
|
|
5257
5622
|
return () => observer.disconnect();
|
|
5258
5623
|
}, [root, rootMargin, props.disabled, props.hasMore]);
|
|
5259
|
-
return /* @__PURE__ */ (0,
|
|
5624
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "hf-infinite-scroll", children: [
|
|
5260
5625
|
children,
|
|
5261
|
-
/* @__PURE__ */ (0,
|
|
5262
|
-
/* @__PURE__ */ (0,
|
|
5626
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("div", { ref: sentinel, className: "hf-infinite-scroll__sentinel", "aria-hidden": "true" }),
|
|
5627
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(LoadMoreControl, { ...props, trigger })
|
|
5263
5628
|
] });
|
|
5264
5629
|
}
|
|
5265
5630
|
|
|
5266
5631
|
// src/data-display/LazyLoad.tsx
|
|
5267
|
-
var
|
|
5268
|
-
var
|
|
5632
|
+
var import_react78 = require("react");
|
|
5633
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
5269
5634
|
function LazyLoad({
|
|
5270
5635
|
children,
|
|
5271
5636
|
placeholder,
|
|
@@ -5276,16 +5641,16 @@ function LazyLoad({
|
|
|
5276
5641
|
label = "\u663E\u793A\u5185\u5BB9",
|
|
5277
5642
|
className = ""
|
|
5278
5643
|
}) {
|
|
5279
|
-
const target = (0,
|
|
5280
|
-
const [mounted, setMounted] = (0,
|
|
5281
|
-
const restoreFocus = (0,
|
|
5282
|
-
(0,
|
|
5644
|
+
const target = (0, import_react78.useRef)(null);
|
|
5645
|
+
const [mounted, setMounted] = (0, import_react78.useState)(false);
|
|
5646
|
+
const restoreFocus = (0, import_react78.useRef)(false);
|
|
5647
|
+
(0, import_react78.useEffect)(() => {
|
|
5283
5648
|
if (mounted && restoreFocus.current) {
|
|
5284
5649
|
target.current?.focus({ preventScroll: true });
|
|
5285
5650
|
restoreFocus.current = false;
|
|
5286
5651
|
}
|
|
5287
5652
|
}, [mounted]);
|
|
5288
|
-
(0,
|
|
5653
|
+
(0, import_react78.useEffect)(() => {
|
|
5289
5654
|
if (mounted) return;
|
|
5290
5655
|
if (disabled) {
|
|
5291
5656
|
setMounted(true);
|
|
@@ -5311,16 +5676,16 @@ function LazyLoad({
|
|
|
5311
5676
|
observer.observe(target.current);
|
|
5312
5677
|
return () => observer.disconnect();
|
|
5313
5678
|
}, [mounted, disabled, root, rootMargin]);
|
|
5314
|
-
return /* @__PURE__ */ (0,
|
|
5679
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsx)(
|
|
5315
5680
|
"div",
|
|
5316
5681
|
{
|
|
5317
5682
|
ref: target,
|
|
5318
5683
|
tabIndex: -1,
|
|
5319
5684
|
className: `hf-lazy-load ${className}`.trim(),
|
|
5320
5685
|
style: { minHeight: Number.isFinite(minHeight) ? Math.max(0, minHeight) : 160 },
|
|
5321
|
-
children: mounted || disabled ? children : /* @__PURE__ */ (0,
|
|
5686
|
+
children: mounted || disabled ? children : /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)(import_jsx_runtime96.Fragment, { children: [
|
|
5322
5687
|
placeholder,
|
|
5323
|
-
/* @__PURE__ */ (0,
|
|
5688
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(Button, { type: "button", variant: "outline", onClick: () => {
|
|
5324
5689
|
restoreFocus.current = true;
|
|
5325
5690
|
setMounted(true);
|
|
5326
5691
|
}, children: label.trim() || "\u663E\u793A\u5185\u5BB9" })
|
|
@@ -5330,24 +5695,24 @@ function LazyLoad({
|
|
|
5330
5695
|
}
|
|
5331
5696
|
|
|
5332
5697
|
// src/feedback/OptimisticUpdate.tsx
|
|
5333
|
-
var
|
|
5698
|
+
var import_react80 = require("react");
|
|
5334
5699
|
|
|
5335
5700
|
// src/feedback/useOptimisticRequest.ts
|
|
5336
|
-
var
|
|
5701
|
+
var import_react79 = require("react");
|
|
5337
5702
|
function useOptimisticRequest(initialValue, onUpdate, disabled) {
|
|
5338
|
-
const [view, setView] = (0,
|
|
5703
|
+
const [view, setView] = (0, import_react79.useState)(
|
|
5339
5704
|
{ value: initialValue, phase: "idle" }
|
|
5340
5705
|
);
|
|
5341
|
-
const currentView = (0,
|
|
5342
|
-
const confirmed = (0,
|
|
5343
|
-
const desired = (0,
|
|
5344
|
-
const failed = (0,
|
|
5345
|
-
const active = (0,
|
|
5346
|
-
const sequence = (0,
|
|
5347
|
-
const alive = (0,
|
|
5348
|
-
const latest = (0,
|
|
5706
|
+
const currentView = (0, import_react79.useRef)(view);
|
|
5707
|
+
const confirmed = (0, import_react79.useRef)(initialValue);
|
|
5708
|
+
const desired = (0, import_react79.useRef)(null);
|
|
5709
|
+
const failed = (0, import_react79.useRef)(null);
|
|
5710
|
+
const active = (0, import_react79.useRef)(null);
|
|
5711
|
+
const sequence = (0, import_react79.useRef)(0);
|
|
5712
|
+
const alive = (0, import_react79.useRef)(true);
|
|
5713
|
+
const latest = (0, import_react79.useRef)({ onUpdate, disabled });
|
|
5349
5714
|
latest.current = { onUpdate, disabled };
|
|
5350
|
-
(0,
|
|
5715
|
+
(0, import_react79.useEffect)(() => {
|
|
5351
5716
|
alive.current = true;
|
|
5352
5717
|
return () => {
|
|
5353
5718
|
alive.current = false;
|
|
@@ -5397,9 +5762,9 @@ function useOptimisticRequest(initialValue, onUpdate, disabled) {
|
|
|
5397
5762
|
}
|
|
5398
5763
|
|
|
5399
5764
|
// src/feedback/OptimisticUpdate.tsx
|
|
5400
|
-
var
|
|
5765
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
5401
5766
|
function OptimisticUpdate(props) {
|
|
5402
|
-
return /* @__PURE__ */ (0,
|
|
5767
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(OptimisticSession, { ...props }, props.operationKey);
|
|
5403
5768
|
}
|
|
5404
5769
|
function OptimisticSession({
|
|
5405
5770
|
initialValue,
|
|
@@ -5411,12 +5776,149 @@ function OptimisticSession({
|
|
|
5411
5776
|
className = ""
|
|
5412
5777
|
}) {
|
|
5413
5778
|
const state = useOptimisticRequest(initialValue, onUpdate, disabled);
|
|
5414
|
-
const statusId = (0,
|
|
5779
|
+
const statusId = (0, import_react80.useId)();
|
|
5415
5780
|
const name = label.trim() || "\u66F4\u65B0";
|
|
5416
|
-
return /* @__PURE__ */ (0,
|
|
5781
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: `hf-optimistic-update ${className}`.trim(), role: "group", "aria-label": name, "aria-describedby": statusId, children: [
|
|
5417
5782
|
children(state),
|
|
5418
|
-
/* @__PURE__ */ (0,
|
|
5419
|
-
state.phase === "error" && /* @__PURE__ */ (0,
|
|
5783
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { id: statusId, role: "status", "aria-atomic": "true", className: "hf-optimistic-update__status", children: state.phase === "pending" ? `${name}\uFF1A\u6B63\u5728\u4FDD\u5B58\u2026` : state.phase === "success" ? `${name}\uFF1A\u5DF2\u4FDD\u5B58` : "" }),
|
|
5784
|
+
state.phase === "error" && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("p", { role: "alert", className: "hf-optimistic-update__error hf-tone--danger", children: errorMessage.trim() || "\u4FDD\u5B58\u5931\u8D25\uFF0C\u5DF2\u6062\u590D\u6700\u8FD1\u786E\u8BA4\u7684\u72B6\u6001\uFF0C\u8BF7\u91CD\u8BD5\u3002" })
|
|
5785
|
+
] });
|
|
5786
|
+
}
|
|
5787
|
+
|
|
5788
|
+
// src/feedback/TaskProgress.tsx
|
|
5789
|
+
var import_react82 = require("react");
|
|
5790
|
+
|
|
5791
|
+
// src/feedback/useTaskProgress.ts
|
|
5792
|
+
var import_react81 = require("react");
|
|
5793
|
+
var clamp = (value) => Math.min(100, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
5794
|
+
function useTaskProgress(run, stageIds, disabled) {
|
|
5795
|
+
const [snapshot, setSnapshot] = (0, import_react81.useState)({
|
|
5796
|
+
phase: "idle",
|
|
5797
|
+
progress: 0
|
|
5798
|
+
});
|
|
5799
|
+
const runRef = (0, import_react81.useRef)(run);
|
|
5800
|
+
const controllerRef = (0, import_react81.useRef)(void 0);
|
|
5801
|
+
const generationRef = (0, import_react81.useRef)(0);
|
|
5802
|
+
runRef.current = run;
|
|
5803
|
+
const start = (0, import_react81.useCallback)(() => {
|
|
5804
|
+
if (disabled || controllerRef.current) return;
|
|
5805
|
+
const generation = ++generationRef.current;
|
|
5806
|
+
const controller = new AbortController();
|
|
5807
|
+
controllerRef.current = controller;
|
|
5808
|
+
setSnapshot({ phase: "running", activeStageId: stageIds[0], progress: 0 });
|
|
5809
|
+
const report = (update) => {
|
|
5810
|
+
if (generation !== generationRef.current || controller.signal.aborted || !stageIds.includes(update.stageId)) return;
|
|
5811
|
+
setSnapshot((current) => current.phase !== "running" ? current : {
|
|
5812
|
+
...current,
|
|
5813
|
+
activeStageId: update.stageId,
|
|
5814
|
+
progress: update.progress === void 0 ? current.progress : clamp(update.progress),
|
|
5815
|
+
message: update.message
|
|
5816
|
+
});
|
|
5817
|
+
};
|
|
5818
|
+
Promise.resolve().then(() => {
|
|
5819
|
+
if (generation !== generationRef.current || controller.signal.aborted) throw new Error("cancelled");
|
|
5820
|
+
return runRef.current({ signal: controller.signal, report });
|
|
5821
|
+
}).then(
|
|
5822
|
+
(result) => {
|
|
5823
|
+
if (generation !== generationRef.current || controller.signal.aborted) return;
|
|
5824
|
+
controllerRef.current = void 0;
|
|
5825
|
+
setSnapshot({ phase: "success", activeStageId: stageIds.at(-1), progress: 100, result });
|
|
5826
|
+
},
|
|
5827
|
+
() => {
|
|
5828
|
+
if (generation !== generationRef.current || controller.signal.aborted) return;
|
|
5829
|
+
controllerRef.current = void 0;
|
|
5830
|
+
setSnapshot((current) => ({ ...current, phase: "error" }));
|
|
5831
|
+
}
|
|
5832
|
+
);
|
|
5833
|
+
}, [disabled, stageIds]);
|
|
5834
|
+
const cancel = (0, import_react81.useCallback)(() => {
|
|
5835
|
+
if (!controllerRef.current) return;
|
|
5836
|
+
generationRef.current += 1;
|
|
5837
|
+
controllerRef.current.abort();
|
|
5838
|
+
controllerRef.current = void 0;
|
|
5839
|
+
setSnapshot((current) => ({ ...current, phase: "cancelled" }));
|
|
5840
|
+
}, []);
|
|
5841
|
+
const retry = (0, import_react81.useCallback)(() => {
|
|
5842
|
+
if (snapshot.phase !== "error" && snapshot.phase !== "cancelled") return;
|
|
5843
|
+
start();
|
|
5844
|
+
}, [snapshot.phase, start]);
|
|
5845
|
+
(0, import_react81.useEffect)(() => () => {
|
|
5846
|
+
generationRef.current += 1;
|
|
5847
|
+
controllerRef.current?.abort();
|
|
5848
|
+
controllerRef.current = void 0;
|
|
5849
|
+
}, []);
|
|
5850
|
+
return { ...snapshot, start, cancel, retry };
|
|
5851
|
+
}
|
|
5852
|
+
|
|
5853
|
+
// src/feedback/TaskProgress.tsx
|
|
5854
|
+
var import_jsx_runtime98 = require("react/jsx-runtime");
|
|
5855
|
+
function TaskProgress(props) {
|
|
5856
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(TaskProgressSession, { ...props }, `${typeof props.taskKey}:${String(props.taskKey)}`);
|
|
5857
|
+
}
|
|
5858
|
+
function TaskProgressSession({
|
|
5859
|
+
stages,
|
|
5860
|
+
run,
|
|
5861
|
+
title = "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
5862
|
+
autoStart = false,
|
|
5863
|
+
disabled = false,
|
|
5864
|
+
renderResult,
|
|
5865
|
+
onPhaseChange,
|
|
5866
|
+
className = ""
|
|
5867
|
+
}) {
|
|
5868
|
+
const stageSignature = JSON.stringify(stages.map((stage) => stage.id));
|
|
5869
|
+
const stageIds = (0, import_react82.useMemo)(() => stages.map((stage) => stage.id), [stageSignature]);
|
|
5870
|
+
const state = useTaskProgress(run, stageIds, disabled || stages.length === 0);
|
|
5871
|
+
const statusId = (0, import_react82.useId)();
|
|
5872
|
+
const activeIndex = state.activeStageId ? stageIds.indexOf(state.activeStageId) : -1;
|
|
5873
|
+
(0, import_react82.useEffect)(() => {
|
|
5874
|
+
if (!autoStart || disabled || stages.length === 0) return;
|
|
5875
|
+
const timer = window.setTimeout(state.start, 0);
|
|
5876
|
+
return () => window.clearTimeout(timer);
|
|
5877
|
+
}, [autoStart, disabled, stages.length, state.start]);
|
|
5878
|
+
(0, import_react82.useEffect)(() => {
|
|
5879
|
+
onPhaseChange?.(state.phase);
|
|
5880
|
+
}, [onPhaseChange, state.phase]);
|
|
5881
|
+
const statusText = state.phase === "running" ? state.message || `\u6B63\u5728\u6267\u884C\uFF0C\u5DF2\u5B8C\u6210 ${Math.round(state.progress)}%` : state.phase === "success" ? "\u4EFB\u52A1\u5DF2\u5B8C\u6210" : state.phase === "error" ? "\u4EFB\u52A1\u6267\u884C\u5931\u8D25\uFF0C\u53EF\u4EE5\u91CD\u8BD5" : state.phase === "cancelled" ? "\u4EFB\u52A1\u5DF2\u53D6\u6D88\uFF0C\u53EF\u4EE5\u91CD\u65B0\u6267\u884C" : "\u4EFB\u52A1\u5C1A\u672A\u5F00\u59CB";
|
|
5882
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("section", { className: `hf-task-progress ${className}`.trim(), "aria-labelledby": `${statusId}-title`, "aria-busy": state.phase === "running", children: [
|
|
5883
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("header", { className: "hf-task-progress__header", children: [
|
|
5884
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { children: [
|
|
5885
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("h3", { id: `${statusId}-title`, children: title }),
|
|
5886
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { id: statusId, role: "status", "aria-live": "polite", "aria-atomic": "true", children: statusText })
|
|
5887
|
+
] }),
|
|
5888
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("strong", { "aria-hidden": "true", children: [
|
|
5889
|
+
Math.round(state.progress),
|
|
5890
|
+
"%"
|
|
5891
|
+
] })
|
|
5892
|
+
] }),
|
|
5893
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)(
|
|
5894
|
+
"div",
|
|
5895
|
+
{
|
|
5896
|
+
className: "hf-task-progress__track",
|
|
5897
|
+
role: "progressbar",
|
|
5898
|
+
"aria-valuemin": 0,
|
|
5899
|
+
"aria-valuemax": 100,
|
|
5900
|
+
"aria-valuenow": Math.round(state.progress),
|
|
5901
|
+
"aria-describedby": statusId,
|
|
5902
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { style: { width: `${state.progress}%` } })
|
|
5903
|
+
}
|
|
5904
|
+
),
|
|
5905
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("ol", { className: "hf-task-progress__stages", children: stages.map((stage, index) => {
|
|
5906
|
+
const status = state.phase === "success" || index < activeIndex ? "complete" : index === activeIndex ? state.phase === "error" ? "error" : state.phase === "cancelled" ? "cancelled" : "active" : "pending";
|
|
5907
|
+
return /* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("li", { "data-status": status, "aria-current": status === "active" ? "step" : void 0, children: [
|
|
5908
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("span", { className: "hf-task-progress__marker", "aria-hidden": "true", children: status === "complete" ? "\u2713" : index + 1 }),
|
|
5909
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { children: [
|
|
5910
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsx)("strong", { children: stage.label }),
|
|
5911
|
+
stage.description && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { children: stage.description })
|
|
5912
|
+
] })
|
|
5913
|
+
] }, stage.id);
|
|
5914
|
+
}) }),
|
|
5915
|
+
state.phase === "error" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("p", { className: "hf-task-progress__error", role: "alert", children: "\u4EFB\u52A1\u672A\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002" }),
|
|
5916
|
+
state.phase === "success" && renderResult && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)("div", { className: "hf-task-progress__result", children: renderResult(state.result) }),
|
|
5917
|
+
/* @__PURE__ */ (0, import_jsx_runtime98.jsxs)("div", { className: "hf-task-progress__actions", children: [
|
|
5918
|
+
state.phase === "idle" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Button, { type: "button", disabled: disabled || stages.length === 0, onClick: state.start, children: "\u5F00\u59CB\u4EFB\u52A1" }),
|
|
5919
|
+
state.phase === "running" && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Button, { type: "button", variant: "outline", onClick: state.cancel, children: "\u53D6\u6D88\u4EFB\u52A1" }),
|
|
5920
|
+
(state.phase === "error" || state.phase === "cancelled") && /* @__PURE__ */ (0, import_jsx_runtime98.jsx)(Button, { type: "button", disabled, onClick: state.retry, children: "\u91CD\u65B0\u6267\u884C" })
|
|
5921
|
+
] })
|
|
5420
5922
|
] });
|
|
5421
5923
|
}
|
|
5422
5924
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -5433,7 +5935,9 @@ function OptimisticSession({
|
|
|
5433
5935
|
AvailabilityGrid,
|
|
5434
5936
|
Avatar,
|
|
5435
5937
|
AvatarGroup,
|
|
5938
|
+
BackToTop,
|
|
5436
5939
|
Badge,
|
|
5940
|
+
BottomNavigation,
|
|
5437
5941
|
Breadcrumb,
|
|
5438
5942
|
Button,
|
|
5439
5943
|
ButtonGroup,
|
|
@@ -5482,6 +5986,7 @@ function OptimisticSession({
|
|
|
5482
5986
|
GanttChart,
|
|
5483
5987
|
Grid,
|
|
5484
5988
|
Hero,
|
|
5989
|
+
HierarchicalSidebar,
|
|
5485
5990
|
HoldToConfirm,
|
|
5486
5991
|
HotspotGuide,
|
|
5487
5992
|
Icon,
|
|
@@ -5498,11 +6003,13 @@ function OptimisticSession({
|
|
|
5498
6003
|
LoadMore,
|
|
5499
6004
|
LoadingDots,
|
|
5500
6005
|
LoadingOverlay,
|
|
6006
|
+
LongPageNavigation,
|
|
5501
6007
|
MarkdownContent,
|
|
5502
6008
|
Masonry,
|
|
5503
6009
|
MegaMenu,
|
|
5504
6010
|
MemberPicker,
|
|
5505
6011
|
MentionInput,
|
|
6012
|
+
MobileContentNavigation,
|
|
5506
6013
|
MobileNavigation,
|
|
5507
6014
|
Modal,
|
|
5508
6015
|
ModelSelector,
|
|
@@ -5524,6 +6031,7 @@ function OptimisticSession({
|
|
|
5524
6031
|
ProgressBar,
|
|
5525
6032
|
ProgressRing,
|
|
5526
6033
|
PromptSuggestions,
|
|
6034
|
+
PullToRefresh,
|
|
5527
6035
|
QueryBuilder,
|
|
5528
6036
|
Radio,
|
|
5529
6037
|
RadioGroup,
|
|
@@ -5559,6 +6067,7 @@ function OptimisticSession({
|
|
|
5559
6067
|
Table,
|
|
5560
6068
|
Tabs,
|
|
5561
6069
|
Tag,
|
|
6070
|
+
TaskProgress,
|
|
5562
6071
|
Textarea,
|
|
5563
6072
|
ThemeProvider,
|
|
5564
6073
|
TimePicker,
|