feat(shared): add UI components, hooks, form fields, and action utils
- Add UI components: confirm-delete-dialog, empty-table-row, list-pagination, pagination, status-badge - Add form-fields directory for reusable form field components - Add hooks: use-action-mutation, use-action-query for server action integration - Add action-utils lib for action state helpers - Update a11y components, charts, global-search, onboarding-gate, question components - Update UI components: chip-nav, filter-bar, page-header, stat-card, stat-item, switch, table - Update hooks: use-action-with-toast, use-aria-live, use-debounce, use-local-storage, use-media-query, use-permission - Update lib: a11y, ai, audit-logger, auth-guard, bcrypt-utils, change-logger, download, excel, file-storage, http-utils, login-logger, password-policy, password-security-service, permissions, rate-limit, role-utils, search-params, session, storage-provider - Update types: action-state, permissions - Update i18n messages (en, zh-CN) for dashboard, diagnostic, grades, lesson-preparation, settings
This commit is contained in:
@@ -46,6 +46,8 @@ interface ChartCardShellProps {
|
||||
className?: string
|
||||
/** CardContent 额外类名 */
|
||||
contentClassName?: string
|
||||
/** 卡片头部右侧操作区(如"查看全部"链接) */
|
||||
action?: ReactNode
|
||||
}
|
||||
|
||||
export function ChartCardShell({
|
||||
@@ -62,15 +64,19 @@ export function ChartCardShell({
|
||||
children,
|
||||
className,
|
||||
contentClassName,
|
||||
action,
|
||||
}: ChartCardShellProps) {
|
||||
const EmptyIcon = emptyIcon ?? Icon
|
||||
return (
|
||||
<Card className={className}>
|
||||
<CardHeader>
|
||||
<CardTitle className={cn("flex items-center gap-2", titleClassName)}>
|
||||
{Icon ? <Icon className={cn("h-4 w-4", iconClassName)} /> : null}
|
||||
{title}
|
||||
</CardTitle>
|
||||
<div className="flex items-center justify-between">
|
||||
<CardTitle className={cn("flex items-center gap-2", titleClassName)}>
|
||||
{Icon ? <Icon className={cn("h-4 w-4", iconClassName)} /> : null}
|
||||
{title}
|
||||
</CardTitle>
|
||||
{action}
|
||||
</div>
|
||||
{description ? <CardDescription>{description}</CardDescription> : null}
|
||||
</CardHeader>
|
||||
<CardContent className={contentClassName}>
|
||||
|
||||
@@ -66,6 +66,8 @@ interface SimpleBarChartProps {
|
||||
tooltipFormatter?: (payload: unknown) => ReactNode
|
||||
/** 按数据项着色的映射(key = xKey 值, value = 颜色);用于单 Bar 分桶着色 */
|
||||
cellColors?: Record<string, string>
|
||||
/** 自定义 SVG defs(如 patterns、gradients),渲染在 BarChart 内部 */
|
||||
defs?: ReactNode
|
||||
/** 容器额外类名 */
|
||||
className?: string
|
||||
}
|
||||
@@ -93,6 +95,7 @@ export function SimpleBarChart({
|
||||
tooltipClassName = "w-[200px]",
|
||||
tooltipFormatter,
|
||||
cellColors,
|
||||
defs,
|
||||
className,
|
||||
}: SimpleBarChartProps) {
|
||||
const chartConfig: ChartConfig = {}
|
||||
@@ -115,6 +118,7 @@ export function SimpleBarChart({
|
||||
return (
|
||||
<ChartContainer config={chartConfig} className={cn(heightClassName, "w-full", className)}>
|
||||
<BarChart data={data} margin={margin}>
|
||||
{defs}
|
||||
<CartesianGrid vertical={false} strokeDasharray="4 4" strokeOpacity={0.4} />
|
||||
<XAxis
|
||||
dataKey={xKey}
|
||||
|
||||
Reference in New Issue
Block a user