import { For, Show } from 'solid-js'; import { defineWebComponent } from './define'; import { Attachments, Attachment, AttachmentPreview, AttachmentInfo, AttachmentRemove, AttachmentHoverCard, AttachmentHoverCardTrigger, AttachmentHoverCardContent, AttachmentEmpty, getAttachmentLabel, getMediaCategory, type AttachmentData, type AttachmentVariant, } from '../components/attachments'; interface Props extends Record { /** The attachments to render. Set as a JS property (array). */ items: AttachmentData[]; /** Layout: `grid` = visual tiles, `inline` = icon + label chips, `list` = rows. */ variant?: AttachmentVariant; /** Wrap each item in a hover card that previews its details. */ hoverCard?: boolean; /** Show a remove button per item; clicking it fires a `kc-remove` event. */ removable?: boolean; /** Also show the media type beneath the filename (non-grid variants). */ showMediaType?: boolean; /** Text shown when `items` is empty. */ emptyText?: string; } /** Events fired by ``. */ interface Events { /** A remove button was clicked. */ 'kc-remove': { id: string }; } /** * `` — the exemplar for the "collapse a compound primitive to * ONE configurable element" pattern (Route 1). The presentation knobs that the * SolidJS layer expresses by composing sub-parts (``, * ``, ``, ``) become * attributes/flags here: * * - icon + label .......... `variant="inline"` * - visual + hover card .... `variant="grid" hover-card` * - removable chips ........ add `removable` (emits `kc-remove` → { id }) * * Data in via the `items` property; the only interaction (`remove`) comes back * as an event. For fully-custom hover content, the SolidJS primitives remain the * escape hatch (a templated slot — "Route 2" — is a deliberate future add). */ defineWebComponent('kc-attachments', { items: [], variant: 'grid', hoverCard: false, removable: false, showMediaType: false, emptyText: undefined, }, (props, { dispatch, flag }) => { const variant = () => props.variant ?? 'grid'; const hoverCard = () => flag('hoverCard'); const removable = () => flag('removable'); const showMediaType = () => flag('showMediaType'); return ( {props.emptyText}} > {(item) => ( dispatch('kc-remove', { id: item.id }) : undefined} > {/* Info only for non-grid; grid is a self-contained visual tile. */} } > {/* The trigger carries the layout itself — a bare inline collapses inline/list rows. Grid wraps just the tile (the label/details surface in the hover card instead). */} {/* For image attachments, preview the actual thumbnail; otherwise fall back to the label + media-type details. */}
{getAttachmentLabel(item)}
{item.mediaType}
} > {getAttachmentLabel(item)}
)}
); });