03a4410272
主要工作是共享同一套“画布内核与通用 UI 源码”,网站和 Tauri 只分别实现宿主适配层。 --------- Co-authored-by: 段舒康 <kdletters@qq.com> Co-authored-by: kdletters <kdletters@qq.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/136 Co-authored-by: menghao <mh18530625731@163.com> Co-committed-by: menghao <mh18530625731@163.com>
178 lines
4.0 KiB
TypeScript
178 lines
4.0 KiB
TypeScript
import { CanvasChromeButton } from '@genarrative/image-canvas-react';
|
|
import type {
|
|
ComponentType,
|
|
DragEventHandler,
|
|
MouseEventHandler,
|
|
PointerEventHandler,
|
|
ReactNode,
|
|
} from 'react';
|
|
|
|
import {
|
|
PlatformIconButton,
|
|
type PlatformIconButtonVariant,
|
|
} from '../common/PlatformIconButton';
|
|
import { PlatformMediaFrame } from '../common/PlatformMediaFrame';
|
|
|
|
type IconComponent = ComponentType<{ className?: string }>;
|
|
|
|
export type EditorIconButtonProps = {
|
|
label: string;
|
|
title?: string;
|
|
icon: IconComponent;
|
|
className?: string;
|
|
type?: 'button' | 'submit';
|
|
disabled?: boolean;
|
|
pressed?: boolean;
|
|
expanded?: boolean;
|
|
variant?: PlatformIconButtonVariant;
|
|
onClick?: () => void;
|
|
};
|
|
|
|
export function EditorIconButton({
|
|
label,
|
|
title = label,
|
|
icon: Icon,
|
|
className,
|
|
type = 'button',
|
|
disabled,
|
|
pressed,
|
|
expanded,
|
|
variant,
|
|
onClick,
|
|
}: EditorIconButtonProps) {
|
|
const iconNode = <Icon className="h-4 w-4" />;
|
|
|
|
if (variant === undefined || variant === 'platformIcon') {
|
|
return (
|
|
<CanvasChromeButton
|
|
type={type}
|
|
className={className}
|
|
label={label}
|
|
title={title}
|
|
disabled={disabled}
|
|
pressed={pressed}
|
|
expanded={expanded}
|
|
onClick={onClick}
|
|
icon={iconNode}
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<PlatformIconButton
|
|
variant={variant}
|
|
type={type}
|
|
className={className}
|
|
label={label}
|
|
title={title}
|
|
disabled={disabled}
|
|
aria-pressed={pressed}
|
|
aria-expanded={expanded}
|
|
onClick={onClick}
|
|
icon={iconNode}
|
|
/>
|
|
);
|
|
}
|
|
|
|
export type SidebarMediaItemProps = {
|
|
title: string;
|
|
detail: string;
|
|
imageSrc: string;
|
|
objectKey?: string | null;
|
|
imageAlt: string;
|
|
selected?: boolean;
|
|
primaryLabel: string;
|
|
primaryDisabled?: boolean;
|
|
onPrimaryClick: MouseEventHandler<HTMLButtonElement>;
|
|
thumbnailClassName: string;
|
|
metaClassName: string;
|
|
rowClassName: string;
|
|
primaryClassName?: string;
|
|
actions?: ReactNode;
|
|
titleNode?: ReactNode;
|
|
previewNode?: ReactNode;
|
|
previewOverlay?: ReactNode;
|
|
footerNode?: ReactNode;
|
|
draggable?: boolean;
|
|
onDragStart?: DragEventHandler<HTMLElement>;
|
|
onDragEnd?: DragEventHandler<HTMLElement>;
|
|
onDragOver?: DragEventHandler<HTMLDivElement>;
|
|
onDrop?: DragEventHandler<HTMLDivElement>;
|
|
onPointerDown?: PointerEventHandler<HTMLDivElement>;
|
|
onPointerEnter?: PointerEventHandler<HTMLDivElement>;
|
|
onContextMenu?: MouseEventHandler<HTMLDivElement>;
|
|
};
|
|
|
|
export function SidebarMediaItem({
|
|
title,
|
|
detail,
|
|
imageSrc,
|
|
objectKey,
|
|
imageAlt,
|
|
selected = false,
|
|
primaryLabel,
|
|
primaryDisabled = false,
|
|
onPrimaryClick,
|
|
thumbnailClassName,
|
|
metaClassName,
|
|
rowClassName,
|
|
primaryClassName,
|
|
actions,
|
|
titleNode,
|
|
previewNode,
|
|
previewOverlay,
|
|
footerNode,
|
|
draggable,
|
|
onDragStart,
|
|
onDragEnd,
|
|
onDragOver,
|
|
onDrop,
|
|
onPointerDown,
|
|
onPointerEnter,
|
|
onContextMenu,
|
|
}: SidebarMediaItemProps) {
|
|
return (
|
|
<div
|
|
className={`${rowClassName} ${selected ? `${rowClassName}--selected` : ''}`}
|
|
draggable={draggable}
|
|
onDragStart={onDragStart}
|
|
onDragEnd={onDragEnd}
|
|
onDragOver={onDragOver}
|
|
onDrop={onDrop}
|
|
onPointerDown={onPointerDown}
|
|
onPointerEnter={onPointerEnter}
|
|
onContextMenu={onContextMenu}
|
|
>
|
|
<button
|
|
type="button"
|
|
className={primaryClassName}
|
|
onClick={onPrimaryClick}
|
|
aria-label={primaryLabel}
|
|
disabled={primaryDisabled}
|
|
draggable={draggable}
|
|
onDragStart={onDragStart}
|
|
onDragEnd={onDragEnd}
|
|
>
|
|
{previewNode ?? (
|
|
<PlatformMediaFrame
|
|
src={imageSrc}
|
|
objectKey={objectKey}
|
|
alt={imageAlt}
|
|
fallbackLabel={title}
|
|
aspect="square"
|
|
surface="none"
|
|
className={thumbnailClassName}
|
|
previewOverlay={previewOverlay}
|
|
/>
|
|
)}
|
|
</button>
|
|
<div className={metaClassName}>
|
|
{titleNode ?? <span>{title}</span>}
|
|
<span>{detail}</span>
|
|
{footerNode}
|
|
</div>
|
|
{actions}
|
|
</div>
|
|
);
|
|
}
|