@runlume/admin-ui 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +6 -13
- package/README.md +5 -11
- package/dist-package/_virtual/_rolldown/runtime.cjs +1 -0
- package/dist-package/admin-ui.cjs +1 -0
- package/dist-package/admin-ui.d.ts +41 -1
- package/dist-package/admin-ui.d.ts.map +1 -1
- package/dist-package/admin-ui.js +79 -0
- package/dist-package/components/calendar.cjs +1 -0
- package/dist-package/components/calendar.d.ts +13 -0
- package/dist-package/components/calendar.d.ts.map +1 -0
- package/dist-package/components/calendar.js +91 -0
- package/dist-package/components/cascader.cjs +1 -0
- package/dist-package/components/cascader.d.ts +19 -0
- package/dist-package/components/cascader.d.ts.map +1 -0
- package/dist-package/components/cascader.js +85 -0
- package/dist-package/components/charts.cjs +1 -0
- package/dist-package/components/charts.d.ts +80 -0
- package/dist-package/components/charts.d.ts.map +1 -0
- package/dist-package/components/charts.js +374 -0
- package/dist-package/components/code-block.cjs +1 -0
- package/dist-package/components/code-block.d.ts +7 -0
- package/dist-package/components/code-block.d.ts.map +1 -0
- package/dist-package/components/code-block.js +47 -0
- package/dist-package/components/column-chart.cjs +1 -0
- package/dist-package/components/column-chart.d.ts +18 -0
- package/dist-package/components/column-chart.d.ts.map +1 -0
- package/dist-package/components/column-chart.js +89 -0
- package/dist-package/components/combobox.cjs +1 -0
- package/dist-package/components/combobox.d.ts +24 -0
- package/dist-package/components/combobox.d.ts.map +1 -0
- package/dist-package/components/combobox.js +111 -0
- package/dist-package/components/confirm-dialog.cjs +1 -0
- package/dist-package/components/confirm-dialog.d.ts +17 -0
- package/dist-package/components/confirm-dialog.d.ts.map +1 -0
- package/dist-package/components/confirm-dialog.js +44 -0
- package/dist-package/components/count-to.cjs +1 -0
- package/dist-package/components/count-to.d.ts +13 -0
- package/dist-package/components/count-to.d.ts.map +1 -0
- package/dist-package/components/count-to.js +36 -0
- package/dist-package/components/cursor-pagination.cjs +1 -0
- package/dist-package/components/cursor-pagination.d.ts +11 -0
- package/dist-package/components/cursor-pagination.d.ts.map +1 -0
- package/dist-package/components/cursor-pagination.js +39 -0
- package/dist-package/components/data-table.cjs +1 -0
- package/dist-package/components/data-table.d.ts +69 -0
- package/dist-package/components/data-table.d.ts.map +1 -0
- package/dist-package/components/data-table.js +377 -0
- package/dist-package/components/descriptions.cjs +1 -0
- package/dist-package/components/descriptions.d.ts +16 -0
- package/dist-package/components/descriptions.d.ts.map +1 -0
- package/dist-package/components/descriptions.js +28 -0
- package/dist-package/components/editable-table.cjs +1 -0
- package/dist-package/components/editable-table.d.ts +27 -0
- package/dist-package/components/editable-table.d.ts.map +1 -0
- package/dist-package/components/editable-table.js +212 -0
- package/dist-package/components/filter-presets.cjs +1 -0
- package/dist-package/components/filter-presets.d.ts +11 -0
- package/dist-package/components/filter-presets.d.ts.map +1 -0
- package/dist-package/components/filter-presets.js +17 -0
- package/dist-package/components/fixed-bar.cjs +1 -0
- package/dist-package/components/fixed-bar.d.ts +11 -0
- package/dist-package/components/fixed-bar.d.ts.map +1 -0
- package/dist-package/components/fixed-bar.js +18 -0
- package/dist-package/components/image-preview.cjs +1 -0
- package/dist-package/components/image-preview.d.ts +14 -0
- package/dist-package/components/image-preview.d.ts.map +1 -0
- package/dist-package/components/image-preview.js +166 -0
- package/dist-package/components/layout-container.cjs +1 -0
- package/dist-package/components/layout-container.d.ts +17 -0
- package/dist-package/components/layout-container.d.ts.map +1 -0
- package/dist-package/components/layout-container.js +85 -0
- package/dist-package/components/mention.cjs +1 -0
- package/dist-package/components/mention.d.ts +20 -0
- package/dist-package/components/mention.d.ts.map +1 -0
- package/dist-package/components/mention.js +126 -0
- package/dist-package/components/multi-select.cjs +1 -0
- package/dist-package/components/multi-select.d.ts +17 -0
- package/dist-package/components/multi-select.d.ts.map +1 -0
- package/dist-package/components/multi-select.js +126 -0
- package/dist-package/components/multi-step-loader.cjs +1 -0
- package/dist-package/components/multi-step-loader.d.ts +18 -0
- package/dist-package/components/multi-step-loader.d.ts.map +1 -0
- package/dist-package/components/multi-step-loader.js +38 -0
- package/dist-package/components/page-button.cjs +1 -0
- package/dist-package/components/page-button.d.ts +6 -0
- package/dist-package/components/page-button.d.ts.map +1 -0
- package/dist-package/components/page-button.js +24 -0
- package/dist-package/components/page-pager.cjs +1 -0
- package/dist-package/components/page-pager.d.ts +11 -0
- package/dist-package/components/page-pager.d.ts.map +1 -0
- package/dist-package/components/page-pager.js +51 -0
- package/dist-package/components/page.cjs +1 -0
- package/dist-package/components/page.d.ts +34 -0
- package/dist-package/components/page.d.ts.map +1 -0
- package/dist-package/components/page.js +208 -0
- package/dist-package/components/pagination-bar.cjs +1 -0
- package/dist-package/components/pagination-bar.d.ts +8 -0
- package/dist-package/components/pagination-bar.d.ts.map +1 -0
- package/dist-package/components/pagination-bar.js +23 -0
- package/dist-package/components/password-strength.cjs +1 -0
- package/dist-package/components/password-strength.d.ts +11 -0
- package/dist-package/components/password-strength.d.ts.map +1 -0
- package/dist-package/components/password-strength.js +70 -0
- package/dist-package/components/rate.cjs +1 -0
- package/dist-package/components/rate.d.ts +13 -0
- package/dist-package/components/rate.d.ts.map +1 -0
- package/dist-package/components/rate.js +56 -0
- package/dist-package/components/resizable-panel.cjs +1 -0
- package/dist-package/components/resizable-panel.d.ts +15 -0
- package/dist-package/components/resizable-panel.d.ts.map +1 -0
- package/dist-package/components/resizable-panel.js +56 -0
- package/dist-package/components/search-filters.cjs +1 -0
- package/dist-package/components/search-filters.d.ts +31 -0
- package/dist-package/components/search-filters.d.ts.map +1 -0
- package/dist-package/components/search-filters.js +110 -0
- package/dist-package/components/sortable-list.cjs +1 -0
- package/dist-package/components/sortable-list.d.ts +14 -0
- package/dist-package/components/sortable-list.d.ts.map +1 -0
- package/dist-package/components/sortable-list.js +48 -0
- package/dist-package/components/sparkline.cjs +1 -0
- package/dist-package/components/sparkline.d.ts +11 -0
- package/dist-package/components/sparkline.d.ts.map +1 -0
- package/dist-package/components/sparkline.js +50 -0
- package/dist-package/components/status-badge.cjs +1 -0
- package/dist-package/components/status-badge.d.ts +4 -0
- package/dist-package/components/status-badge.d.ts.map +1 -0
- package/dist-package/components/status-badge.js +28 -0
- package/dist-package/components/steps.cjs +1 -0
- package/dist-package/components/steps.d.ts +15 -0
- package/dist-package/components/steps.d.ts.map +1 -0
- package/dist-package/components/steps.js +41 -0
- package/dist-package/components/storage-box.cjs +1 -0
- package/dist-package/components/storage-box.d.ts +19 -0
- package/dist-package/components/storage-box.d.ts.map +1 -0
- package/dist-package/components/storage-box.js +153 -0
- package/dist-package/components/table-cell-overflow.cjs +1 -0
- package/dist-package/components/table-cell-overflow.d.ts +5 -0
- package/dist-package/components/table-cell-overflow.d.ts.map +1 -0
- package/dist-package/components/table-cell-overflow.js +31 -0
- package/dist-package/components/table-toolbar.cjs +1 -0
- package/dist-package/components/table-toolbar.d.ts +5 -0
- package/dist-package/components/table-toolbar.d.ts.map +1 -0
- package/dist-package/components/table-toolbar.js +11 -0
- package/dist-package/components/timeline.cjs +1 -0
- package/dist-package/components/timeline.d.ts +14 -0
- package/dist-package/components/timeline.d.ts.map +1 -0
- package/dist-package/components/timeline.js +40 -0
- package/dist-package/components/transfer.cjs +1 -0
- package/dist-package/components/transfer.d.ts +18 -0
- package/dist-package/components/transfer.d.ts.map +1 -0
- package/dist-package/components/transfer.js +98 -0
- package/dist-package/components/tree-table.cjs +1 -0
- package/dist-package/components/tree-table.d.ts +23 -0
- package/dist-package/components/tree-table.d.ts.map +1 -0
- package/dist-package/components/tree-table.js +53 -0
- package/dist-package/components/tree.cjs +1 -0
- package/dist-package/components/tree.d.ts +36 -0
- package/dist-package/components/tree.d.ts.map +1 -0
- package/dist-package/components/tree.js +204 -0
- package/dist-package/components/trend.cjs +1 -0
- package/dist-package/components/trend.d.ts +19 -0
- package/dist-package/components/trend.d.ts.map +1 -0
- package/dist-package/components/trend.js +18 -0
- package/dist-package/components/ui/alert-dialog.cjs +1 -0
- package/dist-package/components/ui/alert-dialog.js +57 -0
- package/dist-package/components/ui/alert.cjs +1 -0
- package/dist-package/components/ui/alert.js +63 -0
- package/dist-package/components/ui/avatar.cjs +1 -0
- package/dist-package/components/ui/avatar.js +27 -0
- package/dist-package/components/ui/badge.cjs +1 -0
- package/dist-package/components/ui/badge.js +40 -0
- package/dist-package/components/ui/breadcrumb.cjs +1 -0
- package/dist-package/components/ui/breadcrumb.js +70 -0
- package/dist-package/components/ui/button.cjs +1 -0
- package/dist-package/components/ui/button.js +58 -0
- package/dist-package/components/ui/card.cjs +1 -0
- package/dist-package/components/ui/card.js +55 -0
- package/dist-package/components/ui/checkbox.cjs +1 -0
- package/dist-package/components/ui/checkbox.js +19 -0
- package/dist-package/components/ui/collapsible.cjs +1 -0
- package/dist-package/components/ui/collapsible.js +32 -0
- package/dist-package/components/ui/context-menu.cjs +1 -0
- package/dist-package/components/ui/context-menu.js +46 -0
- package/dist-package/components/ui/date-input.cjs +1 -0
- package/dist-package/components/ui/date-input.js +183 -0
- package/dist-package/components/ui/date-range-input.cjs +1 -0
- package/dist-package/components/ui/date-range-input.js +209 -0
- package/dist-package/components/ui/date-time-input.cjs +1 -0
- package/dist-package/components/ui/date-time-input.js +23 -0
- package/dist-package/components/ui/dialog.cjs +1 -0
- package/dist-package/components/ui/dialog.js +189 -0
- package/dist-package/components/ui/dropdown-menu.cjs +1 -0
- package/dist-package/components/ui/dropdown-menu.js +124 -0
- package/dist-package/components/ui/file-upload.cjs +1 -0
- package/dist-package/components/ui/file-upload.js +160 -0
- package/dist-package/components/ui/hover-card.cjs +1 -0
- package/dist-package/components/ui/hover-card.js +28 -0
- package/dist-package/components/ui/input-otp.cjs +1 -0
- package/dist-package/components/ui/input-otp.js +33 -0
- package/dist-package/components/ui/input.cjs +1 -0
- package/dist-package/components/ui/input.js +65 -0
- package/dist-package/components/ui/kbd.cjs +1 -0
- package/dist-package/components/ui/kbd.js +20 -0
- package/dist-package/components/ui/label.cjs +1 -0
- package/dist-package/components/ui/label.js +14 -0
- package/dist-package/components/ui/native-select.cjs +1 -0
- package/dist-package/components/ui/native-select.js +125 -0
- package/dist-package/components/ui/number-field.cjs +1 -0
- package/dist-package/components/ui/number-field.js +50 -0
- package/dist-package/components/ui/progress.cjs +1 -0
- package/dist-package/components/ui/progress.js +28 -0
- package/dist-package/components/ui/radio-group.cjs +1 -0
- package/dist-package/components/ui/radio-group.js +27 -0
- package/dist-package/components/ui/scroll-area.cjs +1 -0
- package/dist-package/components/ui/scroll-area.js +25 -0
- package/dist-package/components/ui/select.cjs +1 -0
- package/dist-package/components/ui/select.js +23 -0
- package/dist-package/components/ui/separator.cjs +1 -0
- package/dist-package/components/ui/separator.js +17 -0
- package/dist-package/components/ui/sheet.cjs +1 -0
- package/dist-package/components/ui/sheet.js +86 -0
- package/dist-package/components/ui/sidebar.cjs +1 -0
- package/dist-package/components/ui/sidebar.js +350 -0
- package/dist-package/components/ui/skeleton.cjs +1 -0
- package/dist-package/components/ui/skeleton.js +12 -0
- package/dist-package/components/ui/slider.cjs +1 -0
- package/dist-package/components/ui/slider.js +36 -0
- package/dist-package/components/ui/switch.cjs +1 -0
- package/dist-package/components/ui/switch.js +14 -0
- package/dist-package/components/ui/table.cjs +1 -0
- package/dist-package/components/ui/table.js +66 -0
- package/dist-package/components/ui/tabs.cjs +1 -0
- package/dist-package/components/ui/tabs.js +47 -0
- package/dist-package/components/ui/tag-variants.cjs +1 -0
- package/dist-package/components/ui/tag-variants.js +15 -0
- package/dist-package/components/ui/tag.cjs +1 -0
- package/dist-package/components/ui/tag.js +31 -0
- package/dist-package/components/ui/textarea.cjs +1 -0
- package/dist-package/components/ui/textarea.js +13 -0
- package/dist-package/components/ui/time-input.cjs +1 -0
- package/dist-package/components/ui/time-input.js +89 -0
- package/dist-package/components/ui/tooltip.cjs +1 -0
- package/dist-package/components/ui/tooltip.js +35 -0
- package/dist-package/hooks/use-mobile.cjs +1 -0
- package/dist-package/hooks/use-mobile.js +11 -0
- package/dist-package/lib/dialog-focus.cjs +1 -0
- package/dist-package/lib/dialog-focus.js +10 -0
- package/dist-package/lib/metrics.cjs +1 -0
- package/dist-package/lib/metrics.d.ts +18 -0
- package/dist-package/lib/metrics.d.ts.map +1 -0
- package/dist-package/lib/metrics.js +22 -0
- package/dist-package/lib/pager.cjs +1 -0
- package/dist-package/lib/pager.d.ts +8 -0
- package/dist-package/lib/pager.d.ts.map +1 -0
- package/dist-package/lib/pager.js +18 -0
- package/dist-package/lib/password.cjs +1 -0
- package/dist-package/lib/password.d.ts +14 -0
- package/dist-package/lib/password.d.ts.map +1 -0
- package/dist-package/lib/password.js +34 -0
- package/dist-package/lib/presets.cjs +1 -0
- package/dist-package/lib/presets.d.ts +25 -0
- package/dist-package/lib/presets.d.ts.map +1 -0
- package/dist-package/lib/presets.js +48 -0
- package/dist-package/lib/range.cjs +1 -0
- package/dist-package/lib/range.js +57 -0
- package/dist-package/lib/storage-key.cjs +1 -0
- package/dist-package/lib/storage-key.d.ts +2 -0
- package/dist-package/lib/storage-key.d.ts.map +1 -0
- package/dist-package/lib/storage-key.js +6 -0
- package/dist-package/lib/table-prefs.cjs +1 -0
- package/dist-package/lib/table-prefs.d.ts +17 -0
- package/dist-package/lib/table-prefs.d.ts.map +1 -0
- package/dist-package/lib/table-prefs.js +64 -0
- package/dist-package/lib/tree.cjs +1 -0
- package/dist-package/lib/tree.d.ts +37 -0
- package/dist-package/lib/tree.d.ts.map +1 -0
- package/dist-package/lib/tree.js +57 -0
- package/dist-package/lib/use-ui-translation.cjs +1 -0
- package/dist-package/lib/use-ui-translation.d.ts +15 -0
- package/dist-package/lib/use-ui-translation.d.ts.map +1 -0
- package/dist-package/lib/use-ui-translation.js +65 -0
- package/dist-package/lib/utils.cjs +1 -0
- package/dist-package/lib/utils.js +8 -0
- package/dist-package/styles.css +1 -1
- package/package.json +25 -15
- package/dist-package/index.js +0 -12212
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
export type TimelineItem = {
|
|
3
|
+
key: string;
|
|
4
|
+
title: ReactNode;
|
|
5
|
+
description?: ReactNode;
|
|
6
|
+
time?: ReactNode;
|
|
7
|
+
tone?: 'default' | 'success' | 'warning' | 'danger';
|
|
8
|
+
};
|
|
9
|
+
/** 时间线:用于操作记录与审批轨迹,按时间倒序展示。 */
|
|
10
|
+
export declare function Timeline({ items, className }: {
|
|
11
|
+
items: TimelineItem[];
|
|
12
|
+
className?: string;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
//# sourceMappingURL=timeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timeline.d.ts","sourceRoot":"","sources":["../../src/components/timeline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtC,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,SAAS,CAAA;IAChB,WAAW,CAAC,EAAE,SAAS,CAAA;IACvB,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;CACpD,CAAA;AASD,+BAA+B;AAC/B,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;IAAE,KAAK,EAAE,YAAY,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAwB3F"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { jsx as t, jsxs as n } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/timeline.tsx
|
|
4
|
+
var r = {
|
|
5
|
+
default: "bg-primary",
|
|
6
|
+
success: "bg-success",
|
|
7
|
+
warning: "bg-warning",
|
|
8
|
+
danger: "bg-danger"
|
|
9
|
+
};
|
|
10
|
+
function i({ items: i, className: a }) {
|
|
11
|
+
return /* @__PURE__ */ t("ol", {
|
|
12
|
+
"data-slot": "timeline",
|
|
13
|
+
className: e("relative space-y-5", a),
|
|
14
|
+
children: i.map((a, o) => /* @__PURE__ */ n("li", {
|
|
15
|
+
className: "relative flex gap-3 pb-1 pl-1",
|
|
16
|
+
children: [/* @__PURE__ */ n("span", {
|
|
17
|
+
"aria-hidden": "true",
|
|
18
|
+
className: "relative flex w-3 shrink-0 justify-center",
|
|
19
|
+
children: [o < i.length - 1 && /* @__PURE__ */ t("span", { className: "absolute top-3 h-[calc(100%+8px)] w-px bg-border" }), /* @__PURE__ */ t("span", { className: e("mt-1.5 size-2 rounded-full", r[a.tone ?? "default"]) })]
|
|
20
|
+
}), /* @__PURE__ */ n("div", {
|
|
21
|
+
className: "min-w-0 flex-1",
|
|
22
|
+
children: [/* @__PURE__ */ n("div", {
|
|
23
|
+
className: "flex flex-wrap items-baseline justify-between gap-2",
|
|
24
|
+
children: [/* @__PURE__ */ t("p", {
|
|
25
|
+
className: "text-sm font-medium",
|
|
26
|
+
children: a.title
|
|
27
|
+
}), a.time && /* @__PURE__ */ t("span", {
|
|
28
|
+
className: "text-xs text-muted-foreground",
|
|
29
|
+
children: a.time
|
|
30
|
+
})]
|
|
31
|
+
}), a.description && /* @__PURE__ */ t("p", {
|
|
32
|
+
className: "mt-1 text-xs leading-5 text-muted-foreground",
|
|
33
|
+
children: a.description
|
|
34
|
+
})]
|
|
35
|
+
})]
|
|
36
|
+
}, a.key))
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
//#endregion
|
|
40
|
+
export { i as Timeline };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../lib/utils.cjs"),t=require("./ui/button.cjs"),n=require("./ui/checkbox.cjs"),r=require("./ui/input.cjs");let i=require("react"),a=require("lucide-react"),o=require("react/jsx-runtime");function s({items:s,value:c,onValueChange:l,sourceTitle:u=`可选项`,targetTitle:d=`已选项`,searchPlaceholder:f=`搜索`,emptyText:p=`暂无数据`,className:m}){let[h,g]=(0,i.useState)(``),[_,v]=(0,i.useState)([]),[y,b]=(0,i.useState)([]),x=new Set(c),S=(0,i.useMemo)(()=>s.filter(e=>e.label.toLowerCase().includes(h.trim().toLowerCase())),[s,h]).filter(e=>!x.has(e.value)),C=s.filter(e=>x.has(e.value));function w(e,t,n){n(e.includes(t)?e.filter(e=>e!==t):[...e,t])}function T(){l([...c,..._.filter(e=>!x.has(e))]),v([])}function E(){l(c.filter(e=>!y.includes(e))),b([])}let D=(t,r,i,a)=>(0,o.jsxs)(`section`,{className:`min-w-0 flex-1 overflow-hidden rounded-lg border bg-card`,children:[(0,o.jsxs)(`header`,{className:`flex items-center justify-between border-b px-3 py-2 text-sm font-medium`,children:[(0,o.jsx)(`span`,{children:t}),(0,o.jsx)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:r.length})]}),(0,o.jsx)(`div`,{className:`max-h-64 min-h-52 overflow-auto p-2`,role:`listbox`,"aria-label":t,children:r.length===0?(0,o.jsx)(`p`,{className:`grid min-h-36 place-items-center text-sm text-muted-foreground`,children:p}):r.map(t=>(0,o.jsxs)(`label`,{className:e.cn(`flex min-h-11 items-start gap-2 rounded-md px-2 py-2 text-sm hover:bg-muted`,t.disabled&&`cursor-not-allowed opacity-50`),children:[(0,o.jsx)(n.Checkbox,{disabled:t.disabled,checked:i.includes(t.value),onCheckedChange:()=>w(i,t.value,a),"aria-label":t.label}),(0,o.jsxs)(`span`,{className:`min-w-0`,children:[(0,o.jsx)(`span`,{className:`block truncate`,children:t.label}),t.description&&(0,o.jsx)(`span`,{className:`block truncate text-xs text-muted-foreground`,children:t.description})]})]},t.value))})]});return(0,o.jsxs)(`div`,{className:e.cn(`space-y-3`,m),children:[(0,o.jsx)(r.Input,{value:h,onChange:e=>g(e.target.value),placeholder:f,"aria-label":f,start:(0,o.jsx)(a.Search,{"aria-hidden":`true`,className:`size-4`}),clearable:!0,onClear:()=>g(``)}),(0,o.jsxs)(`div`,{className:`flex min-w-0 items-center gap-2`,children:[D(u,S,_,v),(0,o.jsxs)(`div`,{className:`flex shrink-0 flex-col gap-2`,children:[(0,o.jsx)(t.Button,{type:`button`,size:`icon`,variant:`outline`,disabled:_.length===0,onClick:T,"aria-label":`移动到${d}`,children:(0,o.jsx)(a.ArrowRight,{"aria-hidden":`true`})}),(0,o.jsx)(t.Button,{type:`button`,size:`icon`,variant:`outline`,disabled:y.length===0,onClick:E,"aria-label":`移动到${u}`,children:(0,o.jsx)(a.ArrowLeft,{"aria-hidden":`true`})})]}),D(d,C,y,b)]})]})}exports.Transfer=s;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type TransferItem = {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type TransferProps = {
|
|
8
|
+
items: TransferItem[];
|
|
9
|
+
value: string[];
|
|
10
|
+
onValueChange: (value: string[]) => void;
|
|
11
|
+
sourceTitle?: string;
|
|
12
|
+
targetTitle?: string;
|
|
13
|
+
searchPlaceholder?: string;
|
|
14
|
+
emptyText?: string;
|
|
15
|
+
className?: string;
|
|
16
|
+
};
|
|
17
|
+
export declare function Transfer({ items, value, onValueChange, sourceTitle, targetTitle, searchPlaceholder, emptyText, className, }: TransferProps): import("react").JSX.Element;
|
|
18
|
+
//# sourceMappingURL=transfer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../../src/components/transfer.tsx"],"names":[],"mappings":"AAOA,MAAM,MAAM,YAAY,GAAG;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,KAAK,EACL,aAAa,EACb,WAAmB,EACnB,WAAmB,EACnB,iBAAwB,EACxB,SAAkB,EAClB,SAAS,GACV,EAAE,aAAa,+BA+Gf"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { Button as t } from "./ui/button.js";
|
|
3
|
+
import { Checkbox as n } from "./ui/checkbox.js";
|
|
4
|
+
import { Input as r } from "./ui/input.js";
|
|
5
|
+
import { useMemo as i, useState as a } from "react";
|
|
6
|
+
import { ArrowLeft as o, ArrowRight as s, Search as c } from "lucide-react";
|
|
7
|
+
import { jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
|
+
//#region src/components/transfer.tsx
|
|
9
|
+
function d({ items: d, value: f, onValueChange: p, sourceTitle: m = "可选项", targetTitle: h = "已选项", searchPlaceholder: g = "搜索", emptyText: _ = "暂无数据", className: v }) {
|
|
10
|
+
let [y, b] = a(""), [x, S] = a([]), [C, w] = a([]), T = new Set(f), E = i(() => d.filter((e) => e.label.toLowerCase().includes(y.trim().toLowerCase())), [d, y]).filter((e) => !T.has(e.value)), D = d.filter((e) => T.has(e.value));
|
|
11
|
+
function O(e, t, n) {
|
|
12
|
+
n(e.includes(t) ? e.filter((e) => e !== t) : [...e, t]);
|
|
13
|
+
}
|
|
14
|
+
function k() {
|
|
15
|
+
p([...f, ...x.filter((e) => !T.has(e))]), S([]);
|
|
16
|
+
}
|
|
17
|
+
function A() {
|
|
18
|
+
p(f.filter((e) => !C.includes(e))), w([]);
|
|
19
|
+
}
|
|
20
|
+
let j = (t, r, i, a) => /* @__PURE__ */ u("section", {
|
|
21
|
+
className: "min-w-0 flex-1 overflow-hidden rounded-lg border bg-card",
|
|
22
|
+
children: [/* @__PURE__ */ u("header", {
|
|
23
|
+
className: "flex items-center justify-between border-b px-3 py-2 text-sm font-medium",
|
|
24
|
+
children: [/* @__PURE__ */ l("span", { children: t }), /* @__PURE__ */ l("span", {
|
|
25
|
+
className: "text-xs font-normal text-muted-foreground",
|
|
26
|
+
children: r.length
|
|
27
|
+
})]
|
|
28
|
+
}), /* @__PURE__ */ l("div", {
|
|
29
|
+
className: "max-h-64 min-h-52 overflow-auto p-2",
|
|
30
|
+
role: "listbox",
|
|
31
|
+
"aria-label": t,
|
|
32
|
+
children: r.length === 0 ? /* @__PURE__ */ l("p", {
|
|
33
|
+
className: "grid min-h-36 place-items-center text-sm text-muted-foreground",
|
|
34
|
+
children: _
|
|
35
|
+
}) : r.map((t) => /* @__PURE__ */ u("label", {
|
|
36
|
+
className: e("flex min-h-11 items-start gap-2 rounded-md px-2 py-2 text-sm hover:bg-muted", t.disabled && "cursor-not-allowed opacity-50"),
|
|
37
|
+
children: [/* @__PURE__ */ l(n, {
|
|
38
|
+
disabled: t.disabled,
|
|
39
|
+
checked: i.includes(t.value),
|
|
40
|
+
onCheckedChange: () => O(i, t.value, a),
|
|
41
|
+
"aria-label": t.label
|
|
42
|
+
}), /* @__PURE__ */ u("span", {
|
|
43
|
+
className: "min-w-0",
|
|
44
|
+
children: [/* @__PURE__ */ l("span", {
|
|
45
|
+
className: "block truncate",
|
|
46
|
+
children: t.label
|
|
47
|
+
}), t.description && /* @__PURE__ */ l("span", {
|
|
48
|
+
className: "block truncate text-xs text-muted-foreground",
|
|
49
|
+
children: t.description
|
|
50
|
+
})]
|
|
51
|
+
})]
|
|
52
|
+
}, t.value))
|
|
53
|
+
})]
|
|
54
|
+
});
|
|
55
|
+
return /* @__PURE__ */ u("div", {
|
|
56
|
+
className: e("space-y-3", v),
|
|
57
|
+
children: [/* @__PURE__ */ l(r, {
|
|
58
|
+
value: y,
|
|
59
|
+
onChange: (e) => b(e.target.value),
|
|
60
|
+
placeholder: g,
|
|
61
|
+
"aria-label": g,
|
|
62
|
+
start: /* @__PURE__ */ l(c, {
|
|
63
|
+
"aria-hidden": "true",
|
|
64
|
+
className: "size-4"
|
|
65
|
+
}),
|
|
66
|
+
clearable: !0,
|
|
67
|
+
onClear: () => b("")
|
|
68
|
+
}), /* @__PURE__ */ u("div", {
|
|
69
|
+
className: "flex min-w-0 items-center gap-2",
|
|
70
|
+
children: [
|
|
71
|
+
j(m, E, x, S),
|
|
72
|
+
/* @__PURE__ */ u("div", {
|
|
73
|
+
className: "flex shrink-0 flex-col gap-2",
|
|
74
|
+
children: [/* @__PURE__ */ l(t, {
|
|
75
|
+
type: "button",
|
|
76
|
+
size: "icon",
|
|
77
|
+
variant: "outline",
|
|
78
|
+
disabled: x.length === 0,
|
|
79
|
+
onClick: k,
|
|
80
|
+
"aria-label": `移动到${h}`,
|
|
81
|
+
children: /* @__PURE__ */ l(s, { "aria-hidden": "true" })
|
|
82
|
+
}), /* @__PURE__ */ l(t, {
|
|
83
|
+
type: "button",
|
|
84
|
+
size: "icon",
|
|
85
|
+
variant: "outline",
|
|
86
|
+
disabled: C.length === 0,
|
|
87
|
+
onClick: A,
|
|
88
|
+
"aria-label": `移动到${m}`,
|
|
89
|
+
children: /* @__PURE__ */ l(o, { "aria-hidden": "true" })
|
|
90
|
+
})]
|
|
91
|
+
}),
|
|
92
|
+
j(h, D, C, w)
|
|
93
|
+
]
|
|
94
|
+
})]
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { d as Transfer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../lib/utils.cjs"),t=require("./ui/button.cjs"),n=require("../lib/use-ui-translation.cjs"),r=require("./data-table.cjs"),i=require("../lib/tree.cjs");let a=require("react"),o=require("lucide-react"),s=require("react/jsx-runtime");function c({nodes:c,columns:l,caption:u,rowLabel:d,defaultExpanded:f=[]}){let{t:p}=n.useUiTranslation(),[m,h]=(0,a.useState)(()=>new Set(f)),g=i.flattenTree(c,m);function _(e){h(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})}let v=l.map((n,r)=>({id:n.id,header:n.header,size:n.width,cell:({row:i})=>r>0?n.cell(i.original):(0,s.jsxs)(`div`,{className:`flex items-center gap-1`,style:{paddingInlineStart:i.original.depth*20},children:[i.original.hasChildren?(0,s.jsx)(t.Button,{type:`button`,variant:`ghost`,size:`icon`,className:`size-7 shrink-0`,"aria-label":p(i.original.expanded?`tree.collapse`:`tree.expand`,{name:d(i.original.node)}),"aria-expanded":i.original.expanded,onClick:()=>_(i.original.node.id),children:(0,s.jsx)(o.ChevronRight,{"aria-hidden":`true`,className:e.cn(`size-4 transition-transform`,i.original.expanded&&`rotate-90`)})}):(0,s.jsx)(`span`,{"aria-hidden":`true`,className:`size-7 shrink-0`}),(0,s.jsx)(`span`,{className:`min-w-0 flex-1`,children:n.cell(i.original)})]})}));return(0,s.jsx)(r.DataTable,{data:g,columns:v,caption:u})}exports.TreeTable=c;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import { type FlatTreeRow, type TreeNode } from '../lib/tree';
|
|
3
|
+
export type TreeTableColumn<T> = {
|
|
4
|
+
id: string;
|
|
5
|
+
header: string;
|
|
6
|
+
/** 固定列宽;省略时由标准表格按可用宽度分配。 */
|
|
7
|
+
width?: number;
|
|
8
|
+
/** 第一列的返回值会自动获得层级缩进与展开按钮。 */
|
|
9
|
+
cell: (row: FlatTreeRow<T>) => ReactNode;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* 表格树:层级数据复用标准表格,表格样式、列宽拖拽、溢出提示与空态都来自 `DataTable`。
|
|
13
|
+
* 只把父子关系拍平成行,并在第一列补上缩进与展开按钮。
|
|
14
|
+
*/
|
|
15
|
+
export declare function TreeTable<T>({ nodes, columns, caption, rowLabel, defaultExpanded, }: {
|
|
16
|
+
nodes: TreeNode<T>[];
|
|
17
|
+
columns: TreeTableColumn<T>[];
|
|
18
|
+
caption: string;
|
|
19
|
+
/** 展开/收起按钮的提示文本,通常返回行的名称。 */
|
|
20
|
+
rowLabel: (node: TreeNode<T>) => string;
|
|
21
|
+
defaultExpanded?: string[];
|
|
22
|
+
}): import("react").JSX.Element;
|
|
23
|
+
//# sourceMappingURL=tree-table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree-table.d.ts","sourceRoot":"","sources":["../../src/components/tree-table.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAMhD,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAGzE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,6BAA6B;IAC7B,IAAI,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS,CAAA;CACzC,CAAA;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,EAC3B,KAAK,EACL,OAAO,EACP,OAAO,EACP,QAAQ,EACR,eAAoB,GACrB,EAAE;IACD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;IACpB,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,6BAA6B;IAC7B,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,MAAM,CAAA;IACvC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAC3B,+BAoDA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { Button as t } from "./ui/button.js";
|
|
3
|
+
import { useUiTranslation as n } from "../lib/use-ui-translation.js";
|
|
4
|
+
import { DataTable as r } from "./data-table.js";
|
|
5
|
+
import { flattenTree as i } from "../lib/tree.js";
|
|
6
|
+
import { useState as a } from "react";
|
|
7
|
+
import { ChevronRight as o } from "lucide-react";
|
|
8
|
+
import { jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
9
|
+
//#region src/components/tree-table.tsx
|
|
10
|
+
function l({ nodes: l, columns: u, caption: d, rowLabel: f, defaultExpanded: p = [] }) {
|
|
11
|
+
let { t: m } = n(), [h, g] = a(() => new Set(p)), _ = i(l, h);
|
|
12
|
+
function v(e) {
|
|
13
|
+
g((t) => {
|
|
14
|
+
let n = new Set(t);
|
|
15
|
+
return n.has(e) ? n.delete(e) : n.add(e), n;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
let y = u.map((n, r) => ({
|
|
19
|
+
id: n.id,
|
|
20
|
+
header: n.header,
|
|
21
|
+
size: n.width,
|
|
22
|
+
cell: ({ row: i }) => r > 0 ? n.cell(i.original) : /* @__PURE__ */ c("div", {
|
|
23
|
+
className: "flex items-center gap-1",
|
|
24
|
+
style: { paddingInlineStart: i.original.depth * 20 },
|
|
25
|
+
children: [i.original.hasChildren ? /* @__PURE__ */ s(t, {
|
|
26
|
+
type: "button",
|
|
27
|
+
variant: "ghost",
|
|
28
|
+
size: "icon",
|
|
29
|
+
className: "size-7 shrink-0",
|
|
30
|
+
"aria-label": m(i.original.expanded ? "tree.collapse" : "tree.expand", { name: f(i.original.node) }),
|
|
31
|
+
"aria-expanded": i.original.expanded,
|
|
32
|
+
onClick: () => v(i.original.node.id),
|
|
33
|
+
children: /* @__PURE__ */ s(o, {
|
|
34
|
+
"aria-hidden": "true",
|
|
35
|
+
className: e("size-4 transition-transform", i.original.expanded && "rotate-90")
|
|
36
|
+
})
|
|
37
|
+
}) : /* @__PURE__ */ s("span", {
|
|
38
|
+
"aria-hidden": "true",
|
|
39
|
+
className: "size-7 shrink-0"
|
|
40
|
+
}), /* @__PURE__ */ s("span", {
|
|
41
|
+
className: "min-w-0 flex-1",
|
|
42
|
+
children: n.cell(i.original)
|
|
43
|
+
})]
|
|
44
|
+
})
|
|
45
|
+
}));
|
|
46
|
+
return /* @__PURE__ */ s(r, {
|
|
47
|
+
data: _,
|
|
48
|
+
columns: y,
|
|
49
|
+
caption: d
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { l as TreeTable };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../lib/utils.cjs"),t=require("./ui/button.cjs"),n=require("../lib/use-ui-translation.cjs"),r=require("./ui/checkbox.cjs"),i=require("./ui/input.cjs"),a=require("./ui/skeleton.cjs"),o=require("../lib/tree.cjs");let s=require("react"),c=require("lucide-react"),l=require("react/jsx-runtime");function u({nodes:u,label:d,defaultExpanded:f=[],defaultSelected:p,guides:m=!0,filterable:h=!1,showExpandControls:g=!1,checkable:_=!1,defaultChecked:v=[],onCheckedChange:y,filterPlaceholder:b,onMove:x,loadChildren:S,virtual:C,className:w}){let{t:T}=n.useUiTranslation(),[E,D]=(0,s.useState)(()=>new Set(f)),[O,k]=(0,s.useState)(p),[ee,A]=(0,s.useState)(p??u[0]?.id),[j,M]=(0,s.useState)(``),[N,P]=(0,s.useState)(),[F,I]=(0,s.useState)(),L=(0,s.useRef)(0),R=(0,s.useRef)(null),[z,B]=(0,s.useState)({start:0,end:40}),[V,H]=(0,s.useState)(()=>new Set),[U,W]=(0,s.useState)(()=>new Set(v)),G=(0,s.useRef)(new Map),K=(0,s.useMemo)(()=>{let e=j.trim().toLowerCase();if(!e)return{nodes:u,matched:new Set,autoExpand:new Set};let t=new Set,n=new Set,r=new Map(u.map(e=>[e.id,e]));for(let i of u){if(!i.data.label.toLowerCase().includes(e))continue;t.add(i.id);let a=i.parentId;for(;a&&r.has(a);)n.add(a),a=r.get(a)?.parentId}return{nodes:u.filter(e=>t.has(e.id)||n.has(e.id)),matched:t,autoExpand:n}},[u,j]),q=o.flattenTree(K.nodes,j?new Set([...E,...K.autoExpand]):E),J=q.map(e=>e.node.id),Y=u.map(e=>e.id),X=K.nodes.map(e=>e.id);function Z(e){let t=!U.has(e),n=o.toggleChecked(u,U,e,t);W(n),y?.([...n])}function Q(e){e&&(A(e),G.current.get(e)?.focus())}function $(e){!e.expanded&&e.hasChildren===!1&&S&&(H(t=>new Set(t).add(e.node.id)),S(e.node.id),window.setTimeout(()=>H(t=>{let n=new Set(t);return n.delete(e.node.id),n}),600)),D(t=>{let n=new Set(t);return n.has(e.node.id)?n.delete(e.node.id):n.add(e.node.id),n})}function te(e,t){let n=J.indexOf(t.node.id),r=q.find(e=>e.node.id===t.node.parentId);e.key===`ArrowDown`?(e.preventDefault(),Q(J[Math.min(n+1,J.length-1)])):e.key===`ArrowUp`?(e.preventDefault(),Q(J[Math.max(n-1,0)])):e.key===`Home`?(e.preventDefault(),Q(J[0])):e.key===`End`?(e.preventDefault(),Q(J.at(-1))):e.key===`ArrowRight`?(e.preventDefault(),t.hasChildren&&!t.expanded?$(t):t.hasChildren&&Q(J[n+1])):e.key===`ArrowLeft`?(e.preventDefault(),t.expanded?$(t):Q(r?.node.id)):(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),t.node.data.disabled||k(t.node.id))}let ne=(h||g)&&(0,l.jsxs)(`div`,{className:`mb-2 flex flex-wrap items-center gap-2`,children:[h&&(0,l.jsxs)(`div`,{className:`relative min-w-40 flex-1`,children:[(0,l.jsx)(c.Search,{"aria-hidden":`true`,className:`pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground`}),(0,l.jsx)(i.Input,{"aria-label":T(`filterNodes`),value:j,placeholder:b??T(`filterNodes`),className:`h-8 pl-8`,onChange:e=>M(e.target.value)})]}),g&&(0,l.jsxs)(`div`,{className:`flex items-center gap-1`,children:[_&&(0,l.jsxs)(`label`,{className:`flex items-center gap-2 whitespace-nowrap text-xs text-muted-foreground`,children:[(0,l.jsx)(r.Checkbox,{"aria-label":T(`tree.selectAll`),checked:X.length>0&&X.every(e=>U.has(e)),indeterminate:X.some(e=>U.has(e))&&!X.every(e=>U.has(e)),onCheckedChange:e=>{let t=new Set(U);for(let n of X)e?t.add(n):t.delete(n);W(t),y?.([...t])}}),T(`tree.selected`,{count:U.size})]}),(0,l.jsxs)(t.Button,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>D(new Set(Y)),children:[(0,l.jsx)(c.ListTree,{"aria-hidden":`true`}),T(`expandAll`)]}),(0,l.jsx)(t.Button,{type:`button`,variant:`outline`,size:`sm`,onClick:()=>D(new Set),children:T(`collapseAll`)})]})]});return u.length?(0,l.jsxs)(`div`,{className:e.cn(`rounded-xl border bg-card p-2 text-sm`,w),children:[ne,(0,l.jsxs)(`div`,{ref:R,role:`tree`,"aria-label":d,className:C?`max-h-96 overflow-y-auto`:void 0,onScroll:e=>{if(!C)return;let t=Math.floor(e.currentTarget.scrollTop/36);B({start:Math.max(0,t-8),end:t+40})},children:[q.length===0&&(0,l.jsx)(`p`,{className:`px-2 py-6 text-center text-sm text-muted-foreground`,children:T(`filterEmpty`)}),(C&&q.length>200?q.slice(z.start,z.end):q).map(n=>{let i=n.node.data;return(0,l.jsxs)(`div`,{role:`treeitem`,"aria-level":n.depth+1,"aria-expanded":n.hasChildren?n.expanded:void 0,"aria-selected":O===n.node.id,"aria-checked":_?U.has(n.node.id)?!0:o.checkState(u,U,n.node.id)===`indeterminate`&&`mixed`:void 0,"aria-disabled":i.disabled||void 0,"data-depth":n.depth,tabIndex:ee===n.node.id?0:-1,ref:e=>{e?G.current.set(n.node.id,e):G.current.delete(n.node.id)},className:e.cn(`relative flex min-h-9 cursor-pointer items-center gap-2 rounded-md pr-2 outline-none`,`hover:bg-accent/60 focus-visible:ring-2 focus-visible:ring-ring/40`,O===n.node.id&&`bg-primary/8 text-primary`,i.disabled&&`pointer-events-none opacity-50`,F===n.node.id&&`ring-2 ring-primary/50`),style:{paddingInlineStart:n.depth*20},draggable:!!x,onDragStart:()=>P(n.node.id),onDragOver:e=>{x&&N&&N!==n.node.id&&(o.subtreeIds(u,N).includes(n.node.id)||(e.preventDefault(),I(n.node.id)))},onDragLeave:()=>I(e=>e===n.node.id?void 0:e),onDrop:e=>{x&&N&&N!==n.node.id&&(e.preventDefault(),o.subtreeIds(u,N).includes(n.node.id)||x(N,n.node.id),P(void 0),I(void 0))},onTouchStart:()=>{x&&(L.current=window.setTimeout(()=>P(n.node.id),400))},onTouchEnd:()=>window.clearTimeout(L.current),onTouchMove:()=>window.clearTimeout(L.current),onClick:()=>{A(n.node.id),k(n.node.id)},onKeyDown:e=>te(e,n),children:[m&&n.depth>0&&Array.from({length:n.depth},(e,t)=>(0,l.jsx)(`span`,{"aria-hidden":`true`,className:`pointer-events-none absolute inset-y-0 border-l border-dashed border-border`,style:{insetInlineStart:t*20+14}},t)),_&&(0,l.jsx)(r.Checkbox,{className:`mr-0.5`,"aria-label":T(`tree.select`,{name:i.label}),checked:U.has(n.node.id),indeterminate:o.checkState(u,U,n.node.id)===`indeterminate`,onCheckedChange:()=>Z(n.node.id)}),n.hasChildren?(0,l.jsx)(t.Button,{type:`button`,variant:`ghost`,size:`icon`,className:`size-7 shrink-0`,tabIndex:-1,"aria-label":T(n.expanded?`tree.collapse`:`tree.expand`,{name:i.label}),onClick:e=>{e.stopPropagation(),$(n)},children:(0,l.jsx)(c.ChevronRight,{"aria-hidden":`true`,className:e.cn(`size-4 transition-transform`,n.expanded&&`rotate-90`)})}):(0,l.jsx)(`span`,{"aria-hidden":`true`,className:`size-7 shrink-0`}),(0,l.jsxs)(`span`,{className:e.cn(`min-w-0 flex-1 truncate`,K.matched.size>0&&K.matched.has(n.node.id)&&`text-primary`),children:[V.has(n.node.id)&&(0,l.jsx)(a.Skeleton,{className:`size-3.5 shrink-0 rounded-full`}),i.label]}),i.description&&(0,l.jsx)(`span`,{className:`shrink-0 text-xs text-muted-foreground`,children:i.description})]},n.node.id)})]})]}):(0,l.jsx)(`p`,{className:e.cn(`rounded-xl border bg-card p-4 text-sm text-muted-foreground`,w),children:T(`tree.empty`)})}exports.Tree=u;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type TreeNode } from '../lib/tree';
|
|
2
|
+
export type TreeItem = {
|
|
3
|
+
label: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* 列表树:层级缩进 + 可选虚线层级线,行本身即选中项,不在行首放其他控件。
|
|
9
|
+
* ↑/↓ 在可见节点间移动,→ 展开或进入子节点,← 收起或回到父节点,Enter/空格 选中。
|
|
10
|
+
*/
|
|
11
|
+
export declare function Tree({ nodes, label, defaultExpanded, defaultSelected, guides, filterable, showExpandControls, checkable, defaultChecked, onCheckedChange, filterPlaceholder, onMove, loadChildren, virtual, className, }: {
|
|
12
|
+
nodes: TreeNode<TreeItem>[];
|
|
13
|
+
/** 树的访问名称,同时用于展开/收起按钮的提示。 */
|
|
14
|
+
label: string;
|
|
15
|
+
defaultExpanded?: string[];
|
|
16
|
+
defaultSelected?: string;
|
|
17
|
+
/** 是否显示层级虚线;层级缩进始终保留。 */
|
|
18
|
+
guides?: boolean;
|
|
19
|
+
/** 显示节点搜索框;命中节点会自动展开其祖先。 */
|
|
20
|
+
filterable?: boolean;
|
|
21
|
+
/** 显示展开全部 / 收起全部按钮。 */
|
|
22
|
+
showExpandControls?: boolean;
|
|
23
|
+
/** 开启后每行带勾选框:父节点级联子节点,子节点全选后父节点自动勾选。 */
|
|
24
|
+
checkable?: boolean;
|
|
25
|
+
defaultChecked?: string[];
|
|
26
|
+
onCheckedChange?: (ids: string[]) => void;
|
|
27
|
+
filterPlaceholder?: string;
|
|
28
|
+
/** 拖拽排序:把 source 拖到 target 之后(target 为空表示成为根节点)。 */
|
|
29
|
+
onMove?: (sourceId: string, targetId: string | undefined) => void;
|
|
30
|
+
/** 懒加载:节点首次展开时回调,业务把子节点补进 nodes。 */
|
|
31
|
+
loadChildren?: (id: string) => void;
|
|
32
|
+
/** 节点超过 200 时启用窗口化渲染,只渲染可视区域。 */
|
|
33
|
+
virtual?: boolean;
|
|
34
|
+
className?: string;
|
|
35
|
+
}): import("react").JSX.Element;
|
|
36
|
+
//# sourceMappingURL=tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.d.ts","sourceRoot":"","sources":["../../src/components/tree.tsx"],"names":[],"mappings":"AAGA,OAAO,EAML,KAAK,QAAQ,EACd,MAAM,YAAY,CAAA;AAOnB,MAAM,MAAM,QAAQ,GAAG;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,KAAK,EACL,eAAoB,EACpB,eAAe,EACf,MAAa,EACb,UAAkB,EAClB,kBAA0B,EAC1B,SAAiB,EACjB,cAAmB,EACnB,eAAe,EACf,iBAAiB,EACjB,MAAM,EACN,YAAY,EACZ,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IAC3B,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,yBAAyB;IACzB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,uBAAuB;IACvB,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,wCAAwC;IACxC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;IACzC,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,oDAAoD;IACpD,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAA;IACjE,oCAAoC;IACpC,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,iCAAiC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,+BA0TA"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { Button as t } from "./ui/button.js";
|
|
3
|
+
import { useUiTranslation as n } from "../lib/use-ui-translation.js";
|
|
4
|
+
import { Checkbox as r } from "./ui/checkbox.js";
|
|
5
|
+
import { Input as i } from "./ui/input.js";
|
|
6
|
+
import { Skeleton as a } from "./ui/skeleton.js";
|
|
7
|
+
import { checkState as o, flattenTree as ee, subtreeIds as s, toggleChecked as c } from "../lib/tree.js";
|
|
8
|
+
import { useMemo as te, useRef as l, useState as u } from "react";
|
|
9
|
+
import { ChevronRight as d, ListTree as f, Search as p } from "lucide-react";
|
|
10
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
11
|
+
//#region src/components/tree.tsx
|
|
12
|
+
function g({ nodes: g, label: ne, defaultExpanded: _ = [], defaultSelected: v, guides: y = !0, filterable: b = !1, showExpandControls: x = !1, checkable: S = !1, defaultChecked: re = [], onCheckedChange: C, filterPlaceholder: ie, onMove: w, loadChildren: T, virtual: E, className: D }) {
|
|
13
|
+
let { t: O } = n(), [k, A] = u(() => new Set(_)), [j, M] = u(v), [N, P] = u(v ?? g[0]?.id), [F, ae] = u(""), [I, L] = u(), [oe, R] = u(), z = l(0), B = l(null), [V, H] = u({
|
|
14
|
+
start: 0,
|
|
15
|
+
end: 40
|
|
16
|
+
}), [U, W] = u(() => /* @__PURE__ */ new Set()), [G, K] = u(() => new Set(re)), q = l(/* @__PURE__ */ new Map()), J = te(() => {
|
|
17
|
+
let e = F.trim().toLowerCase();
|
|
18
|
+
if (!e) return {
|
|
19
|
+
nodes: g,
|
|
20
|
+
matched: /* @__PURE__ */ new Set(),
|
|
21
|
+
autoExpand: /* @__PURE__ */ new Set()
|
|
22
|
+
};
|
|
23
|
+
let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = new Map(g.map((e) => [e.id, e]));
|
|
24
|
+
for (let i of g) {
|
|
25
|
+
if (!i.data.label.toLowerCase().includes(e)) continue;
|
|
26
|
+
t.add(i.id);
|
|
27
|
+
let a = i.parentId;
|
|
28
|
+
for (; a && r.has(a);) n.add(a), a = r.get(a)?.parentId;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
nodes: g.filter((e) => t.has(e.id) || n.has(e.id)),
|
|
32
|
+
matched: t,
|
|
33
|
+
autoExpand: n
|
|
34
|
+
};
|
|
35
|
+
}, [g, F]), Y = ee(J.nodes, F ? /* @__PURE__ */ new Set([...k, ...J.autoExpand]) : k), X = Y.map((e) => e.node.id), se = g.map((e) => e.id), Z = J.nodes.map((e) => e.id);
|
|
36
|
+
function ce(e) {
|
|
37
|
+
let t = !G.has(e), n = c(g, G, e, t);
|
|
38
|
+
K(n), C?.([...n]);
|
|
39
|
+
}
|
|
40
|
+
function Q(e) {
|
|
41
|
+
e && (P(e), q.current.get(e)?.focus());
|
|
42
|
+
}
|
|
43
|
+
function $(e) {
|
|
44
|
+
!e.expanded && e.hasChildren === !1 && T && (W((t) => new Set(t).add(e.node.id)), T(e.node.id), window.setTimeout(() => W((t) => {
|
|
45
|
+
let n = new Set(t);
|
|
46
|
+
return n.delete(e.node.id), n;
|
|
47
|
+
}), 600)), A((t) => {
|
|
48
|
+
let n = new Set(t);
|
|
49
|
+
return n.has(e.node.id) ? n.delete(e.node.id) : n.add(e.node.id), n;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function le(e, t) {
|
|
53
|
+
let n = X.indexOf(t.node.id), r = Y.find((e) => e.node.id === t.node.parentId);
|
|
54
|
+
e.key === "ArrowDown" ? (e.preventDefault(), Q(X[Math.min(n + 1, X.length - 1)])) : e.key === "ArrowUp" ? (e.preventDefault(), Q(X[Math.max(n - 1, 0)])) : e.key === "Home" ? (e.preventDefault(), Q(X[0])) : e.key === "End" ? (e.preventDefault(), Q(X.at(-1))) : e.key === "ArrowRight" ? (e.preventDefault(), t.hasChildren && !t.expanded ? $(t) : t.hasChildren && Q(X[n + 1])) : e.key === "ArrowLeft" ? (e.preventDefault(), t.expanded ? $(t) : Q(r?.node.id)) : (e.key === "Enter" || e.key === " ") && (e.preventDefault(), t.node.data.disabled || M(t.node.id));
|
|
55
|
+
}
|
|
56
|
+
let ue = (b || x) && /* @__PURE__ */ h("div", {
|
|
57
|
+
className: "mb-2 flex flex-wrap items-center gap-2",
|
|
58
|
+
children: [b && /* @__PURE__ */ h("div", {
|
|
59
|
+
className: "relative min-w-40 flex-1",
|
|
60
|
+
children: [/* @__PURE__ */ m(p, {
|
|
61
|
+
"aria-hidden": "true",
|
|
62
|
+
className: "pointer-events-none absolute left-2.5 top-1/2 size-3.5 -translate-y-1/2 text-muted-foreground"
|
|
63
|
+
}), /* @__PURE__ */ m(i, {
|
|
64
|
+
"aria-label": O("filterNodes"),
|
|
65
|
+
value: F,
|
|
66
|
+
placeholder: ie ?? O("filterNodes"),
|
|
67
|
+
className: "h-8 pl-8",
|
|
68
|
+
onChange: (e) => ae(e.target.value)
|
|
69
|
+
})]
|
|
70
|
+
}), x && /* @__PURE__ */ h("div", {
|
|
71
|
+
className: "flex items-center gap-1",
|
|
72
|
+
children: [
|
|
73
|
+
S && /* @__PURE__ */ h("label", {
|
|
74
|
+
className: "flex items-center gap-2 whitespace-nowrap text-xs text-muted-foreground",
|
|
75
|
+
children: [/* @__PURE__ */ m(r, {
|
|
76
|
+
"aria-label": O("tree.selectAll"),
|
|
77
|
+
checked: Z.length > 0 && Z.every((e) => G.has(e)),
|
|
78
|
+
indeterminate: Z.some((e) => G.has(e)) && !Z.every((e) => G.has(e)),
|
|
79
|
+
onCheckedChange: (e) => {
|
|
80
|
+
let t = new Set(G);
|
|
81
|
+
for (let n of Z) e ? t.add(n) : t.delete(n);
|
|
82
|
+
K(t), C?.([...t]);
|
|
83
|
+
}
|
|
84
|
+
}), O("tree.selected", { count: G.size })]
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ h(t, {
|
|
87
|
+
type: "button",
|
|
88
|
+
variant: "outline",
|
|
89
|
+
size: "sm",
|
|
90
|
+
onClick: () => A(new Set(se)),
|
|
91
|
+
children: [/* @__PURE__ */ m(f, { "aria-hidden": "true" }), O("expandAll")]
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ m(t, {
|
|
94
|
+
type: "button",
|
|
95
|
+
variant: "outline",
|
|
96
|
+
size: "sm",
|
|
97
|
+
onClick: () => A(/* @__PURE__ */ new Set()),
|
|
98
|
+
children: O("collapseAll")
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
})]
|
|
102
|
+
});
|
|
103
|
+
return g.length ? /* @__PURE__ */ h("div", {
|
|
104
|
+
className: e("rounded-xl border bg-card p-2 text-sm", D),
|
|
105
|
+
children: [ue, /* @__PURE__ */ h("div", {
|
|
106
|
+
ref: B,
|
|
107
|
+
role: "tree",
|
|
108
|
+
"aria-label": ne,
|
|
109
|
+
className: E ? "max-h-96 overflow-y-auto" : void 0,
|
|
110
|
+
onScroll: (e) => {
|
|
111
|
+
if (!E) return;
|
|
112
|
+
let t = Math.floor(e.currentTarget.scrollTop / 36);
|
|
113
|
+
H({
|
|
114
|
+
start: Math.max(0, t - 8),
|
|
115
|
+
end: t + 40
|
|
116
|
+
});
|
|
117
|
+
},
|
|
118
|
+
children: [Y.length === 0 && /* @__PURE__ */ m("p", {
|
|
119
|
+
className: "px-2 py-6 text-center text-sm text-muted-foreground",
|
|
120
|
+
children: O("filterEmpty")
|
|
121
|
+
}), (E && Y.length > 200 ? Y.slice(V.start, V.end) : Y).map((n) => {
|
|
122
|
+
let i = n.node.data;
|
|
123
|
+
return /* @__PURE__ */ h("div", {
|
|
124
|
+
role: "treeitem",
|
|
125
|
+
"aria-level": n.depth + 1,
|
|
126
|
+
"aria-expanded": n.hasChildren ? n.expanded : void 0,
|
|
127
|
+
"aria-selected": j === n.node.id,
|
|
128
|
+
"aria-checked": S ? G.has(n.node.id) ? !0 : o(g, G, n.node.id) === "indeterminate" && "mixed" : void 0,
|
|
129
|
+
"aria-disabled": i.disabled || void 0,
|
|
130
|
+
"data-depth": n.depth,
|
|
131
|
+
tabIndex: N === n.node.id ? 0 : -1,
|
|
132
|
+
ref: (e) => {
|
|
133
|
+
e ? q.current.set(n.node.id, e) : q.current.delete(n.node.id);
|
|
134
|
+
},
|
|
135
|
+
className: e("relative flex min-h-9 cursor-pointer items-center gap-2 rounded-md pr-2 outline-none", "hover:bg-accent/60 focus-visible:ring-2 focus-visible:ring-ring/40", j === n.node.id && "bg-primary/8 text-primary", i.disabled && "pointer-events-none opacity-50", oe === n.node.id && "ring-2 ring-primary/50"),
|
|
136
|
+
style: { paddingInlineStart: n.depth * 20 },
|
|
137
|
+
draggable: !!w,
|
|
138
|
+
onDragStart: () => L(n.node.id),
|
|
139
|
+
onDragOver: (e) => {
|
|
140
|
+
w && I && I !== n.node.id && (s(g, I).includes(n.node.id) || (e.preventDefault(), R(n.node.id)));
|
|
141
|
+
},
|
|
142
|
+
onDragLeave: () => R((e) => e === n.node.id ? void 0 : e),
|
|
143
|
+
onDrop: (e) => {
|
|
144
|
+
w && I && I !== n.node.id && (e.preventDefault(), s(g, I).includes(n.node.id) || w(I, n.node.id), L(void 0), R(void 0));
|
|
145
|
+
},
|
|
146
|
+
onTouchStart: () => {
|
|
147
|
+
w && (z.current = window.setTimeout(() => L(n.node.id), 400));
|
|
148
|
+
},
|
|
149
|
+
onTouchEnd: () => window.clearTimeout(z.current),
|
|
150
|
+
onTouchMove: () => window.clearTimeout(z.current),
|
|
151
|
+
onClick: () => {
|
|
152
|
+
P(n.node.id), M(n.node.id);
|
|
153
|
+
},
|
|
154
|
+
onKeyDown: (e) => le(e, n),
|
|
155
|
+
children: [
|
|
156
|
+
y && n.depth > 0 && Array.from({ length: n.depth }, (e, t) => /* @__PURE__ */ m("span", {
|
|
157
|
+
"aria-hidden": "true",
|
|
158
|
+
className: "pointer-events-none absolute inset-y-0 border-l border-dashed border-border",
|
|
159
|
+
style: { insetInlineStart: t * 20 + 14 }
|
|
160
|
+
}, t)),
|
|
161
|
+
S && /* @__PURE__ */ m(r, {
|
|
162
|
+
className: "mr-0.5",
|
|
163
|
+
"aria-label": O("tree.select", { name: i.label }),
|
|
164
|
+
checked: G.has(n.node.id),
|
|
165
|
+
indeterminate: o(g, G, n.node.id) === "indeterminate",
|
|
166
|
+
onCheckedChange: () => ce(n.node.id)
|
|
167
|
+
}),
|
|
168
|
+
n.hasChildren ? /* @__PURE__ */ m(t, {
|
|
169
|
+
type: "button",
|
|
170
|
+
variant: "ghost",
|
|
171
|
+
size: "icon",
|
|
172
|
+
className: "size-7 shrink-0",
|
|
173
|
+
tabIndex: -1,
|
|
174
|
+
"aria-label": O(n.expanded ? "tree.collapse" : "tree.expand", { name: i.label }),
|
|
175
|
+
onClick: (e) => {
|
|
176
|
+
e.stopPropagation(), $(n);
|
|
177
|
+
},
|
|
178
|
+
children: /* @__PURE__ */ m(d, {
|
|
179
|
+
"aria-hidden": "true",
|
|
180
|
+
className: e("size-4 transition-transform", n.expanded && "rotate-90")
|
|
181
|
+
})
|
|
182
|
+
}) : /* @__PURE__ */ m("span", {
|
|
183
|
+
"aria-hidden": "true",
|
|
184
|
+
className: "size-7 shrink-0"
|
|
185
|
+
}),
|
|
186
|
+
/* @__PURE__ */ h("span", {
|
|
187
|
+
className: e("min-w-0 flex-1 truncate", J.matched.size > 0 && J.matched.has(n.node.id) && "text-primary"),
|
|
188
|
+
children: [U.has(n.node.id) && /* @__PURE__ */ m(a, { className: "size-3.5 shrink-0 rounded-full" }), i.label]
|
|
189
|
+
}),
|
|
190
|
+
i.description && /* @__PURE__ */ m("span", {
|
|
191
|
+
className: "shrink-0 text-xs text-muted-foreground",
|
|
192
|
+
children: i.description
|
|
193
|
+
})
|
|
194
|
+
]
|
|
195
|
+
}, n.node.id);
|
|
196
|
+
})]
|
|
197
|
+
})]
|
|
198
|
+
}) : /* @__PURE__ */ m("p", {
|
|
199
|
+
className: e("rounded-xl border bg-card p-4 text-sm text-muted-foreground", D),
|
|
200
|
+
children: O("tree.empty")
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
//#endregion
|
|
204
|
+
export { g as Tree };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../lib/utils.cjs");let t=require("lucide-react"),n=require("react/jsx-runtime");function r({value:r,direction:i,reverse:a=!1,variant:o=`soft`,suffix:s=`%`,className:c}){let l=i===`flat`?void 0:i===`up`!==a,u=i===`flat`?t.Minus:i===`up`?t.ArrowUpRight:t.ArrowDownRight,d=r===void 0?``:`${r>0?`+`:``}${r.toFixed(1)}${s}`;return(0,n.jsxs)(`span`,{"data-slot":`trend`,"data-direction":i,className:e.cn(`inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums`,l===void 0&&`bg-muted text-muted-foreground`,l===!0&&`bg-success-soft text-success`,l===!1&&`bg-danger-soft text-danger`,o===`outline`&&`border-current/30 bg-transparent`,c),children:[(0,n.jsx)(u,{"aria-hidden":`true`,className:`size-3`}),i===`flat`?`0.0`+s:d]})}exports.Trend=r;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare const tones: {
|
|
2
|
+
readonly default: "";
|
|
3
|
+
readonly soft: "";
|
|
4
|
+
readonly outline: "border";
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* 指标涨跌徽标。`reverse` 表示"数值上升是坏事"(如待处理数)。
|
|
8
|
+
*/
|
|
9
|
+
export declare function Trend({ value, direction, reverse, variant, suffix, className, }: {
|
|
10
|
+
/** 百分比数值,undefined 时显示持平。 */
|
|
11
|
+
value?: number;
|
|
12
|
+
direction: 'up' | 'down' | 'flat';
|
|
13
|
+
reverse?: boolean;
|
|
14
|
+
variant?: keyof typeof tones;
|
|
15
|
+
suffix?: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
}): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=trend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trend.d.ts","sourceRoot":"","sources":["../../src/components/trend.tsx"],"names":[],"mappings":"AAGA,QAAA,MAAM,KAAK;;;;CAID,CAAA;AAEV;;GAEG;AACH,wBAAgB,KAAK,CAAC,EACpB,KAAK,EACL,SAAS,EACT,OAAe,EACf,OAAgB,EAChB,MAAY,EACZ,SAAS,GACV,EAAE;IACD,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,OAAO,KAAK,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,+BAqBA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { cn as e } from "../lib/utils.js";
|
|
2
|
+
import { ArrowDownRight as t, ArrowUpRight as n, Minus as r } from "lucide-react";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/trend.tsx
|
|
5
|
+
function o({ value: o, direction: s, reverse: c = !1, variant: l = "soft", suffix: u = "%", className: d }) {
|
|
6
|
+
let f = s === "flat" ? void 0 : s === "up" !== c, p = s === "flat" ? r : s === "up" ? n : t, m = o === void 0 ? "" : `${o > 0 ? "+" : ""}${o.toFixed(1)}${u}`;
|
|
7
|
+
return /* @__PURE__ */ a("span", {
|
|
8
|
+
"data-slot": "trend",
|
|
9
|
+
"data-direction": s,
|
|
10
|
+
className: e("inline-flex items-center gap-0.5 rounded-full px-1.5 py-0.5 text-xs font-medium tabular-nums", f === void 0 && "bg-muted text-muted-foreground", f === !0 && "bg-success-soft text-success", f === !1 && "bg-danger-soft text-danger", l === "outline" && "border-current/30 bg-transparent", d),
|
|
11
|
+
children: [/* @__PURE__ */ i(p, {
|
|
12
|
+
"aria-hidden": "true",
|
|
13
|
+
className: "size-3"
|
|
14
|
+
}), s === "flat" ? "0.0" + u : m]
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
export { o as Trend };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=require("../../_virtual/_rolldown/runtime.cjs"),t=require("../../lib/utils.cjs"),n=require("./button.cjs");let r=require("react");r=e.__toESM(r,1);let i=require("radix-ui"),a=require("react/jsx-runtime");var o=i.AlertDialog.Root,s=i.AlertDialog.Trigger,c=i.AlertDialog.Portal;function l({className:e,...n}){return(0,a.jsx)(i.AlertDialog.Overlay,{className:t.cn(`fixed inset-0 z-50 bg-black/50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0`,e),...n})}function u({className:e,...n}){return(0,a.jsxs)(c,{children:[(0,a.jsx)(l,{}),(0,a.jsx)(i.AlertDialog.Content,{className:t.cn(`fixed left-1/2 top-1/2 z-50 grid w-[calc(100%-2rem)] max-w-lg -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl border bg-background p-6 shadow-lg`,e),...n})]})}function d({className:e,...n}){return(0,a.jsx)(`div`,{className:t.cn(`flex flex-col gap-2 text-center sm:text-left`,e),...n})}function f({className:e,...n}){return(0,a.jsx)(`div`,{className:t.cn(`flex flex-col-reverse gap-2 sm:flex-row sm:justify-end`,e),...n})}function p({className:e,...n}){return(0,a.jsx)(i.AlertDialog.Title,{className:t.cn(`text-lg font-semibold`,e),...n})}function m({className:e,...n}){return(0,a.jsx)(i.AlertDialog.Description,{className:t.cn(`text-sm leading-6 text-muted-foreground`,e),...n})}function h({className:e,...r}){return(0,a.jsx)(i.AlertDialog.Action,{className:t.cn(n.buttonVariants({variant:`destructive`}),e),...r})}function g({className:e,...r}){return(0,a.jsx)(i.AlertDialog.Cancel,{className:t.cn(n.buttonVariants({variant:`outline`}),e),...r})}exports.AlertDialog=o,exports.AlertDialogAction=h,exports.AlertDialogCancel=g,exports.AlertDialogContent=u,exports.AlertDialogDescription=m,exports.AlertDialogFooter=f,exports.AlertDialogHeader=d,exports.AlertDialogTitle=p,exports.AlertDialogTrigger=s;
|