@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.js
CHANGED
|
@@ -2442,30 +2442,307 @@ function MobileNavigation({ brand, items, mode = "drawer", activeKey, open, onOp
|
|
|
2442
2442
|
// src/navigation/Scrollspy.tsx
|
|
2443
2443
|
import { useEffect as useEffect9, useState as useState22 } from "react";
|
|
2444
2444
|
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2445
|
-
function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%", className = "", ...props }) {
|
|
2445
|
+
function Scrollspy({ items, activeKey, onItemSelect, rootMargin = "-20% 0px -65%", target, className = "", ...props }) {
|
|
2446
2446
|
const [observedKey, setObservedKey] = useState22(items[0]?.key);
|
|
2447
2447
|
const currentKey = activeKey ?? observedKey;
|
|
2448
2448
|
useEffect9(() => {
|
|
2449
|
-
|
|
2450
|
-
const
|
|
2449
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2450
|
+
const Observer = view.IntersectionObserver;
|
|
2451
|
+
if (activeKey !== void 0 || target === null || !Observer) return;
|
|
2452
|
+
const observer = new Observer((entries) => {
|
|
2451
2453
|
const visible = entries.find((entry) => entry.isIntersecting);
|
|
2452
2454
|
if (visible?.target.id) setObservedKey(visible.target.id);
|
|
2453
|
-
}, { rootMargin });
|
|
2455
|
+
}, { root: target ?? null, rootMargin });
|
|
2454
2456
|
items.forEach((item) => {
|
|
2455
|
-
const section = document.getElementById(item.key);
|
|
2456
|
-
if (section) observer.observe(section);
|
|
2457
|
+
const section = target ? [...target.querySelectorAll("[id]")].find((element) => element.id === item.key) : view.document.getElementById(item.key);
|
|
2458
|
+
if (section && (!target || target.contains(section))) observer.observe(section);
|
|
2457
2459
|
});
|
|
2458
2460
|
return () => observer.disconnect();
|
|
2459
|
-
}, [activeKey, items, rootMargin]);
|
|
2461
|
+
}, [activeKey, items, rootMargin, target]);
|
|
2460
2462
|
return /* @__PURE__ */ jsx40("nav", { className: `hf-scrollspy ${className}`.trim(), "aria-label": "\u9875\u5185\u5BFC\u822A", ...props, children: items.map((item) => /* @__PURE__ */ jsx40("a", { href: item.href ?? `#${item.key}`, "aria-current": currentKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) });
|
|
2461
2463
|
}
|
|
2462
2464
|
|
|
2463
|
-
// src/navigation/
|
|
2465
|
+
// src/navigation/BackToTop.tsx
|
|
2464
2466
|
import { useEffect as useEffect10, useState as useState23 } from "react";
|
|
2465
2467
|
import { jsx as jsx41, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2466
|
-
function
|
|
2467
|
-
const [
|
|
2468
|
+
function BackToTop({ target, threshold = 320, behavior = "smooth", label = "\u8FD4\u56DE\u9876\u90E8", onActivate, className = "", ...props }) {
|
|
2469
|
+
const [visible, setVisible] = useState23(false);
|
|
2468
2470
|
useEffect10(() => {
|
|
2471
|
+
if (target === null) {
|
|
2472
|
+
setVisible(false);
|
|
2473
|
+
return;
|
|
2474
|
+
}
|
|
2475
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2476
|
+
const source = target ?? view;
|
|
2477
|
+
const measure = () => setVisible((target?.scrollTop ?? view.scrollY) >= threshold);
|
|
2478
|
+
measure();
|
|
2479
|
+
source.addEventListener("scroll", measure, { passive: true });
|
|
2480
|
+
return () => source.removeEventListener("scroll", measure);
|
|
2481
|
+
}, [target, threshold]);
|
|
2482
|
+
const handleActivate = () => {
|
|
2483
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2484
|
+
const reduceMotion = view.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
2485
|
+
const resolvedBehavior = reduceMotion ? "auto" : behavior;
|
|
2486
|
+
if (target) target.scrollTo({ top: 0, behavior: resolvedBehavior });
|
|
2487
|
+
else view.scrollTo({ top: 0, behavior: resolvedBehavior });
|
|
2488
|
+
onActivate?.();
|
|
2489
|
+
};
|
|
2490
|
+
if (!visible) return null;
|
|
2491
|
+
return /* @__PURE__ */ jsxs36("button", { ...props, type: "button", className: `hf-back-to-top hf-back-to-top--visible ${className}`.trim(), onClick: handleActivate, children: [
|
|
2492
|
+
/* @__PURE__ */ jsx41("span", { "aria-hidden": "true", children: "\u2191" }),
|
|
2493
|
+
/* @__PURE__ */ jsx41("span", { children: label })
|
|
2494
|
+
] });
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
// src/navigation/HierarchicalSidebar.tsx
|
|
2498
|
+
import { useEffect as useEffect11, useMemo as useMemo5, useState as useState24 } from "react";
|
|
2499
|
+
|
|
2500
|
+
// src/navigation/navigationTree.ts
|
|
2501
|
+
function flattenNavigationItems(items) {
|
|
2502
|
+
return items.flatMap((item) => [item, ...flattenNavigationItems(item.children ?? [])]);
|
|
2503
|
+
}
|
|
2504
|
+
function getNavigationAncestorKeys(items, activeKey) {
|
|
2505
|
+
if (!activeKey) return [];
|
|
2506
|
+
for (const item of items) {
|
|
2507
|
+
if (item.key === activeKey) return [];
|
|
2508
|
+
const childPath = getNavigationAncestorKeys(item.children ?? [], activeKey);
|
|
2509
|
+
if (childPath.length || item.children?.some((child) => child.key === activeKey)) return [item.key, ...childPath];
|
|
2510
|
+
}
|
|
2511
|
+
return [];
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2514
|
+
// src/navigation/HierarchicalSidebar.tsx
|
|
2515
|
+
import { jsx as jsx42, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2516
|
+
function HierarchicalSidebar({ items, title = "\u5185\u5BB9\u5BFC\u822A", activeKey, onItemSelect, expandedKeys, defaultExpandedKeys = [], onExpandedChange, className = "", ...props }) {
|
|
2517
|
+
const [internalExpanded, setInternalExpanded] = useState24(() => /* @__PURE__ */ new Set([...defaultExpandedKeys, ...getNavigationAncestorKeys(items, activeKey)]));
|
|
2518
|
+
const activeAncestorKeys = useMemo5(() => getNavigationAncestorKeys(items, activeKey), [activeKey, items]);
|
|
2519
|
+
const activeAncestorSignature = activeAncestorKeys.join("\0");
|
|
2520
|
+
const expanded = new Set(expandedKeys ?? internalExpanded);
|
|
2521
|
+
useEffect11(() => {
|
|
2522
|
+
if (expandedKeys !== void 0) return;
|
|
2523
|
+
setInternalExpanded((current) => {
|
|
2524
|
+
const next = new Set(current);
|
|
2525
|
+
activeAncestorKeys.forEach((key) => next.add(key));
|
|
2526
|
+
return next;
|
|
2527
|
+
});
|
|
2528
|
+
}, [activeAncestorSignature, expandedKeys]);
|
|
2529
|
+
const toggle = (key) => {
|
|
2530
|
+
const next = new Set(expandedKeys ?? internalExpanded);
|
|
2531
|
+
if (next.has(key)) next.delete(key);
|
|
2532
|
+
else next.add(key);
|
|
2533
|
+
if (expandedKeys === void 0) setInternalExpanded(next);
|
|
2534
|
+
onExpandedChange?.([...next]);
|
|
2535
|
+
};
|
|
2536
|
+
const renderItems = (nodes, level = 0) => /* @__PURE__ */ jsx42("ul", { className: "hf-hierarchical-sidebar__list", "data-level": level, children: nodes.map((item) => {
|
|
2537
|
+
const hasChildren = Boolean(item.children?.length);
|
|
2538
|
+
const isExpanded = expanded.has(item.key);
|
|
2539
|
+
return /* @__PURE__ */ jsxs37("li", { children: [
|
|
2540
|
+
hasChildren ? /* @__PURE__ */ jsxs37("button", { type: "button", className: "hf-hierarchical-sidebar__group", "aria-expanded": isExpanded, onClick: () => toggle(item.key), children: [
|
|
2541
|
+
/* @__PURE__ */ jsx42("span", { children: item.icon }),
|
|
2542
|
+
/* @__PURE__ */ jsx42("span", { children: item.label }),
|
|
2543
|
+
/* @__PURE__ */ jsx42("span", { "aria-hidden": "true", className: "hf-hierarchical-sidebar__chevron", children: "\u203A" })
|
|
2544
|
+
] }) : /* @__PURE__ */ jsxs37("a", { href: item.href ?? `#${item.key}`, "aria-current": activeKey === item.key ? "location" : void 0, onClick: () => onItemSelect?.(item), children: [
|
|
2545
|
+
item.icon && /* @__PURE__ */ jsx42("span", { "aria-hidden": "true", children: item.icon }),
|
|
2546
|
+
/* @__PURE__ */ jsx42("span", { children: item.label })
|
|
2547
|
+
] }),
|
|
2548
|
+
hasChildren && isExpanded && renderItems(item.children ?? [], level + 1)
|
|
2549
|
+
] }, item.key);
|
|
2550
|
+
}) });
|
|
2551
|
+
return /* @__PURE__ */ jsxs37("aside", { className: `hf-hierarchical-sidebar ${className}`.trim(), ...props, children: [
|
|
2552
|
+
/* @__PURE__ */ jsx42("div", { className: "hf-hierarchical-sidebar__title", children: title }),
|
|
2553
|
+
/* @__PURE__ */ jsx42("nav", { "aria-label": "\u5C42\u7EA7\u4FA7\u680F", children: renderItems(items) })
|
|
2554
|
+
] });
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
// src/navigation/useReadingPosition.ts
|
|
2558
|
+
import { useEffect as useEffect12, useState as useState25 } from "react";
|
|
2559
|
+
function useReadingPosition(target) {
|
|
2560
|
+
const [snapshot, setSnapshot] = useState25({ target, value: 0 });
|
|
2561
|
+
useEffect12(() => {
|
|
2562
|
+
if (target === null) return;
|
|
2563
|
+
const view = target?.ownerDocument.defaultView ?? window;
|
|
2564
|
+
const root = target ?? view.document.documentElement;
|
|
2565
|
+
const events = target ?? view;
|
|
2566
|
+
let frame = 0;
|
|
2567
|
+
let disposed = false;
|
|
2568
|
+
const measure = () => {
|
|
2569
|
+
frame = 0;
|
|
2570
|
+
if (disposed) return;
|
|
2571
|
+
const viewport = target ? root.clientHeight : view.innerHeight;
|
|
2572
|
+
const height = target ? root.scrollHeight : Math.max(root.scrollHeight, view.document.body?.scrollHeight ?? 0);
|
|
2573
|
+
const offset = target ? root.scrollTop : view.scrollY;
|
|
2574
|
+
const range = Math.max(0, height - viewport);
|
|
2575
|
+
const value = range === 0 ? 100 : Math.round(Math.min(1, Math.max(0, offset / range)) * 100);
|
|
2576
|
+
setSnapshot((previous) => previous.target === target && previous.value === value ? previous : { target, value });
|
|
2577
|
+
};
|
|
2578
|
+
const schedule = () => {
|
|
2579
|
+
if (!disposed && !frame) frame = view.requestAnimationFrame(measure);
|
|
2580
|
+
};
|
|
2581
|
+
const resize = new ResizeObserver(schedule);
|
|
2582
|
+
const observeContent = () => {
|
|
2583
|
+
resize.disconnect();
|
|
2584
|
+
resize.observe(root);
|
|
2585
|
+
for (const child of root.children) resize.observe(child);
|
|
2586
|
+
if (!target && view.document.body) {
|
|
2587
|
+
resize.observe(view.document.body);
|
|
2588
|
+
for (const child of view.document.body.children) resize.observe(child);
|
|
2589
|
+
}
|
|
2590
|
+
schedule();
|
|
2591
|
+
};
|
|
2592
|
+
const mutations = new MutationObserver(observeContent);
|
|
2593
|
+
mutations.observe(root, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
2594
|
+
events.addEventListener("scroll", schedule, { passive: true });
|
|
2595
|
+
view.addEventListener("resize", schedule);
|
|
2596
|
+
root.addEventListener("load", schedule, true);
|
|
2597
|
+
observeContent();
|
|
2598
|
+
return () => {
|
|
2599
|
+
disposed = true;
|
|
2600
|
+
view.cancelAnimationFrame(frame);
|
|
2601
|
+
resize.disconnect();
|
|
2602
|
+
mutations.disconnect();
|
|
2603
|
+
events.removeEventListener("scroll", schedule);
|
|
2604
|
+
view.removeEventListener("resize", schedule);
|
|
2605
|
+
root.removeEventListener("load", schedule, true);
|
|
2606
|
+
};
|
|
2607
|
+
}, [target]);
|
|
2608
|
+
return target === null || snapshot.target !== target ? 0 : snapshot.value;
|
|
2609
|
+
}
|
|
2610
|
+
|
|
2611
|
+
// src/navigation/ReadingProgress.tsx
|
|
2612
|
+
import { jsx as jsx43, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2613
|
+
function ReadingProgress({ target, label = "\u9605\u8BFB\u8FDB\u5EA6", showValue = true, className = "" }) {
|
|
2614
|
+
const value = useReadingPosition(target);
|
|
2615
|
+
const name = label.trim() || "\u9605\u8BFB\u8FDB\u5EA6";
|
|
2616
|
+
return /* @__PURE__ */ jsxs38("div", { className: `hf-reading-progress ${className}`.trim(), children: [
|
|
2617
|
+
showValue && /* @__PURE__ */ jsxs38("div", { className: "hf-reading-progress__caption", "aria-hidden": "true", children: [
|
|
2618
|
+
/* @__PURE__ */ jsx43("span", { children: name }),
|
|
2619
|
+
/* @__PURE__ */ jsxs38("span", { children: [
|
|
2620
|
+
value,
|
|
2621
|
+
"%"
|
|
2622
|
+
] })
|
|
2623
|
+
] }),
|
|
2624
|
+
/* @__PURE__ */ jsx43(
|
|
2625
|
+
"div",
|
|
2626
|
+
{
|
|
2627
|
+
className: "hf-reading-progress__track",
|
|
2628
|
+
role: "progressbar",
|
|
2629
|
+
"aria-label": name,
|
|
2630
|
+
"aria-valuemin": 0,
|
|
2631
|
+
"aria-valuemax": 100,
|
|
2632
|
+
"aria-valuenow": value,
|
|
2633
|
+
children: /* @__PURE__ */ jsx43("span", { className: "hf-reading-progress__fill", style: { width: `${value}%` } })
|
|
2634
|
+
}
|
|
2635
|
+
)
|
|
2636
|
+
] });
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
// src/navigation/LongPageNavigation.tsx
|
|
2640
|
+
import { jsx as jsx44, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
2641
|
+
function LongPageNavigation({ items, target, title = "\u672C\u9875\u5185\u5BB9", progressLabel = "\u9605\u8BFB\u8FDB\u5EA6", rootMargin, backToTopThreshold = 320, showProgress = true, activeKey, onItemSelect, className = "", ...props }) {
|
|
2642
|
+
const flattenedItems = flattenNavigationItems(items);
|
|
2643
|
+
return /* @__PURE__ */ jsxs39("aside", { className: `hf-long-page-navigation ${className}`.trim(), ...props, children: [
|
|
2644
|
+
showProgress && /* @__PURE__ */ jsx44(ReadingProgress, { target, label: progressLabel }),
|
|
2645
|
+
/* @__PURE__ */ jsx44("div", { className: "hf-long-page-navigation__title", children: title }),
|
|
2646
|
+
/* @__PURE__ */ jsx44(Scrollspy, { items: flattenedItems, target, rootMargin, activeKey, onItemSelect }),
|
|
2647
|
+
/* @__PURE__ */ jsx44(BackToTop, { target, threshold: backToTopThreshold })
|
|
2648
|
+
] });
|
|
2649
|
+
}
|
|
2650
|
+
|
|
2651
|
+
// src/navigation/BottomNavigation.tsx
|
|
2652
|
+
import { jsx as jsx45, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
2653
|
+
function BottomNavigation({ items, label = "\u5E95\u90E8\u5BFC\u822A", activeKey, onItemSelect, className = "", ...props }) {
|
|
2654
|
+
return /* @__PURE__ */ jsx45("nav", { className: `hf-bottom-navigation ${className}`.trim(), "aria-label": label, ...props, children: items.map((item) => /* @__PURE__ */ jsxs40("a", { href: item.href ?? `#${item.key}`, "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => activateNavigationItem(item, onItemSelect), children: [
|
|
2655
|
+
item.icon && /* @__PURE__ */ jsx45("span", { className: "hf-bottom-navigation__icon", "aria-hidden": "true", children: item.icon }),
|
|
2656
|
+
/* @__PURE__ */ jsx45("span", { children: item.label })
|
|
2657
|
+
] }, item.key)) });
|
|
2658
|
+
}
|
|
2659
|
+
|
|
2660
|
+
// src/navigation/PullToRefresh.tsx
|
|
2661
|
+
import { useRef as useRef11, useState as useState26 } from "react";
|
|
2662
|
+
import { jsx as jsx46, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
2663
|
+
function PullToRefresh({ children, onRefresh, threshold = 72, disabled = false, label = "\u5237\u65B0\u5185\u5BB9", onRefreshError, className = "", onPointerDown, onPointerMove, onPointerUp, onPointerCancel, ...props }) {
|
|
2664
|
+
const rootRef = useRef11(null);
|
|
2665
|
+
const gestureRef = useRef11(null);
|
|
2666
|
+
const [distance, setDistance] = useState26(0);
|
|
2667
|
+
const [refreshing, setRefreshing] = useState26(false);
|
|
2668
|
+
const refreshingRef = useRef11(false);
|
|
2669
|
+
const runRefresh = async () => {
|
|
2670
|
+
if (disabled || refreshingRef.current) return;
|
|
2671
|
+
refreshingRef.current = true;
|
|
2672
|
+
setRefreshing(true);
|
|
2673
|
+
try {
|
|
2674
|
+
await onRefresh();
|
|
2675
|
+
} catch (error) {
|
|
2676
|
+
onRefreshError?.(error);
|
|
2677
|
+
} finally {
|
|
2678
|
+
refreshingRef.current = false;
|
|
2679
|
+
setRefreshing(false);
|
|
2680
|
+
}
|
|
2681
|
+
};
|
|
2682
|
+
const start = (event) => {
|
|
2683
|
+
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;
|
|
2684
|
+
gestureRef.current = { pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, tracking: false };
|
|
2685
|
+
};
|
|
2686
|
+
const move = (event) => {
|
|
2687
|
+
const gesture = gestureRef.current;
|
|
2688
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
2689
|
+
const dx = event.clientX - gesture.startX;
|
|
2690
|
+
const dy = event.clientY - gesture.startY;
|
|
2691
|
+
if (!gesture.tracking && (dy <= 8 || Math.abs(dx) >= dy)) {
|
|
2692
|
+
if (Math.abs(dx) > 8 || dy < 0) gestureRef.current = null;
|
|
2693
|
+
return;
|
|
2694
|
+
}
|
|
2695
|
+
gesture.tracking = true;
|
|
2696
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
2697
|
+
setDistance(Math.min(threshold * 1.35, dy * 0.55));
|
|
2698
|
+
};
|
|
2699
|
+
const finish = async (event) => {
|
|
2700
|
+
const gesture = gestureRef.current;
|
|
2701
|
+
gestureRef.current = null;
|
|
2702
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
2703
|
+
const shouldRefresh = distance >= threshold;
|
|
2704
|
+
setDistance(0);
|
|
2705
|
+
if (!shouldRefresh) return;
|
|
2706
|
+
await runRefresh();
|
|
2707
|
+
};
|
|
2708
|
+
const refresh = async () => {
|
|
2709
|
+
await runRefresh();
|
|
2710
|
+
};
|
|
2711
|
+
return /* @__PURE__ */ jsxs41("div", { ...props, ref: rootRef, className: `hf-pull-to-refresh${distance > 0 ? " hf-pull-to-refresh--dragging" : ""} ${className}`.trim(), onPointerDown: (event) => {
|
|
2712
|
+
start(event);
|
|
2713
|
+
onPointerDown?.(event);
|
|
2714
|
+
}, onPointerMove: (event) => {
|
|
2715
|
+
move(event);
|
|
2716
|
+
onPointerMove?.(event);
|
|
2717
|
+
}, onPointerUp: (event) => {
|
|
2718
|
+
void finish(event);
|
|
2719
|
+
onPointerUp?.(event);
|
|
2720
|
+
}, onPointerCancel: (event) => {
|
|
2721
|
+
gestureRef.current = null;
|
|
2722
|
+
setDistance(0);
|
|
2723
|
+
onPointerCancel?.(event);
|
|
2724
|
+
}, children: [
|
|
2725
|
+
/* @__PURE__ */ jsx46("div", { className: "hf-pull-to-refresh__indicator", style: { "--hf-pull-distance": `${distance}px` }, "aria-live": "polite", children: /* @__PURE__ */ jsx46("button", { type: "button", onClick: () => void refresh(), disabled: disabled || refreshing, children: refreshing ? "\u6B63\u5728\u5237\u65B0\u2026" : distance >= threshold ? "\u677E\u5F00\u5237\u65B0" : label }) }),
|
|
2726
|
+
/* @__PURE__ */ jsx46("div", { className: "hf-pull-to-refresh__content", style: { transform: `translateY(${distance}px)` }, children })
|
|
2727
|
+
] });
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
// src/navigation/MobileContentNavigation.tsx
|
|
2731
|
+
import { jsx as jsx47, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
2732
|
+
function MobileContentNavigation({ items, children, onRefresh, refreshThreshold, navigationLabel, activeKey, onItemSelect, className = "", ...props }) {
|
|
2733
|
+
const content = onRefresh ? /* @__PURE__ */ jsx47(PullToRefresh, { onRefresh, threshold: refreshThreshold, children }) : children;
|
|
2734
|
+
return /* @__PURE__ */ jsxs42("div", { className: `hf-mobile-content-navigation${onRefresh ? " hf-mobile-content-navigation--refreshable" : ""} ${className}`.trim(), ...props, children: [
|
|
2735
|
+
/* @__PURE__ */ jsx47("div", { className: "hf-mobile-content-navigation__body", children: content }),
|
|
2736
|
+
/* @__PURE__ */ jsx47(BottomNavigation, { items, label: navigationLabel, activeKey, onItemSelect })
|
|
2737
|
+
] });
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
// src/navigation/ShrinkNav.tsx
|
|
2741
|
+
import { useEffect as useEffect13, useState as useState27 } from "react";
|
|
2742
|
+
import { jsx as jsx48, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
2743
|
+
function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSelect, className = "", ...props }) {
|
|
2744
|
+
const [compact, setCompact] = useState27(false);
|
|
2745
|
+
useEffect13(() => {
|
|
2469
2746
|
let frame = 0;
|
|
2470
2747
|
const update = () => {
|
|
2471
2748
|
cancelAnimationFrame(frame);
|
|
@@ -2478,16 +2755,16 @@ function ShrinkNav({ brand, items, threshold = 48, action, activeKey, onItemSele
|
|
|
2478
2755
|
window.removeEventListener("scroll", update);
|
|
2479
2756
|
};
|
|
2480
2757
|
}, [threshold]);
|
|
2481
|
-
return /* @__PURE__ */
|
|
2482
|
-
/* @__PURE__ */
|
|
2483
|
-
/* @__PURE__ */
|
|
2758
|
+
return /* @__PURE__ */ jsxs43("nav", { className: `hf-shrink-nav ${compact ? "hf-shrink-nav--compact" : ""} ${className}`.trim(), "aria-label": "\u6EDA\u52A8\u5BFC\u822A", ...props, children: [
|
|
2759
|
+
/* @__PURE__ */ jsx48("div", { className: "hf-shrink-nav__brand", children: brand }),
|
|
2760
|
+
/* @__PURE__ */ jsx48("div", { className: "hf-shrink-nav__items", children: items.map((item) => /* @__PURE__ */ jsx48("a", { href: item.href ?? "#", "aria-current": activeKey === item.key ? "page" : void 0, onClick: () => onItemSelect?.(item), children: item.label }, item.key)) }),
|
|
2484
2761
|
action
|
|
2485
2762
|
] });
|
|
2486
2763
|
}
|
|
2487
2764
|
|
|
2488
2765
|
// src/navigation/Tabs.tsx
|
|
2489
2766
|
import { useId as useId15 } from "react";
|
|
2490
|
-
import { jsx as
|
|
2767
|
+
import { jsx as jsx49, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
2491
2768
|
function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\u6807\u7B7E" }) {
|
|
2492
2769
|
const id = useId15();
|
|
2493
2770
|
const active = items.find((item) => item.key === value) ?? items[0];
|
|
@@ -2500,43 +2777,43 @@ function Tabs({ items, value, onChange, variant = "line", label = "\u5185\u5BB9\
|
|
|
2500
2777
|
const next = enabled[(current + offset + enabled.length) % enabled.length];
|
|
2501
2778
|
if (next) onChange(next.key);
|
|
2502
2779
|
};
|
|
2503
|
-
return /* @__PURE__ */
|
|
2504
|
-
/* @__PURE__ */
|
|
2780
|
+
return /* @__PURE__ */ jsxs44("div", { className: `hf-tabs hf-tabs--${variant}`, children: [
|
|
2781
|
+
/* @__PURE__ */ jsx49("div", { role: "tablist", "aria-label": label, onKeyDown, children: items.map((item) => /* @__PURE__ */ jsxs44("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: [
|
|
2505
2782
|
item.icon,
|
|
2506
|
-
/* @__PURE__ */
|
|
2507
|
-
item.badge && /* @__PURE__ */
|
|
2783
|
+
/* @__PURE__ */ jsx49("span", { children: item.label }),
|
|
2784
|
+
item.badge && /* @__PURE__ */ jsx49("small", { children: item.badge })
|
|
2508
2785
|
] }, item.key)) }),
|
|
2509
|
-
active && /* @__PURE__ */
|
|
2786
|
+
active && /* @__PURE__ */ jsx49("div", { role: "tabpanel", id: `${id}-${active.key}-panel`, "aria-labelledby": `${id}-${active.key}`, tabIndex: 0, children: active.content })
|
|
2510
2787
|
] });
|
|
2511
2788
|
}
|
|
2512
2789
|
|
|
2513
2790
|
// src/navigation/Steps.tsx
|
|
2514
|
-
import { jsx as
|
|
2791
|
+
import { jsx as jsx50, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
2515
2792
|
function Steps({ items, current, onChange, orientation = "horizontal" }) {
|
|
2516
2793
|
const currentIndex = Math.max(0, items.findIndex((item) => item.key === current));
|
|
2517
|
-
return /* @__PURE__ */
|
|
2794
|
+
return /* @__PURE__ */ jsx50("ol", { className: `hf-steps hf-steps--${orientation}`, children: items.map((item, index) => {
|
|
2518
2795
|
const state = index < currentIndex ? "complete" : index === currentIndex ? "current" : "upcoming";
|
|
2519
|
-
return /* @__PURE__ */
|
|
2520
|
-
/* @__PURE__ */
|
|
2521
|
-
/* @__PURE__ */
|
|
2522
|
-
/* @__PURE__ */
|
|
2523
|
-
item.optional && /* @__PURE__ */
|
|
2524
|
-
item.description && /* @__PURE__ */
|
|
2796
|
+
return /* @__PURE__ */ jsx50("li", { className: `is-${state}`, "aria-current": state === "current" ? "step" : void 0, children: /* @__PURE__ */ jsxs45("button", { type: "button", disabled: item.disabled || !onChange, onClick: () => onChange?.(item.key), children: [
|
|
2797
|
+
/* @__PURE__ */ jsx50("span", { children: state === "complete" ? "\u2713" : index + 1 }),
|
|
2798
|
+
/* @__PURE__ */ jsxs45("span", { children: [
|
|
2799
|
+
/* @__PURE__ */ jsx50("strong", { children: item.title }),
|
|
2800
|
+
item.optional && /* @__PURE__ */ jsx50("small", { children: "\u53EF\u9009" }),
|
|
2801
|
+
item.description && /* @__PURE__ */ jsx50("small", { children: item.description })
|
|
2525
2802
|
] })
|
|
2526
2803
|
] }) }, item.key);
|
|
2527
2804
|
}) });
|
|
2528
2805
|
}
|
|
2529
2806
|
|
|
2530
2807
|
// src/navigation/CommandPalette.tsx
|
|
2531
|
-
import { useEffect as
|
|
2808
|
+
import { useEffect as useEffect14, useMemo as useMemo6, useState as useState28 } from "react";
|
|
2532
2809
|
import { createPortal as createPortal4 } from "react-dom";
|
|
2533
|
-
import { jsx as
|
|
2810
|
+
import { jsx as jsx51, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
2534
2811
|
function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u8F93\u5165\u547D\u4EE4\u6216\u641C\u7D22\u2026" }) {
|
|
2535
|
-
const [query, setQuery] =
|
|
2536
|
-
const [active, setActive] =
|
|
2537
|
-
const enabled =
|
|
2812
|
+
const [query, setQuery] = useState28("");
|
|
2813
|
+
const [active, setActive] = useState28(0);
|
|
2814
|
+
const enabled = useMemo6(() => items.filter((item) => !item.disabled && `${item.label} ${item.description ?? ""} ${item.group ?? ""}`.toLowerCase().includes(query.toLowerCase())), [items, query]);
|
|
2538
2815
|
const dialogRef = useDismissibleLayer(open, () => onOpenChange(false), true);
|
|
2539
|
-
|
|
2816
|
+
useEffect14(() => {
|
|
2540
2817
|
if (!open) {
|
|
2541
2818
|
setQuery("");
|
|
2542
2819
|
setActive(0);
|
|
@@ -2560,39 +2837,39 @@ function CommandPalette({ open, onOpenChange, items, onSelect, placeholder = "\u
|
|
|
2560
2837
|
}
|
|
2561
2838
|
};
|
|
2562
2839
|
if (!open) return null;
|
|
2563
|
-
return createPortal4(/* @__PURE__ */
|
|
2564
|
-
/* @__PURE__ */
|
|
2565
|
-
/* @__PURE__ */
|
|
2566
|
-
/* @__PURE__ */
|
|
2840
|
+
return createPortal4(/* @__PURE__ */ jsx51("div", { className: "hf-command-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onOpenChange(false), children: /* @__PURE__ */ jsxs46("div", { ref: dialogRef, tabIndex: -1, className: "hf-command", role: "dialog", "aria-modal": "true", "aria-label": "\u547D\u4EE4\u9762\u677F", children: [
|
|
2841
|
+
/* @__PURE__ */ jsxs46("div", { className: "hf-command__search", children: [
|
|
2842
|
+
/* @__PURE__ */ jsx51("span", { "aria-hidden": "true", children: "\u2315" }),
|
|
2843
|
+
/* @__PURE__ */ jsx51("input", { autoFocus: true, role: "combobox", "aria-expanded": "true", "aria-controls": "hf-command-list", value: query, placeholder, onChange: (event) => {
|
|
2567
2844
|
setQuery(event.target.value);
|
|
2568
2845
|
setActive(0);
|
|
2569
2846
|
}, onKeyDown: keydown }),
|
|
2570
|
-
/* @__PURE__ */
|
|
2847
|
+
/* @__PURE__ */ jsx51("kbd", { children: "Esc" })
|
|
2571
2848
|
] }),
|
|
2572
|
-
/* @__PURE__ */
|
|
2573
|
-
enabled.map((item, index) => /* @__PURE__ */
|
|
2849
|
+
/* @__PURE__ */ jsxs46("div", { id: "hf-command-list", className: "hf-command__list", role: "listbox", children: [
|
|
2850
|
+
enabled.map((item, index) => /* @__PURE__ */ jsxs46("button", { type: "button", role: "option", "aria-selected": index === active, onPointerMove: () => setActive(index), onClick: () => {
|
|
2574
2851
|
onSelect(item.key);
|
|
2575
2852
|
onOpenChange(false);
|
|
2576
2853
|
}, children: [
|
|
2577
2854
|
item.icon,
|
|
2578
|
-
/* @__PURE__ */
|
|
2579
|
-
/* @__PURE__ */
|
|
2580
|
-
item.description && /* @__PURE__ */
|
|
2855
|
+
/* @__PURE__ */ jsxs46("span", { children: [
|
|
2856
|
+
/* @__PURE__ */ jsx51("strong", { children: item.label }),
|
|
2857
|
+
item.description && /* @__PURE__ */ jsx51("small", { children: item.description })
|
|
2581
2858
|
] }),
|
|
2582
|
-
item.shortcut && /* @__PURE__ */
|
|
2859
|
+
item.shortcut && /* @__PURE__ */ jsx51("kbd", { children: item.shortcut })
|
|
2583
2860
|
] }, item.key)),
|
|
2584
|
-
!enabled.length && /* @__PURE__ */
|
|
2861
|
+
!enabled.length && /* @__PURE__ */ jsx51("div", { className: "hf-command__empty", children: "\u6CA1\u6709\u5339\u914D\u547D\u4EE4" })
|
|
2585
2862
|
] })
|
|
2586
2863
|
] }) }), document.body);
|
|
2587
2864
|
}
|
|
2588
2865
|
|
|
2589
2866
|
// src/layout/Layout.tsx
|
|
2590
|
-
import { jsx as
|
|
2867
|
+
import { jsx as jsx52, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
2591
2868
|
function Container({ size = "lg", padding = 24, className = "", style, ...props }) {
|
|
2592
|
-
return /* @__PURE__ */
|
|
2869
|
+
return /* @__PURE__ */ jsx52("div", { className: `hf-container hf-container--${size} ${className}`.trim(), style: { "--hf-container-padding": `${padding}px`, ...style }, ...props });
|
|
2593
2870
|
}
|
|
2594
2871
|
function Stack({ direction = "column", gap = 12, align, justify, wrap = false, className = "", style, ...props }) {
|
|
2595
|
-
return /* @__PURE__ */
|
|
2872
|
+
return /* @__PURE__ */ jsx52("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 });
|
|
2596
2873
|
}
|
|
2597
2874
|
function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "", style, ...props }) {
|
|
2598
2875
|
const gridStyle = {
|
|
@@ -2600,7 +2877,7 @@ function Grid({ columns = "auto", minItemWidth = 240, gap = 16, className = "",
|
|
|
2600
2877
|
"--hf-grid-gap": `${gap}px`,
|
|
2601
2878
|
...style
|
|
2602
2879
|
};
|
|
2603
|
-
return /* @__PURE__ */
|
|
2880
|
+
return /* @__PURE__ */ jsx52("div", { className: `hf-grid ${className}`.trim(), style: gridStyle, ...props });
|
|
2604
2881
|
}
|
|
2605
2882
|
function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", style, children, ...props }) {
|
|
2606
2883
|
const masonryStyle = {
|
|
@@ -2609,71 +2886,71 @@ function Masonry({ columns, minColumnWidth = 260, gap = 16, className = "", styl
|
|
|
2609
2886
|
"--hf-masonry-gap": `${gap}px`,
|
|
2610
2887
|
...style
|
|
2611
2888
|
};
|
|
2612
|
-
return /* @__PURE__ */
|
|
2889
|
+
return /* @__PURE__ */ jsx52("div", { className: `hf-masonry ${className}`.trim(), style: masonryStyle, ...props, children });
|
|
2613
2890
|
}
|
|
2614
2891
|
function PageLayout({ variant = "single", sidebar, header, sidebarWidth = 280, className = "", style, children, ...props }) {
|
|
2615
2892
|
const layoutStyle = { "--hf-layout-sidebar": `${sidebarWidth}px`, ...style };
|
|
2616
|
-
return /* @__PURE__ */
|
|
2617
|
-
header && /* @__PURE__ */
|
|
2618
|
-
sidebar && /* @__PURE__ */
|
|
2619
|
-
/* @__PURE__ */
|
|
2893
|
+
return /* @__PURE__ */ jsxs47("div", { className: `hf-page-layout hf-page-layout--${variant} ${className}`.trim(), style: layoutStyle, ...props, children: [
|
|
2894
|
+
header && /* @__PURE__ */ jsx52("header", { className: "hf-page-layout__header", children: header }),
|
|
2895
|
+
sidebar && /* @__PURE__ */ jsx52("aside", { className: "hf-page-layout__sidebar", children: sidebar }),
|
|
2896
|
+
/* @__PURE__ */ jsx52("main", { className: "hf-page-layout__main", children })
|
|
2620
2897
|
] });
|
|
2621
2898
|
}
|
|
2622
2899
|
|
|
2623
2900
|
// src/layout/Skeleton.tsx
|
|
2624
|
-
import { jsx as
|
|
2901
|
+
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
2625
2902
|
function Skeleton({ width = "100%", height = 16, radius, circle, animated = true, className = "", style, ...props }) {
|
|
2626
2903
|
const value = (input) => typeof input === "number" ? `${input}px` : input;
|
|
2627
|
-
return /* @__PURE__ */
|
|
2904
|
+
return /* @__PURE__ */ jsx53("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 });
|
|
2628
2905
|
}
|
|
2629
2906
|
|
|
2630
2907
|
// src/feedback/Loading.tsx
|
|
2631
|
-
import { jsx as
|
|
2908
|
+
import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
2632
2909
|
function Spinner({ label = "\u6B63\u5728\u52A0\u8F7D", size = 20, className = "" }) {
|
|
2633
|
-
return /* @__PURE__ */
|
|
2910
|
+
return /* @__PURE__ */ jsx54("span", { className: `hf-loading-spinner ${className}`.trim(), role: "status", "aria-label": label, style: { "--hf-loading-size": `${size}px` } });
|
|
2634
2911
|
}
|
|
2635
2912
|
function LoadingDots({ label = "\u6B63\u5728\u52A0\u8F7D" }) {
|
|
2636
|
-
return /* @__PURE__ */
|
|
2637
|
-
/* @__PURE__ */
|
|
2638
|
-
/* @__PURE__ */
|
|
2639
|
-
/* @__PURE__ */
|
|
2913
|
+
return /* @__PURE__ */ jsxs48("span", { className: "hf-loading-dots", role: "status", "aria-label": label, children: [
|
|
2914
|
+
/* @__PURE__ */ jsx54("i", {}),
|
|
2915
|
+
/* @__PURE__ */ jsx54("i", {}),
|
|
2916
|
+
/* @__PURE__ */ jsx54("i", {})
|
|
2640
2917
|
] });
|
|
2641
2918
|
}
|
|
2642
2919
|
function ProgressBar({ value, label, indeterminate = false, className = "" }) {
|
|
2643
2920
|
const percent = Math.min(100, Math.max(0, value ?? 0));
|
|
2644
|
-
return /* @__PURE__ */
|
|
2645
|
-
label && /* @__PURE__ */
|
|
2646
|
-
/* @__PURE__ */
|
|
2647
|
-
!indeterminate && /* @__PURE__ */
|
|
2921
|
+
return /* @__PURE__ */ jsxs48("div", { className: `hf-progress ${indeterminate ? "is-indeterminate" : ""} ${className}`.trim(), children: [
|
|
2922
|
+
label && /* @__PURE__ */ jsxs48("div", { className: "hf-progress__label", children: [
|
|
2923
|
+
/* @__PURE__ */ jsx54("span", { children: label }),
|
|
2924
|
+
!indeterminate && /* @__PURE__ */ jsxs48("strong", { children: [
|
|
2648
2925
|
percent,
|
|
2649
2926
|
"%"
|
|
2650
2927
|
] })
|
|
2651
2928
|
] }),
|
|
2652
|
-
/* @__PURE__ */
|
|
2929
|
+
/* @__PURE__ */ jsx54("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": 100, "aria-valuenow": indeterminate ? void 0 : percent, children: /* @__PURE__ */ jsx54("i", { style: { "--hf-progress": `${percent}%` } }) })
|
|
2653
2930
|
] });
|
|
2654
2931
|
}
|
|
2655
2932
|
function ProgressRing({ value, size = 72, label }) {
|
|
2656
2933
|
const percent = Math.min(100, Math.max(0, value));
|
|
2657
|
-
return /* @__PURE__ */
|
|
2934
|
+
return /* @__PURE__ */ jsx54("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__ */ jsxs48("strong", { children: [
|
|
2658
2935
|
percent,
|
|
2659
2936
|
"%"
|
|
2660
2937
|
] }) });
|
|
2661
2938
|
}
|
|
2662
2939
|
function LoadingOverlay({ active = true, label = "\u6B63\u5728\u51C6\u5907\u5185\u5BB9", className = "", children, ...props }) {
|
|
2663
|
-
return /* @__PURE__ */
|
|
2940
|
+
return /* @__PURE__ */ jsxs48("div", { className: `hf-loading-overlay ${className}`.trim(), "aria-busy": active, ...props, children: [
|
|
2664
2941
|
children,
|
|
2665
|
-
active && /* @__PURE__ */
|
|
2666
|
-
/* @__PURE__ */
|
|
2667
|
-
/* @__PURE__ */
|
|
2942
|
+
active && /* @__PURE__ */ jsxs48("div", { className: "hf-loading-overlay__veil", role: "status", children: [
|
|
2943
|
+
/* @__PURE__ */ jsx54(Spinner, { label, size: 28 }),
|
|
2944
|
+
/* @__PURE__ */ jsx54("span", { children: label })
|
|
2668
2945
|
] })
|
|
2669
2946
|
] });
|
|
2670
2947
|
}
|
|
2671
2948
|
|
|
2672
2949
|
// src/forms/MultiSelect.tsx
|
|
2673
|
-
import { useId as useId16, useState as
|
|
2674
|
-
import { jsx as
|
|
2950
|
+
import { useId as useId16, useState as useState29 } from "react";
|
|
2951
|
+
import { jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
2675
2952
|
function MultiSelect({ label, options, value, onChange, placeholder = "\u8BF7\u9009\u62E9", max, hint, disabled }) {
|
|
2676
|
-
const [open, setOpen] =
|
|
2953
|
+
const [open, setOpen] = useState29(false);
|
|
2677
2954
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
2678
2955
|
const listId = useId16();
|
|
2679
2956
|
const toggle = (next) => {
|
|
@@ -2681,48 +2958,48 @@ function MultiSelect({ label, options, value, onChange, placeholder = "\u8BF7\u9
|
|
|
2681
2958
|
if (!selected && max && value.length >= max) return;
|
|
2682
2959
|
onChange(selected ? value.filter((item) => item !== next) : [...value, next]);
|
|
2683
2960
|
};
|
|
2684
|
-
return /* @__PURE__ */
|
|
2685
|
-
label && /* @__PURE__ */
|
|
2686
|
-
/* @__PURE__ */
|
|
2961
|
+
return /* @__PURE__ */ jsxs49("div", { className: "hf-field hf-multiselect", ref: rootRef, children: [
|
|
2962
|
+
label && /* @__PURE__ */ jsx55("span", { className: "hf-field__label", children: label }),
|
|
2963
|
+
/* @__PURE__ */ jsxs49("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) => {
|
|
2687
2964
|
if (!disabled && (event.key === "Enter" || event.key === " ")) {
|
|
2688
2965
|
event.preventDefault();
|
|
2689
2966
|
setOpen(!open);
|
|
2690
2967
|
}
|
|
2691
2968
|
}, children: [
|
|
2692
|
-
/* @__PURE__ */
|
|
2969
|
+
/* @__PURE__ */ jsx55("span", { children: value.length ? value.map((item) => {
|
|
2693
2970
|
const option = options.find((candidate) => candidate.value === item);
|
|
2694
|
-
return /* @__PURE__ */
|
|
2971
|
+
return /* @__PURE__ */ jsxs49("i", { children: [
|
|
2695
2972
|
option?.label,
|
|
2696
|
-
/* @__PURE__ */
|
|
2973
|
+
/* @__PURE__ */ jsx55("button", { type: "button", "aria-label": `\u79FB\u9664 ${String(option?.label)}`, onClick: (event) => {
|
|
2697
2974
|
event.stopPropagation();
|
|
2698
2975
|
toggle(item);
|
|
2699
|
-
}, children: /* @__PURE__ */
|
|
2976
|
+
}, children: /* @__PURE__ */ jsx55(Icon, { name: "close", size: 13 }) })
|
|
2700
2977
|
] }, item);
|
|
2701
|
-
}) : /* @__PURE__ */
|
|
2702
|
-
/* @__PURE__ */
|
|
2978
|
+
}) : /* @__PURE__ */ jsx55("em", { children: placeholder }) }),
|
|
2979
|
+
/* @__PURE__ */ jsx55(Icon, { name: "chevron-down", size: 16, className: "hf-multiselect__chevron" })
|
|
2703
2980
|
] }),
|
|
2704
|
-
open && /* @__PURE__ */
|
|
2705
|
-
/* @__PURE__ */
|
|
2706
|
-
/* @__PURE__ */
|
|
2981
|
+
open && /* @__PURE__ */ jsx55("div", { id: listId, className: "hf-multiselect__menu", role: "listbox", "aria-multiselectable": "true", children: options.map((option) => /* @__PURE__ */ jsxs49("button", { type: "button", role: "option", "aria-selected": value.includes(option.value), disabled: option.disabled, onClick: () => toggle(option.value), children: [
|
|
2982
|
+
/* @__PURE__ */ jsx55("span", { children: option.label }),
|
|
2983
|
+
/* @__PURE__ */ jsx55("i", { children: value.includes(option.value) ? "\u2713" : "" })
|
|
2707
2984
|
] }, option.value)) }),
|
|
2708
|
-
hint && /* @__PURE__ */
|
|
2985
|
+
hint && /* @__PURE__ */ jsx55("span", { className: "hf-field__hint", children: hint })
|
|
2709
2986
|
] });
|
|
2710
2987
|
}
|
|
2711
2988
|
|
|
2712
2989
|
// src/forms/ChoiceGroup.tsx
|
|
2713
2990
|
import { useId as useId17 } from "react";
|
|
2714
|
-
import { jsx as
|
|
2991
|
+
import { jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
2715
2992
|
function ChoiceGroup({ label, options, value, defaultValue, onChange, type = "radio", direction = "column", disabled, name }) {
|
|
2716
2993
|
const id = useId17();
|
|
2717
2994
|
const groupName = name ?? id;
|
|
2718
2995
|
const values = Array.isArray(value) ? value : value ? [value] : void 0;
|
|
2719
2996
|
const defaults = Array.isArray(defaultValue) ? defaultValue : defaultValue ? [defaultValue] : [];
|
|
2720
|
-
return /* @__PURE__ */
|
|
2721
|
-
label && /* @__PURE__ */
|
|
2997
|
+
return /* @__PURE__ */ jsxs50("fieldset", { className: `hf-choice-group hf-choice-group--${direction}`, disabled, children: [
|
|
2998
|
+
label && /* @__PURE__ */ jsx56("legend", { children: label }),
|
|
2722
2999
|
options.map((option) => {
|
|
2723
3000
|
const checked = values?.includes(option.value);
|
|
2724
|
-
return /* @__PURE__ */
|
|
2725
|
-
/* @__PURE__ */
|
|
3001
|
+
return /* @__PURE__ */ jsxs50("label", { className: "hf-choice", children: [
|
|
3002
|
+
/* @__PURE__ */ jsx56("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) => {
|
|
2726
3003
|
if (type === "radio") onChange?.(option.value);
|
|
2727
3004
|
else {
|
|
2728
3005
|
const next = new Set(values ?? defaults);
|
|
@@ -2730,37 +3007,37 @@ function ChoiceGroup({ label, options, value, defaultValue, onChange, type = "ra
|
|
|
2730
3007
|
onChange?.([...next]);
|
|
2731
3008
|
}
|
|
2732
3009
|
} }),
|
|
2733
|
-
/* @__PURE__ */
|
|
2734
|
-
/* @__PURE__ */
|
|
2735
|
-
/* @__PURE__ */
|
|
2736
|
-
option.description && /* @__PURE__ */
|
|
3010
|
+
/* @__PURE__ */ jsx56("span", { className: "hf-choice__control", "aria-hidden": "true" }),
|
|
3011
|
+
/* @__PURE__ */ jsxs50("span", { className: "hf-choice__copy", children: [
|
|
3012
|
+
/* @__PURE__ */ jsx56("strong", { children: option.label }),
|
|
3013
|
+
option.description && /* @__PURE__ */ jsx56("small", { children: option.description })
|
|
2737
3014
|
] })
|
|
2738
3015
|
] }, option.value);
|
|
2739
3016
|
})
|
|
2740
3017
|
] });
|
|
2741
3018
|
}
|
|
2742
3019
|
function RadioGroup(props) {
|
|
2743
|
-
return /* @__PURE__ */
|
|
3020
|
+
return /* @__PURE__ */ jsx56(ChoiceGroup, { ...props, type: "radio", onChange: (next) => props.onChange?.(next) });
|
|
2744
3021
|
}
|
|
2745
3022
|
function CheckboxGroup(props) {
|
|
2746
|
-
return /* @__PURE__ */
|
|
3023
|
+
return /* @__PURE__ */ jsx56(ChoiceGroup, { ...props, type: "checkbox", onChange: (next) => props.onChange?.(next) });
|
|
2747
3024
|
}
|
|
2748
3025
|
|
|
2749
3026
|
// src/forms/ValidatedInput.tsx
|
|
2750
|
-
import { useState as
|
|
2751
|
-
import { jsx as
|
|
3027
|
+
import { useState as useState30 } from "react";
|
|
3028
|
+
import { jsx as jsx57 } from "react/jsx-runtime";
|
|
2752
3029
|
function validateValue(value, rules) {
|
|
2753
3030
|
return rules.find((rule) => !rule.validate(value))?.message;
|
|
2754
3031
|
}
|
|
2755
3032
|
function ValidatedInput({ value, rules, validateOn = "blur", onChange, onValidityChange, ...props }) {
|
|
2756
|
-
const [touched, setTouched] =
|
|
3033
|
+
const [touched, setTouched] = useState30(false);
|
|
2757
3034
|
const error = touched ? validateValue(value, rules) : void 0;
|
|
2758
3035
|
const update = (next) => {
|
|
2759
3036
|
onChange(next);
|
|
2760
3037
|
if (validateOn === "change") setTouched(true);
|
|
2761
3038
|
onValidityChange?.(!validateValue(next, rules));
|
|
2762
3039
|
};
|
|
2763
|
-
return /* @__PURE__ */
|
|
3040
|
+
return /* @__PURE__ */ jsx57(Input, { ...props, value, error, onChange: (event) => update(event.target.value), onBlur: () => setTouched(true) });
|
|
2764
3041
|
}
|
|
2765
3042
|
function validateForm(event) {
|
|
2766
3043
|
if (!event.currentTarget.checkValidity()) {
|
|
@@ -2773,25 +3050,25 @@ function validateForm(event) {
|
|
|
2773
3050
|
|
|
2774
3051
|
// src/forms/Textarea.tsx
|
|
2775
3052
|
import { forwardRef as forwardRef6, useId as useId18 } from "react";
|
|
2776
|
-
import { jsx as
|
|
3053
|
+
import { jsx as jsx58, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
2777
3054
|
var Textarea = forwardRef6(function Textarea2({ label, hint, error, resize = "vertical", id, className = "", ...props }, ref) {
|
|
2778
3055
|
const generated = useId18();
|
|
2779
3056
|
const fieldId = id ?? generated;
|
|
2780
3057
|
const message = error ?? hint;
|
|
2781
3058
|
const messageId = message ? `${fieldId}-message` : void 0;
|
|
2782
|
-
return /* @__PURE__ */
|
|
2783
|
-
label && /* @__PURE__ */
|
|
2784
|
-
/* @__PURE__ */
|
|
2785
|
-
message && /* @__PURE__ */
|
|
3059
|
+
return /* @__PURE__ */ jsxs51("label", { className: "hf-field", htmlFor: fieldId, children: [
|
|
3060
|
+
label && /* @__PURE__ */ jsx58("span", { className: "hf-field__label", children: label }),
|
|
3061
|
+
/* @__PURE__ */ jsx58("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 }),
|
|
3062
|
+
message && /* @__PURE__ */ jsx58("span", { id: messageId, className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: message })
|
|
2786
3063
|
] });
|
|
2787
3064
|
});
|
|
2788
3065
|
|
|
2789
3066
|
// src/forms/Choice.tsx
|
|
2790
|
-
import { forwardRef as forwardRef7, useEffect as
|
|
2791
|
-
import { jsx as
|
|
3067
|
+
import { forwardRef as forwardRef7, useEffect as useEffect15, useRef as useRef12 } from "react";
|
|
3068
|
+
import { jsx as jsx59, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
2792
3069
|
var Checkbox = forwardRef7(function Checkbox2({ label, description, indeterminate, className = "", ...props }, forwardedRef) {
|
|
2793
|
-
const local =
|
|
2794
|
-
|
|
3070
|
+
const local = useRef12(null);
|
|
3071
|
+
useEffect15(() => {
|
|
2795
3072
|
if (local.current) local.current.indeterminate = Boolean(indeterminate);
|
|
2796
3073
|
}, [indeterminate]);
|
|
2797
3074
|
const setRef = (node) => {
|
|
@@ -2799,78 +3076,78 @@ var Checkbox = forwardRef7(function Checkbox2({ label, description, indeterminat
|
|
|
2799
3076
|
if (typeof forwardedRef === "function") forwardedRef(node);
|
|
2800
3077
|
else if (forwardedRef) forwardedRef.current = node;
|
|
2801
3078
|
};
|
|
2802
|
-
return /* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
/* @__PURE__ */
|
|
2805
|
-
/* @__PURE__ */
|
|
2806
|
-
/* @__PURE__ */
|
|
2807
|
-
description && /* @__PURE__ */
|
|
3079
|
+
return /* @__PURE__ */ jsxs52("label", { className: `hf-choice-control ${className}`, children: [
|
|
3080
|
+
/* @__PURE__ */ jsx59("input", { ref: setRef, type: "checkbox", ...props }),
|
|
3081
|
+
/* @__PURE__ */ jsx59("span", { className: "hf-choice-control__mark", children: /* @__PURE__ */ jsx59(IconCheck, {}) }),
|
|
3082
|
+
/* @__PURE__ */ jsxs52("span", { children: [
|
|
3083
|
+
/* @__PURE__ */ jsx59("strong", { children: label }),
|
|
3084
|
+
description && /* @__PURE__ */ jsx59("small", { children: description })
|
|
2808
3085
|
] })
|
|
2809
3086
|
] });
|
|
2810
3087
|
});
|
|
2811
3088
|
var Radio = forwardRef7(function Radio2({ label, description, className = "", ...props }, ref) {
|
|
2812
|
-
return /* @__PURE__ */
|
|
2813
|
-
/* @__PURE__ */
|
|
2814
|
-
/* @__PURE__ */
|
|
2815
|
-
/* @__PURE__ */
|
|
2816
|
-
/* @__PURE__ */
|
|
2817
|
-
description && /* @__PURE__ */
|
|
3089
|
+
return /* @__PURE__ */ jsxs52("label", { className: `hf-choice-control hf-choice-control--radio ${className}`, children: [
|
|
3090
|
+
/* @__PURE__ */ jsx59("input", { ref, type: "radio", ...props }),
|
|
3091
|
+
/* @__PURE__ */ jsx59("span", { className: "hf-choice-control__mark", children: /* @__PURE__ */ jsx59("i", {}) }),
|
|
3092
|
+
/* @__PURE__ */ jsxs52("span", { children: [
|
|
3093
|
+
/* @__PURE__ */ jsx59("strong", { children: label }),
|
|
3094
|
+
description && /* @__PURE__ */ jsx59("small", { children: description })
|
|
2818
3095
|
] })
|
|
2819
3096
|
] });
|
|
2820
3097
|
});
|
|
2821
3098
|
function IconCheck() {
|
|
2822
|
-
return /* @__PURE__ */
|
|
3099
|
+
return /* @__PURE__ */ jsx59("svg", { viewBox: "0 0 16 16", "aria-hidden": "true", children: /* @__PURE__ */ jsx59("path", { d: "m3.5 8 3 3 6-6" }) });
|
|
2823
3100
|
}
|
|
2824
3101
|
|
|
2825
3102
|
// src/forms/Advanced.tsx
|
|
2826
3103
|
import {
|
|
2827
|
-
useState as
|
|
3104
|
+
useState as useState31
|
|
2828
3105
|
} from "react";
|
|
2829
|
-
import { jsx as
|
|
3106
|
+
import { jsx as jsx60, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
2830
3107
|
var iso = (date) => `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
|
|
2831
3108
|
function Calendar({ value, onChange, min, max, className = "" }) {
|
|
2832
3109
|
const initial = value ? /* @__PURE__ */ new Date(`${value}T00:00:00`) : /* @__PURE__ */ new Date();
|
|
2833
|
-
const [view, setView] =
|
|
3110
|
+
const [view, setView] = useState31(new Date(initial.getFullYear(), initial.getMonth(), 1));
|
|
2834
3111
|
const first = view.getDay();
|
|
2835
3112
|
const days = new Date(view.getFullYear(), view.getMonth() + 1, 0).getDate();
|
|
2836
3113
|
const cells = Array.from(
|
|
2837
3114
|
{ length: Math.ceil((first + days) / 7) * 7 },
|
|
2838
3115
|
(_, index) => index - first + 1
|
|
2839
3116
|
);
|
|
2840
|
-
return /* @__PURE__ */
|
|
2841
|
-
/* @__PURE__ */
|
|
2842
|
-
/* @__PURE__ */
|
|
3117
|
+
return /* @__PURE__ */ jsxs53("div", { className: `hf-calendar ${className}`, children: [
|
|
3118
|
+
/* @__PURE__ */ jsxs53("header", { children: [
|
|
3119
|
+
/* @__PURE__ */ jsx60(
|
|
2843
3120
|
"button",
|
|
2844
3121
|
{
|
|
2845
3122
|
type: "button",
|
|
2846
3123
|
"aria-label": "\u4E0A\u4E2A\u6708",
|
|
2847
3124
|
onClick: () => setView(new Date(view.getFullYear(), view.getMonth() - 1, 1)),
|
|
2848
|
-
children: /* @__PURE__ */
|
|
3125
|
+
children: /* @__PURE__ */ jsx60(Icon, { name: "chevron-down", className: "hf-calendar__prev" })
|
|
2849
3126
|
}
|
|
2850
3127
|
),
|
|
2851
|
-
/* @__PURE__ */
|
|
3128
|
+
/* @__PURE__ */ jsxs53("strong", { children: [
|
|
2852
3129
|
view.getFullYear(),
|
|
2853
3130
|
" \u5E74 ",
|
|
2854
3131
|
view.getMonth() + 1,
|
|
2855
3132
|
" \u6708"
|
|
2856
3133
|
] }),
|
|
2857
|
-
/* @__PURE__ */
|
|
3134
|
+
/* @__PURE__ */ jsx60(
|
|
2858
3135
|
"button",
|
|
2859
3136
|
{
|
|
2860
3137
|
type: "button",
|
|
2861
3138
|
"aria-label": "\u4E0B\u4E2A\u6708",
|
|
2862
3139
|
onClick: () => setView(new Date(view.getFullYear(), view.getMonth() + 1, 1)),
|
|
2863
|
-
children: /* @__PURE__ */
|
|
3140
|
+
children: /* @__PURE__ */ jsx60(Icon, { name: "chevron-down", className: "hf-calendar__next" })
|
|
2864
3141
|
}
|
|
2865
3142
|
)
|
|
2866
3143
|
] }),
|
|
2867
|
-
/* @__PURE__ */
|
|
2868
|
-
/* @__PURE__ */
|
|
2869
|
-
if (day2 < 1 || day2 > days) return /* @__PURE__ */
|
|
3144
|
+
/* @__PURE__ */ jsx60("div", { className: "hf-calendar__week", children: "\u65E5\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D".split("").map((day2) => /* @__PURE__ */ jsx60("span", { children: day2 }, day2)) }),
|
|
3145
|
+
/* @__PURE__ */ jsx60("div", { className: "hf-calendar__days", children: cells.map((day2, index) => {
|
|
3146
|
+
if (day2 < 1 || day2 > days) return /* @__PURE__ */ jsx60("span", {}, index);
|
|
2870
3147
|
const date = iso(new Date(view.getFullYear(), view.getMonth(), day2));
|
|
2871
3148
|
const disabled = Boolean(min && date < min || max && date > max);
|
|
2872
3149
|
const stateClass = date === value ? "is-selected" : date === iso(/* @__PURE__ */ new Date()) ? "is-today" : "";
|
|
2873
|
-
return /* @__PURE__ */
|
|
3150
|
+
return /* @__PURE__ */ jsx60(
|
|
2874
3151
|
"button",
|
|
2875
3152
|
{
|
|
2876
3153
|
type: "button",
|
|
@@ -2894,13 +3171,13 @@ function DatePicker({
|
|
|
2894
3171
|
max,
|
|
2895
3172
|
error
|
|
2896
3173
|
}) {
|
|
2897
|
-
const [open, setOpen] =
|
|
3174
|
+
const [open, setOpen] = useState31(false);
|
|
2898
3175
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), {
|
|
2899
3176
|
autoFocus: false
|
|
2900
3177
|
});
|
|
2901
|
-
return /* @__PURE__ */
|
|
2902
|
-
label && /* @__PURE__ */
|
|
2903
|
-
/* @__PURE__ */
|
|
3178
|
+
return /* @__PURE__ */ jsxs53("div", { ref: rootRef, className: "hf-field hf-date-picker", children: [
|
|
3179
|
+
label && /* @__PURE__ */ jsx60("span", { className: "hf-field__label", children: label }),
|
|
3180
|
+
/* @__PURE__ */ jsxs53(
|
|
2904
3181
|
"button",
|
|
2905
3182
|
{
|
|
2906
3183
|
type: "button",
|
|
@@ -2908,12 +3185,12 @@ function DatePicker({
|
|
|
2908
3185
|
"aria-expanded": open,
|
|
2909
3186
|
onClick: () => setOpen(!open),
|
|
2910
3187
|
children: [
|
|
2911
|
-
/* @__PURE__ */
|
|
2912
|
-
/* @__PURE__ */
|
|
3188
|
+
/* @__PURE__ */ jsx60("span", { className: value ? "" : "is-placeholder", children: value || placeholder }),
|
|
3189
|
+
/* @__PURE__ */ jsx60(Icon, { name: "chevron-down", size: 16 })
|
|
2913
3190
|
]
|
|
2914
3191
|
}
|
|
2915
3192
|
),
|
|
2916
|
-
open && /* @__PURE__ */
|
|
3193
|
+
open && /* @__PURE__ */ jsx60("div", { className: "hf-date-picker__panel", children: /* @__PURE__ */ jsx60(
|
|
2917
3194
|
Calendar,
|
|
2918
3195
|
{
|
|
2919
3196
|
value,
|
|
@@ -2925,11 +3202,11 @@ function DatePicker({
|
|
|
2925
3202
|
}
|
|
2926
3203
|
}
|
|
2927
3204
|
) }),
|
|
2928
|
-
error && /* @__PURE__ */
|
|
3205
|
+
error && /* @__PURE__ */ jsx60("span", { className: "hf-field__hint hf-field__hint--error", children: error })
|
|
2929
3206
|
] });
|
|
2930
3207
|
}
|
|
2931
3208
|
function TimePicker({ label, value, onChange, step = 30 }) {
|
|
2932
|
-
const [open, setOpen] =
|
|
3209
|
+
const [open, setOpen] = useState31(false);
|
|
2933
3210
|
const rootRef = useDismissibleLayer(open, () => setOpen(false), {
|
|
2934
3211
|
autoFocus: false
|
|
2935
3212
|
});
|
|
@@ -2937,9 +3214,9 @@ function TimePicker({ label, value, onChange, step = 30 }) {
|
|
|
2937
3214
|
const minutes = index * step;
|
|
2938
3215
|
return `${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}`;
|
|
2939
3216
|
});
|
|
2940
|
-
return /* @__PURE__ */
|
|
2941
|
-
label && /* @__PURE__ */
|
|
2942
|
-
/* @__PURE__ */
|
|
3217
|
+
return /* @__PURE__ */ jsxs53("div", { ref: rootRef, className: "hf-field hf-time-picker", children: [
|
|
3218
|
+
label && /* @__PURE__ */ jsx60("span", { className: "hf-field__label", children: label }),
|
|
3219
|
+
/* @__PURE__ */ jsxs53(
|
|
2943
3220
|
"button",
|
|
2944
3221
|
{
|
|
2945
3222
|
type: "button",
|
|
@@ -2947,12 +3224,12 @@ function TimePicker({ label, value, onChange, step = 30 }) {
|
|
|
2947
3224
|
"aria-expanded": open,
|
|
2948
3225
|
onClick: () => setOpen(!open),
|
|
2949
3226
|
children: [
|
|
2950
|
-
/* @__PURE__ */
|
|
2951
|
-
/* @__PURE__ */
|
|
3227
|
+
/* @__PURE__ */ jsx60("span", { className: value ? "" : "is-placeholder", children: value || "\u9009\u62E9\u65F6\u95F4" }),
|
|
3228
|
+
/* @__PURE__ */ jsx60(Icon, { name: "chevron-down", size: 16 })
|
|
2952
3229
|
]
|
|
2953
3230
|
}
|
|
2954
3231
|
),
|
|
2955
|
-
open && /* @__PURE__ */
|
|
3232
|
+
open && /* @__PURE__ */ jsx60("div", { className: "hf-time-picker__panel", role: "listbox", children: times.map((time) => /* @__PURE__ */ jsx60(
|
|
2956
3233
|
"button",
|
|
2957
3234
|
{
|
|
2958
3235
|
type: "button",
|
|
@@ -2979,12 +3256,12 @@ function Slider({
|
|
|
2979
3256
|
...props
|
|
2980
3257
|
}) {
|
|
2981
3258
|
const percent = (value - Number(min)) / (Number(max) - Number(min)) * 100;
|
|
2982
|
-
return /* @__PURE__ */
|
|
2983
|
-
/* @__PURE__ */
|
|
3259
|
+
return /* @__PURE__ */ jsxs53("label", { className: "hf-slider", children: [
|
|
3260
|
+
/* @__PURE__ */ jsxs53("span", { children: [
|
|
2984
3261
|
label,
|
|
2985
|
-
showValue && /* @__PURE__ */
|
|
3262
|
+
showValue && /* @__PURE__ */ jsx60("strong", { children: value })
|
|
2986
3263
|
] }),
|
|
2987
|
-
/* @__PURE__ */
|
|
3264
|
+
/* @__PURE__ */ jsx60(
|
|
2988
3265
|
"input",
|
|
2989
3266
|
{
|
|
2990
3267
|
type: "range",
|
|
@@ -3005,7 +3282,7 @@ import {
|
|
|
3005
3282
|
createContext,
|
|
3006
3283
|
useContext
|
|
3007
3284
|
} from "react";
|
|
3008
|
-
import { jsx as
|
|
3285
|
+
import { jsx as jsx61, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
3009
3286
|
var FormContext = createContext({});
|
|
3010
3287
|
function Form({
|
|
3011
3288
|
layout = "vertical",
|
|
@@ -3014,13 +3291,13 @@ function Form({
|
|
|
3014
3291
|
children,
|
|
3015
3292
|
...props
|
|
3016
3293
|
}) {
|
|
3017
|
-
return /* @__PURE__ */
|
|
3294
|
+
return /* @__PURE__ */ jsx61(FormContext.Provider, { value: { disabled }, children: /* @__PURE__ */ jsx61(
|
|
3018
3295
|
"form",
|
|
3019
3296
|
{
|
|
3020
3297
|
className: `hf-form hf-form--${layout} ${className}`.trim(),
|
|
3021
3298
|
"aria-disabled": disabled || void 0,
|
|
3022
3299
|
...props,
|
|
3023
|
-
children: /* @__PURE__ */
|
|
3300
|
+
children: /* @__PURE__ */ jsx61("fieldset", { className: "hf-form__fieldset", disabled, children })
|
|
3024
3301
|
}
|
|
3025
3302
|
) });
|
|
3026
3303
|
}
|
|
@@ -3034,20 +3311,20 @@ function FormItem({
|
|
|
3034
3311
|
...props
|
|
3035
3312
|
}) {
|
|
3036
3313
|
const { disabled } = useContext(FormContext);
|
|
3037
|
-
return /* @__PURE__ */
|
|
3314
|
+
return /* @__PURE__ */ jsxs54(
|
|
3038
3315
|
"div",
|
|
3039
3316
|
{
|
|
3040
3317
|
className: `hf-form-item${error ? " is-error" : ""} ${className}`.trim(),
|
|
3041
3318
|
"aria-disabled": disabled || void 0,
|
|
3042
3319
|
...props,
|
|
3043
3320
|
children: [
|
|
3044
|
-
label && /* @__PURE__ */
|
|
3321
|
+
label && /* @__PURE__ */ jsxs54("div", { className: "hf-form-item__label", children: [
|
|
3045
3322
|
label,
|
|
3046
|
-
required && /* @__PURE__ */
|
|
3323
|
+
required && /* @__PURE__ */ jsx61("span", { "aria-hidden": "true", children: "*" })
|
|
3047
3324
|
] }),
|
|
3048
|
-
/* @__PURE__ */
|
|
3325
|
+
/* @__PURE__ */ jsxs54("div", { children: [
|
|
3049
3326
|
children,
|
|
3050
|
-
(error || hint) && /* @__PURE__ */
|
|
3327
|
+
(error || hint) && /* @__PURE__ */ jsx61("small", { className: error ? "is-error" : "", children: error || hint })
|
|
3051
3328
|
] })
|
|
3052
3329
|
]
|
|
3053
3330
|
}
|
|
@@ -3057,10 +3334,10 @@ function FormItem({
|
|
|
3057
3334
|
// src/forms/Upload.tsx
|
|
3058
3335
|
import {
|
|
3059
3336
|
useId as useId19,
|
|
3060
|
-
useRef as
|
|
3061
|
-
useState as
|
|
3337
|
+
useRef as useRef13,
|
|
3338
|
+
useState as useState32
|
|
3062
3339
|
} from "react";
|
|
3063
|
-
import { jsx as
|
|
3340
|
+
import { jsx as jsx62, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
3064
3341
|
function formatFileSize(bytes) {
|
|
3065
3342
|
if (bytes >= 1024 * 1024) {
|
|
3066
3343
|
const megabytes = bytes / (1024 * 1024);
|
|
@@ -3120,9 +3397,9 @@ function Upload({
|
|
|
3120
3397
|
disabled
|
|
3121
3398
|
}) {
|
|
3122
3399
|
const id = useId19();
|
|
3123
|
-
const ref =
|
|
3124
|
-
const [dragging, setDragging] =
|
|
3125
|
-
const [rejections, setRejections] =
|
|
3400
|
+
const ref = useRef13(null);
|
|
3401
|
+
const [dragging, setDragging] = useState32(false);
|
|
3402
|
+
const [rejections, setRejections] = useState32([]);
|
|
3126
3403
|
const takeFiles = (list) => {
|
|
3127
3404
|
const result = validateUploadFiles(Array.from(list ?? []), {
|
|
3128
3405
|
accept,
|
|
@@ -3133,8 +3410,8 @@ function Upload({
|
|
|
3133
3410
|
onFiles(result.accepted);
|
|
3134
3411
|
if (result.rejected.length) onReject?.(result.rejected);
|
|
3135
3412
|
};
|
|
3136
|
-
return /* @__PURE__ */
|
|
3137
|
-
/* @__PURE__ */
|
|
3413
|
+
return /* @__PURE__ */ jsxs55("div", { className: "hf-upload", children: [
|
|
3414
|
+
/* @__PURE__ */ jsx62(
|
|
3138
3415
|
"input",
|
|
3139
3416
|
{
|
|
3140
3417
|
ref,
|
|
@@ -3146,7 +3423,7 @@ function Upload({
|
|
|
3146
3423
|
onChange: (event) => takeFiles(event.target.files)
|
|
3147
3424
|
}
|
|
3148
3425
|
),
|
|
3149
|
-
/* @__PURE__ */
|
|
3426
|
+
/* @__PURE__ */ jsxs55(
|
|
3150
3427
|
"button",
|
|
3151
3428
|
{
|
|
3152
3429
|
type: "button",
|
|
@@ -3164,32 +3441,32 @@ function Upload({
|
|
|
3164
3441
|
if (!disabled) takeFiles(event.dataTransfer.files);
|
|
3165
3442
|
},
|
|
3166
3443
|
children: [
|
|
3167
|
-
/* @__PURE__ */
|
|
3168
|
-
/* @__PURE__ */
|
|
3169
|
-
/* @__PURE__ */
|
|
3444
|
+
/* @__PURE__ */ jsx62(Icon, { name: "inbox", size: 24 }),
|
|
3445
|
+
/* @__PURE__ */ jsx62("strong", { children: label }),
|
|
3446
|
+
/* @__PURE__ */ jsx62("span", { children: "\u62D6\u653E\u5230\u8FD9\u91CC\uFF0C\u6216\u70B9\u51FB\u9009\u62E9" })
|
|
3170
3447
|
]
|
|
3171
3448
|
}
|
|
3172
3449
|
),
|
|
3173
|
-
rejections.length > 0 && /* @__PURE__ */
|
|
3450
|
+
rejections.length > 0 && /* @__PURE__ */ jsx62("div", { className: "hf-upload__errors", role: "alert", children: rejections.map(({ file, reason, message }, index) => /* @__PURE__ */ jsxs55("span", { children: [
|
|
3174
3451
|
file.name,
|
|
3175
3452
|
"\uFF1A",
|
|
3176
3453
|
message
|
|
3177
3454
|
] }, `${file.name}-${reason}-${index}`)) }),
|
|
3178
|
-
hint && /* @__PURE__ */
|
|
3455
|
+
hint && /* @__PURE__ */ jsx62("small", { children: hint })
|
|
3179
3456
|
] });
|
|
3180
3457
|
}
|
|
3181
3458
|
|
|
3182
3459
|
// src/forms/Combobox.tsx
|
|
3183
|
-
import { useId as useId20, useMemo as
|
|
3184
|
-
import { jsx as
|
|
3460
|
+
import { useId as useId20, useMemo as useMemo7, useState as useState33 } from "react";
|
|
3461
|
+
import { jsx as jsx63, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
3185
3462
|
function Combobox({ label, options, value = "", onChange, placeholder = "\u641C\u7D22\u6216\u9009\u62E9", hint, error, disabled, emptyText = "\u6CA1\u6709\u5339\u914D\u9879" }) {
|
|
3186
3463
|
const id = useId20();
|
|
3187
|
-
const [open, setOpen] =
|
|
3464
|
+
const [open, setOpen] = useState33(false);
|
|
3188
3465
|
const root = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
3189
|
-
const [query, setQuery] =
|
|
3190
|
-
const [active, setActive] =
|
|
3466
|
+
const [query, setQuery] = useState33("");
|
|
3467
|
+
const [active, setActive] = useState33(0);
|
|
3191
3468
|
const selected = options.find((item) => item.value === value);
|
|
3192
|
-
const filtered =
|
|
3469
|
+
const filtered = useMemo7(() => options.filter((item) => `${typeof item.label === "string" ? item.label : item.value} ${item.keywords ?? ""}`.toLowerCase().includes(query.toLowerCase())), [options, query]);
|
|
3193
3470
|
const choose = (next) => {
|
|
3194
3471
|
onChange(next);
|
|
3195
3472
|
setQuery("");
|
|
@@ -3206,51 +3483,51 @@ function Combobox({ label, options, value = "", onChange, placeholder = "\u641C\
|
|
|
3206
3483
|
if (option && !option.disabled) choose(option.value);
|
|
3207
3484
|
} else if (event.key === "Escape") setOpen(false);
|
|
3208
3485
|
};
|
|
3209
|
-
return /* @__PURE__ */
|
|
3210
|
-
label && /* @__PURE__ */
|
|
3211
|
-
/* @__PURE__ */
|
|
3212
|
-
/* @__PURE__ */
|
|
3486
|
+
return /* @__PURE__ */ jsxs56("div", { className: "hf-field hf-combobox", ref: root, children: [
|
|
3487
|
+
label && /* @__PURE__ */ jsx63("label", { className: "hf-field__label", htmlFor: id, children: label }),
|
|
3488
|
+
/* @__PURE__ */ jsxs56("div", { className: `hf-combobox__control${open ? " is-open" : ""}${error ? " is-error" : ""}`, children: [
|
|
3489
|
+
/* @__PURE__ */ jsx63("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) => {
|
|
3213
3490
|
setQuery(event.target.value);
|
|
3214
3491
|
setActive(0);
|
|
3215
3492
|
setOpen(true);
|
|
3216
3493
|
}, onKeyDown }),
|
|
3217
|
-
/* @__PURE__ */
|
|
3494
|
+
/* @__PURE__ */ jsx63("button", { type: "button", "aria-label": open ? "\u5173\u95ED\u9009\u9879" : "\u6253\u5F00\u9009\u9879", disabled, onClick: () => setOpen((current) => !current), children: /* @__PURE__ */ jsx63(Icon, { name: "chevron-down", size: 16 }) })
|
|
3218
3495
|
] }),
|
|
3219
|
-
open && /* @__PURE__ */
|
|
3220
|
-
/* @__PURE__ */
|
|
3221
|
-
option.value === value && /* @__PURE__ */
|
|
3222
|
-
] }, option.value)) : /* @__PURE__ */
|
|
3223
|
-
(error || hint) && /* @__PURE__ */
|
|
3496
|
+
open && /* @__PURE__ */ jsx63("div", { id: `${id}-listbox`, className: "hf-combobox__menu", role: "listbox", children: filtered.length ? filtered.map((option, index) => /* @__PURE__ */ jsxs56("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: [
|
|
3497
|
+
/* @__PURE__ */ jsx63("span", { children: option.label }),
|
|
3498
|
+
option.value === value && /* @__PURE__ */ jsx63("span", { "aria-hidden": "true", children: "\u2713" })
|
|
3499
|
+
] }, option.value)) : /* @__PURE__ */ jsx63("div", { className: "hf-combobox__empty", children: emptyText }) }),
|
|
3500
|
+
(error || hint) && /* @__PURE__ */ jsx63("span", { className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: error ?? hint })
|
|
3224
3501
|
] });
|
|
3225
3502
|
}
|
|
3226
3503
|
|
|
3227
3504
|
// src/forms/NumberInput.tsx
|
|
3228
3505
|
import { useId as useId21 } from "react";
|
|
3229
|
-
import { jsx as
|
|
3506
|
+
import { jsx as jsx64, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
3230
3507
|
function NumberInput({ label, value, onChange, min, max, step = 1, prefix, suffix, hint, error, disabled }) {
|
|
3231
3508
|
const id = useId21();
|
|
3232
|
-
const
|
|
3233
|
-
return /* @__PURE__ */
|
|
3234
|
-
label && /* @__PURE__ */
|
|
3235
|
-
/* @__PURE__ */
|
|
3236
|
-
prefix && /* @__PURE__ */
|
|
3237
|
-
/* @__PURE__ */
|
|
3509
|
+
const clamp2 = (next) => Math.min(max ?? Infinity, Math.max(min ?? -Infinity, next));
|
|
3510
|
+
return /* @__PURE__ */ jsxs57("div", { className: "hf-field hf-number-input", children: [
|
|
3511
|
+
label && /* @__PURE__ */ jsx64("label", { className: "hf-field__label", htmlFor: id, children: label }),
|
|
3512
|
+
/* @__PURE__ */ jsxs57("div", { className: `hf-number-input__control${error ? " is-error" : ""}`, children: [
|
|
3513
|
+
prefix && /* @__PURE__ */ jsx64("span", { children: prefix }),
|
|
3514
|
+
/* @__PURE__ */ jsx64("input", { id, type: "number", value, min, max, step, disabled, "aria-invalid": Boolean(error), onChange: (event) => {
|
|
3238
3515
|
const next = event.currentTarget.valueAsNumber;
|
|
3239
|
-
if (!Number.isNaN(next)) onChange(
|
|
3516
|
+
if (!Number.isNaN(next)) onChange(clamp2(next));
|
|
3240
3517
|
} }),
|
|
3241
|
-
/* @__PURE__ */
|
|
3242
|
-
/* @__PURE__ */
|
|
3243
|
-
/* @__PURE__ */
|
|
3518
|
+
/* @__PURE__ */ jsxs57("div", { children: [
|
|
3519
|
+
/* @__PURE__ */ jsx64("button", { type: "button", disabled: disabled || max !== void 0 && value >= max, "aria-label": "\u589E\u52A0", onClick: () => onChange(clamp2(value + step)), children: "\uFF0B" }),
|
|
3520
|
+
/* @__PURE__ */ jsx64("button", { type: "button", disabled: disabled || min !== void 0 && value <= min, "aria-label": "\u51CF\u5C11", onClick: () => onChange(clamp2(value - step)), children: "\u2212" })
|
|
3244
3521
|
] }),
|
|
3245
|
-
suffix && /* @__PURE__ */
|
|
3522
|
+
suffix && /* @__PURE__ */ jsx64("span", { children: suffix })
|
|
3246
3523
|
] }),
|
|
3247
|
-
(error || hint) && /* @__PURE__ */
|
|
3524
|
+
(error || hint) && /* @__PURE__ */ jsx64("span", { className: `hf-field__hint${error ? " hf-field__hint--error" : ""}`, children: error ?? hint })
|
|
3248
3525
|
] });
|
|
3249
3526
|
}
|
|
3250
3527
|
|
|
3251
3528
|
// src/forms/NextBatch.tsx
|
|
3252
|
-
import { useState as
|
|
3253
|
-
import { jsx as
|
|
3529
|
+
import { useState as useState34 } from "react";
|
|
3530
|
+
import { jsx as jsx65, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
3254
3531
|
function Cascader({ options, value = [], onChange, label }) {
|
|
3255
3532
|
const levels = [options];
|
|
3256
3533
|
let current = options;
|
|
@@ -3260,44 +3537,44 @@ function Cascader({ options, value = [], onChange, label }) {
|
|
|
3260
3537
|
levels.push(next);
|
|
3261
3538
|
current = next;
|
|
3262
3539
|
}
|
|
3263
|
-
return /* @__PURE__ */
|
|
3264
|
-
label && /* @__PURE__ */
|
|
3265
|
-
/* @__PURE__ */
|
|
3540
|
+
return /* @__PURE__ */ jsxs58("div", { className: "hf-field hf-cascader", children: [
|
|
3541
|
+
label && /* @__PURE__ */ jsx65("span", { className: "hf-field__label", children: label }),
|
|
3542
|
+
/* @__PURE__ */ jsx65("div", { children: levels.map((items, level) => /* @__PURE__ */ jsx65(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)) })
|
|
3266
3543
|
] });
|
|
3267
3544
|
}
|
|
3268
3545
|
function TreeSelect({ options, value, onChange, label, placeholder = "\u9009\u62E9\u8282\u70B9" }) {
|
|
3269
|
-
const [open, setOpen] =
|
|
3546
|
+
const [open, setOpen] = useState34(false);
|
|
3270
3547
|
const flatten = (nodes, depth = 0) => nodes.flatMap((node) => [{ node, depth }, ...flatten(node.children ?? [], depth + 1)]);
|
|
3271
3548
|
const all = flatten(options);
|
|
3272
|
-
return /* @__PURE__ */
|
|
3273
|
-
label && /* @__PURE__ */
|
|
3274
|
-
/* @__PURE__ */
|
|
3275
|
-
/* @__PURE__ */
|
|
3276
|
-
/* @__PURE__ */
|
|
3549
|
+
return /* @__PURE__ */ jsxs58("div", { className: "hf-field hf-tree-select", children: [
|
|
3550
|
+
label && /* @__PURE__ */ jsx65("span", { className: "hf-field__label", children: label }),
|
|
3551
|
+
/* @__PURE__ */ jsxs58("button", { type: "button", className: "hf-picker-trigger", "aria-expanded": open, onClick: () => setOpen(!open), children: [
|
|
3552
|
+
/* @__PURE__ */ jsx65("span", { children: all.find((item) => item.node.key === value)?.node.label ?? placeholder }),
|
|
3553
|
+
/* @__PURE__ */ jsx65(Icon, { className: "hf-picker-trigger__chevron", name: "chevron-down", size: 16 })
|
|
3277
3554
|
] }),
|
|
3278
|
-
open && /* @__PURE__ */
|
|
3555
|
+
open && /* @__PURE__ */ jsx65("div", { role: "listbox", children: all.map(({ node, depth }) => /* @__PURE__ */ jsx65("button", { type: "button", role: "option", "aria-selected": node.key === value, disabled: node.disabled, style: { paddingLeft: 12 + depth * 18 }, onClick: () => {
|
|
3279
3556
|
onChange(node.key);
|
|
3280
3557
|
setOpen(false);
|
|
3281
3558
|
}, children: node.label }, node.key)) })
|
|
3282
3559
|
] });
|
|
3283
3560
|
}
|
|
3284
3561
|
function Transfer({ items, value, onChange, titles = ["\u53EF\u9009\u9879", "\u5DF2\u9009\u62E9"] }) {
|
|
3285
|
-
const [marked, setMarked] =
|
|
3286
|
-
const pane = (selected) => /* @__PURE__ */
|
|
3287
|
-
/* @__PURE__ */
|
|
3288
|
-
items.filter((item) => value.includes(item.key) === selected).map((item) => /* @__PURE__ */
|
|
3289
|
-
/* @__PURE__ */
|
|
3562
|
+
const [marked, setMarked] = useState34([]);
|
|
3563
|
+
const pane = (selected) => /* @__PURE__ */ jsxs58("section", { children: [
|
|
3564
|
+
/* @__PURE__ */ jsx65("strong", { children: titles[selected ? 1 : 0] }),
|
|
3565
|
+
items.filter((item) => value.includes(item.key) === selected).map((item) => /* @__PURE__ */ jsxs58("label", { children: [
|
|
3566
|
+
/* @__PURE__ */ jsx65("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]) }),
|
|
3290
3567
|
item.label
|
|
3291
3568
|
] }, item.key))
|
|
3292
3569
|
] });
|
|
3293
|
-
return /* @__PURE__ */
|
|
3570
|
+
return /* @__PURE__ */ jsxs58("div", { className: "hf-transfer", children: [
|
|
3294
3571
|
pane(false),
|
|
3295
|
-
/* @__PURE__ */
|
|
3296
|
-
/* @__PURE__ */
|
|
3572
|
+
/* @__PURE__ */ jsxs58("div", { children: [
|
|
3573
|
+
/* @__PURE__ */ jsx65("button", { type: "button", "aria-label": "\u79FB\u81F3\u5DF2\u9009\u62E9", onClick: () => {
|
|
3297
3574
|
onChange([.../* @__PURE__ */ new Set([...value, ...marked])]);
|
|
3298
3575
|
setMarked([]);
|
|
3299
3576
|
}, children: "\u2192" }),
|
|
3300
|
-
/* @__PURE__ */
|
|
3577
|
+
/* @__PURE__ */ jsx65("button", { type: "button", "aria-label": "\u79FB\u56DE\u53EF\u9009\u9879", onClick: () => {
|
|
3301
3578
|
onChange(value.filter((key) => !marked.includes(key)));
|
|
3302
3579
|
setMarked([]);
|
|
3303
3580
|
}, children: "\u2190" })
|
|
@@ -3306,54 +3583,54 @@ function Transfer({ items, value, onChange, titles = ["\u53EF\u9009\u9879", "\u5
|
|
|
3306
3583
|
] });
|
|
3307
3584
|
}
|
|
3308
3585
|
function DateRangePicker({ label, value, onChange, min, max }) {
|
|
3309
|
-
return /* @__PURE__ */
|
|
3310
|
-
label && /* @__PURE__ */
|
|
3311
|
-
/* @__PURE__ */
|
|
3312
|
-
/* @__PURE__ */
|
|
3313
|
-
/* @__PURE__ */
|
|
3314
|
-
/* @__PURE__ */
|
|
3586
|
+
return /* @__PURE__ */ jsxs58("div", { className: "hf-field hf-date-range", children: [
|
|
3587
|
+
label && /* @__PURE__ */ jsx65("span", { className: "hf-field__label", children: label }),
|
|
3588
|
+
/* @__PURE__ */ jsxs58("div", { children: [
|
|
3589
|
+
/* @__PURE__ */ jsx65("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]]) }),
|
|
3590
|
+
/* @__PURE__ */ jsx65("span", { children: "\u81F3" }),
|
|
3591
|
+
/* @__PURE__ */ jsx65("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]) })
|
|
3315
3592
|
] })
|
|
3316
3593
|
] });
|
|
3317
3594
|
}
|
|
3318
3595
|
function SearchInput({ onSearch, loading, clearable = true, ...props }) {
|
|
3319
|
-
const [value, setValue] =
|
|
3320
|
-
return /* @__PURE__ */
|
|
3596
|
+
const [value, setValue] = useState34(String(props.defaultValue ?? props.value ?? ""));
|
|
3597
|
+
return /* @__PURE__ */ jsxs58("form", { className: "hf-search-input", role: "search", onSubmit: (event) => {
|
|
3321
3598
|
event.preventDefault();
|
|
3322
3599
|
onSearch(value);
|
|
3323
3600
|
}, children: [
|
|
3324
|
-
/* @__PURE__ */
|
|
3325
|
-
/* @__PURE__ */
|
|
3601
|
+
/* @__PURE__ */ jsx65("span", { "aria-hidden": "true", children: "\u2315" }),
|
|
3602
|
+
/* @__PURE__ */ jsx65("input", { ...props, value, onChange: (event) => {
|
|
3326
3603
|
setValue(event.target.value);
|
|
3327
3604
|
props.onChange?.(event);
|
|
3328
3605
|
} }),
|
|
3329
|
-
clearable && value && /* @__PURE__ */
|
|
3330
|
-
/* @__PURE__ */
|
|
3606
|
+
clearable && value && /* @__PURE__ */ jsx65("button", { type: "button", "aria-label": "\u6E05\u9664\u641C\u7D22", onClick: () => setValue(""), children: /* @__PURE__ */ jsx65(Icon, { name: "close", size: 14 }) }),
|
|
3607
|
+
/* @__PURE__ */ jsx65("button", { type: "submit", disabled: loading, children: loading ? "\u641C\u7D22\u4E2D" : "\u641C\u7D22" })
|
|
3331
3608
|
] });
|
|
3332
3609
|
}
|
|
3333
3610
|
|
|
3334
3611
|
// src/feedback/Drawer.tsx
|
|
3335
3612
|
import { useId as useId22 } from "react";
|
|
3336
3613
|
import { createPortal as createPortal5 } from "react-dom";
|
|
3337
|
-
import { jsx as
|
|
3614
|
+
import { jsx as jsx66, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
3338
3615
|
function Drawer({ open, title, children, onClose, footer, side = "right", size = "md" }) {
|
|
3339
3616
|
const titleId = useId22();
|
|
3340
3617
|
const drawerRef = useDismissibleLayer(open, onClose, true);
|
|
3341
3618
|
if (!open) return null;
|
|
3342
|
-
return createPortal5(/* @__PURE__ */
|
|
3343
|
-
/* @__PURE__ */
|
|
3344
|
-
/* @__PURE__ */
|
|
3345
|
-
/* @__PURE__ */
|
|
3619
|
+
return createPortal5(/* @__PURE__ */ jsx66("div", { className: "hf-drawer-backdrop", onMouseDown: (event) => event.target === event.currentTarget && onClose(), children: /* @__PURE__ */ jsxs59("div", { ref: drawerRef, className: `hf-drawer hf-drawer--${side} hf-drawer--${size}`, role: "dialog", "aria-modal": "true", "aria-labelledby": titleId, tabIndex: -1, children: [
|
|
3620
|
+
/* @__PURE__ */ jsxs59("header", { children: [
|
|
3621
|
+
/* @__PURE__ */ jsx66("h2", { id: titleId, children: title }),
|
|
3622
|
+
/* @__PURE__ */ jsx66(Button, { variant: "quiet", size: "sm", iconOnly: true, leadingIcon: /* @__PURE__ */ jsx66(Icon, { name: "close", size: 16 }), onClick: onClose, "aria-label": "\u5173\u95ED\u62BD\u5C49" })
|
|
3346
3623
|
] }),
|
|
3347
|
-
/* @__PURE__ */
|
|
3348
|
-
footer && /* @__PURE__ */
|
|
3624
|
+
/* @__PURE__ */ jsx66("div", { className: "hf-drawer__body", children }),
|
|
3625
|
+
footer && /* @__PURE__ */ jsx66("footer", { children: footer })
|
|
3349
3626
|
] }) }), document.body);
|
|
3350
3627
|
}
|
|
3351
3628
|
|
|
3352
3629
|
// src/feedback/Popover.tsx
|
|
3353
|
-
import { cloneElement as cloneElement2, isValidElement, useId as useId23, useState as
|
|
3354
|
-
import { jsx as
|
|
3630
|
+
import { cloneElement as cloneElement2, isValidElement, useId as useId23, useState as useState35 } from "react";
|
|
3631
|
+
import { jsx as jsx67, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
3355
3632
|
function Popover({ trigger, children, open, defaultOpen = false, onOpenChange, placement = "bottom", label = "\u66F4\u591A\u5185\u5BB9" }) {
|
|
3356
|
-
const [innerOpen, setInnerOpen] =
|
|
3633
|
+
const [innerOpen, setInnerOpen] = useState35(defaultOpen);
|
|
3357
3634
|
const controlled = open !== void 0;
|
|
3358
3635
|
const visible = controlled ? open : innerOpen;
|
|
3359
3636
|
const contentId = useId23();
|
|
@@ -3363,51 +3640,51 @@ function Popover({ trigger, children, open, defaultOpen = false, onOpenChange, p
|
|
|
3363
3640
|
};
|
|
3364
3641
|
const rootRef = useDismissibleLayer(visible, () => update(false));
|
|
3365
3642
|
const triggerProps = { "aria-expanded": visible, "aria-controls": visible ? contentId : void 0, "aria-haspopup": "dialog", onClick: () => update(!visible) };
|
|
3366
|
-
return /* @__PURE__ */
|
|
3643
|
+
return /* @__PURE__ */ jsxs60("span", { className: "hf-popover", ref: rootRef, children: [
|
|
3367
3644
|
isValidElement(trigger) && cloneElement2(trigger, triggerProps),
|
|
3368
|
-
visible && /* @__PURE__ */
|
|
3645
|
+
visible && /* @__PURE__ */ jsx67("span", { id: contentId, role: "dialog", "aria-label": label, className: `hf-popover__content hf-popover__content--${placement}`, children })
|
|
3369
3646
|
] });
|
|
3370
3647
|
}
|
|
3371
3648
|
|
|
3372
3649
|
// src/feedback/Status.tsx
|
|
3373
|
-
import { cloneElement as cloneElement3, useId as useId24, useState as
|
|
3374
|
-
import { jsx as
|
|
3650
|
+
import { cloneElement as cloneElement3, useId as useId24, useState as useState36 } from "react";
|
|
3651
|
+
import { jsx as jsx68, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
3375
3652
|
function Tooltip({ content, children, placement = "top" }) {
|
|
3376
|
-
const [open, setOpen] =
|
|
3653
|
+
const [open, setOpen] = useState36(false);
|
|
3377
3654
|
const id = useId24();
|
|
3378
3655
|
const trigger = cloneElement3(children, { "aria-describedby": open ? id : void 0 });
|
|
3379
|
-
return /* @__PURE__ */
|
|
3656
|
+
return /* @__PURE__ */ jsxs61("span", { className: "hf-tooltip", onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false), onFocus: () => setOpen(true), onBlur: () => setOpen(false), children: [
|
|
3380
3657
|
trigger,
|
|
3381
|
-
open && /* @__PURE__ */
|
|
3658
|
+
open && /* @__PURE__ */ jsx68("span", { id, role: "tooltip", className: `hf-tooltip__bubble hf-tooltip__bubble--${placement}`, children: content })
|
|
3382
3659
|
] });
|
|
3383
3660
|
}
|
|
3384
3661
|
function Alert({ tone = "info", title, children, onClose, action }) {
|
|
3385
3662
|
const icon = { info: "info", success: "check", warning: "warning", danger: "error" };
|
|
3386
|
-
return /* @__PURE__ */
|
|
3387
|
-
/* @__PURE__ */
|
|
3388
|
-
/* @__PURE__ */
|
|
3389
|
-
/* @__PURE__ */
|
|
3390
|
-
children && /* @__PURE__ */
|
|
3391
|
-
action && /* @__PURE__ */
|
|
3663
|
+
return /* @__PURE__ */ jsxs61("div", { className: `hf-alert hf-alert--${tone}`, role: tone === "danger" ? "alert" : "status", children: [
|
|
3664
|
+
/* @__PURE__ */ jsx68(Icon, { name: icon[tone] }),
|
|
3665
|
+
/* @__PURE__ */ jsxs61("div", { children: [
|
|
3666
|
+
/* @__PURE__ */ jsx68("strong", { children: title }),
|
|
3667
|
+
children && /* @__PURE__ */ jsx68("div", { children }),
|
|
3668
|
+
action && /* @__PURE__ */ jsx68("div", { className: "hf-alert__action", children: action })
|
|
3392
3669
|
] }),
|
|
3393
|
-
onClose && /* @__PURE__ */
|
|
3670
|
+
onClose && /* @__PURE__ */ jsx68("button", { type: "button", onClick: onClose, "aria-label": "\u5173\u95ED\u63D0\u793A", children: /* @__PURE__ */ jsx68(Icon, { name: "close", size: 16 }) })
|
|
3394
3671
|
] });
|
|
3395
3672
|
}
|
|
3396
3673
|
|
|
3397
3674
|
// src/feedback/Essentials.tsx
|
|
3398
|
-
import { cloneElement as cloneElement4, isValidElement as isValidElement2, useState as
|
|
3399
|
-
import { jsx as
|
|
3675
|
+
import { cloneElement as cloneElement4, isValidElement as isValidElement2, useState as useState37 } from "react";
|
|
3676
|
+
import { jsx as jsx69, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
3400
3677
|
function Popconfirm({ trigger, title, description, confirmText = "\u786E\u8BA4", cancelText = "\u53D6\u6D88", tone = "primary", onConfirm }) {
|
|
3401
|
-
const [open, setOpen] =
|
|
3678
|
+
const [open, setOpen] = useState37(false);
|
|
3402
3679
|
const root = useDismissibleLayer(open, () => setOpen(false), { autoFocus: false });
|
|
3403
|
-
return /* @__PURE__ */
|
|
3680
|
+
return /* @__PURE__ */ jsxs62("span", { className: "hf-popconfirm", ref: root, children: [
|
|
3404
3681
|
isValidElement2(trigger) && cloneElement4(trigger, { onClick: () => setOpen(true), "aria-expanded": open }),
|
|
3405
|
-
open && /* @__PURE__ */
|
|
3406
|
-
/* @__PURE__ */
|
|
3407
|
-
description && /* @__PURE__ */
|
|
3408
|
-
/* @__PURE__ */
|
|
3409
|
-
/* @__PURE__ */
|
|
3410
|
-
/* @__PURE__ */
|
|
3682
|
+
open && /* @__PURE__ */ jsxs62("div", { role: "alertdialog", "aria-modal": "false", className: "hf-popconfirm__panel", children: [
|
|
3683
|
+
/* @__PURE__ */ jsx69("strong", { children: title }),
|
|
3684
|
+
description && /* @__PURE__ */ jsx69("p", { children: description }),
|
|
3685
|
+
/* @__PURE__ */ jsxs62("div", { children: [
|
|
3686
|
+
/* @__PURE__ */ jsx69(Button, { size: "sm", variant: "quiet", onClick: () => setOpen(false), children: cancelText }),
|
|
3687
|
+
/* @__PURE__ */ jsx69(Button, { size: "sm", variant: tone === "danger" ? "danger" : "primary", onClick: () => {
|
|
3411
3688
|
onConfirm();
|
|
3412
3689
|
setOpen(false);
|
|
3413
3690
|
}, children: confirmText })
|
|
@@ -3417,82 +3694,82 @@ function Popconfirm({ trigger, title, description, confirmText = "\u786E\u8BA4",
|
|
|
3417
3694
|
}
|
|
3418
3695
|
function Notification({ title, children, tone = "info", time, unread, action, onClose }) {
|
|
3419
3696
|
const icons = { info: "info", success: "check", warning: "warning", danger: "error" };
|
|
3420
|
-
return /* @__PURE__ */
|
|
3421
|
-
/* @__PURE__ */
|
|
3422
|
-
/* @__PURE__ */
|
|
3423
|
-
/* @__PURE__ */
|
|
3424
|
-
/* @__PURE__ */
|
|
3425
|
-
time && /* @__PURE__ */
|
|
3697
|
+
return /* @__PURE__ */ jsxs62("article", { className: `hf-notification hf-notification--${tone}${unread ? " is-unread" : ""}`, children: [
|
|
3698
|
+
/* @__PURE__ */ jsx69("span", { className: "hf-notification__icon", children: /* @__PURE__ */ jsx69(Icon, { name: icons[tone], size: 18 }) }),
|
|
3699
|
+
/* @__PURE__ */ jsxs62("div", { children: [
|
|
3700
|
+
/* @__PURE__ */ jsxs62("header", { children: [
|
|
3701
|
+
/* @__PURE__ */ jsx69("strong", { children: title }),
|
|
3702
|
+
time && /* @__PURE__ */ jsx69("time", { children: time })
|
|
3426
3703
|
] }),
|
|
3427
|
-
children && /* @__PURE__ */
|
|
3428
|
-
action && /* @__PURE__ */
|
|
3704
|
+
children && /* @__PURE__ */ jsx69("p", { children }),
|
|
3705
|
+
action && /* @__PURE__ */ jsx69("div", { className: "hf-notification__action", children: action })
|
|
3429
3706
|
] }),
|
|
3430
|
-
onClose && /* @__PURE__ */
|
|
3707
|
+
onClose && /* @__PURE__ */ jsx69("button", { type: "button", "aria-label": "\u5173\u95ED\u901A\u77E5", onClick: onClose, children: /* @__PURE__ */ jsx69(Icon, { name: "close", size: 15 }) })
|
|
3431
3708
|
] });
|
|
3432
3709
|
}
|
|
3433
3710
|
function Result({ status = "info", title, description, actions, extra }) {
|
|
3434
3711
|
const icon = status === "success" ? "\u2713" : status === "error" ? "\xD7" : status === "warning" ? "!" : status === "info" ? "i" : status;
|
|
3435
|
-
return /* @__PURE__ */
|
|
3436
|
-
/* @__PURE__ */
|
|
3437
|
-
/* @__PURE__ */
|
|
3438
|
-
description && /* @__PURE__ */
|
|
3439
|
-
actions && /* @__PURE__ */
|
|
3440
|
-
extra && /* @__PURE__ */
|
|
3712
|
+
return /* @__PURE__ */ jsxs62("section", { className: `hf-result hf-result--${status}`, children: [
|
|
3713
|
+
/* @__PURE__ */ jsx69("span", { className: "hf-result__icon", "aria-hidden": "true", children: icon }),
|
|
3714
|
+
/* @__PURE__ */ jsx69("h2", { children: title }),
|
|
3715
|
+
description && /* @__PURE__ */ jsx69("p", { children: description }),
|
|
3716
|
+
actions && /* @__PURE__ */ jsx69("div", { className: "hf-result__actions", children: actions }),
|
|
3717
|
+
extra && /* @__PURE__ */ jsx69("div", { className: "hf-result__extra", children: extra })
|
|
3441
3718
|
] });
|
|
3442
3719
|
}
|
|
3443
3720
|
|
|
3444
3721
|
// src/data-display/DataDisplay.tsx
|
|
3445
|
-
import { Fragment as Fragment8, jsx as
|
|
3722
|
+
import { Fragment as Fragment8, jsx as jsx70, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
3446
3723
|
function StatisticCard({ label, value, trend, icon, tone = "blue", className = "", ...props }) {
|
|
3447
|
-
return /* @__PURE__ */
|
|
3448
|
-
/* @__PURE__ */
|
|
3449
|
-
/* @__PURE__ */
|
|
3450
|
-
icon && /* @__PURE__ */
|
|
3724
|
+
return /* @__PURE__ */ jsxs63("article", { className: `hf-stat hf-stat--${tone} ${className}`.trim(), ...props, children: [
|
|
3725
|
+
/* @__PURE__ */ jsxs63("div", { className: "hf-stat__top", children: [
|
|
3726
|
+
/* @__PURE__ */ jsx70("span", { children: label }),
|
|
3727
|
+
icon && /* @__PURE__ */ jsx70("i", { children: icon })
|
|
3451
3728
|
] }),
|
|
3452
|
-
/* @__PURE__ */
|
|
3453
|
-
trend && /* @__PURE__ */
|
|
3454
|
-
/* @__PURE__ */
|
|
3729
|
+
/* @__PURE__ */ jsx70("strong", { children: value }),
|
|
3730
|
+
trend && /* @__PURE__ */ jsx70("small", { children: trend }),
|
|
3731
|
+
/* @__PURE__ */ jsx70("span", { className: "hf-stat__glow", "aria-hidden": "true" })
|
|
3455
3732
|
] });
|
|
3456
3733
|
}
|
|
3457
3734
|
var Stat = StatisticCard;
|
|
3458
3735
|
function Progress({ value, max = 100, label, showValue = true, size = "md", tone = "primary", className = "", ...props }) {
|
|
3459
3736
|
const percent = Math.min(100, Math.max(0, max ? value / max * 100 : 0));
|
|
3460
|
-
return /* @__PURE__ */
|
|
3461
|
-
(label || showValue) && /* @__PURE__ */
|
|
3462
|
-
/* @__PURE__ */
|
|
3463
|
-
showValue && /* @__PURE__ */
|
|
3737
|
+
return /* @__PURE__ */ jsxs63("div", { className: `hf-progress hf-progress--${size} hf-progress--${tone} ${className}`.trim(), ...props, children: [
|
|
3738
|
+
(label || showValue) && /* @__PURE__ */ jsxs63("div", { className: "hf-progress__meta", children: [
|
|
3739
|
+
/* @__PURE__ */ jsx70("span", { children: label }),
|
|
3740
|
+
showValue && /* @__PURE__ */ jsxs63("strong", { children: [
|
|
3464
3741
|
Math.round(percent),
|
|
3465
3742
|
"%"
|
|
3466
3743
|
] })
|
|
3467
3744
|
] }),
|
|
3468
|
-
/* @__PURE__ */
|
|
3745
|
+
/* @__PURE__ */ jsx70("div", { className: "hf-progress__track", role: "progressbar", "aria-valuemin": 0, "aria-valuemax": max, "aria-valuenow": value, children: /* @__PURE__ */ jsx70("span", { style: { "--hf-progress": `${percent}%` } }) })
|
|
3469
3746
|
] });
|
|
3470
3747
|
}
|
|
3471
3748
|
function CircularProgress({ value, max = 100, label, size = 92, thickness = 8, className = "", ...props }) {
|
|
3472
3749
|
const percent = Math.min(100, Math.max(0, max ? value / max * 100 : 0));
|
|
3473
|
-
return /* @__PURE__ */
|
|
3474
|
-
/* @__PURE__ */
|
|
3750
|
+
return /* @__PURE__ */ jsx70("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__ */ jsxs63("span", { children: [
|
|
3751
|
+
/* @__PURE__ */ jsxs63("strong", { children: [
|
|
3475
3752
|
Math.round(percent),
|
|
3476
3753
|
"%"
|
|
3477
3754
|
] }),
|
|
3478
|
-
label && /* @__PURE__ */
|
|
3755
|
+
label && /* @__PURE__ */ jsx70("small", { children: label })
|
|
3479
3756
|
] }) });
|
|
3480
3757
|
}
|
|
3481
3758
|
function StepProgress({ steps, current, className = "", ...props }) {
|
|
3482
|
-
return /* @__PURE__ */
|
|
3483
|
-
/* @__PURE__ */
|
|
3484
|
-
/* @__PURE__ */
|
|
3759
|
+
return /* @__PURE__ */ jsx70("ol", { className: `hf-step-progress ${className}`.trim(), ...props, children: steps.map((step, index) => /* @__PURE__ */ jsxs63("li", { className: index < current ? "is-complete" : index === current ? "is-current" : "", children: [
|
|
3760
|
+
/* @__PURE__ */ jsx70("span", { children: index < current ? "\u2713" : index + 1 }),
|
|
3761
|
+
/* @__PURE__ */ jsx70("small", { children: step })
|
|
3485
3762
|
] }, index)) });
|
|
3486
3763
|
}
|
|
3487
3764
|
function ActivityIndicator({ variant = "spinner", label = "\u6B63\u5728\u52A0\u8F7D", size = "md", className = "", ...props }) {
|
|
3488
|
-
return /* @__PURE__ */
|
|
3489
|
-
variant === "dots" && /* @__PURE__ */
|
|
3490
|
-
/* @__PURE__ */
|
|
3491
|
-
/* @__PURE__ */
|
|
3492
|
-
/* @__PURE__ */
|
|
3765
|
+
return /* @__PURE__ */ jsxs63("span", { className: `hf-activity hf-activity--${variant} hf-activity--${size} ${className}`.trim(), role: "status", "aria-label": label, ...props, children: [
|
|
3766
|
+
variant === "dots" && /* @__PURE__ */ jsxs63(Fragment8, { children: [
|
|
3767
|
+
/* @__PURE__ */ jsx70("i", {}),
|
|
3768
|
+
/* @__PURE__ */ jsx70("i", {}),
|
|
3769
|
+
/* @__PURE__ */ jsx70("i", {})
|
|
3493
3770
|
] }),
|
|
3494
|
-
variant === "wave" && Array.from({ length: 5 }, (_, index) => /* @__PURE__ */
|
|
3495
|
-
variant === "radar" && /* @__PURE__ */
|
|
3771
|
+
variant === "wave" && Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx70("i", {}, index)),
|
|
3772
|
+
variant === "radar" && /* @__PURE__ */ jsx70("i", {})
|
|
3496
3773
|
] });
|
|
3497
3774
|
}
|
|
3498
3775
|
function Sparkline({ data, width = 160, height = 48, label = "\u8D8B\u52BF\u56FE", filled = true, ...props }) {
|
|
@@ -3501,27 +3778,27 @@ function Sparkline({ data, width = 160, height = 48, label = "\u8D8B\u52BF\u56FE
|
|
|
3501
3778
|
const range = max - min || 1;
|
|
3502
3779
|
const points = data.map((value, index) => `${data.length === 1 ? width / 2 : index / (data.length - 1) * width},${height - ((value - min) / range * (height - 8) + 4)}`).join(" ");
|
|
3503
3780
|
const area = `0,${height} ${points} ${width},${height}`;
|
|
3504
|
-
return /* @__PURE__ */
|
|
3505
|
-
filled && /* @__PURE__ */
|
|
3506
|
-
/* @__PURE__ */
|
|
3781
|
+
return /* @__PURE__ */ jsxs63("svg", { className: "hf-sparkline", viewBox: `0 0 ${width} ${height}`, role: "img", "aria-label": label, ...props, children: [
|
|
3782
|
+
filled && /* @__PURE__ */ jsx70("polygon", { points: area, className: "hf-sparkline__area" }),
|
|
3783
|
+
/* @__PURE__ */ jsx70("polyline", { points, className: "hf-sparkline__line" })
|
|
3507
3784
|
] });
|
|
3508
3785
|
}
|
|
3509
3786
|
|
|
3510
3787
|
// src/data-display/Collections.tsx
|
|
3511
|
-
import { jsx as
|
|
3788
|
+
import { jsx as jsx71, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
3512
3789
|
function Table({ columns, data, rowKey, caption, empty = "\u6682\u65E0\u6570\u636E", striped, onRowClick, className = "", ...props }) {
|
|
3513
3790
|
const keyOf = (item, index) => typeof rowKey === "function" ? rowKey(item, index) : String(item[rowKey]);
|
|
3514
|
-
return /* @__PURE__ */
|
|
3515
|
-
caption && /* @__PURE__ */
|
|
3516
|
-
/* @__PURE__ */
|
|
3517
|
-
/* @__PURE__ */
|
|
3518
|
-
data.map((item, index) => /* @__PURE__ */
|
|
3791
|
+
return /* @__PURE__ */ jsx71("div", { className: `hf-table-wrap ${className}`, ...props, children: /* @__PURE__ */ jsxs64("table", { className: `hf-table${striped ? " hf-table--striped" : ""}`, children: [
|
|
3792
|
+
caption && /* @__PURE__ */ jsx71("caption", { children: caption }),
|
|
3793
|
+
/* @__PURE__ */ jsx71("thead", { children: /* @__PURE__ */ jsx71("tr", { children: columns.map((column) => /* @__PURE__ */ jsx71("th", { style: { textAlign: column.align, width: column.width }, children: column.header }, column.key)) }) }),
|
|
3794
|
+
/* @__PURE__ */ jsxs64("tbody", { children: [
|
|
3795
|
+
data.map((item, index) => /* @__PURE__ */ jsx71("tr", { className: onRowClick ? "is-clickable" : "", onClick: () => onRowClick?.(item, index), tabIndex: onRowClick ? 0 : void 0, onKeyDown: (event) => {
|
|
3519
3796
|
if (onRowClick && (event.key === "Enter" || event.key === " ")) {
|
|
3520
3797
|
event.preventDefault();
|
|
3521
3798
|
onRowClick(item, index);
|
|
3522
3799
|
}
|
|
3523
|
-
}, children: columns.map((column) => /* @__PURE__ */
|
|
3524
|
-
!data.length && /* @__PURE__ */
|
|
3800
|
+
}, children: columns.map((column) => /* @__PURE__ */ jsx71("td", { style: { textAlign: column.align }, children: column.render ? column.render(item, index) : String(item[column.key] ?? "") }, column.key)) }, keyOf(item, index))),
|
|
3801
|
+
!data.length && /* @__PURE__ */ jsx71("tr", { children: /* @__PURE__ */ jsx71("td", { className: "hf-table__empty", colSpan: columns.length, children: empty }) })
|
|
3525
3802
|
] })
|
|
3526
3803
|
] }) });
|
|
3527
3804
|
}
|
|
@@ -3534,71 +3811,71 @@ function Pagination({ page, total, pageSize = 10, siblingCount = 1, onChange, cl
|
|
|
3534
3811
|
if (index && value - visible[index - 1] > 1) parts.push("ellipsis");
|
|
3535
3812
|
parts.push(value);
|
|
3536
3813
|
});
|
|
3537
|
-
return /* @__PURE__ */
|
|
3538
|
-
/* @__PURE__ */
|
|
3539
|
-
parts.map((part, index) => part === "ellipsis" ? /* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3814
|
+
return /* @__PURE__ */ jsxs64("nav", { className: `hf-pagination ${className}`, "aria-label": "\u5206\u9875", ...props, children: [
|
|
3815
|
+
/* @__PURE__ */ jsx71("button", { disabled: current === 1, onClick: () => onChange(current - 1), "aria-label": "\u4E0A\u4E00\u9875", children: /* @__PURE__ */ jsx71(Icon, { name: "chevron-down", size: 16, className: "hf-pagination__prev" }) }),
|
|
3816
|
+
parts.map((part, index) => part === "ellipsis" ? /* @__PURE__ */ jsx71("span", { "aria-hidden": "true", children: "\u2026" }, `e-${index}`) : /* @__PURE__ */ jsx71("button", { className: part === current ? "is-active" : "", "aria-current": part === current ? "page" : void 0, onClick: () => onChange(part), children: part }, part)),
|
|
3817
|
+
/* @__PURE__ */ jsx71("button", { disabled: current === count, onClick: () => onChange(current + 1), "aria-label": "\u4E0B\u4E00\u9875", children: /* @__PURE__ */ jsx71(Icon, { name: "chevron-down", size: 16, className: "hf-pagination__next" }) })
|
|
3541
3818
|
] });
|
|
3542
3819
|
}
|
|
3543
3820
|
function List({ items, divided = true, className = "", ...props }) {
|
|
3544
|
-
return /* @__PURE__ */
|
|
3545
|
-
item.leading && /* @__PURE__ */
|
|
3546
|
-
/* @__PURE__ */
|
|
3547
|
-
/* @__PURE__ */
|
|
3548
|
-
item.description && /* @__PURE__ */
|
|
3821
|
+
return /* @__PURE__ */ jsx71("ul", { className: `hf-list${divided ? " hf-list--divided" : ""} ${className}`, ...props, children: items.map((item) => /* @__PURE__ */ jsxs64("li", { children: [
|
|
3822
|
+
item.leading && /* @__PURE__ */ jsx71("span", { className: "hf-list__leading", children: item.leading }),
|
|
3823
|
+
/* @__PURE__ */ jsxs64("div", { children: [
|
|
3824
|
+
/* @__PURE__ */ jsx71("strong", { children: item.title }),
|
|
3825
|
+
item.description && /* @__PURE__ */ jsx71("small", { children: item.description })
|
|
3549
3826
|
] }),
|
|
3550
|
-
item.trailing && /* @__PURE__ */
|
|
3827
|
+
item.trailing && /* @__PURE__ */ jsx71("span", { className: "hf-list__trailing", children: item.trailing })
|
|
3551
3828
|
] }, item.key)) });
|
|
3552
3829
|
}
|
|
3553
3830
|
function Descriptions({ items, columns = 2, bordered, className = "", ...props }) {
|
|
3554
|
-
return /* @__PURE__ */
|
|
3555
|
-
/* @__PURE__ */
|
|
3556
|
-
/* @__PURE__ */
|
|
3831
|
+
return /* @__PURE__ */ jsx71("dl", { className: `hf-descriptions hf-descriptions--${columns}${bordered ? " hf-descriptions--bordered" : ""} ${className}`, ...props, children: items.map((item) => /* @__PURE__ */ jsxs64("div", { style: { gridColumn: `span ${Math.min(item.span ?? 1, columns)}` }, children: [
|
|
3832
|
+
/* @__PURE__ */ jsx71("dt", { children: item.label }),
|
|
3833
|
+
/* @__PURE__ */ jsx71("dd", { children: item.value })
|
|
3557
3834
|
] }, item.key)) });
|
|
3558
3835
|
}
|
|
3559
3836
|
|
|
3560
3837
|
// src/data-display/Insight.tsx
|
|
3561
|
-
import { jsx as
|
|
3838
|
+
import { jsx as jsx72, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
3562
3839
|
function Timeline({ items, label = "\u65F6\u95F4\u8F74" }) {
|
|
3563
|
-
return /* @__PURE__ */
|
|
3564
|
-
/* @__PURE__ */
|
|
3565
|
-
/* @__PURE__ */
|
|
3566
|
-
/* @__PURE__ */
|
|
3567
|
-
item.description && /* @__PURE__ */
|
|
3840
|
+
return /* @__PURE__ */ jsx72("ol", { className: "hf-timeline", "aria-label": label, children: items.map((item) => /* @__PURE__ */ jsxs65("li", { className: `hf-timeline--${item.status ?? "upcoming"}`, children: [
|
|
3841
|
+
/* @__PURE__ */ jsx72("i", { "aria-hidden": "true" }),
|
|
3842
|
+
/* @__PURE__ */ jsxs65("div", { children: [
|
|
3843
|
+
/* @__PURE__ */ jsx72("strong", { children: item.title }),
|
|
3844
|
+
item.description && /* @__PURE__ */ jsx72("p", { children: item.description })
|
|
3568
3845
|
] }),
|
|
3569
|
-
item.time && /* @__PURE__ */
|
|
3846
|
+
item.time && /* @__PURE__ */ jsx72("time", { children: item.time })
|
|
3570
3847
|
] }, item.key)) });
|
|
3571
3848
|
}
|
|
3572
3849
|
function InsightBoard({ summary, trend, detail, heading, filters }) {
|
|
3573
|
-
return /* @__PURE__ */
|
|
3574
|
-
(heading || filters) && /* @__PURE__ */
|
|
3575
|
-
/* @__PURE__ */
|
|
3850
|
+
return /* @__PURE__ */ jsxs65("section", { className: "hf-insight-board", children: [
|
|
3851
|
+
(heading || filters) && /* @__PURE__ */ jsxs65("header", { children: [
|
|
3852
|
+
/* @__PURE__ */ jsx72("div", { children: heading }),
|
|
3576
3853
|
filters
|
|
3577
3854
|
] }),
|
|
3578
|
-
/* @__PURE__ */
|
|
3579
|
-
/* @__PURE__ */
|
|
3580
|
-
/* @__PURE__ */
|
|
3855
|
+
/* @__PURE__ */ jsx72("div", { className: "hf-insight-board__summary", "aria-label": "\u6838\u5FC3\u7ED3\u679C", children: summary }),
|
|
3856
|
+
/* @__PURE__ */ jsx72("div", { className: "hf-insight-board__trend", "aria-label": "\u53D8\u5316\u8D8B\u52BF", children: trend }),
|
|
3857
|
+
/* @__PURE__ */ jsx72("div", { className: "hf-insight-board__detail", "aria-label": "\u660E\u7EC6\u4E0E\u539F\u56E0", children: detail })
|
|
3581
3858
|
] });
|
|
3582
3859
|
}
|
|
3583
3860
|
|
|
3584
3861
|
// src/data-display/EmptyState.tsx
|
|
3585
|
-
import { jsx as
|
|
3862
|
+
import { jsx as jsx73, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
3586
3863
|
function EmptyState({ icon = "inbox", title, description, action, size = "md" }) {
|
|
3587
|
-
return /* @__PURE__ */
|
|
3588
|
-
/* @__PURE__ */
|
|
3589
|
-
/* @__PURE__ */
|
|
3590
|
-
description && /* @__PURE__ */
|
|
3591
|
-
action && /* @__PURE__ */
|
|
3864
|
+
return /* @__PURE__ */ jsxs66("div", { className: `hf-empty hf-empty--${size}`, children: [
|
|
3865
|
+
/* @__PURE__ */ jsx73("span", { className: "hf-empty__icon", children: /* @__PURE__ */ jsx73(Icon, { name: icon, size: size === "sm" ? 22 : 28 }) }),
|
|
3866
|
+
/* @__PURE__ */ jsx73("strong", { children: title }),
|
|
3867
|
+
description && /* @__PURE__ */ jsx73("p", { children: description }),
|
|
3868
|
+
action && /* @__PURE__ */ jsx73("div", { children: action })
|
|
3592
3869
|
] });
|
|
3593
3870
|
}
|
|
3594
3871
|
|
|
3595
3872
|
// src/data-display/DataGrid.tsx
|
|
3596
|
-
import { useMemo as
|
|
3597
|
-
import { jsx as
|
|
3873
|
+
import { useMemo as useMemo8, useState as useState38 } from "react";
|
|
3874
|
+
import { jsx as jsx74, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
3598
3875
|
function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange, empty = "\u6682\u65E0\u6570\u636E", caption }) {
|
|
3599
|
-
const [sort, setSort] =
|
|
3876
|
+
const [sort, setSort] = useState38();
|
|
3600
3877
|
const keyOf = (item) => typeof rowKey === "function" ? rowKey(item) : String(item[rowKey]);
|
|
3601
|
-
const rows =
|
|
3878
|
+
const rows = useMemo8(() => {
|
|
3602
3879
|
if (!sort) return [...data];
|
|
3603
3880
|
const column = columns.find((item) => item.key === sort.key);
|
|
3604
3881
|
if (!column) return [...data];
|
|
@@ -3611,7 +3888,7 @@ function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange,
|
|
|
3611
3888
|
}, [columns, data, sort]);
|
|
3612
3889
|
const all = data.length > 0 && data.every((item) => selectedKeys.includes(keyOf(item)));
|
|
3613
3890
|
const changeAll = () => onSelectionChange?.(all ? [] : data.map(keyOf));
|
|
3614
|
-
return /* @__PURE__ */
|
|
3891
|
+
return /* @__PURE__ */ jsx74("div", { className: "hf-data-grid", onKeyDown: (event) => {
|
|
3615
3892
|
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
3616
3893
|
const controls = [...event.currentTarget.querySelectorAll("button,input")];
|
|
3617
3894
|
const current = controls.indexOf(event.target);
|
|
@@ -3619,95 +3896,258 @@ function DataGrid({ columns, data, rowKey, selectedKeys = [], onSelectionChange,
|
|
|
3619
3896
|
event.preventDefault();
|
|
3620
3897
|
const direction = event.key === "ArrowLeft" || event.key === "ArrowUp" ? -1 : 1;
|
|
3621
3898
|
controls[(current + direction + controls.length) % controls.length]?.focus();
|
|
3622
|
-
}, children: /* @__PURE__ */
|
|
3623
|
-
caption && /* @__PURE__ */
|
|
3624
|
-
/* @__PURE__ */
|
|
3625
|
-
onSelectionChange && /* @__PURE__ */
|
|
3626
|
-
columns.map((column) => /* @__PURE__ */
|
|
3899
|
+
}, children: /* @__PURE__ */ jsxs67("table", { children: [
|
|
3900
|
+
caption && /* @__PURE__ */ jsx74("caption", { children: caption }),
|
|
3901
|
+
/* @__PURE__ */ jsx74("thead", { children: /* @__PURE__ */ jsxs67("tr", { children: [
|
|
3902
|
+
onSelectionChange && /* @__PURE__ */ jsx74("th", { className: "hf-data-grid__check", children: /* @__PURE__ */ jsx74("input", { type: "checkbox", "aria-label": "\u9009\u62E9\u5168\u90E8", checked: all, onChange: changeAll }) }),
|
|
3903
|
+
columns.map((column) => /* @__PURE__ */ jsx74("th", { style: { width: column.width }, children: column.sortable ? /* @__PURE__ */ jsxs67("button", { type: "button", onClick: () => setSort((current) => ({ key: column.key, direction: current?.key === column.key && current.direction === "asc" ? "desc" : "asc" })), children: [
|
|
3627
3904
|
column.header,
|
|
3628
|
-
/* @__PURE__ */
|
|
3905
|
+
/* @__PURE__ */ jsx74("span", { "aria-hidden": "true", children: sort?.key === column.key ? sort.direction === "asc" ? "\u2191" : "\u2193" : "\u2195" })
|
|
3629
3906
|
] }) : column.header }, column.key))
|
|
3630
3907
|
] }) }),
|
|
3631
|
-
/* @__PURE__ */
|
|
3908
|
+
/* @__PURE__ */ jsxs67("tbody", { children: [
|
|
3632
3909
|
rows.map((item) => {
|
|
3633
3910
|
const key = keyOf(item);
|
|
3634
|
-
return /* @__PURE__ */
|
|
3635
|
-
onSelectionChange && /* @__PURE__ */
|
|
3636
|
-
columns.map((column) => /* @__PURE__ */
|
|
3911
|
+
return /* @__PURE__ */ jsxs67("tr", { className: selectedKeys.includes(key) ? "is-selected" : "", children: [
|
|
3912
|
+
onSelectionChange && /* @__PURE__ */ jsx74("td", { children: /* @__PURE__ */ jsx74("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]) }) }),
|
|
3913
|
+
columns.map((column) => /* @__PURE__ */ jsx74("td", { children: column.render ? column.render(item) : String(item[column.key] ?? "") }, column.key))
|
|
3637
3914
|
] }, key);
|
|
3638
3915
|
}),
|
|
3639
|
-
!rows.length && /* @__PURE__ */
|
|
3916
|
+
!rows.length && /* @__PURE__ */ jsx74("tr", { children: /* @__PURE__ */ jsx74("td", { className: "hf-data-grid__empty", colSpan: columns.length + (onSelectionChange ? 1 : 0), children: empty }) })
|
|
3640
3917
|
] })
|
|
3641
3918
|
] }) });
|
|
3642
3919
|
}
|
|
3643
3920
|
|
|
3644
3921
|
// src/data-display/Tree.tsx
|
|
3645
|
-
import {
|
|
3646
|
-
|
|
3647
|
-
|
|
3648
|
-
|
|
3649
|
-
|
|
3650
|
-
|
|
3922
|
+
import { useId as useId26 } from "react";
|
|
3923
|
+
|
|
3924
|
+
// src/data-display/TreeFileIcon.tsx
|
|
3925
|
+
import { Fragment as Fragment9, jsx as jsx75, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
3926
|
+
function TreeFileIcon({ folder, open }) {
|
|
3927
|
+
return /* @__PURE__ */ jsx75(
|
|
3928
|
+
"svg",
|
|
3929
|
+
{
|
|
3930
|
+
width: "18",
|
|
3931
|
+
height: "18",
|
|
3932
|
+
viewBox: "0 0 24 24",
|
|
3933
|
+
fill: "none",
|
|
3934
|
+
stroke: "currentColor",
|
|
3935
|
+
strokeWidth: "1.6",
|
|
3936
|
+
strokeLinecap: "round",
|
|
3937
|
+
strokeLinejoin: "round",
|
|
3938
|
+
"aria-hidden": "true",
|
|
3939
|
+
children: folder ? /* @__PURE__ */ jsxs68(Fragment9, { children: [
|
|
3940
|
+
/* @__PURE__ */ jsx75("path", { d: "M3 18V6a2 2 0 0 1 2-2h5l2 3h7a2 2 0 0 1 2 2v2" }),
|
|
3941
|
+
/* @__PURE__ */ jsx75("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" })
|
|
3942
|
+
] }) : /* @__PURE__ */ jsxs68(Fragment9, { children: [
|
|
3943
|
+
/* @__PURE__ */ jsx75("path", { d: "M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8Z M14 3v5h5" }),
|
|
3944
|
+
/* @__PURE__ */ jsx75("path", { d: "M9 12h6M9 16h4" })
|
|
3945
|
+
] })
|
|
3946
|
+
}
|
|
3947
|
+
);
|
|
3948
|
+
}
|
|
3949
|
+
|
|
3950
|
+
// src/data-display/useTreeState.ts
|
|
3951
|
+
import { useRef as useRef15, useState as useState39 } from "react";
|
|
3952
|
+
function visibleNodes(nodes, expanded, parent) {
|
|
3953
|
+
const result = [];
|
|
3954
|
+
for (const node of nodes) {
|
|
3955
|
+
result.push({ node, parent });
|
|
3956
|
+
if (node.children && expanded.has(node.key)) result.push(...visibleNodes(node.children, expanded, node.key));
|
|
3957
|
+
}
|
|
3958
|
+
return result;
|
|
3959
|
+
}
|
|
3960
|
+
function useTreeState({ nodes, selectedKey, onSelect, defaultExpandedKeys = [], expandedKeys, onExpand }) {
|
|
3961
|
+
const [internalExpanded, setExpanded] = useState39([...defaultExpandedKeys]);
|
|
3962
|
+
const [focusedKey, setFocusedKey] = useState39();
|
|
3963
|
+
const elements = useRef15(/* @__PURE__ */ new Map());
|
|
3964
|
+
const expanded = new Set(expandedKeys ?? internalExpanded);
|
|
3965
|
+
const visible = visibleNodes(nodes, expanded);
|
|
3966
|
+
const enabled = visible.filter(({ node }) => !node.disabled);
|
|
3967
|
+
const activeKey = enabled.find(({ node }) => node.key === focusedKey)?.node.key ?? enabled.find(({ node }) => node.key === selectedKey)?.node.key ?? enabled[0]?.node.key;
|
|
3968
|
+
function focus(key) {
|
|
3969
|
+
if (key === void 0) return;
|
|
3970
|
+
setFocusedKey(key);
|
|
3971
|
+
elements.current.get(key)?.focus();
|
|
3972
|
+
}
|
|
3973
|
+
function toggle(node) {
|
|
3974
|
+
if (node.disabled || !node.children?.length) return;
|
|
3975
|
+
const next = new Set(expanded);
|
|
3976
|
+
if (next.has(node.key)) next.delete(node.key);
|
|
3977
|
+
else next.add(node.key);
|
|
3978
|
+
if (expandedKeys === void 0) setExpanded([...next]);
|
|
3979
|
+
onExpand?.([...next]);
|
|
3980
|
+
}
|
|
3981
|
+
function onKeyDown(event, node) {
|
|
3982
|
+
if (event.target !== event.currentTarget || node.disabled) return;
|
|
3983
|
+
const index = enabled.findIndex((item) => item.node.key === node.key);
|
|
3651
3984
|
const branch = Boolean(node.children?.length);
|
|
3652
|
-
|
|
3653
|
-
|
|
3654
|
-
|
|
3655
|
-
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
|
|
3659
|
-
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3985
|
+
const open = expanded.has(node.key);
|
|
3986
|
+
const actions = {
|
|
3987
|
+
ArrowDown: () => focus(enabled[Math.min(index + 1, enabled.length - 1)]?.node.key),
|
|
3988
|
+
ArrowUp: () => focus(enabled[Math.max(index - 1, 0)]?.node.key),
|
|
3989
|
+
Home: () => focus(enabled[0]?.node.key),
|
|
3990
|
+
End: () => focus(enabled.at(-1)?.node.key),
|
|
3991
|
+
ArrowRight: () => {
|
|
3992
|
+
if (branch && !open) toggle(node);
|
|
3993
|
+
else if (branch) focus(node.children?.find((child) => !child.disabled)?.key);
|
|
3994
|
+
},
|
|
3995
|
+
ArrowLeft: () => {
|
|
3996
|
+
if (branch && open) toggle(node);
|
|
3997
|
+
else {
|
|
3998
|
+
let parent = visible.find((item) => item.node.key === node.key)?.parent;
|
|
3999
|
+
while (parent !== void 0 && visible.find((item) => item.node.key === parent)?.node.disabled) {
|
|
4000
|
+
parent = visible.find((item) => item.node.key === parent)?.parent;
|
|
4001
|
+
}
|
|
4002
|
+
focus(parent);
|
|
4003
|
+
}
|
|
4004
|
+
},
|
|
4005
|
+
Enter: () => onSelect?.(node.key),
|
|
4006
|
+
" ": () => onSelect?.(node.key)
|
|
4007
|
+
};
|
|
4008
|
+
const action = actions[event.key];
|
|
4009
|
+
if (action) {
|
|
3666
4010
|
event.preventDefault();
|
|
3667
|
-
|
|
3668
|
-
|
|
4011
|
+
event.stopPropagation();
|
|
4012
|
+
action();
|
|
3669
4013
|
}
|
|
3670
|
-
}
|
|
4014
|
+
}
|
|
4015
|
+
return { elements, expanded, activeKey, focus, toggle, onKeyDown, setFocusedKey };
|
|
4016
|
+
}
|
|
4017
|
+
|
|
4018
|
+
// src/data-display/Tree.tsx
|
|
4019
|
+
import { jsx as jsx76, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
4020
|
+
function Tree({
|
|
4021
|
+
nodes,
|
|
4022
|
+
selectedKey,
|
|
4023
|
+
onSelect,
|
|
4024
|
+
defaultExpandedKeys = [],
|
|
4025
|
+
expandedKeys,
|
|
4026
|
+
onExpand,
|
|
4027
|
+
label = "\u6811\u5F62\u5217\u8868",
|
|
4028
|
+
showIcon = false,
|
|
4029
|
+
showLine = true,
|
|
4030
|
+
emptyText = "\u6682\u65E0\u5185\u5BB9"
|
|
4031
|
+
}) {
|
|
4032
|
+
const id = useId26();
|
|
4033
|
+
const { elements, expanded, activeKey, focus, toggle, onKeyDown, setFocusedKey } = useTreeState({
|
|
4034
|
+
nodes,
|
|
4035
|
+
selectedKey,
|
|
4036
|
+
onSelect,
|
|
4037
|
+
defaultExpandedKeys,
|
|
4038
|
+
expandedKeys,
|
|
4039
|
+
onExpand
|
|
4040
|
+
});
|
|
4041
|
+
function render(items, level) {
|
|
4042
|
+
return /* @__PURE__ */ jsx76("ul", { role: level ? "group" : "tree", "aria-label": level ? void 0 : label, children: items.map((node) => {
|
|
4043
|
+
const open = expanded.has(node.key);
|
|
4044
|
+
const branch = Boolean(node.children?.length);
|
|
4045
|
+
const folder = node.children !== void 0;
|
|
4046
|
+
const labelId = `${id}-${encodeURIComponent(node.key)}`;
|
|
4047
|
+
return /* @__PURE__ */ jsxs69(
|
|
4048
|
+
"li",
|
|
4049
|
+
{
|
|
4050
|
+
role: "treeitem",
|
|
4051
|
+
"aria-labelledby": labelId,
|
|
4052
|
+
"aria-level": level + 1,
|
|
4053
|
+
"aria-expanded": branch ? open : void 0,
|
|
4054
|
+
"aria-selected": node.key === selectedKey,
|
|
4055
|
+
"aria-disabled": node.disabled || void 0,
|
|
4056
|
+
tabIndex: !node.disabled && node.key === activeKey ? 0 : -1,
|
|
4057
|
+
ref: (element) => {
|
|
4058
|
+
if (element) elements.current.set(node.key, element);
|
|
4059
|
+
else elements.current.delete(node.key);
|
|
4060
|
+
},
|
|
4061
|
+
onFocus: (event) => {
|
|
4062
|
+
if (event.target === event.currentTarget) setFocusedKey(node.key);
|
|
4063
|
+
},
|
|
4064
|
+
onKeyDown: (event) => onKeyDown(event, node),
|
|
4065
|
+
children: [
|
|
4066
|
+
/* @__PURE__ */ jsxs69(
|
|
4067
|
+
"div",
|
|
4068
|
+
{
|
|
4069
|
+
className: `hf-tree__row${node.key === selectedKey ? " is-selected" : ""}`,
|
|
4070
|
+
style: { "--hf-tree-depth": level },
|
|
4071
|
+
onClick: () => {
|
|
4072
|
+
if (!node.disabled) {
|
|
4073
|
+
focus(node.key);
|
|
4074
|
+
onSelect?.(node.key);
|
|
4075
|
+
}
|
|
4076
|
+
},
|
|
4077
|
+
children: [
|
|
4078
|
+
/* @__PURE__ */ jsx76("span", { className: "hf-tree__guides", "aria-hidden": "true", children: Array.from({ length: level }, (_, depth) => /* @__PURE__ */ jsx76("i", {}, depth)) }),
|
|
4079
|
+
branch ? /* @__PURE__ */ jsx76(
|
|
4080
|
+
"button",
|
|
4081
|
+
{
|
|
4082
|
+
type: "button",
|
|
4083
|
+
className: "hf-tree__toggle",
|
|
4084
|
+
tabIndex: -1,
|
|
4085
|
+
disabled: node.disabled,
|
|
4086
|
+
"aria-label": `${open ? "\u6536\u8D77" : "\u5C55\u5F00"}${typeof node.label === "string" ? node.label : "\u8282\u70B9"}`,
|
|
4087
|
+
onClick: (event) => {
|
|
4088
|
+
event.stopPropagation();
|
|
4089
|
+
focus(node.key);
|
|
4090
|
+
toggle(node);
|
|
4091
|
+
},
|
|
4092
|
+
children: /* @__PURE__ */ jsx76(Icon, { name: "chevron-down", size: 14, className: open ? "is-open" : "" })
|
|
4093
|
+
}
|
|
4094
|
+
) : /* @__PURE__ */ jsx76("span", { className: "hf-tree__spacer", "aria-hidden": "true" }),
|
|
4095
|
+
(node.icon != null || showIcon) && /* @__PURE__ */ jsx76("span", { className: `hf-tree__icon${folder ? " is-folder" : ""}`, "aria-hidden": "true", children: node.icon ?? /* @__PURE__ */ jsx76(TreeFileIcon, { folder, open }) }),
|
|
4096
|
+
/* @__PURE__ */ jsx76("span", { id: labelId, className: "hf-tree__label", title: typeof node.label === "string" ? node.label : void 0, children: node.label })
|
|
4097
|
+
]
|
|
4098
|
+
}
|
|
4099
|
+
),
|
|
4100
|
+
branch && open && render(node.children, level + 1)
|
|
4101
|
+
]
|
|
4102
|
+
},
|
|
4103
|
+
node.key
|
|
4104
|
+
);
|
|
4105
|
+
}) });
|
|
4106
|
+
}
|
|
4107
|
+
return /* @__PURE__ */ jsxs69("div", { className: `hf-tree${showLine ? " hf-tree--lines" : ""}`, children: [
|
|
4108
|
+
render(nodes, 0),
|
|
4109
|
+
!nodes.length && /* @__PURE__ */ jsx76("div", { className: "hf-tree__empty", role: "status", children: emptyText })
|
|
4110
|
+
] });
|
|
3671
4111
|
}
|
|
3672
4112
|
|
|
3673
4113
|
// src/layout/AuthLayout.tsx
|
|
3674
|
-
import { jsx as
|
|
4114
|
+
import { jsx as jsx77, jsxs as jsxs70 } from "react/jsx-runtime";
|
|
3675
4115
|
function AuthLayout({ children, brand, aside, footer, variant = "card", backgroundImage, currentStep = 1, steps = 1 }) {
|
|
3676
4116
|
const style = backgroundImage ? { "--hf-auth-image": `url("${backgroundImage}")` } : void 0;
|
|
3677
|
-
return /* @__PURE__ */
|
|
3678
|
-
brand && /* @__PURE__ */
|
|
3679
|
-
aside && /* @__PURE__ */
|
|
3680
|
-
/* @__PURE__ */
|
|
3681
|
-
variant === "step" && /* @__PURE__ */
|
|
3682
|
-
/* @__PURE__ */
|
|
3683
|
-
footer && /* @__PURE__ */
|
|
4117
|
+
return /* @__PURE__ */ jsxs70("section", { className: `hf-auth hf-auth--${variant}`, style, children: [
|
|
4118
|
+
brand && /* @__PURE__ */ jsx77("header", { className: "hf-auth__brand", children: brand }),
|
|
4119
|
+
aside && /* @__PURE__ */ jsx77("aside", { className: "hf-auth__aside", children: aside }),
|
|
4120
|
+
/* @__PURE__ */ jsxs70("main", { className: "hf-auth__main", children: [
|
|
4121
|
+
variant === "step" && /* @__PURE__ */ jsx77("div", { className: "hf-auth__steps", "aria-label": `\u7B2C ${currentStep} \u6B65\uFF0C\u5171 ${steps} \u6B65`, children: Array.from({ length: steps }, (_, index) => /* @__PURE__ */ jsx77("span", { className: index < currentStep ? "is-active" : "" }, index)) }),
|
|
4122
|
+
/* @__PURE__ */ jsx77("div", { className: "hf-auth__card", children }),
|
|
4123
|
+
footer && /* @__PURE__ */ jsx77("footer", { children: footer })
|
|
3684
4124
|
] })
|
|
3685
4125
|
] });
|
|
3686
4126
|
}
|
|
3687
4127
|
|
|
3688
4128
|
// src/layout/Hero.tsx
|
|
3689
|
-
import { jsx as
|
|
4129
|
+
import { jsx as jsx78, jsxs as jsxs71 } from "react/jsx-runtime";
|
|
3690
4130
|
function Hero({ eyebrow, title, description, primaryAction, secondaryAction, visual, proof, align = "left", kind = "product" }) {
|
|
3691
|
-
return /* @__PURE__ */
|
|
3692
|
-
/* @__PURE__ */
|
|
3693
|
-
eyebrow && /* @__PURE__ */
|
|
3694
|
-
/* @__PURE__ */
|
|
3695
|
-
description && /* @__PURE__ */
|
|
3696
|
-
(primaryAction || secondaryAction) && /* @__PURE__ */
|
|
4131
|
+
return /* @__PURE__ */ jsxs71("section", { className: `hf-hero hf-hero--${align} hf-hero--${kind}`, children: [
|
|
4132
|
+
/* @__PURE__ */ jsxs71("div", { className: "hf-hero__content", children: [
|
|
4133
|
+
eyebrow && /* @__PURE__ */ jsx78("div", { className: "hf-hero__eyebrow", children: eyebrow }),
|
|
4134
|
+
/* @__PURE__ */ jsx78("h1", { children: title }),
|
|
4135
|
+
description && /* @__PURE__ */ jsx78("p", { children: description }),
|
|
4136
|
+
(primaryAction || secondaryAction) && /* @__PURE__ */ jsxs71("div", { className: "hf-hero__actions", children: [
|
|
3697
4137
|
primaryAction,
|
|
3698
4138
|
secondaryAction
|
|
3699
4139
|
] }),
|
|
3700
|
-
proof && /* @__PURE__ */
|
|
4140
|
+
proof && /* @__PURE__ */ jsx78("div", { className: "hf-hero__proof", children: proof })
|
|
3701
4141
|
] }),
|
|
3702
|
-
visual && /* @__PURE__ */
|
|
4142
|
+
visual && /* @__PURE__ */ jsx78("div", { className: "hf-hero__visual", children: visual })
|
|
3703
4143
|
] });
|
|
3704
4144
|
}
|
|
3705
4145
|
|
|
3706
4146
|
// src/layout/ResizablePanel.tsx
|
|
3707
|
-
import { useState as
|
|
3708
|
-
import { jsx as
|
|
4147
|
+
import { useState as useState40 } from "react";
|
|
4148
|
+
import { jsx as jsx79, jsxs as jsxs72 } from "react/jsx-runtime";
|
|
3709
4149
|
function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, maxSize = 80, direction = "horizontal", onResize }) {
|
|
3710
|
-
const [size, setSize] =
|
|
4150
|
+
const [size, setSize] = useState40(defaultSize);
|
|
3711
4151
|
const start = (event) => {
|
|
3712
4152
|
const root = event.currentTarget.parentElement;
|
|
3713
4153
|
event.currentTarget.setPointerCapture(event.pointerId);
|
|
@@ -3725,9 +4165,9 @@ function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, ma
|
|
|
3725
4165
|
document.addEventListener("pointermove", move);
|
|
3726
4166
|
document.addEventListener("pointerup", end);
|
|
3727
4167
|
};
|
|
3728
|
-
return /* @__PURE__ */
|
|
3729
|
-
/* @__PURE__ */
|
|
3730
|
-
/* @__PURE__ */
|
|
4168
|
+
return /* @__PURE__ */ jsxs72("div", { className: `hf-resizable hf-resizable--${direction}`, children: [
|
|
4169
|
+
/* @__PURE__ */ jsx79("div", { style: { flexBasis: `${size}%` }, children: primary }),
|
|
4170
|
+
/* @__PURE__ */ jsx79("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) => {
|
|
3731
4171
|
if (!["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"].includes(event.key)) return;
|
|
3732
4172
|
event.preventDefault();
|
|
3733
4173
|
const grow = event.key === "ArrowRight" || event.key === "ArrowDown";
|
|
@@ -3735,61 +4175,61 @@ function ResizablePanel({ primary, secondary, defaultSize = 50, minSize = 20, ma
|
|
|
3735
4175
|
setSize(value);
|
|
3736
4176
|
onResize?.(value);
|
|
3737
4177
|
} }),
|
|
3738
|
-
/* @__PURE__ */
|
|
4178
|
+
/* @__PURE__ */ jsx79("div", { children: secondary })
|
|
3739
4179
|
] });
|
|
3740
4180
|
}
|
|
3741
4181
|
|
|
3742
4182
|
// src/feedback/NotificationCenter.tsx
|
|
3743
|
-
import { jsx as
|
|
4183
|
+
import { jsx as jsx80, jsxs as jsxs73 } from "react/jsx-runtime";
|
|
3744
4184
|
function NotificationCenter({ items, onRead, onDismiss, onReadAll, empty = "\u6682\u65E0\u901A\u77E5", title = "\u901A\u77E5\u4E2D\u5FC3" }) {
|
|
3745
4185
|
const unread = items.filter((item) => item.unread).length;
|
|
3746
|
-
return /* @__PURE__ */
|
|
3747
|
-
/* @__PURE__ */
|
|
3748
|
-
/* @__PURE__ */
|
|
3749
|
-
/* @__PURE__ */
|
|
3750
|
-
unread > 0 && /* @__PURE__ */
|
|
4186
|
+
return /* @__PURE__ */ jsxs73("section", { className: "hf-notification-center", children: [
|
|
4187
|
+
/* @__PURE__ */ jsxs73("header", { children: [
|
|
4188
|
+
/* @__PURE__ */ jsxs73("div", { children: [
|
|
4189
|
+
/* @__PURE__ */ jsx80("strong", { children: title }),
|
|
4190
|
+
unread > 0 && /* @__PURE__ */ jsx80("span", { children: unread })
|
|
3751
4191
|
] }),
|
|
3752
|
-
unread > 0 && onReadAll && /* @__PURE__ */
|
|
4192
|
+
unread > 0 && onReadAll && /* @__PURE__ */ jsx80("button", { type: "button", onClick: onReadAll, children: "\u5168\u90E8\u5DF2\u8BFB" })
|
|
3753
4193
|
] }),
|
|
3754
|
-
/* @__PURE__ */
|
|
4194
|
+
/* @__PURE__ */ jsx80("div", { children: items.length ? items.map(({ key, content, ...item }) => /* @__PURE__ */ jsx80("div", { onClick: () => item.unread && onRead?.(key), children: /* @__PURE__ */ jsx80(Notification, { ...item, onClose: onDismiss ? () => onDismiss(key) : void 0, children: content }) }, key)) : /* @__PURE__ */ jsx80("p", { className: "hf-notification-center__empty", children: empty }) })
|
|
3755
4195
|
] });
|
|
3756
4196
|
}
|
|
3757
4197
|
|
|
3758
4198
|
// src/data-display/VirtualList.tsx
|
|
3759
|
-
import { useState as
|
|
3760
|
-
import { jsx as
|
|
4199
|
+
import { useState as useState41 } from "react";
|
|
4200
|
+
import { jsx as jsx81 } from "react/jsx-runtime";
|
|
3761
4201
|
function VirtualList({ items, itemHeight, height, renderItem, itemKey, overscan = 3, label = "\u865A\u62DF\u5217\u8868" }) {
|
|
3762
|
-
const [scrollTop, setScrollTop] =
|
|
4202
|
+
const [scrollTop, setScrollTop] = useState41(0);
|
|
3763
4203
|
const start = Math.max(0, Math.floor(scrollTop / itemHeight) - overscan);
|
|
3764
4204
|
const end = Math.min(items.length, Math.ceil((scrollTop + height) / itemHeight) + overscan);
|
|
3765
|
-
return /* @__PURE__ */
|
|
4205
|
+
return /* @__PURE__ */ jsx81("div", { className: "hf-virtual-list", role: "list", "aria-label": label, style: { height }, onScroll: (event) => setScrollTop(event.currentTarget.scrollTop), children: /* @__PURE__ */ jsx81("div", { style: { height: items.length * itemHeight, position: "relative" }, children: items.slice(start, end).map((item, offset) => {
|
|
3766
4206
|
const index = start + offset;
|
|
3767
|
-
return /* @__PURE__ */
|
|
4207
|
+
return /* @__PURE__ */ jsx81("div", { role: "listitem", style: { height: itemHeight, left: 0, position: "absolute", right: 0, top: index * itemHeight }, children: renderItem(item, index) }, itemKey(item, index));
|
|
3768
4208
|
}) }) });
|
|
3769
4209
|
}
|
|
3770
4210
|
|
|
3771
4211
|
// src/data-display/DeveloperView.tsx
|
|
3772
|
-
import { useState as
|
|
3773
|
-
import { jsx as
|
|
4212
|
+
import { useState as useState42 } from "react";
|
|
4213
|
+
import { jsx as jsx82, jsxs as jsxs74 } from "react/jsx-runtime";
|
|
3774
4214
|
function JsonNode({ name, value, depth, defaultExpanded, maxDepth }) {
|
|
3775
4215
|
const complex = value !== null && typeof value === "object";
|
|
3776
|
-
const [open, setOpen] =
|
|
3777
|
-
if (!complex) return /* @__PURE__ */
|
|
3778
|
-
/* @__PURE__ */
|
|
3779
|
-
/* @__PURE__ */
|
|
4216
|
+
const [open, setOpen] = useState42(defaultExpanded && depth < maxDepth);
|
|
4217
|
+
if (!complex) return /* @__PURE__ */ jsxs74("div", { className: "hf-json-viewer__row", children: [
|
|
4218
|
+
/* @__PURE__ */ jsx82("span", { children: name !== void 0 && `${name}: ` }),
|
|
4219
|
+
/* @__PURE__ */ jsx82("code", { className: `is-${value === null ? "null" : typeof value}`, children: value === null ? "null" : JSON.stringify(value) })
|
|
3780
4220
|
] });
|
|
3781
4221
|
const entries = Object.entries(value);
|
|
3782
|
-
return /* @__PURE__ */
|
|
3783
|
-
/* @__PURE__ */
|
|
3784
|
-
/* @__PURE__ */
|
|
3785
|
-
/* @__PURE__ */
|
|
3786
|
-
/* @__PURE__ */
|
|
4222
|
+
return /* @__PURE__ */ jsxs74("div", { className: "hf-json-viewer__node", children: [
|
|
4223
|
+
/* @__PURE__ */ jsxs74("button", { type: "button", "aria-expanded": open, onClick: () => setOpen(!open), children: [
|
|
4224
|
+
/* @__PURE__ */ jsx82("span", { children: open ? "\u2304" : "\u203A" }),
|
|
4225
|
+
/* @__PURE__ */ jsx82("strong", { children: name ?? (Array.isArray(value) ? "Array" : "Object") }),
|
|
4226
|
+
/* @__PURE__ */ jsx82("small", { children: Array.isArray(value) ? `[${entries.length}]` : `{${entries.length}}` })
|
|
3787
4227
|
] }),
|
|
3788
|
-
open && /* @__PURE__ */
|
|
4228
|
+
open && /* @__PURE__ */ jsx82("div", { children: entries.map(([key, item]) => /* @__PURE__ */ jsx82(JsonNode, { name: key, value: item, depth: depth + 1, defaultExpanded, maxDepth }, key)) })
|
|
3789
4229
|
] });
|
|
3790
4230
|
}
|
|
3791
4231
|
function JsonViewer({ data, name, defaultExpanded = true, maxDepth = 2 }) {
|
|
3792
|
-
return /* @__PURE__ */
|
|
4232
|
+
return /* @__PURE__ */ jsx82("div", { className: "hf-json-viewer", role: "tree", "aria-label": name ?? "JSON \u67E5\u770B\u5668", children: /* @__PURE__ */ jsx82(JsonNode, { name, value: data, depth: 0, defaultExpanded, maxDepth }) });
|
|
3793
4233
|
}
|
|
3794
4234
|
function compareLines(before, after) {
|
|
3795
4235
|
const a = before.split("\n"), b = after.split("\n"), matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
|
|
@@ -3808,28 +4248,28 @@ function compareLines(before, after) {
|
|
|
3808
4248
|
return rows;
|
|
3809
4249
|
}
|
|
3810
4250
|
function DiffCell({ number, marker, children }) {
|
|
3811
|
-
return /* @__PURE__ */
|
|
3812
|
-
/* @__PURE__ */
|
|
3813
|
-
/* @__PURE__ */
|
|
3814
|
-
/* @__PURE__ */
|
|
4251
|
+
return /* @__PURE__ */ jsxs74("div", { className: "hf-diff-viewer__cell", children: [
|
|
4252
|
+
/* @__PURE__ */ jsx82("span", { children: number ?? "" }),
|
|
4253
|
+
/* @__PURE__ */ jsx82("i", { children: marker }),
|
|
4254
|
+
/* @__PURE__ */ jsx82("code", { children: children ?? "" })
|
|
3815
4255
|
] });
|
|
3816
4256
|
}
|
|
3817
4257
|
function DiffViewer({ before, after, beforeLabel = "\u4FEE\u6539\u524D", afterLabel = "\u4FEE\u6539\u540E", mode = "split" }) {
|
|
3818
4258
|
const rows = compareLines(before, after);
|
|
3819
|
-
return /* @__PURE__ */
|
|
3820
|
-
/* @__PURE__ */
|
|
3821
|
-
/* @__PURE__ */
|
|
3822
|
-
mode === "split" && /* @__PURE__ */
|
|
4259
|
+
return /* @__PURE__ */ jsxs74("div", { className: `hf-diff-viewer hf-diff-viewer--${mode}`, children: [
|
|
4260
|
+
/* @__PURE__ */ jsxs74("header", { children: [
|
|
4261
|
+
/* @__PURE__ */ jsx82("strong", { children: beforeLabel }),
|
|
4262
|
+
mode === "split" && /* @__PURE__ */ jsx82("strong", { children: afterLabel })
|
|
3823
4263
|
] }),
|
|
3824
|
-
/* @__PURE__ */
|
|
3825
|
-
/* @__PURE__ */
|
|
3826
|
-
/* @__PURE__ */
|
|
3827
|
-
] }, index) : /* @__PURE__ */
|
|
4264
|
+
/* @__PURE__ */ jsx82("div", { children: rows.map((row, index) => mode === "split" ? /* @__PURE__ */ jsxs74("div", { className: `is-${row.kind}`, children: [
|
|
4265
|
+
/* @__PURE__ */ jsx82(DiffCell, { number: row.leftNo, marker: row.kind === "remove" ? "\u2212" : " ", children: row.left }),
|
|
4266
|
+
/* @__PURE__ */ jsx82(DiffCell, { number: row.rightNo, marker: row.kind === "add" ? "+" : " ", children: row.right })
|
|
4267
|
+
] }, index) : /* @__PURE__ */ jsx82("div", { className: `is-${row.kind}`, children: /* @__PURE__ */ jsx82(DiffCell, { number: row.leftNo ?? row.rightNo, marker: row.kind === "add" ? "+" : row.kind === "remove" ? "\u2212" : " ", children: row.kind === "add" ? row.right : row.left }) }, index)) })
|
|
3828
4268
|
] });
|
|
3829
4269
|
}
|
|
3830
4270
|
|
|
3831
4271
|
// src/forms/QueryBuilder.tsx
|
|
3832
|
-
import { jsx as
|
|
4272
|
+
import { jsx as jsx83, jsxs as jsxs75 } from "react/jsx-runtime";
|
|
3833
4273
|
var defaultOperators = [{ value: "equals", label: "\u7B49\u4E8E" }, { value: "notEquals", label: "\u4E0D\u7B49\u4E8E" }, { value: "contains", label: "\u5305\u542B" }];
|
|
3834
4274
|
function QueryBuilder({ fields, rules, onChange, conjunction = "and", onConjunctionChange, disabled }) {
|
|
3835
4275
|
const update = (id, patch) => onChange(rules.map((rule) => rule.id === id ? { ...rule, ...patch } : rule));
|
|
@@ -3839,39 +4279,39 @@ function QueryBuilder({ fields, rules, onChange, conjunction = "and", onConjunct
|
|
|
3839
4279
|
const operator = (field.operators ?? defaultOperators)[0]?.value ?? "equals";
|
|
3840
4280
|
onChange([...rules, { id: `rule-${Date.now()}`, field: field.key, operator, value: "" }]);
|
|
3841
4281
|
};
|
|
3842
|
-
return /* @__PURE__ */
|
|
3843
|
-
/* @__PURE__ */
|
|
3844
|
-
/* @__PURE__ */
|
|
3845
|
-
/* @__PURE__ */
|
|
4282
|
+
return /* @__PURE__ */ jsxs75("div", { className: "hf-query-builder", children: [
|
|
4283
|
+
/* @__PURE__ */ jsxs75("header", { children: [
|
|
4284
|
+
/* @__PURE__ */ jsx83("strong", { children: "\u6EE1\u8DB3" }),
|
|
4285
|
+
/* @__PURE__ */ jsx83(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) })
|
|
3846
4286
|
] }),
|
|
3847
|
-
/* @__PURE__ */
|
|
4287
|
+
/* @__PURE__ */ jsx83("div", { children: rules.map((rule, index) => {
|
|
3848
4288
|
const field = fields.find((item) => item.key === rule.field) ?? fields[0];
|
|
3849
4289
|
const operators = field?.operators ?? defaultOperators;
|
|
3850
|
-
return /* @__PURE__ */
|
|
3851
|
-
/* @__PURE__ */
|
|
3852
|
-
/* @__PURE__ */
|
|
4290
|
+
return /* @__PURE__ */ jsxs75("div", { className: "hf-query-builder__rule", children: [
|
|
4291
|
+
/* @__PURE__ */ jsx83("span", { children: index + 1 }),
|
|
4292
|
+
/* @__PURE__ */ jsx83(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) => {
|
|
3853
4293
|
const next = fields.find((item) => item.key === event.target.value);
|
|
3854
4294
|
update(rule.id, { field: next.key, operator: (next.operators ?? defaultOperators)[0]?.value ?? "equals", value: "" });
|
|
3855
4295
|
} }),
|
|
3856
|
-
/* @__PURE__ */
|
|
3857
|
-
/* @__PURE__ */
|
|
3858
|
-
/* @__PURE__ */
|
|
4296
|
+
/* @__PURE__ */ jsx83(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 }) }),
|
|
4297
|
+
/* @__PURE__ */ jsx83("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 }) }),
|
|
4298
|
+
/* @__PURE__ */ jsx83("button", { type: "button", "aria-label": `\u5220\u9664\u6761\u4EF6 ${index + 1}`, disabled, onClick: () => onChange(rules.filter((item) => item.id !== rule.id)), children: /* @__PURE__ */ jsx83(Icon, { name: "close", size: 15 }) })
|
|
3859
4299
|
] }, rule.id);
|
|
3860
4300
|
}) }),
|
|
3861
|
-
/* @__PURE__ */
|
|
4301
|
+
/* @__PURE__ */ jsx83("button", { type: "button", className: "hf-query-builder__add", disabled: disabled || !fields.length, onClick: add, children: "\uFF0B \u6DFB\u52A0\u6761\u4EF6" })
|
|
3862
4302
|
] });
|
|
3863
4303
|
}
|
|
3864
4304
|
|
|
3865
4305
|
// src/data-display/WorkflowViews.tsx
|
|
3866
|
-
import { useMemo as
|
|
4306
|
+
import { useMemo as useMemo9 } from "react";
|
|
3867
4307
|
|
|
3868
4308
|
// src/data-display/useKanbanMove.ts
|
|
3869
|
-
import { useRef as
|
|
4309
|
+
import { useRef as useRef16, useState as useState43 } from "react";
|
|
3870
4310
|
function useKanbanMove({ columns, onMove }) {
|
|
3871
|
-
const root =
|
|
3872
|
-
const session =
|
|
3873
|
-
const [target, setTarget] =
|
|
3874
|
-
const [announcement, setAnnouncement] =
|
|
4311
|
+
const root = useRef16(null);
|
|
4312
|
+
const session = useRef16(null);
|
|
4313
|
+
const [target, setTarget] = useState43(null);
|
|
4314
|
+
const [announcement, setAnnouncement] = useState43("");
|
|
3875
4315
|
const snapshot = JSON.stringify(columns.map((column) => [column.id, column.cards.map((card) => card.id)]));
|
|
3876
4316
|
function cancel() {
|
|
3877
4317
|
if (session.current) setAnnouncement("\u5DF2\u53D6\u6D88\u79FB\u52A8\uFF0C\u672A\u63D0\u4EA4\u66F4\u6539");
|
|
@@ -3935,13 +4375,13 @@ function useKanbanMove({ columns, onMove }) {
|
|
|
3935
4375
|
}
|
|
3936
4376
|
|
|
3937
4377
|
// src/data-display/KanbanBoardView.tsx
|
|
3938
|
-
import { jsx as
|
|
4378
|
+
import { jsx as jsx84, jsxs as jsxs76 } from "react/jsx-runtime";
|
|
3939
4379
|
function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
3940
4380
|
const drag = useKanbanMove({ columns, onMove });
|
|
3941
|
-
if (!columns.length) return /* @__PURE__ */
|
|
3942
|
-
return /* @__PURE__ */
|
|
3943
|
-
onMove && /* @__PURE__ */
|
|
3944
|
-
/* @__PURE__ */
|
|
4381
|
+
if (!columns.length) return /* @__PURE__ */ jsx84("div", { className: "hf-kanban-board__empty", children: empty });
|
|
4382
|
+
return /* @__PURE__ */ jsxs76("div", { className: "hf-kanban-enhanced", children: [
|
|
4383
|
+
onMove && /* @__PURE__ */ jsx84("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" }),
|
|
4384
|
+
/* @__PURE__ */ jsx84(
|
|
3945
4385
|
"div",
|
|
3946
4386
|
{
|
|
3947
4387
|
ref: drag.root,
|
|
@@ -3953,7 +4393,7 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
3953
4393
|
onKeyDown: (event) => {
|
|
3954
4394
|
if (event.key === "Escape") drag.cancel();
|
|
3955
4395
|
},
|
|
3956
|
-
children: columns.map((column) => /* @__PURE__ */
|
|
4396
|
+
children: columns.map((column) => /* @__PURE__ */ jsxs76(
|
|
3957
4397
|
"section",
|
|
3958
4398
|
{
|
|
3959
4399
|
"data-hf-kanban-column": column.id,
|
|
@@ -3968,18 +4408,18 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
3968
4408
|
drag.drop(column.id);
|
|
3969
4409
|
},
|
|
3970
4410
|
children: [
|
|
3971
|
-
/* @__PURE__ */
|
|
3972
|
-
/* @__PURE__ */
|
|
3973
|
-
/* @__PURE__ */
|
|
4411
|
+
/* @__PURE__ */ jsxs76("header", { children: [
|
|
4412
|
+
/* @__PURE__ */ jsx84("strong", { children: column.title }),
|
|
4413
|
+
/* @__PURE__ */ jsxs76("span", { children: [
|
|
3974
4414
|
column.cards.length,
|
|
3975
4415
|
column.limit ? ` / ${column.limit}` : ""
|
|
3976
4416
|
] })
|
|
3977
4417
|
] }),
|
|
3978
|
-
/* @__PURE__ */
|
|
4418
|
+
/* @__PURE__ */ jsxs76("div", { children: [
|
|
3979
4419
|
column.cards.map((card, index) => {
|
|
3980
4420
|
const label = typeof card.title === "string" ? card.title : `\u5361\u7247${index + 1}`;
|
|
3981
|
-
return /* @__PURE__ */
|
|
3982
|
-
/* @__PURE__ */
|
|
4421
|
+
return /* @__PURE__ */ jsxs76("div", { className: "hf-kanban-enhanced__item", "data-card-id": card.id, children: [
|
|
4422
|
+
/* @__PURE__ */ jsxs76(
|
|
3983
4423
|
"button",
|
|
3984
4424
|
{
|
|
3985
4425
|
type: "button",
|
|
@@ -3997,15 +4437,15 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
3997
4437
|
onDragEnd: drag.cancel,
|
|
3998
4438
|
onClick: () => onCardClick?.(card.id, column.id),
|
|
3999
4439
|
children: [
|
|
4000
|
-
/* @__PURE__ */
|
|
4001
|
-
card.description && /* @__PURE__ */
|
|
4002
|
-
card.tags?.length ? /* @__PURE__ */
|
|
4003
|
-
card.meta && /* @__PURE__ */
|
|
4440
|
+
/* @__PURE__ */ jsx84("strong", { children: card.title }),
|
|
4441
|
+
card.description && /* @__PURE__ */ jsx84("p", { children: card.description }),
|
|
4442
|
+
card.tags?.length ? /* @__PURE__ */ jsx84("span", { children: card.tags.map((tag) => /* @__PURE__ */ jsx84("i", { children: tag }, tag)) }) : null,
|
|
4443
|
+
card.meta && /* @__PURE__ */ jsx84("small", { children: card.meta })
|
|
4004
4444
|
]
|
|
4005
4445
|
}
|
|
4006
4446
|
),
|
|
4007
|
-
onMove && /* @__PURE__ */
|
|
4008
|
-
/* @__PURE__ */
|
|
4447
|
+
onMove && /* @__PURE__ */ jsxs76("div", { className: "hf-kanban-enhanced__controls", children: [
|
|
4448
|
+
/* @__PURE__ */ jsx84(
|
|
4009
4449
|
"button",
|
|
4010
4450
|
{
|
|
4011
4451
|
type: "button",
|
|
@@ -4019,17 +4459,17 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4019
4459
|
children: "\u2194"
|
|
4020
4460
|
}
|
|
4021
4461
|
),
|
|
4022
|
-
/* @__PURE__ */
|
|
4462
|
+
/* @__PURE__ */ jsxs76("select", { "aria-label": `\u79FB\u52A8${label}\u5230`, value: "", onChange: (event) => {
|
|
4023
4463
|
drag.cancel();
|
|
4024
4464
|
drag.request(card.id, column.id, event.target.value);
|
|
4025
4465
|
}, children: [
|
|
4026
|
-
/* @__PURE__ */
|
|
4027
|
-
columns.filter((candidate) => candidate.id !== column.id).map((candidate, destinationIndex) => /* @__PURE__ */
|
|
4466
|
+
/* @__PURE__ */ jsx84("option", { value: "", disabled: true, children: "\u79FB\u52A8\u5230\u2026" }),
|
|
4467
|
+
columns.filter((candidate) => candidate.id !== column.id).map((candidate, destinationIndex) => /* @__PURE__ */ jsx84("option", { value: candidate.id, children: typeof candidate.title === "string" ? candidate.title : `\u76EE\u6807\u5217${destinationIndex + 1}` }, candidate.id))
|
|
4028
4468
|
] })
|
|
4029
4469
|
] })
|
|
4030
4470
|
] }, card.id);
|
|
4031
4471
|
}),
|
|
4032
|
-
!column.cards.length && /* @__PURE__ */
|
|
4472
|
+
!column.cards.length && /* @__PURE__ */ jsxs76("p", { className: "hf-kanban-enhanced__empty", children: [
|
|
4033
4473
|
"\u6682\u65E0\u5361\u7247",
|
|
4034
4474
|
onMove ? "\uFF0C\u53EF\u62D6\u5165\u6B64\u5217" : ""
|
|
4035
4475
|
] })
|
|
@@ -4040,59 +4480,59 @@ function KanbanBoardView({ columns, onMove, onCardClick, empty }) {
|
|
|
4040
4480
|
))
|
|
4041
4481
|
}
|
|
4042
4482
|
),
|
|
4043
|
-
/* @__PURE__ */
|
|
4483
|
+
/* @__PURE__ */ jsx84("span", { className: "hf-sr-only", role: "status", children: drag.announcement })
|
|
4044
4484
|
] });
|
|
4045
4485
|
}
|
|
4046
4486
|
|
|
4047
4487
|
// src/data-display/WorkflowViews.tsx
|
|
4048
|
-
import { jsx as
|
|
4488
|
+
import { jsx as jsx85, jsxs as jsxs77 } from "react/jsx-runtime";
|
|
4049
4489
|
function FlowCanvas({ nodes, edges, width = 900, height = 420, selectedId, onSelect, empty = "\u6682\u65E0\u6D41\u7A0B\u8282\u70B9" }) {
|
|
4050
4490
|
const map = new Map(nodes.map((node) => [node.id, node]));
|
|
4051
|
-
if (!nodes.length) return /* @__PURE__ */
|
|
4052
|
-
return /* @__PURE__ */
|
|
4053
|
-
/* @__PURE__ */
|
|
4491
|
+
if (!nodes.length) return /* @__PURE__ */ jsx85("div", { className: "hf-flow-canvas hf-flow-canvas__empty", children: empty });
|
|
4492
|
+
return /* @__PURE__ */ jsx85("div", { className: "hf-flow-canvas", role: "group", "aria-label": "\u6D41\u7A0B\u753B\u5E03", children: /* @__PURE__ */ jsxs77("div", { style: { width, height }, children: [
|
|
4493
|
+
/* @__PURE__ */ jsx85("svg", { viewBox: `0 0 ${width} ${height}`, "aria-hidden": "true", children: edges.map((edge, index) => {
|
|
4054
4494
|
const from = map.get(edge.from), to = map.get(edge.to);
|
|
4055
4495
|
if (!from || !to) return null;
|
|
4056
4496
|
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);
|
|
4057
|
-
return /* @__PURE__ */
|
|
4058
|
-
/* @__PURE__ */
|
|
4059
|
-
/* @__PURE__ */
|
|
4060
|
-
edge.label && /* @__PURE__ */
|
|
4497
|
+
return /* @__PURE__ */ jsxs77("g", { children: [
|
|
4498
|
+
/* @__PURE__ */ jsx85("path", { d: `M${x1} ${y1} C${x1 + bend} ${y1},${x2 - bend} ${y2},${x2} ${y2}` }),
|
|
4499
|
+
/* @__PURE__ */ jsx85("circle", { cx: x2, cy: y2, r: "3" }),
|
|
4500
|
+
edge.label && /* @__PURE__ */ jsx85("text", { x: (x1 + x2) / 2, y: (y1 + y2) / 2 - 8, children: edge.label })
|
|
4061
4501
|
] }, edge.id ?? index);
|
|
4062
4502
|
}) }),
|
|
4063
|
-
nodes.map((node) => /* @__PURE__ */
|
|
4064
|
-
/* @__PURE__ */
|
|
4065
|
-
node.description && /* @__PURE__ */
|
|
4503
|
+
nodes.map((node) => /* @__PURE__ */ jsxs77("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: [
|
|
4504
|
+
/* @__PURE__ */ jsx85("strong", { children: node.label }),
|
|
4505
|
+
node.description && /* @__PURE__ */ jsx85("small", { children: node.description })
|
|
4066
4506
|
] }, node.id))
|
|
4067
4507
|
] }) });
|
|
4068
4508
|
}
|
|
4069
4509
|
function KanbanBoard({ columns, onMove, onCardClick, empty = "\u6682\u65E0\u770B\u677F\u5217" }) {
|
|
4070
|
-
return /* @__PURE__ */
|
|
4510
|
+
return /* @__PURE__ */ jsx85(KanbanBoardView, { columns, onMove, onCardClick, empty });
|
|
4071
4511
|
}
|
|
4072
4512
|
var day = 864e5;
|
|
4073
4513
|
var toTime = (value) => new Date(value).setHours(0, 0, 0, 0);
|
|
4074
4514
|
function GanttChart({ tasks, start, end, onTaskClick, empty = "\u6682\u65E0\u6392\u671F\u4EFB\u52A1" }) {
|
|
4075
|
-
const range =
|
|
4515
|
+
const range = useMemo9(() => {
|
|
4076
4516
|
const starts = tasks.map((task) => toTime(task.start)), ends = tasks.map((task) => toTime(task.end));
|
|
4077
4517
|
const from = start ? toTime(start) : Math.min(...starts), to = end ? toTime(end) : Math.max(...ends);
|
|
4078
4518
|
return { from, days: Math.max(1, Math.round((to - from) / day) + 1) };
|
|
4079
4519
|
}, [tasks, start, end]);
|
|
4080
|
-
if (!tasks.length) return /* @__PURE__ */
|
|
4081
|
-
return /* @__PURE__ */
|
|
4082
|
-
/* @__PURE__ */
|
|
4083
|
-
/* @__PURE__ */
|
|
4084
|
-
/* @__PURE__ */
|
|
4520
|
+
if (!tasks.length) return /* @__PURE__ */ jsx85("div", { className: "hf-gantt-chart__empty", children: empty });
|
|
4521
|
+
return /* @__PURE__ */ jsxs77("div", { className: "hf-gantt-chart", children: [
|
|
4522
|
+
/* @__PURE__ */ jsxs77("header", { children: [
|
|
4523
|
+
/* @__PURE__ */ jsx85("strong", { children: "\u4EFB\u52A1" }),
|
|
4524
|
+
/* @__PURE__ */ jsx85("div", { children: Array.from({ length: Math.min(range.days, 31) }, (_, index) => /* @__PURE__ */ jsx85("span", { children: new Date(range.from + index * day).getDate() }, index)) })
|
|
4085
4525
|
] }),
|
|
4086
4526
|
tasks.map((task) => {
|
|
4087
4527
|
const offset = Math.max(0, (toTime(task.start) - range.from) / day), length = Math.max(1, (toTime(task.end) - toTime(task.start)) / day + 1);
|
|
4088
|
-
return /* @__PURE__ */
|
|
4089
|
-
/* @__PURE__ */
|
|
4090
|
-
/* @__PURE__ */
|
|
4091
|
-
task.group && /* @__PURE__ */
|
|
4528
|
+
return /* @__PURE__ */ jsxs77("div", { className: "hf-gantt-chart__row", children: [
|
|
4529
|
+
/* @__PURE__ */ jsxs77("span", { children: [
|
|
4530
|
+
/* @__PURE__ */ jsx85("strong", { children: task.label }),
|
|
4531
|
+
task.group && /* @__PURE__ */ jsx85("small", { children: task.group })
|
|
4092
4532
|
] }),
|
|
4093
|
-
/* @__PURE__ */
|
|
4094
|
-
/* @__PURE__ */
|
|
4095
|
-
/* @__PURE__ */
|
|
4533
|
+
/* @__PURE__ */ jsx85("div", { children: /* @__PURE__ */ jsxs77("button", { type: "button", style: { left: `${offset / range.days * 100}%`, width: `${length / range.days * 100}%`, "--hf-gantt-color": task.color }, onClick: () => onTaskClick?.(task.id), children: [
|
|
4534
|
+
/* @__PURE__ */ jsx85("i", { style: { width: `${Math.max(0, Math.min(100, task.progress ?? 0))}%` } }),
|
|
4535
|
+
/* @__PURE__ */ jsxs77("span", { children: [
|
|
4096
4536
|
task.progress ?? 0,
|
|
4097
4537
|
"%"
|
|
4098
4538
|
] })
|
|
@@ -4102,23 +4542,23 @@ function GanttChart({ tasks, start, end, onTaskClick, empty = "\u6682\u65E0\u639
|
|
|
4102
4542
|
] });
|
|
4103
4543
|
}
|
|
4104
4544
|
function ChartContainer({ title, description, actions, legend, children, height = 320, loading, empty, emptyContent = "\u6682\u65E0\u56FE\u8868\u6570\u636E" }) {
|
|
4105
|
-
return /* @__PURE__ */
|
|
4106
|
-
/* @__PURE__ */
|
|
4107
|
-
/* @__PURE__ */
|
|
4108
|
-
title && /* @__PURE__ */
|
|
4109
|
-
description && /* @__PURE__ */
|
|
4545
|
+
return /* @__PURE__ */ jsxs77("section", { className: "hf-chart-container", children: [
|
|
4546
|
+
/* @__PURE__ */ jsxs77("header", { children: [
|
|
4547
|
+
/* @__PURE__ */ jsxs77("div", { children: [
|
|
4548
|
+
title && /* @__PURE__ */ jsx85("strong", { children: title }),
|
|
4549
|
+
description && /* @__PURE__ */ jsx85("p", { children: description })
|
|
4110
4550
|
] }),
|
|
4111
4551
|
actions
|
|
4112
4552
|
] }),
|
|
4113
|
-
legend?.length ? /* @__PURE__ */
|
|
4114
|
-
/* @__PURE__ */
|
|
4553
|
+
legend?.length ? /* @__PURE__ */ jsx85("div", { className: "hf-chart-container__legend", children: legend.map((item, index) => /* @__PURE__ */ jsxs77("span", { children: [
|
|
4554
|
+
/* @__PURE__ */ jsx85("i", { style: { background: item.color } }),
|
|
4115
4555
|
item.label,
|
|
4116
|
-
item.value && /* @__PURE__ */
|
|
4556
|
+
item.value && /* @__PURE__ */ jsx85("strong", { children: item.value })
|
|
4117
4557
|
] }, index)) }) : null,
|
|
4118
|
-
/* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4558
|
+
/* @__PURE__ */ jsx85("div", { className: "hf-chart-container__body", style: { height }, children: loading ? /* @__PURE__ */ jsxs77("div", { className: "hf-chart-container__state", children: [
|
|
4559
|
+
/* @__PURE__ */ jsx85("span", { className: "hf-spinner" }),
|
|
4120
4560
|
"\u6B63\u5728\u52A0\u8F7D\u56FE\u8868"
|
|
4121
|
-
] }) : empty ? /* @__PURE__ */
|
|
4561
|
+
] }) : empty ? /* @__PURE__ */ jsx85("div", { className: "hf-chart-container__state", children: emptyContent }) : children })
|
|
4122
4562
|
] });
|
|
4123
4563
|
}
|
|
4124
4564
|
function PivotTable({ data, row, column, values, rowLabel = "\u9879\u76EE", showTotals = true, empty = "\u6682\u65E0\u900F\u89C6\u6570\u636E" }) {
|
|
@@ -4128,60 +4568,60 @@ function PivotTable({ data, row, column, values, rowLabel = "\u9879\u76EE", show
|
|
|
4128
4568
|
const sum = items.reduce((total, item) => total + metric.value(item), 0);
|
|
4129
4569
|
return metric.aggregate === "average" ? items.length ? sum / items.length : 0 : sum;
|
|
4130
4570
|
};
|
|
4131
|
-
if (!data.length || !values.length) return /* @__PURE__ */
|
|
4132
|
-
return /* @__PURE__ */
|
|
4133
|
-
/* @__PURE__ */
|
|
4134
|
-
/* @__PURE__ */
|
|
4135
|
-
/* @__PURE__ */
|
|
4136
|
-
columns.map((item) => /* @__PURE__ */
|
|
4137
|
-
showTotals && /* @__PURE__ */
|
|
4571
|
+
if (!data.length || !values.length) return /* @__PURE__ */ jsx85("div", { className: "hf-pivot-table__empty", children: empty });
|
|
4572
|
+
return /* @__PURE__ */ jsx85("div", { className: "hf-pivot-table", children: /* @__PURE__ */ jsxs77("table", { children: [
|
|
4573
|
+
/* @__PURE__ */ jsxs77("thead", { children: [
|
|
4574
|
+
/* @__PURE__ */ jsxs77("tr", { children: [
|
|
4575
|
+
/* @__PURE__ */ jsx85("th", { rowSpan: 2, children: rowLabel }),
|
|
4576
|
+
columns.map((item) => /* @__PURE__ */ jsx85("th", { colSpan: values.length, children: item }, item)),
|
|
4577
|
+
showTotals && /* @__PURE__ */ jsx85("th", { colSpan: values.length, children: "\u5408\u8BA1" })
|
|
4138
4578
|
] }),
|
|
4139
|
-
/* @__PURE__ */
|
|
4579
|
+
/* @__PURE__ */ jsx85("tr", { children: [...columns, ...showTotals ? ["__total"] : []].flatMap((col) => values.map((metric) => /* @__PURE__ */ jsx85("th", { children: metric.label }, `${col}-${metric.key}`))) })
|
|
4140
4580
|
] }),
|
|
4141
|
-
/* @__PURE__ */
|
|
4142
|
-
/* @__PURE__ */
|
|
4581
|
+
/* @__PURE__ */ jsx85("tbody", { children: rows.map((rowName) => /* @__PURE__ */ jsxs77("tr", { children: [
|
|
4582
|
+
/* @__PURE__ */ jsx85("th", { children: rowName }),
|
|
4143
4583
|
[...columns, ...showTotals ? ["__total"] : []].flatMap((columnName) => values.map((metric) => {
|
|
4144
4584
|
const items = data.filter((item) => row(item) === rowName && (columnName === "__total" || column(item) === columnName));
|
|
4145
4585
|
const result = calculate(items, metric);
|
|
4146
|
-
return /* @__PURE__ */
|
|
4586
|
+
return /* @__PURE__ */ jsx85("td", { children: metric.format?.(result) ?? result }, `${columnName}-${metric.key}`);
|
|
4147
4587
|
}))
|
|
4148
4588
|
] }, rowName)) })
|
|
4149
4589
|
] }) });
|
|
4150
4590
|
}
|
|
4151
4591
|
|
|
4152
4592
|
// src/forms/FilterBuilder.tsx
|
|
4153
|
-
import { jsx as
|
|
4593
|
+
import { jsx as jsx86, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
4154
4594
|
function FilterBuilder({ fields, value, onChange, disabled, addLabel = "\u6DFB\u52A0\u7B5B\u9009" }) {
|
|
4155
4595
|
const add = () => {
|
|
4156
4596
|
const field = fields.find((item) => !value.some((filter) => filter.field === item.key)) ?? fields[0];
|
|
4157
4597
|
if (field) onChange([...value, { id: `filter-${Date.now()}`, field: field.key, value: "" }]);
|
|
4158
4598
|
};
|
|
4159
4599
|
const update = (id, patch) => onChange(value.map((item) => item.id === id ? { ...item, ...patch } : item));
|
|
4160
|
-
return /* @__PURE__ */
|
|
4161
|
-
/* @__PURE__ */
|
|
4600
|
+
return /* @__PURE__ */ jsxs78("div", { className: "hf-filter-builder", role: "group", "aria-label": "\u7B5B\u9009\u6761\u4EF6", children: [
|
|
4601
|
+
/* @__PURE__ */ jsx86("div", { children: value.map((filter, index) => {
|
|
4162
4602
|
const field = fields.find((item) => item.key === filter.field) ?? fields[0];
|
|
4163
|
-
return /* @__PURE__ */
|
|
4164
|
-
/* @__PURE__ */
|
|
4165
|
-
field?.options ? /* @__PURE__ */
|
|
4166
|
-
/* @__PURE__ */
|
|
4603
|
+
return /* @__PURE__ */ jsxs78("div", { className: "hf-filter-builder__item", children: [
|
|
4604
|
+
/* @__PURE__ */ jsx86(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: "" }) }),
|
|
4605
|
+
field?.options ? /* @__PURE__ */ jsx86(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__ */ jsx86("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 }) }),
|
|
4606
|
+
/* @__PURE__ */ jsx86("button", { type: "button", "aria-label": `\u5220\u9664\u7B5B\u9009 ${index + 1}`, disabled, onClick: () => onChange(value.filter((item) => item.id !== filter.id)), children: /* @__PURE__ */ jsx86(Icon, { name: "close", size: 15 }) })
|
|
4167
4607
|
] }, filter.id);
|
|
4168
4608
|
}) }),
|
|
4169
|
-
/* @__PURE__ */
|
|
4609
|
+
/* @__PURE__ */ jsxs78("button", { type: "button", className: "hf-filter-builder__add", disabled: disabled || !fields.length, onClick: add, children: [
|
|
4170
4610
|
"\uFF0B ",
|
|
4171
4611
|
addLabel
|
|
4172
4612
|
] }),
|
|
4173
|
-
value.length > 0 && /* @__PURE__ */
|
|
4613
|
+
value.length > 0 && /* @__PURE__ */ jsx86("button", { type: "button", className: "hf-filter-builder__clear", disabled, onClick: () => onChange([]), children: "\u6E05\u7A7A" })
|
|
4174
4614
|
] });
|
|
4175
4615
|
}
|
|
4176
4616
|
|
|
4177
4617
|
// src/data-display/ZoomableChart.tsx
|
|
4178
|
-
import { useMemo as
|
|
4179
|
-
import { jsx as
|
|
4618
|
+
import { useMemo as useMemo10, useState as useState44 } from "react";
|
|
4619
|
+
import { jsx as jsx87, jsxs as jsxs79 } from "react/jsx-runtime";
|
|
4180
4620
|
function normalizeWindow(value, length) {
|
|
4181
4621
|
const last = Math.max(0, length - 1);
|
|
4182
|
-
const
|
|
4183
|
-
let start =
|
|
4184
|
-
let end =
|
|
4622
|
+
const clamp2 = (number, fallback) => Number.isFinite(number) ? Math.max(0, Math.min(last, Math.round(number))) : fallback;
|
|
4623
|
+
let start = clamp2(value[0], 0);
|
|
4624
|
+
let end = clamp2(value[1], last);
|
|
4185
4625
|
if (start > end) [start, end] = [end, start];
|
|
4186
4626
|
if (start === end && length > 1) {
|
|
4187
4627
|
if (end < last) end++;
|
|
@@ -4199,9 +4639,9 @@ function ZoomableChart({
|
|
|
4199
4639
|
disabled = false,
|
|
4200
4640
|
className = ""
|
|
4201
4641
|
}) {
|
|
4202
|
-
const [internal, setInternal] =
|
|
4642
|
+
const [internal, setInternal] = useState44(defaultWindow);
|
|
4203
4643
|
const [start, end] = normalizeWindow(controlled ?? internal ?? [0, points.length - 1], points.length);
|
|
4204
|
-
const visible =
|
|
4644
|
+
const visible = useMemo10(() => points.slice(start, end + 1), [points, start, end]);
|
|
4205
4645
|
const count = end - start + 1;
|
|
4206
4646
|
function update(next) {
|
|
4207
4647
|
if (disabled) return;
|
|
@@ -4219,13 +4659,13 @@ function ZoomableChart({
|
|
|
4219
4659
|
const left = Math.max(0, Math.min(points.length - count, start + direction * Math.max(1, Math.floor(count / 2))));
|
|
4220
4660
|
update([left, left + count - 1]);
|
|
4221
4661
|
}
|
|
4222
|
-
return /* @__PURE__ */
|
|
4223
|
-
/* @__PURE__ */
|
|
4224
|
-
/* @__PURE__ */
|
|
4225
|
-
/* @__PURE__ */
|
|
4226
|
-
/* @__PURE__ */
|
|
4227
|
-
/* @__PURE__ */
|
|
4228
|
-
/* @__PURE__ */
|
|
4662
|
+
return /* @__PURE__ */ jsxs79("div", { className: `hf-zoomable-chart ${className}`, children: [
|
|
4663
|
+
/* @__PURE__ */ jsxs79("div", { className: "hf-zoomable-chart__controls", role: "group", "aria-label": `${label}\u89C6\u7A97\u64CD\u4F5C`, children: [
|
|
4664
|
+
/* @__PURE__ */ jsx87(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || count <= 2, onClick: () => resize(0.5), children: "\u653E\u5927" }),
|
|
4665
|
+
/* @__PURE__ */ jsx87(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || count >= points.length, onClick: () => resize(2), children: "\u7F29\u5C0F" }),
|
|
4666
|
+
/* @__PURE__ */ jsx87(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || start === 0, onClick: () => pan(-1), children: "\u5411\u524D\u5E73\u79FB" }),
|
|
4667
|
+
/* @__PURE__ */ jsx87(Button, { type: "button", size: "sm", variant: "outline", disabled: disabled || end >= points.length - 1, onClick: () => pan(1), children: "\u5411\u540E\u5E73\u79FB" }),
|
|
4668
|
+
/* @__PURE__ */ jsx87(
|
|
4229
4669
|
Button,
|
|
4230
4670
|
{
|
|
4231
4671
|
type: "button",
|
|
@@ -4237,8 +4677,8 @@ function ZoomableChart({
|
|
|
4237
4677
|
}
|
|
4238
4678
|
)
|
|
4239
4679
|
] }),
|
|
4240
|
-
/* @__PURE__ */
|
|
4241
|
-
points.length > 1 && /* @__PURE__ */
|
|
4680
|
+
/* @__PURE__ */ jsx87(ChartCrosshair, { points: visible, label, formatValue, disabled }),
|
|
4681
|
+
points.length > 1 && /* @__PURE__ */ jsx87(
|
|
4242
4682
|
RangeBrush,
|
|
4243
4683
|
{
|
|
4244
4684
|
label: "\u53EF\u89C1\u6570\u636E\u8303\u56F4",
|
|
@@ -4250,22 +4690,22 @@ function ZoomableChart({
|
|
|
4250
4690
|
formatValue: (index) => points[index]?.label ?? String(index)
|
|
4251
4691
|
}
|
|
4252
4692
|
),
|
|
4253
|
-
/* @__PURE__ */
|
|
4693
|
+
/* @__PURE__ */ jsx87("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" })
|
|
4254
4694
|
] });
|
|
4255
4695
|
}
|
|
4256
4696
|
|
|
4257
4697
|
// src/feedback/HoldToConfirm.tsx
|
|
4258
|
-
import { useId as
|
|
4698
|
+
import { useId as useId28 } from "react";
|
|
4259
4699
|
|
|
4260
4700
|
// src/feedback/useHoldConfirmation.ts
|
|
4261
|
-
import { useEffect as
|
|
4701
|
+
import { useEffect as useEffect17, useRef as useRef17, useState as useState45 } from "react";
|
|
4262
4702
|
function useHoldConfirmation(options) {
|
|
4263
|
-
const latest =
|
|
4703
|
+
const latest = useRef17(options);
|
|
4264
4704
|
latest.current = options;
|
|
4265
|
-
const session =
|
|
4266
|
-
const frame =
|
|
4267
|
-
const [progress, setProgress] =
|
|
4268
|
-
const [message, setMessage] =
|
|
4705
|
+
const session = useRef17(null);
|
|
4706
|
+
const frame = useRef17(void 0);
|
|
4707
|
+
const [progress, setProgress] = useState45(0);
|
|
4708
|
+
const [message, setMessage] = useState45("");
|
|
4269
4709
|
function stopFrame() {
|
|
4270
4710
|
if (frame.current !== void 0) cancelAnimationFrame(frame.current);
|
|
4271
4711
|
frame.current = void 0;
|
|
@@ -4311,10 +4751,10 @@ function useHoldConfirmation(options) {
|
|
|
4311
4751
|
function release(source) {
|
|
4312
4752
|
if (session.current?.source === source) cancel();
|
|
4313
4753
|
}
|
|
4314
|
-
|
|
4754
|
+
useEffect17(() => {
|
|
4315
4755
|
cancel();
|
|
4316
4756
|
}, [options.actionKey, options.duration, options.blocked]);
|
|
4317
|
-
|
|
4757
|
+
useEffect17(() => {
|
|
4318
4758
|
const hide = () => {
|
|
4319
4759
|
if (document.hidden) cancel();
|
|
4320
4760
|
};
|
|
@@ -4336,15 +4776,15 @@ function useHoldConfirmation(options) {
|
|
|
4336
4776
|
}
|
|
4337
4777
|
|
|
4338
4778
|
// src/feedback/ConfirmationAlternative.tsx
|
|
4339
|
-
import { useEffect as
|
|
4340
|
-
import { jsx as
|
|
4779
|
+
import { useEffect as useEffect18, useId as useId27, useRef as useRef18, useState as useState46 } from "react";
|
|
4780
|
+
import { jsx as jsx88, jsxs as jsxs80 } from "react/jsx-runtime";
|
|
4341
4781
|
function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
4342
|
-
const [open, setOpen] =
|
|
4343
|
-
const [requested, setRequested] =
|
|
4344
|
-
const requestedRef =
|
|
4345
|
-
const trigger =
|
|
4346
|
-
const confirm =
|
|
4347
|
-
const id =
|
|
4782
|
+
const [open, setOpen] = useState46(false);
|
|
4783
|
+
const [requested, setRequested] = useState46(false);
|
|
4784
|
+
const requestedRef = useRef18(false);
|
|
4785
|
+
const trigger = useRef18(null);
|
|
4786
|
+
const confirm = useRef18(null);
|
|
4787
|
+
const id = useId27();
|
|
4348
4788
|
function close() {
|
|
4349
4789
|
setOpen(false);
|
|
4350
4790
|
trigger.current?.focus();
|
|
@@ -4365,11 +4805,11 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4365
4805
|
setRequested(true);
|
|
4366
4806
|
onConfirm();
|
|
4367
4807
|
}
|
|
4368
|
-
|
|
4808
|
+
useEffect18(() => {
|
|
4369
4809
|
if (open) confirm.current?.focus();
|
|
4370
4810
|
}, [open]);
|
|
4371
|
-
return /* @__PURE__ */
|
|
4372
|
-
/* @__PURE__ */
|
|
4811
|
+
return /* @__PURE__ */ jsxs80("div", { children: [
|
|
4812
|
+
/* @__PURE__ */ jsx88(
|
|
4373
4813
|
Button,
|
|
4374
4814
|
{
|
|
4375
4815
|
type: "button",
|
|
@@ -4383,7 +4823,7 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4383
4823
|
children: "\u5206\u6B65\u786E\u8BA4\uFF08\u65E0\u9700\u957F\u6309\uFF09"
|
|
4384
4824
|
}
|
|
4385
4825
|
),
|
|
4386
|
-
open && /* @__PURE__ */
|
|
4826
|
+
open && /* @__PURE__ */ jsxs80(
|
|
4387
4827
|
"div",
|
|
4388
4828
|
{
|
|
4389
4829
|
id,
|
|
@@ -4394,16 +4834,16 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4394
4834
|
if (event.key === "Escape") close();
|
|
4395
4835
|
},
|
|
4396
4836
|
children: [
|
|
4397
|
-
/* @__PURE__ */
|
|
4837
|
+
/* @__PURE__ */ jsxs80("p", { children: [
|
|
4398
4838
|
"\u786E\u8BA4\u6267\u884C\u201C",
|
|
4399
4839
|
label,
|
|
4400
4840
|
"\u201D\uFF1F"
|
|
4401
4841
|
] }),
|
|
4402
|
-
/* @__PURE__ */
|
|
4403
|
-
/* @__PURE__ */
|
|
4404
|
-
/* @__PURE__ */
|
|
4842
|
+
/* @__PURE__ */ jsxs80("div", { className: "hf-confirm-actions", children: [
|
|
4843
|
+
/* @__PURE__ */ jsx88(Button, { type: "button", variant: "outline", onClick: close, children: "\u53D6\u6D88" }),
|
|
4844
|
+
/* @__PURE__ */ jsx88(Button, { type: "button", ref: confirm, disabled: blocked || requested, onClick: request, children: "\u786E\u8BA4\u6267\u884C" })
|
|
4405
4845
|
] }),
|
|
4406
|
-
requested && /* @__PURE__ */
|
|
4846
|
+
requested && /* @__PURE__ */ jsx88("p", { className: "hf-confirm-hint", role: "status", children: "\u5DF2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u8BF7\u7B49\u5F85\u64CD\u4F5C\u7ED3\u679C" })
|
|
4407
4847
|
]
|
|
4408
4848
|
}
|
|
4409
4849
|
)
|
|
@@ -4411,7 +4851,7 @@ function ConfirmationAlternative({ label, blocked, onOpen, onConfirm }) {
|
|
|
4411
4851
|
}
|
|
4412
4852
|
|
|
4413
4853
|
// src/feedback/HoldToConfirm.tsx
|
|
4414
|
-
import { jsx as
|
|
4854
|
+
import { jsx as jsx89, jsxs as jsxs81 } from "react/jsx-runtime";
|
|
4415
4855
|
function HoldToConfirm({
|
|
4416
4856
|
actionKey,
|
|
4417
4857
|
label,
|
|
@@ -4425,14 +4865,14 @@ function HoldToConfirm({
|
|
|
4425
4865
|
const milliseconds = Number.isFinite(duration) ? Math.max(500, Math.min(1e4, duration)) : 1500;
|
|
4426
4866
|
const blocked = disabled || loading;
|
|
4427
4867
|
const hold = useHoldConfirmation({ actionKey, duration: milliseconds, blocked, onConfirm });
|
|
4428
|
-
const hintId =
|
|
4429
|
-
return /* @__PURE__ */
|
|
4430
|
-
/* @__PURE__ */
|
|
4868
|
+
const hintId = useId28();
|
|
4869
|
+
return /* @__PURE__ */ jsxs81("div", { className: `hf-hold-confirm ${className}`, children: [
|
|
4870
|
+
/* @__PURE__ */ jsxs81("p", { id: hintId, className: "hf-confirm-hint", children: [
|
|
4431
4871
|
"\u6309\u4F4F",
|
|
4432
4872
|
milliseconds / 1e3,
|
|
4433
4873
|
"\u79D2\u53D1\u51FA\u786E\u8BA4\u8BF7\u6C42\uFF0C\u63D0\u524D\u677E\u5F00\u53EF\u53D6\u6D88\u3002"
|
|
4434
4874
|
] }),
|
|
4435
|
-
/* @__PURE__ */
|
|
4875
|
+
/* @__PURE__ */ jsx89(
|
|
4436
4876
|
Button,
|
|
4437
4877
|
{
|
|
4438
4878
|
type: "button",
|
|
@@ -4469,8 +4909,8 @@ function HoldToConfirm({
|
|
|
4469
4909
|
children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : label
|
|
4470
4910
|
}
|
|
4471
4911
|
),
|
|
4472
|
-
/* @__PURE__ */
|
|
4473
|
-
/* @__PURE__ */
|
|
4912
|
+
/* @__PURE__ */ jsx89("div", { className: "hf-hold-confirm__track", "aria-hidden": "true", children: /* @__PURE__ */ jsx89("span", { style: { width: `${hold.progress * 100}%` } }) }),
|
|
4913
|
+
/* @__PURE__ */ jsx89(
|
|
4474
4914
|
ConfirmationAlternative,
|
|
4475
4915
|
{
|
|
4476
4916
|
label,
|
|
@@ -4480,16 +4920,16 @@ function HoldToConfirm({
|
|
|
4480
4920
|
},
|
|
4481
4921
|
JSON.stringify([actionKey, milliseconds, blocked])
|
|
4482
4922
|
),
|
|
4483
|
-
/* @__PURE__ */
|
|
4484
|
-
error && /* @__PURE__ */
|
|
4923
|
+
/* @__PURE__ */ jsx89("p", { className: "hf-confirm-hint", role: "status", children: hold.message }),
|
|
4924
|
+
error && /* @__PURE__ */ jsx89("p", { className: "hf-confirm-error hf-tone--danger", role: "alert", children: error })
|
|
4485
4925
|
] });
|
|
4486
4926
|
}
|
|
4487
4927
|
|
|
4488
4928
|
// src/feedback/TypedConfirm.tsx
|
|
4489
|
-
import { useId as
|
|
4490
|
-
import { jsx as
|
|
4929
|
+
import { useId as useId29, useRef as useRef19, useState as useState47 } from "react";
|
|
4930
|
+
import { jsx as jsx90, jsxs as jsxs82 } from "react/jsx-runtime";
|
|
4491
4931
|
function TypedConfirm(props) {
|
|
4492
|
-
return /* @__PURE__ */
|
|
4932
|
+
return /* @__PURE__ */ jsx90(TypedConfirmFields, { ...props }, JSON.stringify([props.actionKey, props.confirmationText]));
|
|
4493
4933
|
}
|
|
4494
4934
|
function TypedConfirmFields({
|
|
4495
4935
|
confirmationText,
|
|
@@ -4502,12 +4942,12 @@ function TypedConfirmFields({
|
|
|
4502
4942
|
error,
|
|
4503
4943
|
className = ""
|
|
4504
4944
|
}) {
|
|
4505
|
-
const [value, setValue] =
|
|
4506
|
-
const [composing, setComposing] =
|
|
4507
|
-
const [requested, setRequested] =
|
|
4508
|
-
const composingRef =
|
|
4509
|
-
const valueRef =
|
|
4510
|
-
const titleId =
|
|
4945
|
+
const [value, setValue] = useState47("");
|
|
4946
|
+
const [composing, setComposing] = useState47(false);
|
|
4947
|
+
const [requested, setRequested] = useState47(false);
|
|
4948
|
+
const composingRef = useRef19(false);
|
|
4949
|
+
const valueRef = useRef19("");
|
|
4950
|
+
const titleId = useId29();
|
|
4511
4951
|
const validTarget = confirmationText.trim().length > 0 && !/[\r\n]/.test(confirmationText);
|
|
4512
4952
|
const blocked = disabled || loading;
|
|
4513
4953
|
const matches = validTarget && value === confirmationText && !composing;
|
|
@@ -4518,15 +4958,15 @@ function TypedConfirmFields({
|
|
|
4518
4958
|
setRequested(true);
|
|
4519
4959
|
onConfirm();
|
|
4520
4960
|
}
|
|
4521
|
-
return /* @__PURE__ */
|
|
4522
|
-
/* @__PURE__ */
|
|
4523
|
-
description && /* @__PURE__ */
|
|
4524
|
-
validTarget ? /* @__PURE__ */
|
|
4961
|
+
return /* @__PURE__ */ jsxs82("section", { className: `hf-typed-confirm ${className}`, "aria-labelledby": titleId, children: [
|
|
4962
|
+
/* @__PURE__ */ jsx90("h3", { id: titleId, children: label }),
|
|
4963
|
+
description && /* @__PURE__ */ jsx90("p", { children: description }),
|
|
4964
|
+
validTarget ? /* @__PURE__ */ jsxs82("p", { children: [
|
|
4525
4965
|
"\u8F93\u5165 ",
|
|
4526
|
-
/* @__PURE__ */
|
|
4966
|
+
/* @__PURE__ */ jsx90("code", { children: confirmationText }),
|
|
4527
4967
|
" \u4EE5\u786E\u8BA4\uFF0C\u9700\u5B8C\u5168\u4E00\u81F4\u3002"
|
|
4528
|
-
] }) : /* @__PURE__ */
|
|
4529
|
-
/* @__PURE__ */
|
|
4968
|
+
] }) : /* @__PURE__ */ jsx90("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" }),
|
|
4969
|
+
/* @__PURE__ */ jsx90(
|
|
4530
4970
|
Input,
|
|
4531
4971
|
{
|
|
4532
4972
|
label: "\u786E\u8BA4\u6587\u5B57",
|
|
@@ -4556,21 +4996,21 @@ function TypedConfirmFields({
|
|
|
4556
4996
|
}
|
|
4557
4997
|
}
|
|
4558
4998
|
),
|
|
4559
|
-
/* @__PURE__ */
|
|
4560
|
-
/* @__PURE__ */
|
|
4561
|
-
error && /* @__PURE__ */
|
|
4999
|
+
/* @__PURE__ */ jsx90(Button, { type: "button", disabled: blocked || !matches, onClick: confirm, children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : confirmLabel }),
|
|
5000
|
+
/* @__PURE__ */ jsx90("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" : "" }),
|
|
5001
|
+
error && /* @__PURE__ */ jsx90("p", { className: "hf-confirm-error hf-tone--danger", role: "alert", children: error })
|
|
4562
5002
|
] });
|
|
4563
5003
|
}
|
|
4564
5004
|
|
|
4565
5005
|
// src/data-display/SwipeActions.tsx
|
|
4566
|
-
import { useEffect as
|
|
5006
|
+
import { useEffect as useEffect20, useId as useId30, useRef as useRef21, useState as useState49 } from "react";
|
|
4567
5007
|
|
|
4568
5008
|
// src/data-display/useSwipeReveal.ts
|
|
4569
|
-
import { useEffect as
|
|
5009
|
+
import { useEffect as useEffect19, useRef as useRef20, useState as useState48 } from "react";
|
|
4570
5010
|
function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
4571
|
-
const session =
|
|
4572
|
-
const [offset, setOffset] =
|
|
4573
|
-
const cleanup =
|
|
5011
|
+
const session = useRef20(null);
|
|
5012
|
+
const [offset, setOffset] = useState48(null);
|
|
5013
|
+
const cleanup = useRef20(null);
|
|
4574
5014
|
function cancel() {
|
|
4575
5015
|
cleanup.current?.();
|
|
4576
5016
|
cleanup.current = null;
|
|
@@ -4616,7 +5056,7 @@ function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
|
4616
5056
|
if (!disabled && current.open === open && Math.abs(current.delta) >= 40) onChange(current.delta < 0);
|
|
4617
5057
|
if (event.currentTarget.hasPointerCapture(event.pointerId)) event.currentTarget.releasePointerCapture(event.pointerId);
|
|
4618
5058
|
}
|
|
4619
|
-
|
|
5059
|
+
useEffect19(() => () => {
|
|
4620
5060
|
cleanup.current?.();
|
|
4621
5061
|
session.current = null;
|
|
4622
5062
|
}, []);
|
|
@@ -4624,10 +5064,10 @@ function useSwipeReveal({ open, disabled, width, onChange }) {
|
|
|
4624
5064
|
}
|
|
4625
5065
|
|
|
4626
5066
|
// src/data-display/SwipeActions.tsx
|
|
4627
|
-
import { jsx as
|
|
5067
|
+
import { jsx as jsx91, jsxs as jsxs83 } from "react/jsx-runtime";
|
|
4628
5068
|
function SwipeActions(props) {
|
|
4629
5069
|
const identity = JSON.stringify([props.actionKey, props.disabled, props.actions.map(({ id, label, disabled, tone }) => [id, label, disabled, tone])]);
|
|
4630
|
-
return /* @__PURE__ */
|
|
5070
|
+
return /* @__PURE__ */ jsx91(SwipeActionsRow, { ...props }, identity);
|
|
4631
5071
|
}
|
|
4632
5072
|
function SwipeActionsRow({
|
|
4633
5073
|
label,
|
|
@@ -4639,10 +5079,10 @@ function SwipeActionsRow({
|
|
|
4639
5079
|
disabled = false,
|
|
4640
5080
|
className = ""
|
|
4641
5081
|
}) {
|
|
4642
|
-
const [internal, setInternal] =
|
|
4643
|
-
const trigger =
|
|
4644
|
-
const tools =
|
|
4645
|
-
const id =
|
|
5082
|
+
const [internal, setInternal] = useState49(defaultOpen);
|
|
5083
|
+
const trigger = useRef21(null);
|
|
5084
|
+
const tools = useRef21(null);
|
|
5085
|
+
const id = useId30();
|
|
4646
5086
|
const valid = actions.length > 0 && actions.every((item) => item.id.trim() && item.label.trim()) && new Set(actions.map((item) => item.id)).size === actions.length;
|
|
4647
5087
|
const blocked = disabled || !valid;
|
|
4648
5088
|
const open = !blocked && (controlled ?? internal);
|
|
@@ -4652,7 +5092,7 @@ function SwipeActionsRow({
|
|
|
4652
5092
|
onOpenChange?.(next);
|
|
4653
5093
|
}
|
|
4654
5094
|
const swipe = useSwipeReveal({ open, disabled: blocked, width: 144, onChange: request });
|
|
4655
|
-
|
|
5095
|
+
useEffect20(() => {
|
|
4656
5096
|
if (!open) return;
|
|
4657
5097
|
const frame = requestAnimationFrame(() => {
|
|
4658
5098
|
if (document.activeElement === trigger.current) tools.current?.querySelector("button:not(:disabled)")?.focus();
|
|
@@ -4669,10 +5109,10 @@ function SwipeActionsRow({
|
|
|
4669
5109
|
close();
|
|
4670
5110
|
action.onAction();
|
|
4671
5111
|
}
|
|
4672
|
-
return /* @__PURE__ */
|
|
5112
|
+
return /* @__PURE__ */ jsxs83("div", { className: `hf-swipe-actions ${className}`, onKeyDown: (event) => {
|
|
4673
5113
|
if (event.key === "Escape") close();
|
|
4674
5114
|
}, children: [
|
|
4675
|
-
/* @__PURE__ */
|
|
5115
|
+
/* @__PURE__ */ jsxs83(
|
|
4676
5116
|
"div",
|
|
4677
5117
|
{
|
|
4678
5118
|
className: "hf-swipe-actions__viewport",
|
|
@@ -4688,7 +5128,7 @@ function SwipeActionsRow({
|
|
|
4688
5128
|
if (!event.currentTarget.contains(event.relatedTarget)) swipe.cancel();
|
|
4689
5129
|
},
|
|
4690
5130
|
children: [
|
|
4691
|
-
open && /* @__PURE__ */
|
|
5131
|
+
open && /* @__PURE__ */ jsx91("div", { id, ref: tools, className: "hf-swipe-actions__tools", children: actions.map((action, index) => /* @__PURE__ */ jsx91(
|
|
4692
5132
|
Button,
|
|
4693
5133
|
{
|
|
4694
5134
|
type: "button",
|
|
@@ -4700,7 +5140,7 @@ function SwipeActionsRow({
|
|
|
4700
5140
|
},
|
|
4701
5141
|
index
|
|
4702
5142
|
)) }),
|
|
4703
|
-
/* @__PURE__ */
|
|
5143
|
+
/* @__PURE__ */ jsx91(
|
|
4704
5144
|
"div",
|
|
4705
5145
|
{
|
|
4706
5146
|
className: "hf-swipe-actions__content",
|
|
@@ -4713,7 +5153,7 @@ function SwipeActionsRow({
|
|
|
4713
5153
|
]
|
|
4714
5154
|
}
|
|
4715
5155
|
),
|
|
4716
|
-
/* @__PURE__ */
|
|
5156
|
+
/* @__PURE__ */ jsxs83(
|
|
4717
5157
|
Button,
|
|
4718
5158
|
{
|
|
4719
5159
|
type: "button",
|
|
@@ -4734,16 +5174,16 @@ function SwipeActionsRow({
|
|
|
4734
5174
|
]
|
|
4735
5175
|
}
|
|
4736
5176
|
),
|
|
4737
|
-
!valid && /* @__PURE__ */
|
|
5177
|
+
!valid && /* @__PURE__ */ jsx91("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" })
|
|
4738
5178
|
] });
|
|
4739
5179
|
}
|
|
4740
5180
|
|
|
4741
5181
|
// src/feedback/ChecklistConfirm.tsx
|
|
4742
|
-
import { useId as
|
|
4743
|
-
import { jsx as
|
|
5182
|
+
import { useId as useId31, useRef as useRef22, useState as useState50 } from "react";
|
|
5183
|
+
import { jsx as jsx92, jsxs as jsxs84 } from "react/jsx-runtime";
|
|
4744
5184
|
function ChecklistConfirm(props) {
|
|
4745
5185
|
const identity = JSON.stringify([props.actionKey, props.items.map(({ id, label, description }) => [id, label, description])]);
|
|
4746
|
-
return /* @__PURE__ */
|
|
5186
|
+
return /* @__PURE__ */ jsx92(ChecklistConfirmFields, { ...props }, identity);
|
|
4747
5187
|
}
|
|
4748
5188
|
function ChecklistConfirmFields({
|
|
4749
5189
|
title,
|
|
@@ -4755,11 +5195,11 @@ function ChecklistConfirmFields({
|
|
|
4755
5195
|
error,
|
|
4756
5196
|
className = ""
|
|
4757
5197
|
}) {
|
|
4758
|
-
const [checked, setChecked] =
|
|
4759
|
-
const [requested, setRequested] =
|
|
4760
|
-
const lock =
|
|
4761
|
-
const first =
|
|
4762
|
-
const titleId =
|
|
5198
|
+
const [checked, setChecked] = useState50(/* @__PURE__ */ new Set());
|
|
5199
|
+
const [requested, setRequested] = useState50(false);
|
|
5200
|
+
const lock = useRef22(false);
|
|
5201
|
+
const first = useRef22(null);
|
|
5202
|
+
const titleId = useId31();
|
|
4763
5203
|
const valid = items.length > 0 && items.every((item) => item.id.trim() && item.label.trim()) && new Set(items.map((item) => item.id)).size === items.length;
|
|
4764
5204
|
const blocked = disabled || loading || !valid;
|
|
4765
5205
|
const allChecked = valid && items.every((item) => checked.has(item.id));
|
|
@@ -4782,10 +5222,10 @@ function ChecklistConfirmFields({
|
|
|
4782
5222
|
first.current?.focus();
|
|
4783
5223
|
onConfirm();
|
|
4784
5224
|
}
|
|
4785
|
-
return /* @__PURE__ */
|
|
4786
|
-
/* @__PURE__ */
|
|
4787
|
-
!valid && /* @__PURE__ */
|
|
4788
|
-
/* @__PURE__ */
|
|
5225
|
+
return /* @__PURE__ */ jsxs84("section", { className: `hf-checklist-confirm ${className}`, "aria-labelledby": titleId, children: [
|
|
5226
|
+
/* @__PURE__ */ jsx92("h3", { id: titleId, children: title }),
|
|
5227
|
+
!valid && /* @__PURE__ */ jsx92("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" }),
|
|
5228
|
+
/* @__PURE__ */ jsx92("div", { className: "hf-checklist-confirm__items", children: items.map((item, index) => /* @__PURE__ */ jsx92(
|
|
4789
5229
|
Checkbox,
|
|
4790
5230
|
{
|
|
4791
5231
|
ref: index === 0 ? first : void 0,
|
|
@@ -4797,22 +5237,22 @@ function ChecklistConfirmFields({
|
|
|
4797
5237
|
},
|
|
4798
5238
|
index
|
|
4799
5239
|
)) }),
|
|
4800
|
-
/* @__PURE__ */
|
|
4801
|
-
/* @__PURE__ */
|
|
4802
|
-
error && /* @__PURE__ */
|
|
5240
|
+
/* @__PURE__ */ jsx92("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` }),
|
|
5241
|
+
/* @__PURE__ */ jsx92(Button, { type: "button", disabled: blocked || !allChecked, onClick: confirm, children: loading ? "\u6B63\u5728\u5904\u7406\u8BF7\u6C42" : confirmLabel }),
|
|
5242
|
+
error && /* @__PURE__ */ jsx92("p", { role: "alert", className: "hf-tone--danger hf-row-error", children: error })
|
|
4803
5243
|
] });
|
|
4804
5244
|
}
|
|
4805
5245
|
|
|
4806
5246
|
// src/feedback/UndoNotice.tsx
|
|
4807
|
-
import { useId as
|
|
5247
|
+
import { useId as useId32 } from "react";
|
|
4808
5248
|
|
|
4809
5249
|
// src/feedback/useUndoDeadline.ts
|
|
4810
|
-
import { useEffect as
|
|
5250
|
+
import { useEffect as useEffect21, useState as useState51 } from "react";
|
|
4811
5251
|
function useUndoDeadline(expiresAt, active) {
|
|
4812
|
-
const [now, setNow] =
|
|
5252
|
+
const [now, setNow] = useState51(() => Date.now());
|
|
4813
5253
|
const valid = expiresAt === void 0 || Number.isFinite(expiresAt);
|
|
4814
5254
|
const expired = expiresAt !== void 0 && valid && expiresAt <= Math.max(now, Date.now());
|
|
4815
|
-
|
|
5255
|
+
useEffect21(() => {
|
|
4816
5256
|
if (!active || !valid || expiresAt === void 0 || expired) return;
|
|
4817
5257
|
const update = () => setNow(Date.now());
|
|
4818
5258
|
const timer = window.setTimeout(update, Math.min(1e3, Math.max(1, expiresAt - Date.now())));
|
|
@@ -4827,12 +5267,12 @@ function useUndoDeadline(expiresAt, active) {
|
|
|
4827
5267
|
}
|
|
4828
5268
|
|
|
4829
5269
|
// src/feedback/useUndoRequest.ts
|
|
4830
|
-
import { useEffect as
|
|
5270
|
+
import { useEffect as useEffect22, useRef as useRef23, useState as useState52 } from "react";
|
|
4831
5271
|
function useUndoRequest(onUndo) {
|
|
4832
|
-
const [phase, setPhase] =
|
|
4833
|
-
const currentPhase =
|
|
4834
|
-
const request =
|
|
4835
|
-
|
|
5272
|
+
const [phase, setPhase] = useState52("ready");
|
|
5273
|
+
const currentPhase = useRef23("ready");
|
|
5274
|
+
const request = useRef23(null);
|
|
5275
|
+
useEffect22(() => () => request.current?.abort(), []);
|
|
4836
5276
|
async function undo() {
|
|
4837
5277
|
if (currentPhase.current === "pending" || currentPhase.current === "undone") return;
|
|
4838
5278
|
const controller = new AbortController();
|
|
@@ -4856,9 +5296,9 @@ function useUndoRequest(onUndo) {
|
|
|
4856
5296
|
}
|
|
4857
5297
|
|
|
4858
5298
|
// src/feedback/UndoNotice.tsx
|
|
4859
|
-
import { jsx as
|
|
5299
|
+
import { jsx as jsx93, jsxs as jsxs85 } from "react/jsx-runtime";
|
|
4860
5300
|
function UndoNotice(props) {
|
|
4861
|
-
return /* @__PURE__ */
|
|
5301
|
+
return /* @__PURE__ */ jsx93(UndoNoticeSession, { ...props }, props.operationKey);
|
|
4862
5302
|
}
|
|
4863
5303
|
function UndoNoticeSession({
|
|
4864
5304
|
operationKey,
|
|
@@ -4873,8 +5313,8 @@ function UndoNoticeSession({
|
|
|
4873
5313
|
}) {
|
|
4874
5314
|
const { phase, undo } = useUndoRequest(onUndo);
|
|
4875
5315
|
const deadline = useUndoDeadline(expiresAt, phase === "ready" || phase === "failed");
|
|
4876
|
-
const messageId =
|
|
4877
|
-
const statusId =
|
|
5316
|
+
const messageId = useId32();
|
|
5317
|
+
const statusId = useId32();
|
|
4878
5318
|
const valid = deadline.valid && !!operationKey.trim() && !!message.trim() && !!undoLabel.trim();
|
|
4879
5319
|
const pending = phase === "pending";
|
|
4880
5320
|
const undone = phase === "undone";
|
|
@@ -4884,18 +5324,18 @@ function UndoNoticeSession({
|
|
|
4884
5324
|
if (blocked || expiresAt !== void 0 && Date.now() >= expiresAt) return;
|
|
4885
5325
|
void undo();
|
|
4886
5326
|
}
|
|
4887
|
-
return /* @__PURE__ */
|
|
4888
|
-
/* @__PURE__ */
|
|
4889
|
-
/* @__PURE__ */
|
|
4890
|
-
/* @__PURE__ */
|
|
4891
|
-
phase === "failed" && /* @__PURE__ */
|
|
4892
|
-
valid && !pending && !undone && !deadline.expired && deadline.remaining !== void 0 && /* @__PURE__ */
|
|
5327
|
+
return /* @__PURE__ */ jsxs85("section", { className: `hf-undo-notice ${className}`.trim(), "aria-labelledby": messageId, children: [
|
|
5328
|
+
/* @__PURE__ */ jsxs85("div", { className: "hf-undo-notice__content", children: [
|
|
5329
|
+
/* @__PURE__ */ jsx93("p", { id: messageId, className: "hf-undo-notice__message", children: message }),
|
|
5330
|
+
/* @__PURE__ */ jsx93("p", { id: statusId, role: "status", "aria-atomic": "true", className: "hf-undo-notice__status", children: status }),
|
|
5331
|
+
phase === "failed" && /* @__PURE__ */ jsx93("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" }),
|
|
5332
|
+
valid && !pending && !undone && !deadline.expired && deadline.remaining !== void 0 && /* @__PURE__ */ jsxs85("p", { className: "hf-undo-notice__deadline", "aria-live": "off", children: [
|
|
4893
5333
|
"\u5269\u4F59 ",
|
|
4894
5334
|
deadline.remaining,
|
|
4895
5335
|
" \u79D2"
|
|
4896
5336
|
] })
|
|
4897
5337
|
] }),
|
|
4898
|
-
/* @__PURE__ */
|
|
5338
|
+
/* @__PURE__ */ jsx93(
|
|
4899
5339
|
Button,
|
|
4900
5340
|
{
|
|
4901
5341
|
type: "button",
|
|
@@ -4910,93 +5350,11 @@ function UndoNoticeSession({
|
|
|
4910
5350
|
] });
|
|
4911
5351
|
}
|
|
4912
5352
|
|
|
4913
|
-
// src/navigation/useReadingPosition.ts
|
|
4914
|
-
import { useEffect as useEffect20, useState as useState49 } from "react";
|
|
4915
|
-
function useReadingPosition(target) {
|
|
4916
|
-
const [snapshot, setSnapshot] = useState49({ target, value: 0 });
|
|
4917
|
-
useEffect20(() => {
|
|
4918
|
-
if (target === null) return;
|
|
4919
|
-
const view = target?.ownerDocument.defaultView ?? window;
|
|
4920
|
-
const root = target ?? view.document.documentElement;
|
|
4921
|
-
const events = target ?? view;
|
|
4922
|
-
let frame = 0;
|
|
4923
|
-
let disposed = false;
|
|
4924
|
-
const measure = () => {
|
|
4925
|
-
frame = 0;
|
|
4926
|
-
if (disposed) return;
|
|
4927
|
-
const viewport = target ? root.clientHeight : view.innerHeight;
|
|
4928
|
-
const height = target ? root.scrollHeight : Math.max(root.scrollHeight, view.document.body?.scrollHeight ?? 0);
|
|
4929
|
-
const offset = target ? root.scrollTop : view.scrollY;
|
|
4930
|
-
const range = Math.max(0, height - viewport);
|
|
4931
|
-
const value = range === 0 ? 100 : Math.round(Math.min(1, Math.max(0, offset / range)) * 100);
|
|
4932
|
-
setSnapshot((previous) => previous.target === target && previous.value === value ? previous : { target, value });
|
|
4933
|
-
};
|
|
4934
|
-
const schedule = () => {
|
|
4935
|
-
if (!disposed && !frame) frame = view.requestAnimationFrame(measure);
|
|
4936
|
-
};
|
|
4937
|
-
const resize = new ResizeObserver(schedule);
|
|
4938
|
-
const observeContent = () => {
|
|
4939
|
-
resize.disconnect();
|
|
4940
|
-
resize.observe(root);
|
|
4941
|
-
for (const child of root.children) resize.observe(child);
|
|
4942
|
-
if (!target && view.document.body) {
|
|
4943
|
-
resize.observe(view.document.body);
|
|
4944
|
-
for (const child of view.document.body.children) resize.observe(child);
|
|
4945
|
-
}
|
|
4946
|
-
schedule();
|
|
4947
|
-
};
|
|
4948
|
-
const mutations = new MutationObserver(observeContent);
|
|
4949
|
-
mutations.observe(root, { childList: true, subtree: true, characterData: true, attributes: true });
|
|
4950
|
-
events.addEventListener("scroll", schedule, { passive: true });
|
|
4951
|
-
view.addEventListener("resize", schedule);
|
|
4952
|
-
root.addEventListener("load", schedule, true);
|
|
4953
|
-
observeContent();
|
|
4954
|
-
return () => {
|
|
4955
|
-
disposed = true;
|
|
4956
|
-
view.cancelAnimationFrame(frame);
|
|
4957
|
-
resize.disconnect();
|
|
4958
|
-
mutations.disconnect();
|
|
4959
|
-
events.removeEventListener("scroll", schedule);
|
|
4960
|
-
view.removeEventListener("resize", schedule);
|
|
4961
|
-
root.removeEventListener("load", schedule, true);
|
|
4962
|
-
};
|
|
4963
|
-
}, [target]);
|
|
4964
|
-
return target === null || snapshot.target !== target ? 0 : snapshot.value;
|
|
4965
|
-
}
|
|
4966
|
-
|
|
4967
|
-
// src/navigation/ReadingProgress.tsx
|
|
4968
|
-
import { jsx as jsx86, jsxs as jsxs78 } from "react/jsx-runtime";
|
|
4969
|
-
function ReadingProgress({ target, label = "\u9605\u8BFB\u8FDB\u5EA6", showValue = true, className = "" }) {
|
|
4970
|
-
const value = useReadingPosition(target);
|
|
4971
|
-
const name = label.trim() || "\u9605\u8BFB\u8FDB\u5EA6";
|
|
4972
|
-
return /* @__PURE__ */ jsxs78("div", { className: `hf-reading-progress ${className}`.trim(), children: [
|
|
4973
|
-
showValue && /* @__PURE__ */ jsxs78("div", { className: "hf-reading-progress__caption", "aria-hidden": "true", children: [
|
|
4974
|
-
/* @__PURE__ */ jsx86("span", { children: name }),
|
|
4975
|
-
/* @__PURE__ */ jsxs78("span", { children: [
|
|
4976
|
-
value,
|
|
4977
|
-
"%"
|
|
4978
|
-
] })
|
|
4979
|
-
] }),
|
|
4980
|
-
/* @__PURE__ */ jsx86(
|
|
4981
|
-
"div",
|
|
4982
|
-
{
|
|
4983
|
-
className: "hf-reading-progress__track",
|
|
4984
|
-
role: "progressbar",
|
|
4985
|
-
"aria-label": name,
|
|
4986
|
-
"aria-valuemin": 0,
|
|
4987
|
-
"aria-valuemax": 100,
|
|
4988
|
-
"aria-valuenow": value,
|
|
4989
|
-
children: /* @__PURE__ */ jsx86("span", { className: "hf-reading-progress__fill", style: { width: `${value}%` } })
|
|
4990
|
-
}
|
|
4991
|
-
)
|
|
4992
|
-
] });
|
|
4993
|
-
}
|
|
4994
|
-
|
|
4995
5353
|
// src/data-display/LoadMore.tsx
|
|
4996
|
-
import { useEffect as
|
|
4997
|
-
import { jsx as
|
|
5354
|
+
import { useEffect as useEffect23, useRef as useRef24, useState as useState53 } from "react";
|
|
5355
|
+
import { jsx as jsx94, jsxs as jsxs86 } from "react/jsx-runtime";
|
|
4998
5356
|
function LoadMore(props) {
|
|
4999
|
-
return /* @__PURE__ */
|
|
5357
|
+
return /* @__PURE__ */ jsx94(LoadMoreControl, { ...props }, props.resetKey);
|
|
5000
5358
|
}
|
|
5001
5359
|
function LoadMoreControl({
|
|
5002
5360
|
onLoad,
|
|
@@ -5007,12 +5365,12 @@ function LoadMoreControl({
|
|
|
5007
5365
|
className = "",
|
|
5008
5366
|
trigger = 0
|
|
5009
5367
|
}) {
|
|
5010
|
-
const [phase, setPhase] =
|
|
5011
|
-
const request =
|
|
5012
|
-
const alive =
|
|
5013
|
-
const latest =
|
|
5368
|
+
const [phase, setPhase] = useState53("idle");
|
|
5369
|
+
const request = useRef24(null);
|
|
5370
|
+
const alive = useRef24(true);
|
|
5371
|
+
const latest = useRef24({ onLoad, hasMore, disabled });
|
|
5014
5372
|
latest.current = { onLoad, hasMore, disabled };
|
|
5015
|
-
|
|
5373
|
+
useEffect23(() => {
|
|
5016
5374
|
alive.current = true;
|
|
5017
5375
|
return () => {
|
|
5018
5376
|
alive.current = false;
|
|
@@ -5033,32 +5391,32 @@ function LoadMoreControl({
|
|
|
5033
5391
|
if (request.current === controller) request.current = null;
|
|
5034
5392
|
}
|
|
5035
5393
|
}
|
|
5036
|
-
const seen =
|
|
5037
|
-
|
|
5394
|
+
const seen = useRef24(0);
|
|
5395
|
+
useEffect23(() => {
|
|
5038
5396
|
if (trigger === seen.current) return;
|
|
5039
5397
|
seen.current = trigger;
|
|
5040
5398
|
if (phase !== "error") void load();
|
|
5041
5399
|
}, [trigger]);
|
|
5042
5400
|
const blocked = disabled || !hasMore || phase === "pending";
|
|
5043
|
-
return /* @__PURE__ */
|
|
5044
|
-
/* @__PURE__ */
|
|
5045
|
-
phase === "error" && hasMore && /* @__PURE__ */
|
|
5046
|
-
/* @__PURE__ */
|
|
5401
|
+
return /* @__PURE__ */ jsxs86("div", { className: `hf-content-loading ${className}`.trim(), "aria-busy": phase === "pending", children: [
|
|
5402
|
+
/* @__PURE__ */ jsx94("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" : "" }),
|
|
5403
|
+
phase === "error" && hasMore && /* @__PURE__ */ jsx94("p", { role: "alert", className: "hf-tone--danger", children: errorMessage.trim() || "\u52A0\u8F7D\u5931\u8D25\uFF0C\u8BF7\u91CD\u8BD5\u3002" }),
|
|
5404
|
+
/* @__PURE__ */ jsx94(Button, { type: "button", variant: "outline", "aria-disabled": blocked, onClick: () => {
|
|
5047
5405
|
if (!blocked) void load();
|
|
5048
5406
|
}, 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" })
|
|
5049
5407
|
] });
|
|
5050
5408
|
}
|
|
5051
5409
|
|
|
5052
5410
|
// src/data-display/InfiniteScroll.tsx
|
|
5053
|
-
import { useEffect as
|
|
5054
|
-
import { jsx as
|
|
5411
|
+
import { useEffect as useEffect24, useRef as useRef25, useState as useState54 } from "react";
|
|
5412
|
+
import { jsx as jsx95, jsxs as jsxs87 } from "react/jsx-runtime";
|
|
5055
5413
|
function InfiniteScroll(props) {
|
|
5056
|
-
return /* @__PURE__ */
|
|
5414
|
+
return /* @__PURE__ */ jsx95(InfiniteScrollSession, { ...props }, props.resetKey);
|
|
5057
5415
|
}
|
|
5058
5416
|
function InfiniteScrollSession({ children, root, rootMargin = "0px", ...props }) {
|
|
5059
|
-
const sentinel =
|
|
5060
|
-
const [trigger, setTrigger] =
|
|
5061
|
-
|
|
5417
|
+
const sentinel = useRef25(null);
|
|
5418
|
+
const [trigger, setTrigger] = useState54(0);
|
|
5419
|
+
useEffect24(() => {
|
|
5062
5420
|
if (!sentinel.current || root === null || props.disabled || !props.hasMore || typeof IntersectionObserver === "undefined") return;
|
|
5063
5421
|
let inside = false;
|
|
5064
5422
|
let observer;
|
|
@@ -5074,16 +5432,16 @@ function InfiniteScrollSession({ children, root, rootMargin = "0px", ...props })
|
|
|
5074
5432
|
observer.observe(sentinel.current);
|
|
5075
5433
|
return () => observer.disconnect();
|
|
5076
5434
|
}, [root, rootMargin, props.disabled, props.hasMore]);
|
|
5077
|
-
return /* @__PURE__ */
|
|
5435
|
+
return /* @__PURE__ */ jsxs87("div", { className: "hf-infinite-scroll", children: [
|
|
5078
5436
|
children,
|
|
5079
|
-
/* @__PURE__ */
|
|
5080
|
-
/* @__PURE__ */
|
|
5437
|
+
/* @__PURE__ */ jsx95("div", { ref: sentinel, className: "hf-infinite-scroll__sentinel", "aria-hidden": "true" }),
|
|
5438
|
+
/* @__PURE__ */ jsx95(LoadMoreControl, { ...props, trigger })
|
|
5081
5439
|
] });
|
|
5082
5440
|
}
|
|
5083
5441
|
|
|
5084
5442
|
// src/data-display/LazyLoad.tsx
|
|
5085
|
-
import { useEffect as
|
|
5086
|
-
import { Fragment as
|
|
5443
|
+
import { useEffect as useEffect25, useRef as useRef26, useState as useState55 } from "react";
|
|
5444
|
+
import { Fragment as Fragment10, jsx as jsx96, jsxs as jsxs88 } from "react/jsx-runtime";
|
|
5087
5445
|
function LazyLoad({
|
|
5088
5446
|
children,
|
|
5089
5447
|
placeholder,
|
|
@@ -5094,16 +5452,16 @@ function LazyLoad({
|
|
|
5094
5452
|
label = "\u663E\u793A\u5185\u5BB9",
|
|
5095
5453
|
className = ""
|
|
5096
5454
|
}) {
|
|
5097
|
-
const target =
|
|
5098
|
-
const [mounted, setMounted] =
|
|
5099
|
-
const restoreFocus =
|
|
5100
|
-
|
|
5455
|
+
const target = useRef26(null);
|
|
5456
|
+
const [mounted, setMounted] = useState55(false);
|
|
5457
|
+
const restoreFocus = useRef26(false);
|
|
5458
|
+
useEffect25(() => {
|
|
5101
5459
|
if (mounted && restoreFocus.current) {
|
|
5102
5460
|
target.current?.focus({ preventScroll: true });
|
|
5103
5461
|
restoreFocus.current = false;
|
|
5104
5462
|
}
|
|
5105
5463
|
}, [mounted]);
|
|
5106
|
-
|
|
5464
|
+
useEffect25(() => {
|
|
5107
5465
|
if (mounted) return;
|
|
5108
5466
|
if (disabled) {
|
|
5109
5467
|
setMounted(true);
|
|
@@ -5129,16 +5487,16 @@ function LazyLoad({
|
|
|
5129
5487
|
observer.observe(target.current);
|
|
5130
5488
|
return () => observer.disconnect();
|
|
5131
5489
|
}, [mounted, disabled, root, rootMargin]);
|
|
5132
|
-
return /* @__PURE__ */
|
|
5490
|
+
return /* @__PURE__ */ jsx96(
|
|
5133
5491
|
"div",
|
|
5134
5492
|
{
|
|
5135
5493
|
ref: target,
|
|
5136
5494
|
tabIndex: -1,
|
|
5137
5495
|
className: `hf-lazy-load ${className}`.trim(),
|
|
5138
5496
|
style: { minHeight: Number.isFinite(minHeight) ? Math.max(0, minHeight) : 160 },
|
|
5139
|
-
children: mounted || disabled ? children : /* @__PURE__ */
|
|
5497
|
+
children: mounted || disabled ? children : /* @__PURE__ */ jsxs88(Fragment10, { children: [
|
|
5140
5498
|
placeholder,
|
|
5141
|
-
/* @__PURE__ */
|
|
5499
|
+
/* @__PURE__ */ jsx96(Button, { type: "button", variant: "outline", onClick: () => {
|
|
5142
5500
|
restoreFocus.current = true;
|
|
5143
5501
|
setMounted(true);
|
|
5144
5502
|
}, children: label.trim() || "\u663E\u793A\u5185\u5BB9" })
|
|
@@ -5148,24 +5506,24 @@ function LazyLoad({
|
|
|
5148
5506
|
}
|
|
5149
5507
|
|
|
5150
5508
|
// src/feedback/OptimisticUpdate.tsx
|
|
5151
|
-
import { useId as
|
|
5509
|
+
import { useId as useId33 } from "react";
|
|
5152
5510
|
|
|
5153
5511
|
// src/feedback/useOptimisticRequest.ts
|
|
5154
|
-
import { useEffect as
|
|
5512
|
+
import { useEffect as useEffect26, useRef as useRef27, useState as useState56 } from "react";
|
|
5155
5513
|
function useOptimisticRequest(initialValue, onUpdate, disabled) {
|
|
5156
|
-
const [view, setView] =
|
|
5514
|
+
const [view, setView] = useState56(
|
|
5157
5515
|
{ value: initialValue, phase: "idle" }
|
|
5158
5516
|
);
|
|
5159
|
-
const currentView =
|
|
5160
|
-
const confirmed =
|
|
5161
|
-
const desired =
|
|
5162
|
-
const failed =
|
|
5163
|
-
const active =
|
|
5164
|
-
const sequence =
|
|
5165
|
-
const alive =
|
|
5166
|
-
const latest =
|
|
5517
|
+
const currentView = useRef27(view);
|
|
5518
|
+
const confirmed = useRef27(initialValue);
|
|
5519
|
+
const desired = useRef27(null);
|
|
5520
|
+
const failed = useRef27(null);
|
|
5521
|
+
const active = useRef27(null);
|
|
5522
|
+
const sequence = useRef27(0);
|
|
5523
|
+
const alive = useRef27(true);
|
|
5524
|
+
const latest = useRef27({ onUpdate, disabled });
|
|
5167
5525
|
latest.current = { onUpdate, disabled };
|
|
5168
|
-
|
|
5526
|
+
useEffect26(() => {
|
|
5169
5527
|
alive.current = true;
|
|
5170
5528
|
return () => {
|
|
5171
5529
|
alive.current = false;
|
|
@@ -5215,9 +5573,9 @@ function useOptimisticRequest(initialValue, onUpdate, disabled) {
|
|
|
5215
5573
|
}
|
|
5216
5574
|
|
|
5217
5575
|
// src/feedback/OptimisticUpdate.tsx
|
|
5218
|
-
import { jsx as
|
|
5576
|
+
import { jsx as jsx97, jsxs as jsxs89 } from "react/jsx-runtime";
|
|
5219
5577
|
function OptimisticUpdate(props) {
|
|
5220
|
-
return /* @__PURE__ */
|
|
5578
|
+
return /* @__PURE__ */ jsx97(OptimisticSession, { ...props }, props.operationKey);
|
|
5221
5579
|
}
|
|
5222
5580
|
function OptimisticSession({
|
|
5223
5581
|
initialValue,
|
|
@@ -5229,12 +5587,149 @@ function OptimisticSession({
|
|
|
5229
5587
|
className = ""
|
|
5230
5588
|
}) {
|
|
5231
5589
|
const state = useOptimisticRequest(initialValue, onUpdate, disabled);
|
|
5232
|
-
const statusId =
|
|
5590
|
+
const statusId = useId33();
|
|
5233
5591
|
const name = label.trim() || "\u66F4\u65B0";
|
|
5234
|
-
return /* @__PURE__ */
|
|
5592
|
+
return /* @__PURE__ */ jsxs89("div", { className: `hf-optimistic-update ${className}`.trim(), role: "group", "aria-label": name, "aria-describedby": statusId, children: [
|
|
5235
5593
|
children(state),
|
|
5236
|
-
/* @__PURE__ */
|
|
5237
|
-
state.phase === "error" && /* @__PURE__ */
|
|
5594
|
+
/* @__PURE__ */ jsx97("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` : "" }),
|
|
5595
|
+
state.phase === "error" && /* @__PURE__ */ jsx97("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" })
|
|
5596
|
+
] });
|
|
5597
|
+
}
|
|
5598
|
+
|
|
5599
|
+
// src/feedback/TaskProgress.tsx
|
|
5600
|
+
import { useEffect as useEffect28, useId as useId34, useMemo as useMemo11 } from "react";
|
|
5601
|
+
|
|
5602
|
+
// src/feedback/useTaskProgress.ts
|
|
5603
|
+
import { useCallback, useEffect as useEffect27, useRef as useRef28, useState as useState57 } from "react";
|
|
5604
|
+
var clamp = (value) => Math.min(100, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
5605
|
+
function useTaskProgress(run, stageIds, disabled) {
|
|
5606
|
+
const [snapshot, setSnapshot] = useState57({
|
|
5607
|
+
phase: "idle",
|
|
5608
|
+
progress: 0
|
|
5609
|
+
});
|
|
5610
|
+
const runRef = useRef28(run);
|
|
5611
|
+
const controllerRef = useRef28(void 0);
|
|
5612
|
+
const generationRef = useRef28(0);
|
|
5613
|
+
runRef.current = run;
|
|
5614
|
+
const start = useCallback(() => {
|
|
5615
|
+
if (disabled || controllerRef.current) return;
|
|
5616
|
+
const generation = ++generationRef.current;
|
|
5617
|
+
const controller = new AbortController();
|
|
5618
|
+
controllerRef.current = controller;
|
|
5619
|
+
setSnapshot({ phase: "running", activeStageId: stageIds[0], progress: 0 });
|
|
5620
|
+
const report = (update) => {
|
|
5621
|
+
if (generation !== generationRef.current || controller.signal.aborted || !stageIds.includes(update.stageId)) return;
|
|
5622
|
+
setSnapshot((current) => current.phase !== "running" ? current : {
|
|
5623
|
+
...current,
|
|
5624
|
+
activeStageId: update.stageId,
|
|
5625
|
+
progress: update.progress === void 0 ? current.progress : clamp(update.progress),
|
|
5626
|
+
message: update.message
|
|
5627
|
+
});
|
|
5628
|
+
};
|
|
5629
|
+
Promise.resolve().then(() => {
|
|
5630
|
+
if (generation !== generationRef.current || controller.signal.aborted) throw new Error("cancelled");
|
|
5631
|
+
return runRef.current({ signal: controller.signal, report });
|
|
5632
|
+
}).then(
|
|
5633
|
+
(result) => {
|
|
5634
|
+
if (generation !== generationRef.current || controller.signal.aborted) return;
|
|
5635
|
+
controllerRef.current = void 0;
|
|
5636
|
+
setSnapshot({ phase: "success", activeStageId: stageIds.at(-1), progress: 100, result });
|
|
5637
|
+
},
|
|
5638
|
+
() => {
|
|
5639
|
+
if (generation !== generationRef.current || controller.signal.aborted) return;
|
|
5640
|
+
controllerRef.current = void 0;
|
|
5641
|
+
setSnapshot((current) => ({ ...current, phase: "error" }));
|
|
5642
|
+
}
|
|
5643
|
+
);
|
|
5644
|
+
}, [disabled, stageIds]);
|
|
5645
|
+
const cancel = useCallback(() => {
|
|
5646
|
+
if (!controllerRef.current) return;
|
|
5647
|
+
generationRef.current += 1;
|
|
5648
|
+
controllerRef.current.abort();
|
|
5649
|
+
controllerRef.current = void 0;
|
|
5650
|
+
setSnapshot((current) => ({ ...current, phase: "cancelled" }));
|
|
5651
|
+
}, []);
|
|
5652
|
+
const retry = useCallback(() => {
|
|
5653
|
+
if (snapshot.phase !== "error" && snapshot.phase !== "cancelled") return;
|
|
5654
|
+
start();
|
|
5655
|
+
}, [snapshot.phase, start]);
|
|
5656
|
+
useEffect27(() => () => {
|
|
5657
|
+
generationRef.current += 1;
|
|
5658
|
+
controllerRef.current?.abort();
|
|
5659
|
+
controllerRef.current = void 0;
|
|
5660
|
+
}, []);
|
|
5661
|
+
return { ...snapshot, start, cancel, retry };
|
|
5662
|
+
}
|
|
5663
|
+
|
|
5664
|
+
// src/feedback/TaskProgress.tsx
|
|
5665
|
+
import { jsx as jsx98, jsxs as jsxs90 } from "react/jsx-runtime";
|
|
5666
|
+
function TaskProgress(props) {
|
|
5667
|
+
return /* @__PURE__ */ jsx98(TaskProgressSession, { ...props }, `${typeof props.taskKey}:${String(props.taskKey)}`);
|
|
5668
|
+
}
|
|
5669
|
+
function TaskProgressSession({
|
|
5670
|
+
stages,
|
|
5671
|
+
run,
|
|
5672
|
+
title = "\u4EFB\u52A1\u8FDB\u5EA6",
|
|
5673
|
+
autoStart = false,
|
|
5674
|
+
disabled = false,
|
|
5675
|
+
renderResult,
|
|
5676
|
+
onPhaseChange,
|
|
5677
|
+
className = ""
|
|
5678
|
+
}) {
|
|
5679
|
+
const stageSignature = JSON.stringify(stages.map((stage) => stage.id));
|
|
5680
|
+
const stageIds = useMemo11(() => stages.map((stage) => stage.id), [stageSignature]);
|
|
5681
|
+
const state = useTaskProgress(run, stageIds, disabled || stages.length === 0);
|
|
5682
|
+
const statusId = useId34();
|
|
5683
|
+
const activeIndex = state.activeStageId ? stageIds.indexOf(state.activeStageId) : -1;
|
|
5684
|
+
useEffect28(() => {
|
|
5685
|
+
if (!autoStart || disabled || stages.length === 0) return;
|
|
5686
|
+
const timer = window.setTimeout(state.start, 0);
|
|
5687
|
+
return () => window.clearTimeout(timer);
|
|
5688
|
+
}, [autoStart, disabled, stages.length, state.start]);
|
|
5689
|
+
useEffect28(() => {
|
|
5690
|
+
onPhaseChange?.(state.phase);
|
|
5691
|
+
}, [onPhaseChange, state.phase]);
|
|
5692
|
+
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";
|
|
5693
|
+
return /* @__PURE__ */ jsxs90("section", { className: `hf-task-progress ${className}`.trim(), "aria-labelledby": `${statusId}-title`, "aria-busy": state.phase === "running", children: [
|
|
5694
|
+
/* @__PURE__ */ jsxs90("header", { className: "hf-task-progress__header", children: [
|
|
5695
|
+
/* @__PURE__ */ jsxs90("div", { children: [
|
|
5696
|
+
/* @__PURE__ */ jsx98("h3", { id: `${statusId}-title`, children: title }),
|
|
5697
|
+
/* @__PURE__ */ jsx98("p", { id: statusId, role: "status", "aria-live": "polite", "aria-atomic": "true", children: statusText })
|
|
5698
|
+
] }),
|
|
5699
|
+
/* @__PURE__ */ jsxs90("strong", { "aria-hidden": "true", children: [
|
|
5700
|
+
Math.round(state.progress),
|
|
5701
|
+
"%"
|
|
5702
|
+
] })
|
|
5703
|
+
] }),
|
|
5704
|
+
/* @__PURE__ */ jsx98(
|
|
5705
|
+
"div",
|
|
5706
|
+
{
|
|
5707
|
+
className: "hf-task-progress__track",
|
|
5708
|
+
role: "progressbar",
|
|
5709
|
+
"aria-valuemin": 0,
|
|
5710
|
+
"aria-valuemax": 100,
|
|
5711
|
+
"aria-valuenow": Math.round(state.progress),
|
|
5712
|
+
"aria-describedby": statusId,
|
|
5713
|
+
children: /* @__PURE__ */ jsx98("span", { style: { width: `${state.progress}%` } })
|
|
5714
|
+
}
|
|
5715
|
+
),
|
|
5716
|
+
/* @__PURE__ */ jsx98("ol", { className: "hf-task-progress__stages", children: stages.map((stage, index) => {
|
|
5717
|
+
const status = state.phase === "success" || index < activeIndex ? "complete" : index === activeIndex ? state.phase === "error" ? "error" : state.phase === "cancelled" ? "cancelled" : "active" : "pending";
|
|
5718
|
+
return /* @__PURE__ */ jsxs90("li", { "data-status": status, "aria-current": status === "active" ? "step" : void 0, children: [
|
|
5719
|
+
/* @__PURE__ */ jsx98("span", { className: "hf-task-progress__marker", "aria-hidden": "true", children: status === "complete" ? "\u2713" : index + 1 }),
|
|
5720
|
+
/* @__PURE__ */ jsxs90("div", { children: [
|
|
5721
|
+
/* @__PURE__ */ jsx98("strong", { children: stage.label }),
|
|
5722
|
+
stage.description && /* @__PURE__ */ jsx98("p", { children: stage.description })
|
|
5723
|
+
] })
|
|
5724
|
+
] }, stage.id);
|
|
5725
|
+
}) }),
|
|
5726
|
+
state.phase === "error" && /* @__PURE__ */ jsx98("p", { className: "hf-task-progress__error", role: "alert", children: "\u4EFB\u52A1\u672A\u5B8C\u6210\uFF0C\u8BF7\u68C0\u67E5\u8FDE\u63A5\u540E\u91CD\u8BD5\u3002" }),
|
|
5727
|
+
state.phase === "success" && renderResult && /* @__PURE__ */ jsx98("div", { className: "hf-task-progress__result", children: renderResult(state.result) }),
|
|
5728
|
+
/* @__PURE__ */ jsxs90("div", { className: "hf-task-progress__actions", children: [
|
|
5729
|
+
state.phase === "idle" && /* @__PURE__ */ jsx98(Button, { type: "button", disabled: disabled || stages.length === 0, onClick: state.start, children: "\u5F00\u59CB\u4EFB\u52A1" }),
|
|
5730
|
+
state.phase === "running" && /* @__PURE__ */ jsx98(Button, { type: "button", variant: "outline", onClick: state.cancel, children: "\u53D6\u6D88\u4EFB\u52A1" }),
|
|
5731
|
+
(state.phase === "error" || state.phase === "cancelled") && /* @__PURE__ */ jsx98(Button, { type: "button", disabled, onClick: state.retry, children: "\u91CD\u65B0\u6267\u884C" })
|
|
5732
|
+
] })
|
|
5238
5733
|
] });
|
|
5239
5734
|
}
|
|
5240
5735
|
export {
|
|
@@ -5250,7 +5745,9 @@ export {
|
|
|
5250
5745
|
AvailabilityGrid,
|
|
5251
5746
|
Avatar,
|
|
5252
5747
|
AvatarGroup,
|
|
5748
|
+
BackToTop,
|
|
5253
5749
|
Badge,
|
|
5750
|
+
BottomNavigation,
|
|
5254
5751
|
Breadcrumb,
|
|
5255
5752
|
Button,
|
|
5256
5753
|
ButtonGroup,
|
|
@@ -5299,6 +5796,7 @@ export {
|
|
|
5299
5796
|
GanttChart,
|
|
5300
5797
|
Grid,
|
|
5301
5798
|
Hero,
|
|
5799
|
+
HierarchicalSidebar,
|
|
5302
5800
|
HoldToConfirm,
|
|
5303
5801
|
HotspotGuide,
|
|
5304
5802
|
Icon,
|
|
@@ -5315,11 +5813,13 @@ export {
|
|
|
5315
5813
|
LoadMore,
|
|
5316
5814
|
LoadingDots,
|
|
5317
5815
|
LoadingOverlay,
|
|
5816
|
+
LongPageNavigation,
|
|
5318
5817
|
MarkdownContent,
|
|
5319
5818
|
Masonry,
|
|
5320
5819
|
MegaMenu,
|
|
5321
5820
|
MemberPicker,
|
|
5322
5821
|
MentionInput,
|
|
5822
|
+
MobileContentNavigation,
|
|
5323
5823
|
MobileNavigation,
|
|
5324
5824
|
Modal,
|
|
5325
5825
|
ModelSelector,
|
|
@@ -5341,6 +5841,7 @@ export {
|
|
|
5341
5841
|
ProgressBar,
|
|
5342
5842
|
ProgressRing,
|
|
5343
5843
|
PromptSuggestions,
|
|
5844
|
+
PullToRefresh,
|
|
5344
5845
|
QueryBuilder,
|
|
5345
5846
|
Radio,
|
|
5346
5847
|
RadioGroup,
|
|
@@ -5376,6 +5877,7 @@ export {
|
|
|
5376
5877
|
Table,
|
|
5377
5878
|
Tabs,
|
|
5378
5879
|
Tag,
|
|
5880
|
+
TaskProgress,
|
|
5379
5881
|
Textarea,
|
|
5380
5882
|
ThemeProvider,
|
|
5381
5883
|
TimePicker,
|