e4e3cab559
主站规范生成支持多张参考图 修复普通生成参考图删除与提交状态不同步 优化触屏设备删除按钮可达性并补充回归测试 --------- Co-authored-by: kdletters <kdletters@qq.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/164 Co-authored-by: 孟豪 <mh18530625731@163.com> Co-committed-by: 孟豪 <mh18530625731@163.com>
132 lines
3.3 KiB
TypeScript
132 lines
3.3 KiB
TypeScript
import { X } from 'lucide-react';
|
|
import { type ReactNode, type RefObject } from 'react';
|
|
|
|
import { ResolvedAssetImage } from '../ResolvedAssetImage';
|
|
|
|
type ImageCanvasReferenceSlotTone =
|
|
| 'default'
|
|
| 'spec'
|
|
| 'icon'
|
|
| 'ui'
|
|
| 'character'
|
|
| 'quick-edit'
|
|
| 'video'
|
|
| 'audio';
|
|
|
|
type ImageCanvasReferenceSlotProps = {
|
|
buttonRef?: RefObject<HTMLButtonElement | null>;
|
|
tone?: ImageCanvasReferenceSlotTone;
|
|
className?: string;
|
|
icon: ReactNode;
|
|
label: string;
|
|
ariaLabel: string;
|
|
title?: string;
|
|
imageSrc?: string | null;
|
|
objectKey?: string | null;
|
|
disabled?: boolean;
|
|
isAdd?: boolean;
|
|
onClick?: () => void;
|
|
onRemove?: () => void;
|
|
removeLabel?: string;
|
|
alwaysShowRemove?: boolean;
|
|
};
|
|
|
|
export function ImageCanvasReferenceSlot({
|
|
buttonRef,
|
|
tone = 'default',
|
|
className,
|
|
icon,
|
|
label,
|
|
ariaLabel,
|
|
title,
|
|
imageSrc,
|
|
objectKey,
|
|
disabled = false,
|
|
isAdd = false,
|
|
onClick,
|
|
onRemove,
|
|
removeLabel,
|
|
alwaysShowRemove = false,
|
|
}: ImageCanvasReferenceSlotProps) {
|
|
const hasPreviewImage = Boolean(imageSrc?.trim() || objectKey?.trim());
|
|
const slotClassName = [
|
|
'image-canvas-editor__reference-chip',
|
|
`image-canvas-editor__reference-chip--${tone}`,
|
|
hasPreviewImage
|
|
? 'image-canvas-editor__reference-chip--has-image'
|
|
: 'image-canvas-editor__reference-chip--icon-only',
|
|
isAdd ? 'image-canvas-editor__reference-chip--upload' : null,
|
|
className,
|
|
]
|
|
.filter(Boolean)
|
|
.join(' ');
|
|
const slotContent = (
|
|
<>
|
|
<span className="image-canvas-editor__reference-chip-icon">
|
|
{hasPreviewImage ? (
|
|
<ResolvedAssetImage
|
|
src={imageSrc}
|
|
objectKey={objectKey}
|
|
alt=""
|
|
aria-hidden="true"
|
|
/>
|
|
) : (
|
|
icon
|
|
)}
|
|
</span>
|
|
<span className="image-canvas-editor__reference-chip-label">{label}</span>
|
|
{title && title !== label ? (
|
|
<span className="image-canvas-editor__reference-chip-source-label">
|
|
{title}
|
|
</span>
|
|
) : null}
|
|
</>
|
|
);
|
|
return (
|
|
<span className="image-canvas-editor__reference-slot">
|
|
{onClick || buttonRef ? (
|
|
<button
|
|
ref={buttonRef}
|
|
type="button"
|
|
className={slotClassName}
|
|
disabled={disabled}
|
|
aria-label={ariaLabel}
|
|
title={title ?? ariaLabel}
|
|
onClick={onClick}
|
|
>
|
|
{slotContent}
|
|
</button>
|
|
) : (
|
|
<span
|
|
className={slotClassName}
|
|
aria-label={ariaLabel}
|
|
title={title ?? ariaLabel}
|
|
>
|
|
{slotContent}
|
|
</span>
|
|
)}
|
|
{onRemove ? (
|
|
<button
|
|
type="button"
|
|
className={`image-canvas-editor__reference-chip-remove${
|
|
alwaysShowRemove
|
|
? ' image-canvas-editor__reference-chip-remove--always-visible'
|
|
: ''
|
|
}`}
|
|
disabled={disabled}
|
|
aria-label={removeLabel ?? `删除${ariaLabel}`}
|
|
title="删除"
|
|
onPointerDown={(event) => event.stopPropagation()}
|
|
onClick={(event) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
onRemove();
|
|
}}
|
|
>
|
|
<X className="h-3 w-3" aria-hidden="true" />
|
|
</button>
|
|
) : null}
|
|
</span>
|
|
);
|
|
}
|