{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "attachment",
  "type": "registry:ui",
  "title": "Attachment",
  "description": "Attachment primitives for Tile UI.",
  "dependencies": [
    "@radix-ui/react-slot"
  ],
  "devDependencies": [
    "sass"
  ],
  "registryDependencies": [
    "@tile-ui/core",
    "button",
    "@tile-ui/styles"
  ],
  "files": [
    {
      "path": "packages/react/src/components/attachment/attachment.tsx",
      "type": "registry:ui",
      "target": "components/ui/attachment/attachment.tsx",
      "content": "import React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport {\n\tattachmentStyleKeys,\n\tgetAttachmentFileKind,\n\tgetAttachmentMediaStyleKeys,\n\tgetAttachmentStyleKeys,\n\tformatAttachmentSize,\n\tisAttachmentActionable,\n\ttruncateAttachmentName,\n} from '../lib/core';\nimport type { AttachmentFileKind, AttachmentMediaVariant, AttachmentOrientation, AttachmentSize, AttachmentState } from '../lib/core';\nimport styles from './attachment.module.scss';\nimport { Button } from '../button/button';\n\n/**\n * 按文件类型渲染对应的内联 SVG 图标\n */\nexport function AttachmentFileIcon({ kind, className }: { kind: AttachmentFileKind; className?: string }) {\n\tconst iconProps = {\n\t\tclassName,\n\t\txmlns: 'http://www.w3.org/2000/svg',\n\t\twidth: 16,\n\t\theight: 16,\n\t\tviewBox: '0 0 24 24',\n\t\tfill: 'none',\n\t\tstroke: 'currentColor',\n\t\tstrokeWidth: 2,\n\t\tstrokeLinecap: 'round' as const,\n\t\tstrokeLinejoin: 'round' as const,\n\t\t'aria-hidden': 'true' as const,\n\t};\n\n\tswitch (kind) {\n\t\tcase 'image':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\" />\n\t\t\t\t\t<circle cx=\"9\" cy=\"9\" r=\"2\" />\n\t\t\t\t\t<path d=\"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'video':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<path d=\"m22 8-6 4 6 4V8Z\" />\n\t\t\t\t\t<rect width=\"14\" height=\"12\" x=\"2\" y=\"6\" rx=\"2\" ry=\"2\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'audio':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<path d=\"M11 5 6 9H2v6h4l5 4V5Z\" />\n\t\t\t\t\t<path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'pdf':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t\t\t<path d=\"M14 2v6h6\" />\n\t\t\t\t\t<path d=\"M9 15c-.5-1 .5-3 2-3s2 2 2 3 0 2-1 2-2.5-.5-3-2Z\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'spreadsheet':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\" />\n\t\t\t\t\t<path d=\"M3 9h18M3 15h18M9 3v18M15 3v18\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'presentation':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<rect width=\"18\" height=\"10\" x=\"3\" y=\"3\" rx=\"2\" ry=\"2\" />\n\t\t\t\t\t<path d=\"M12 13v5M8 21l4-3 4 3M7 6h10\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'archive':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<rect width=\"20\" height=\"5\" x=\"2\" y=\"3\" rx=\"1\" />\n\t\t\t\t\t<path d=\"M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8M10 12h4\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tcase 'code':\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<path d=\"m16 18 6-6-6-6M8 6l-6 6 6 6\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t\tdefault:\n\t\t\treturn (\n\t\t\t\t<svg {...iconProps}>\n\t\t\t\t\t<path d=\"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z\" />\n\t\t\t\t\t<path d=\"M14 2v6h6\" />\n\t\t\t\t</svg>\n\t\t\t);\n\t}\n}\n\n/**\n * 下载 / 删除 图标的辅助函数\n */\nfunction DownloadIcon() {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\taria-hidden=\"true\">\n\t\t\t<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n\t\t\t<path d=\"m7 10 5 5 5-5\" />\n\t\t\t<path d=\"M12 15V3\" />\n\t\t</svg>\n\t);\n}\n\nfunction TrashIcon() {\n\treturn (\n\t\t<svg\n\t\t\txmlns=\"http://www.w3.org/2000/svg\"\n\t\t\twidth=\"16\"\n\t\t\theight=\"16\"\n\t\t\tviewBox=\"0 0 24 24\"\n\t\t\tfill=\"none\"\n\t\t\tstroke=\"currentColor\"\n\t\t\tstrokeWidth=\"2\"\n\t\t\tstrokeLinecap=\"round\"\n\t\t\tstrokeLinejoin=\"round\"\n\t\t\taria-hidden=\"true\">\n\t\t\t<path d=\"M3 6h18\" />\n\t\t\t<path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n\t\t\t<path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n\t\t</svg>\n\t);\n}\n\nexport interface AttachmentProps extends React.HTMLAttributes<HTMLDivElement> {\n\tstate?: AttachmentState;\n\tsize?: AttachmentSize;\n\torientation?: AttachmentOrientation;\n}\n\nconst Attachment = React.forwardRef<HTMLDivElement, AttachmentProps>(\n\t({ className = '', state = 'done', size = 'default', orientation = 'horizontal', children, ...props }, ref) => {\n\t\tconst styleKeys = getAttachmentStyleKeys(size, orientation);\n\n\t\treturn (\n\t\t\t<div\n\t\t\t\tref={ref}\n\t\t\t\tdata-slot=\"attachment\"\n\t\t\t\tdata-state={state}\n\t\t\t\tdata-size={size}\n\t\t\t\tdata-orientation={orientation}\n\t\t\t\tclassName={`${styles[styleKeys.base]} ${styles[styleKeys.size]} ${styles[styleKeys.orientation]} ${className}`}\n\t\t\t\t{...props}>\n\t\t\t\t{children}\n\t\t\t</div>\n\t\t);\n\t},\n);\nAttachment.displayName = 'Attachment';\n\nexport interface AttachmentGroupProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst AttachmentGroup = React.forwardRef<HTMLDivElement, AttachmentGroupProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<div ref={ref} data-slot=\"attachment-group\" className={`${styles[attachmentStyleKeys.group]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n});\nAttachmentGroup.displayName = 'AttachmentGroup';\n\nexport interface AttachmentMediaProps extends React.HTMLAttributes<HTMLDivElement> {\n\tvariant?: AttachmentMediaVariant;\n}\n\nconst AttachmentMedia = React.forwardRef<HTMLDivElement, AttachmentMediaProps>(({ className = '', variant = 'icon', children, ...props }, ref) => {\n\tconst styleKeys = getAttachmentMediaStyleKeys(variant);\n\n\treturn (\n\t\t<div ref={ref} data-slot=\"attachment-media\" data-variant={variant} className={`${styles[styleKeys.base]} ${styles[styleKeys.variant]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n});\nAttachmentMedia.displayName = 'AttachmentMedia';\n\nexport interface AttachmentContentProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst AttachmentContent = React.forwardRef<HTMLDivElement, AttachmentContentProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<div ref={ref} data-slot=\"attachment-content\" className={`${styles[attachmentStyleKeys.content]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n});\nAttachmentContent.displayName = 'AttachmentContent';\n\nexport interface AttachmentTitleProps extends React.HTMLAttributes<HTMLSpanElement> {}\n\nconst AttachmentTitle = React.forwardRef<HTMLSpanElement, AttachmentTitleProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<span ref={ref} data-slot=\"attachment-title\" className={`${styles[attachmentStyleKeys.title]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</span>\n\t);\n});\nAttachmentTitle.displayName = 'AttachmentTitle';\n\nexport interface AttachmentDescriptionProps extends React.HTMLAttributes<HTMLSpanElement> {}\n\nconst AttachmentDescription = React.forwardRef<HTMLSpanElement, AttachmentDescriptionProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<span ref={ref} data-slot=\"attachment-description\" className={`${styles[attachmentStyleKeys.description]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</span>\n\t);\n});\nAttachmentDescription.displayName = 'AttachmentDescription';\n\nexport interface AttachmentActionsProps extends React.HTMLAttributes<HTMLDivElement> {}\n\nconst AttachmentActions = React.forwardRef<HTMLDivElement, AttachmentActionsProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<div ref={ref} data-slot=\"attachment-actions\" className={`${styles[attachmentStyleKeys.actions]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n});\nAttachmentActions.displayName = 'AttachmentActions';\n\nexport interface AttachmentActionProps extends React.ComponentProps<typeof Button> {}\n\nconst AttachmentAction = React.forwardRef<HTMLButtonElement, AttachmentActionProps>(({ className = '', variant, size = 'icon-xs', children, ...props }, ref) => {\n\treturn (\n\t\t<Button ref={ref} data-slot=\"attachment-action\" variant={variant ?? 'ghost'} size={size} className={`${styles[attachmentStyleKeys.action]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</Button>\n\t);\n});\nAttachmentAction.displayName = 'AttachmentAction';\n\nexport interface AttachmentTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n\tasChild?: boolean;\n}\n\nconst AttachmentTrigger = React.forwardRef<HTMLButtonElement, AttachmentTriggerProps>(({ className = '', asChild = false, type, children, ...props }, ref) => {\n\tconst Comp = asChild ? Slot : 'button';\n\n\treturn (\n\t\t<Comp ref={ref} data-slot=\"attachment-trigger\" type={asChild ? undefined : (type ?? 'button')} className={`${styles[attachmentStyleKeys.trigger]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</Comp>\n\t);\n});\nAttachmentTrigger.displayName = 'AttachmentTrigger';\n\nexport interface AttachmentCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n\tname?: string;\n\tsize?: number;\n\tfile?: File;\n\tstate?: AttachmentState;\n\torientation?: AttachmentOrientation;\n\tdownloading?: boolean;\n\taction?: React.ReactNode;\n\tonRemove?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n\tonDownload?: (event: React.MouseEvent<HTMLButtonElement>) => void;\n\tonPreview?: (event: React.MouseEvent<HTMLDivElement>) => void;\n}\n\nconst AttachmentCard = React.forwardRef<HTMLDivElement, AttachmentCardProps>(\n\t({ className = '', name, size, file, state = 'done', orientation = 'horizontal', downloading = false, action, onRemove, onDownload, onPreview, onClick, ...props }, ref) => {\n\t\tconst kind = getAttachmentFileKind(name, file?.type);\n\t\tconst actionable = isAttachmentActionable(state);\n\t\tconst displayName = name ? truncateAttachmentName(name) : '';\n\t\tconst description = size !== undefined ? formatAttachmentSize(size) : state;\n\n\t\treturn (\n\t\t\t<Attachment\n\t\t\t\tref={ref}\n\t\t\t\tstate={state}\n\t\t\t\tsize=\"default\"\n\t\t\t\torientation={orientation}\n\t\t\t\tclassName={`${styles[attachmentStyleKeys.card]} ${className}`}\n\t\t\t\tonClick={(event: React.MouseEvent<HTMLDivElement>) => {\n\t\t\t\t\tonClick?.(event);\n\t\t\t\t\tonPreview?.(event);\n\t\t\t\t}}\n\t\t\t\t{...props}>\n\t\t\t\t<AttachmentMedia variant=\"icon\">\n\t\t\t\t\t<AttachmentFileIcon kind={kind} />\n\t\t\t\t</AttachmentMedia>\n\t\t\t\t<AttachmentContent>\n\t\t\t\t\t{displayName && <AttachmentTitle>{displayName}</AttachmentTitle>}\n\t\t\t\t\t{description && <AttachmentDescription>{description}</AttachmentDescription>}\n\t\t\t\t</AttachmentContent>\n\t\t\t\t<AttachmentActions>\n\t\t\t\t\t{onDownload && (\n\t\t\t\t\t\t<AttachmentAction type=\"button\" size=\"icon\" aria-label=\"下载\" disabled={!actionable || downloading} onClick={onDownload}>\n\t\t\t\t\t\t\t<DownloadIcon />\n\t\t\t\t\t\t</AttachmentAction>\n\t\t\t\t\t)}\n\t\t\t\t\t{action ??\n\t\t\t\t\t\t(onRemove && (\n\t\t\t\t\t\t\t<AttachmentAction type=\"button\" size=\"icon\" aria-label=\"删除\" disabled={!actionable} onClick={onRemove}>\n\t\t\t\t\t\t\t\t<TrashIcon />\n\t\t\t\t\t\t\t</AttachmentAction>\n\t\t\t\t\t\t))}\n\t\t\t\t</AttachmentActions>\n\t\t\t</Attachment>\n\t\t);\n\t},\n);\nAttachmentCard.displayName = 'AttachmentCard';\n\nexport {\n\tAttachment,\n\tAttachmentGroup,\n\tAttachmentMedia,\n\tAttachmentContent,\n\tAttachmentTitle,\n\tAttachmentDescription,\n\tAttachmentActions,\n\tAttachmentAction,\n\tAttachmentTrigger,\n\tAttachmentCard,\n};\nexport default Attachment;\n"
    },
    {
      "path": "packages/styles/scss/components/attachment.module.scss",
      "type": "registry:file",
      "target": "components/ui/attachment/attachment.module.scss",
      "content": "@use '../../../styles/variables/colors' as *;\n\n// 附件根容器\n.attachment {\n\tposition: relative;\n\tdisplay: flex;\n\twidth: fit-content;\n\tmax-width: 100%;\n\tmin-width: 0;\n\tflex-shrink: 0;\n\tflex-wrap: wrap;\n\tborder: 1px solid var(--tile-attachment-border, $border);\n\tborder-radius: var(--tile-attachment-radius, $radius);\n\tbackground-color: var(--tile-attachment-background, $card);\n\tcolor: $card-foreground;\n\ttransition:\n\t\tbackground-color $transition-fast,\n\t\tborder-color $transition-fast;\n\n\t&:focus-within {\n\t\toutline: none;\n\t\tbox-shadow: var(--tile-attachment-focus-shadow, 0 0 0 1px color-mix(in srgb, $ring 50%, transparent));\n\t}\n\n\t// 尺寸\n\t&[data-size='default'] {\n\t\tgap: $spacing-2;\n\t\tpadding-inline: $spacing-2_5;\n\n\t\t.content {\n\t\t\tpadding: $spacing-2 0;\n\t\t}\n\n\t\t.media {\n\t\t\tpadding: $spacing-2 0;\n\t\t}\n\t}\n\n\t&[data-size='sm'] {\n\t\tgap: $spacing-2_5;\n\t\tpadding-inline: $spacing-2;\n\n\t\t.content {\n\t\t\tpadding: $spacing-1_5 0;\n\t\t}\n\n\t\t.media {\n\t\t\tpadding: $spacing-1_5 0;\n\t\t}\n\t}\n\n\t&[data-size='xs'] {\n\t\tgap: $spacing-1_5;\n\t\tpadding-inline: $spacing-1_5;\n\t\tborder-radius: $radius-md;\n\n\t\t.content {\n\t\t\tpadding: $spacing-1 0;\n\t\t}\n\n\t\t.media {\n\t\t\tpadding: $spacing-1 0;\n\t\t}\n\t}\n\n\t// 排版方向\n\t&[data-orientation='horizontal'] {\n\t\tmin-width: 10rem;\n\t\talign-items: center;\n\t}\n\n\t&[data-orientation='vertical'] {\n\t\twidth: 6rem;\n\t\tflex-direction: column;\n\n\t\t.content {\n\t\t\twidth: 100%;\n\t\t}\n\t}\n\n\t// 状态\n\t&[data-state='idle'] {\n\t\tborder-style: dashed;\n\t}\n\n\t&[data-state='error'] {\n\t\tborder-color: var(--tile-attachment-error-border, color-mix(in srgb, $destructive 30%, transparent));\n\t}\n\n\t&:has(> a, > button):hover {\n\t\tbackground-color: var(--tile-attachment-hover-background, color-mix(in srgb, $muted 50%, transparent));\n\t}\n}\n\n// 附件卡片（AttachmentCard 组合根）\n.card {\n\tposition: relative;\n\tdisplay: flex;\n\twidth: 100%;\n\tmin-width: 0;\n\talign-items: center;\n\tgap: $spacing-2;\n\tborder-radius: var(--tile-attachment-radius, $radius);\n\tbackground-color: var(--tile-attachment-background, $card);\n\tcolor: $card-foreground;\n\ttransition:\n\t\tbackground-color $transition-fast,\n\t\tborder-color $transition-fast;\n\n\t&[data-orientation='vertical'] {\n\t\tflex-direction: column;\n\t\talign-items: flex-start;\n\t}\n\n\t&[data-state='idle'] {\n\t\tborder: 1px dashed var(--tile-attachment-border, $border);\n\t}\n\n\t&[data-state='error'] {\n\t\tborder-color: var(--tile-attachment-error-border, color-mix(in srgb, $destructive 30%, transparent));\n\t}\n}\n\n// 媒体区\n.media {\n\tposition: relative;\n\tdisplay: flex;\n\twidth: 2.5rem;\n\theight: 2.5rem;\n\tflex-shrink: 0;\n\talign-items: center;\n\tjustify-content: center;\n\toverflow: hidden;\n\tborder-radius: $radius;\n\tbackground-color: var(--tile-attachment-media-background, $muted);\n\tcolor: $foreground;\n\n\tsvg {\n\t\tpointer-events: none;\n\t\tflex-shrink: 0;\n\t\twidth: $spacing-4;\n\t\theight: $spacing-4;\n\t}\n\n\t// 变体\n\t&.variantIcon {\n\t\t[data-size='xs'] & {\n\t\t\twidth: 1.75rem;\n\t\t\theight: 1.75rem;\n\t\t\tborder-radius: $radius-md;\n\n\t\t\tsvg {\n\t\t\t\twidth: 0.875rem;\n\t\t\t\theight: 0.875rem;\n\t\t\t}\n\t\t}\n\n\t\t[data-orientation='vertical'] & {\n\t\t\twidth: 100%;\n\n\t\t\tsvg {\n\t\t\t\twidth: $spacing-6;\n\t\t\t\theight: $spacing-6;\n\t\t\t}\n\t\t}\n\t}\n\n\t&.variantImage {\n\t\topacity: 0.6;\n\n\t\timg {\n\t\t\twidth: 100%;\n\t\t\theight: 100%;\n\t\t\taspect-ratio: 1 / 1;\n\t\t\tobject-fit: cover;\n\t\t}\n\n\t\t[data-state='done'] &,\n\t\t[data-state='idle'] & {\n\t\t\topacity: 1;\n\t\t}\n\t}\n\n\t// 状态\n\t[data-state='error'] & {\n\t\tbackground-color: var(--tile-attachment-error-background, color-mix(in srgb, $destructive 10%, transparent));\n\t\tcolor: var(--tile-attachment-error-color, $destructive);\n\t}\n}\n\n// 内容区\n.content {\n\tdisplay: flex;\n\tmin-width: 0;\n\tflex: 1;\n\tflex-direction: column;\n\tline-height: $leading-tight;\n}\n\n// 标题\n.title {\n\tdisplay: block;\n\tmax-width: 100%;\n\tmin-width: 0;\n\toverflow: hidden;\n\tfont-weight: $font-medium;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\n\t[data-state='processing'] &,\n\t[data-state='uploading'] & {\n\t\tcolor: $muted-foreground;\n\t}\n}\n\n// 描述\n.description {\n\tdisplay: block;\n\tmargin-top: 0.125rem;\n\tmin-width: 0;\n\toverflow: hidden;\n\tfont-size: $text-xs;\n\tcolor: $muted-foreground;\n\ttext-overflow: ellipsis;\n\twhite-space: nowrap;\n\n\t[data-state='error'] & {\n\t\tcolor: var(--tile-attachment-error-color, color-mix(in srgb, $destructive 80%, transparent));\n\t}\n}\n\n// 操作区\n.actions {\n\tposition: relative;\n\tz-index: 20;\n\tdisplay: flex;\n\tflex-shrink: 0;\n\talign-items: center;\n\tgap: $spacing-1;\n\n\t[data-orientation='vertical'] & {\n\t\tposition: absolute;\n\t\ttop: $spacing-3;\n\t\tright: $spacing-3;\n\t}\n}\n\n// 单个操作按钮\n.action {\n\tdisplay: inline-flex;\n\tflex-shrink: 0;\n\talign-items: center;\n\tjustify-content: center;\n\tborder: none;\n\tborder-radius: $radius;\n\tbackground-color: transparent;\n\tcolor: $muted-foreground;\n\tcursor: pointer;\n\ttransition:\n\t\tbackground-color $transition-fast,\n\t\tcolor $transition-fast;\n\n\t&:hover {\n\t\tbackground-color: $muted;\n\t\tcolor: $foreground;\n\t}\n\n\t&:focus-visible {\n\t\toutline: none;\n\t\tbox-shadow: var(--tile-attachment-focus-shadow, 0 0 0 1px $ring);\n\t}\n\n\t&:disabled {\n\t\tpointer-events: none;\n\t\topacity: 0.5;\n\t}\n\n\tsvg {\n\t\twidth: $spacing-4;\n\t\theight: $spacing-4;\n\t}\n}\n\n// 触发层（覆盖整个附件，点击跳转/选择）\n.trigger {\n\tposition: absolute;\n\tinset: 0;\n\tz-index: 10;\n\toutline: none;\n\tcursor: pointer;\n}\n\n// 附件组（横向滚动容器）\n.group {\n\tdisplay: flex;\n\tmin-width: 0;\n\tgap: $spacing-3;\n\toverflow-x: auto;\n\toverscroll-behavior-x: contain;\n\tpadding-block: $spacing-1;\n\n\t> [data-slot='attachment'],\n\t> .attachment {\n\t\tflex: none;\n\t}\n}\n"
    },
    {
      "path": "packages/react/src/components/attachment/index.ts",
      "type": "registry:ui",
      "target": "components/ui/attachment/index.ts",
      "content": "export {\n\tAttachment,\n\tAttachmentGroup,\n\tAttachmentMedia,\n\tAttachmentContent,\n\tAttachmentTitle,\n\tAttachmentDescription,\n\tAttachmentActions,\n\tAttachmentAction,\n\tAttachmentTrigger,\n\tAttachmentCard,\n\tAttachmentFileIcon,\n\ttype AttachmentProps,\n\ttype AttachmentGroupProps,\n\ttype AttachmentMediaProps,\n\ttype AttachmentContentProps,\n\ttype AttachmentTitleProps,\n\ttype AttachmentDescriptionProps,\n\ttype AttachmentActionsProps,\n\ttype AttachmentActionProps,\n\ttype AttachmentTriggerProps,\n\ttype AttachmentCardProps,\n} from './attachment';\n"
    }
  ]
}
