@namroodinc/liquid-editorial 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +2 -0
- package/README.md +1 -1
- package/UPGRADING.md +50 -0
- package/dist/chunks/Board-BLhB5_xx.cjs +2 -0
- package/dist/chunks/Board-BLhB5_xx.cjs.map +1 -0
- package/dist/chunks/Board-BTFSzn6c.js +239 -0
- package/dist/chunks/Board-BTFSzn6c.js.map +1 -0
- package/dist/chunks/EntryEditor-CcyYtH74.js +191 -0
- package/dist/chunks/EntryEditor-CcyYtH74.js.map +1 -0
- package/dist/chunks/EntryEditor-DIpc1iPF.cjs +2 -0
- package/dist/chunks/EntryEditor-DIpc1iPF.cjs.map +1 -0
- package/dist/chunks/{RichTextEditor-DC_0oN1s.cjs → RichTextEditor-BxtlbjXj.cjs} +2 -2
- package/dist/chunks/RichTextEditor-BxtlbjXj.cjs.map +1 -0
- package/dist/chunks/{RichTextEditor-CSpjsL1z.js → RichTextEditor-Dnx4i7bQ.js} +104 -93
- package/dist/chunks/RichTextEditor-Dnx4i7bQ.js.map +1 -0
- package/dist/chunks/mergeRefs-Bc3qS0Tt.cjs +2 -0
- package/dist/chunks/mergeRefs-Bc3qS0Tt.cjs.map +1 -0
- package/dist/chunks/mergeRefs-DGM402mE.js +10 -0
- package/dist/chunks/mergeRefs-DGM402mE.js.map +1 -0
- package/dist/components/AssetCard/index.cjs +2 -0
- package/dist/components/AssetCard/index.cjs.map +1 -0
- package/dist/components/AssetCard/index.d.cts +41 -0
- package/dist/components/AssetCard/index.d.cts.map +1 -0
- package/dist/components/AssetCard/index.d.ts +41 -0
- package/dist/components/AssetCard/index.d.ts.map +1 -0
- package/dist/components/AssetCard/index.js +159 -0
- package/dist/components/AssetCard/index.js.map +1 -0
- package/dist/components/AssetCard/style.css +204 -0
- package/dist/components/AssetGrid/index.cjs +1 -1
- package/dist/components/AssetGrid/index.cjs.map +1 -1
- package/dist/components/AssetGrid/index.d.cts +5 -30
- package/dist/components/AssetGrid/index.d.cts.map +1 -1
- package/dist/components/AssetGrid/index.d.ts +5 -30
- package/dist/components/AssetGrid/index.d.ts.map +1 -1
- package/dist/components/AssetGrid/index.js +20 -107
- package/dist/components/AssetGrid/index.js.map +1 -1
- package/dist/components/AssetGrid/style.css +0 -161
- package/dist/components/Board/index.cjs +1 -2
- package/dist/components/Board/index.d.cts.map +1 -1
- package/dist/components/Board/index.d.ts.map +1 -1
- package/dist/components/Board/index.js +1 -231
- package/dist/components/Board/keyboard.d.cts +7 -0
- package/dist/components/Board/keyboard.d.cts.map +1 -0
- package/dist/components/Board/keyboard.d.ts +7 -0
- package/dist/components/Board/keyboard.d.ts.map +1 -0
- package/dist/components/Board/keyboard.test.d.cts +2 -0
- package/dist/components/Board/keyboard.test.d.cts.map +1 -0
- package/dist/components/Board/keyboard.test.d.ts +2 -0
- package/dist/components/Board/keyboard.test.d.ts.map +1 -0
- package/dist/components/Board/moves.d.cts +5 -0
- package/dist/components/Board/moves.d.cts.map +1 -0
- package/dist/components/Board/moves.d.ts +5 -0
- package/dist/components/Board/moves.d.ts.map +1 -0
- package/dist/components/Board/moves.test.d.cts +2 -0
- package/dist/components/Board/moves.test.d.cts.map +1 -0
- package/dist/components/Board/moves.test.d.ts +2 -0
- package/dist/components/Board/moves.test.d.ts.map +1 -0
- package/dist/components/Button/index.cjs +1 -1
- package/dist/components/Button/index.cjs.map +1 -1
- package/dist/components/Button/index.js +1 -1
- package/dist/components/Button/index.js.map +1 -1
- package/dist/components/Button/style.css +0 -16
- package/dist/components/DatePicker/index.cjs +1 -1
- package/dist/components/DatePicker/index.cjs.map +1 -1
- package/dist/components/DatePicker/index.d.cts.map +1 -1
- package/dist/components/DatePicker/index.d.ts.map +1 -1
- package/dist/components/DatePicker/index.js +39 -36
- package/dist/components/DatePicker/index.js.map +1 -1
- package/dist/components/Drawer/index.cjs +1 -1
- package/dist/components/Drawer/index.cjs.map +1 -1
- package/dist/components/Drawer/index.d.cts.map +1 -1
- package/dist/components/Drawer/index.d.ts.map +1 -1
- package/dist/components/Drawer/index.js +69 -62
- package/dist/components/Drawer/index.js.map +1 -1
- package/dist/components/EntryEditor/index.cjs +1 -1
- package/dist/components/EntryEditor/index.d.cts.map +1 -1
- package/dist/components/EntryEditor/index.d.ts.map +1 -1
- package/dist/components/EntryEditor/index.js +1 -1
- package/dist/components/EntryEditor/model.d.cts.map +1 -1
- package/dist/components/EntryEditor/model.d.ts.map +1 -1
- package/dist/components/Icon/style.css +18 -0
- package/dist/components/ImageCropper/index.cjs +1 -1
- package/dist/components/ImageCropper/index.cjs.map +1 -1
- package/dist/components/ImageCropper/index.d.cts +16 -1
- package/dist/components/ImageCropper/index.d.cts.map +1 -1
- package/dist/components/ImageCropper/index.d.ts +16 -1
- package/dist/components/ImageCropper/index.d.ts.map +1 -1
- package/dist/components/ImageCropper/index.js +143 -107
- package/dist/components/ImageCropper/index.js.map +1 -1
- package/dist/components/Pagination/index.cjs +1 -1
- package/dist/components/Pagination/index.cjs.map +1 -1
- package/dist/components/Pagination/index.js +1 -1
- package/dist/components/Pagination/index.js.map +1 -1
- package/dist/components/Pagination/style.css +0 -1
- package/dist/components/RichTextEditor/index.cjs +1 -1
- package/dist/components/RichTextEditor/index.d.cts.map +1 -1
- package/dist/components/RichTextEditor/index.d.ts.map +1 -1
- package/dist/components/RichTextEditor/index.js +1 -1
- package/dist/components/Select/index.cjs +1 -1
- package/dist/components/Select/index.cjs.map +1 -1
- package/dist/components/Select/index.d.cts.map +1 -1
- package/dist/components/Select/index.d.ts.map +1 -1
- package/dist/components/Select/index.js +32 -18
- package/dist/components/Select/index.js.map +1 -1
- package/dist/components/SortableList/index.cjs +1 -1
- package/dist/components/SortableList/index.cjs.map +1 -1
- package/dist/components/SortableList/index.d.cts.map +1 -1
- package/dist/components/SortableList/index.d.ts.map +1 -1
- package/dist/components/SortableList/index.js +49 -50
- package/dist/components/SortableList/index.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -33
- package/dist/internal/mergeRefs.d.cts +4 -0
- package/dist/internal/mergeRefs.d.cts.map +1 -0
- package/dist/internal/mergeRefs.d.ts +4 -0
- package/dist/internal/mergeRefs.d.ts.map +1 -0
- package/dist/styles.css +1 -0
- package/dist/test/dragEvent.d.cts +3 -0
- package/dist/test/dragEvent.d.cts.map +1 -0
- package/dist/test/dragEvent.d.ts +3 -0
- package/dist/test/dragEvent.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/chunks/EntryEditor-C32lKKnV.cjs +0 -2
- package/dist/chunks/EntryEditor-C32lKKnV.cjs.map +0 -1
- package/dist/chunks/EntryEditor-xVuiqtFo.js +0 -181
- package/dist/chunks/EntryEditor-xVuiqtFo.js.map +0 -1
- package/dist/chunks/RichTextEditor-CSpjsL1z.js.map +0 -1
- package/dist/chunks/RichTextEditor-DC_0oN1s.cjs.map +0 -1
- package/dist/components/Board/index.cjs.map +0 -1
- package/dist/components/Board/index.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["Icon","useState","useCallback","_Fragment","Skeleton","forwardRef","Button","require_Icon","require_components_Button_index","require_components_Skeleton_index","react","react_jsx_runtime","Placeholder","icon","label","AssetImage","status","setStatus","ratio","setRatio","adopt","image","imageRef","alt","event","AssetCard","rest","className","fit","isSelected","isPending","src","actions","onSelect","name","meta","description","footer","AssetCardSkeleton","delay","index"],"sources":["../../../src/components/AssetCard/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"../Button\";\nimport { Icon } from \"../Icon\";\nimport type { IconName } from \"../Icon/icons\";\nimport { Skeleton } from \"../Skeleton\";\nimport \"./style.css\";\n\nexport interface AssetCardProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\" | \"title\"> {\n /** File name or crop label, displayed in full. */\n name: string;\n /** Thumbnail source. Omit to display the fallback icon. */\n src?: string;\n /** Alternative text for the preview; empty when the image is decorative. */\n alt?: string;\n /** Fallback for assets without a thumbnail, such as videos and PDFs. */\n icon?: IconName;\n /** Fill the frame, or show the complete image on an inset preview stage. */\n fit?: \"cover\" | \"contain\";\n /** Dimensions, size, ratio, or other metadata below the name. */\n meta?: ReactNode;\n /** Supporting content below the metadata, such as a source file name. */\n description?: ReactNode;\n /** Paint the selection fill and rail without changing the card's size. */\n isSelected?: boolean;\n /** Show an uploading overlay and disable the thumbnail action. */\n isPending?: boolean;\n /** Makes the thumbnail a selection toggle, independent of overlay and footer controls. */\n onSelect?: () => void;\n /** Badges, buttons, or menus pinned across the top of the thumbnail. */\n actions?: ReactNode;\n /** Actions or content below the card's text. */\n footer?: ReactNode;\n}\n\nfunction Placeholder({ icon, label }: { icon: IconName; label?: string }) {\n return <span className=\"ds-asset-card__placeholder ds-asset-tile__placeholder\"><Icon name={icon} size={24} aria-label={label} /></span>;\n}\n\n/** Remount for each source so failed and loaded states cannot leak to another image. */\nfunction AssetImage({ src, alt }: { src: string; alt: string }) {\n const [status, setStatus] = useState<\"loading\" | \"loaded\" | \"failed\">(\"loading\");\n // The picture's own shape lets a contained preview fill the stage exactly.\n const [ratio, setRatio] = useState<number>();\n const adopt = useCallback((image: HTMLImageElement) => {\n setStatus(\"loaded\");\n if (image.naturalWidth && image.naturalHeight) setRatio(image.naturalWidth / image.naturalHeight);\n }, []);\n // A cached image can finish before onLoad is attached. Only success is read\n // here: an SVG without intrinsic size and a deferred lazy image also report\n // a zero naturalWidth, so failure is left to the error event.\n const imageRef = useCallback((image: HTMLImageElement | null) => {\n if (!image?.complete) return;\n if (image.naturalWidth > 0) adopt(image);\n else image.decode().then(() => adopt(image), () => {});\n }, [adopt]);\n\n if (status === \"failed\") {\n return <Placeholder icon=\"alert-triangle\" label={alt ? `${alt} (preview unavailable)` : \"Preview unavailable\"} />;\n }\n\n return <>\n {status === \"loading\" && <Skeleton shape=\"block\" className=\"ds-asset-card__thumb-skeleton ds-asset-tile__thumb-skeleton\" />}\n <img\n ref={imageRef}\n src={src}\n alt={alt}\n loading=\"lazy\"\n data-loaded={status === \"loaded\" || undefined}\n style={ratio ? ({ \"--asset-ratio\": ratio } as CSSProperties) : undefined}\n onLoad={(event) => adopt(event.currentTarget)}\n onError={() => setStatus(\"failed\")}\n />\n </>;\n}\n\n/** Shared presentation for assets, source files, and crop variants. */\nexport const AssetCard = forwardRef<HTMLDivElement, AssetCardProps>(function AssetCard(\n {\n name,\n src,\n alt = \"\",\n icon = \"image\",\n fit = \"cover\",\n meta,\n description,\n isSelected = false,\n isPending = false,\n onSelect,\n actions,\n footer,\n className,\n ...rest\n },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={[\"ds-asset-card\", \"ds-asset-tile\", className].filter(Boolean).join(\" \")}\n data-fit={fit}\n data-selected={isSelected || undefined}\n data-pending={isPending || undefined}\n {...rest}\n >\n <div className=\"ds-asset-card__thumb ds-asset-tile__thumb\">\n {src ? <AssetImage key={src} src={src} alt={alt} /> : <Placeholder icon={icon} />}\n {isPending && (\n <span className=\"ds-asset-card__pending ds-asset-tile__pending\" role=\"status\">\n <Icon name=\"spinner\" size={20} className=\"ds-asset-card__spinner ds-asset-tile__spinner ds-icon--spin\" />\n <span className=\"ds-asset-card__pending-label ds-asset-tile__pending-label\">Uploading</span>\n </span>\n )}\n {/* Slots render only for truthy content, so `count && …` never leaves a stray 0. */}\n {actions ? <div className=\"ds-asset-card__actions ds-asset-tile__actions\">{actions}</div> : null}\n {onSelect && (\n <Button\n variant=\"simple\"\n className=\"ds-asset-card__hit ds-asset-tile__hit\"\n aria-pressed={isSelected}\n aria-label={name}\n isDisabled={isPending}\n onClick={onSelect}\n />\n )}\n </div>\n <div className=\"ds-asset-card__text ds-asset-tile__text\">\n <span className=\"ds-asset-card__name ds-asset-tile__name\">{name}</span>\n {meta ? <div className=\"ds-asset-card__meta ds-asset-tile__meta\">{meta}</div> : null}\n {description ? <div className=\"ds-asset-card__description\">{description}</div> : null}\n </div>\n {footer ? <div className=\"ds-asset-card__footer\">{footer}</div> : null}\n </div>\n );\n});\n\nexport interface AssetCardSkeletonProps {\n /** Position in the collection, used for the skeleton stagger. */\n index?: number;\n /** Reserve the description line, for cards that pass `description`. */\n description?: boolean;\n /** Reserve a footer row the height of a small Button, for cards that pass `footer`. */\n footer?: boolean;\n}\n\n/** A loading card. Match its slots to the real cards so nothing moves when they arrive. */\nexport function AssetCardSkeleton({ index = 0, description = false, footer = false }: AssetCardSkeletonProps) {\n const delay = { animationDelay: `calc(var(--skeleton-stagger) * ${index})` };\n return (\n <div className=\"ds-asset-card ds-asset-tile\" data-loading=\"true\" aria-hidden=\"true\">\n <Skeleton shape=\"block\" className=\"ds-asset-card__thumb ds-asset-tile__thumb\" style={delay} />\n <div className=\"ds-asset-card__text ds-asset-tile__text\">\n <Skeleton shape=\"text\" width=\"80%\" style={delay} />\n <Skeleton shape=\"text\" width=\"45%\" style={delay} />\n {description && <Skeleton shape=\"text\" width=\"65%\" style={delay} />}\n </div>\n {footer && (\n <div className=\"ds-asset-card__footer\">\n <Skeleton shape=\"block\" width=\"45%\" style={{ ...delay, blockSize: \"var(--field-height-sm)\" }} />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
+
import type { IconName } from "../Icon/icons.cjs";
|
|
3
|
+
export interface AssetCardProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect" | "title"> {
|
|
4
|
+
/** File name or crop label, displayed in full. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Thumbnail source. Omit to display the fallback icon. */
|
|
7
|
+
src?: string;
|
|
8
|
+
/** Alternative text for the preview; empty when the image is decorative. */
|
|
9
|
+
alt?: string;
|
|
10
|
+
/** Fallback for assets without a thumbnail, such as videos and PDFs. */
|
|
11
|
+
icon?: IconName;
|
|
12
|
+
/** Fill the frame, or show the complete image on an inset preview stage. */
|
|
13
|
+
fit?: "cover" | "contain";
|
|
14
|
+
/** Dimensions, size, ratio, or other metadata below the name. */
|
|
15
|
+
meta?: ReactNode;
|
|
16
|
+
/** Supporting content below the metadata, such as a source file name. */
|
|
17
|
+
description?: ReactNode;
|
|
18
|
+
/** Paint the selection fill and rail without changing the card's size. */
|
|
19
|
+
isSelected?: boolean;
|
|
20
|
+
/** Show an uploading overlay and disable the thumbnail action. */
|
|
21
|
+
isPending?: boolean;
|
|
22
|
+
/** Makes the thumbnail a selection toggle, independent of overlay and footer controls. */
|
|
23
|
+
onSelect?: () => void;
|
|
24
|
+
/** Badges, buttons, or menus pinned across the top of the thumbnail. */
|
|
25
|
+
actions?: ReactNode;
|
|
26
|
+
/** Actions or content below the card's text. */
|
|
27
|
+
footer?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/** Shared presentation for assets, source files, and crop variants. */
|
|
30
|
+
export declare const AssetCard: import("react").ForwardRefExoticComponent<AssetCardProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
31
|
+
export interface AssetCardSkeletonProps {
|
|
32
|
+
/** Position in the collection, used for the skeleton stagger. */
|
|
33
|
+
index?: number;
|
|
34
|
+
/** Reserve the description line, for cards that pass `description`. */
|
|
35
|
+
description?: boolean;
|
|
36
|
+
/** Reserve a footer row the height of a small Button, for cards that pass `footer`. */
|
|
37
|
+
footer?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** A loading card. Match its slots to the real cards so nothing moves when they arrive. */
|
|
40
|
+
export declare function AssetCardSkeleton({ index, description, footer }: AssetCardSkeletonProps): import("react").JSX.Element;
|
|
41
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/AssetCard/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAClE,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,iEAAiE;IACjE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gDAAgD;IAChD,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA2CD,uEAAuE;AACvE,eAAO,MAAM,SAAS,2GAyDpB,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,EAAE,KAAS,EAAE,WAAmB,EAAE,MAAc,EAAE,EAAE,sBAAsB,+BAiB3G"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
+
import type { IconName } from "../Icon/icons.js";
|
|
3
|
+
export interface AssetCardProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect" | "title"> {
|
|
4
|
+
/** File name or crop label, displayed in full. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** Thumbnail source. Omit to display the fallback icon. */
|
|
7
|
+
src?: string;
|
|
8
|
+
/** Alternative text for the preview; empty when the image is decorative. */
|
|
9
|
+
alt?: string;
|
|
10
|
+
/** Fallback for assets without a thumbnail, such as videos and PDFs. */
|
|
11
|
+
icon?: IconName;
|
|
12
|
+
/** Fill the frame, or show the complete image on an inset preview stage. */
|
|
13
|
+
fit?: "cover" | "contain";
|
|
14
|
+
/** Dimensions, size, ratio, or other metadata below the name. */
|
|
15
|
+
meta?: ReactNode;
|
|
16
|
+
/** Supporting content below the metadata, such as a source file name. */
|
|
17
|
+
description?: ReactNode;
|
|
18
|
+
/** Paint the selection fill and rail without changing the card's size. */
|
|
19
|
+
isSelected?: boolean;
|
|
20
|
+
/** Show an uploading overlay and disable the thumbnail action. */
|
|
21
|
+
isPending?: boolean;
|
|
22
|
+
/** Makes the thumbnail a selection toggle, independent of overlay and footer controls. */
|
|
23
|
+
onSelect?: () => void;
|
|
24
|
+
/** Badges, buttons, or menus pinned across the top of the thumbnail. */
|
|
25
|
+
actions?: ReactNode;
|
|
26
|
+
/** Actions or content below the card's text. */
|
|
27
|
+
footer?: ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/** Shared presentation for assets, source files, and crop variants. */
|
|
30
|
+
export declare const AssetCard: import("react").ForwardRefExoticComponent<AssetCardProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
31
|
+
export interface AssetCardSkeletonProps {
|
|
32
|
+
/** Position in the collection, used for the skeleton stagger. */
|
|
33
|
+
index?: number;
|
|
34
|
+
/** Reserve the description line, for cards that pass `description`. */
|
|
35
|
+
description?: boolean;
|
|
36
|
+
/** Reserve a footer row the height of a small Button, for cards that pass `footer`. */
|
|
37
|
+
footer?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** A loading card. Match its slots to the real cards so nothing moves when they arrive. */
|
|
40
|
+
export declare function AssetCardSkeleton({ index, description, footer }: AssetCardSkeletonProps): import("react").JSX.Element;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/AssetCard/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,cACf,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IAClE,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,4EAA4E;IAC5E,GAAG,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,iEAAiE;IACjE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,gDAAgD;IAChD,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA2CD,uEAAuE;AACvE,eAAO,MAAM,SAAS,2GAyDpB,CAAC;AAEH,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,uFAAuF;IACvF,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,2FAA2F;AAC3F,wBAAgB,iBAAiB,CAAC,EAAE,KAAS,EAAE,WAAmB,EAAE,MAAc,EAAE,EAAE,sBAAsB,+BAiB3G"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { t as e } from "../../chunks/Icon-CGY1FNXT.js";
|
|
2
|
+
import { Button as t } from "../Button/index.js";
|
|
3
|
+
import { Skeleton as n } from "../Skeleton/index.js";
|
|
4
|
+
import { forwardRef as r, useCallback as i, useState as a } from "react";
|
|
5
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/AssetCard/index.tsx
|
|
7
|
+
function l({ icon: t, label: n }) {
|
|
8
|
+
return /* @__PURE__ */ s("span", {
|
|
9
|
+
className: "ds-asset-card__placeholder ds-asset-tile__placeholder",
|
|
10
|
+
children: /* @__PURE__ */ s(e, {
|
|
11
|
+
name: t,
|
|
12
|
+
size: 24,
|
|
13
|
+
"aria-label": n
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function u({ src: e, alt: t }) {
|
|
18
|
+
let [r, u] = a("loading"), [d, f] = a(), p = i((e) => {
|
|
19
|
+
u("loaded"), e.naturalWidth && e.naturalHeight && f(e.naturalWidth / e.naturalHeight);
|
|
20
|
+
}, []), m = i((e) => {
|
|
21
|
+
e?.complete && (e.naturalWidth > 0 ? p(e) : e.decode().then(() => p(e), () => {}));
|
|
22
|
+
}, [p]);
|
|
23
|
+
return r === "failed" ? /* @__PURE__ */ s(l, {
|
|
24
|
+
icon: "alert-triangle",
|
|
25
|
+
label: t ? `${t} (preview unavailable)` : "Preview unavailable"
|
|
26
|
+
}) : /* @__PURE__ */ c(o, { children: [r === "loading" && /* @__PURE__ */ s(n, {
|
|
27
|
+
shape: "block",
|
|
28
|
+
className: "ds-asset-card__thumb-skeleton ds-asset-tile__thumb-skeleton"
|
|
29
|
+
}), /* @__PURE__ */ s("img", {
|
|
30
|
+
ref: m,
|
|
31
|
+
src: e,
|
|
32
|
+
alt: t,
|
|
33
|
+
loading: "lazy",
|
|
34
|
+
"data-loaded": r === "loaded" || void 0,
|
|
35
|
+
style: d ? { "--asset-ratio": d } : void 0,
|
|
36
|
+
onLoad: (e) => p(e.currentTarget),
|
|
37
|
+
onError: () => u("failed")
|
|
38
|
+
})] });
|
|
39
|
+
}
|
|
40
|
+
var d = r(function({ name: n, src: r, alt: i = "", icon: a = "image", fit: o = "cover", meta: d, description: f, isSelected: p = !1, isPending: m = !1, onSelect: h, actions: g, footer: _, className: v, ...y }, b) {
|
|
41
|
+
return /* @__PURE__ */ c("div", {
|
|
42
|
+
ref: b,
|
|
43
|
+
className: [
|
|
44
|
+
"ds-asset-card",
|
|
45
|
+
"ds-asset-tile",
|
|
46
|
+
v
|
|
47
|
+
].filter(Boolean).join(" "),
|
|
48
|
+
"data-fit": o,
|
|
49
|
+
"data-selected": p || void 0,
|
|
50
|
+
"data-pending": m || void 0,
|
|
51
|
+
...y,
|
|
52
|
+
children: [
|
|
53
|
+
/* @__PURE__ */ c("div", {
|
|
54
|
+
className: "ds-asset-card__thumb ds-asset-tile__thumb",
|
|
55
|
+
children: [
|
|
56
|
+
r ? /* @__PURE__ */ s(u, {
|
|
57
|
+
src: r,
|
|
58
|
+
alt: i
|
|
59
|
+
}, r) : /* @__PURE__ */ s(l, { icon: a }),
|
|
60
|
+
m && /* @__PURE__ */ c("span", {
|
|
61
|
+
className: "ds-asset-card__pending ds-asset-tile__pending",
|
|
62
|
+
role: "status",
|
|
63
|
+
children: [/* @__PURE__ */ s(e, {
|
|
64
|
+
name: "spinner",
|
|
65
|
+
size: 20,
|
|
66
|
+
className: "ds-asset-card__spinner ds-asset-tile__spinner ds-icon--spin"
|
|
67
|
+
}), /* @__PURE__ */ s("span", {
|
|
68
|
+
className: "ds-asset-card__pending-label ds-asset-tile__pending-label",
|
|
69
|
+
children: "Uploading"
|
|
70
|
+
})]
|
|
71
|
+
}),
|
|
72
|
+
g ? /* @__PURE__ */ s("div", {
|
|
73
|
+
className: "ds-asset-card__actions ds-asset-tile__actions",
|
|
74
|
+
children: g
|
|
75
|
+
}) : null,
|
|
76
|
+
h && /* @__PURE__ */ s(t, {
|
|
77
|
+
variant: "simple",
|
|
78
|
+
className: "ds-asset-card__hit ds-asset-tile__hit",
|
|
79
|
+
"aria-pressed": p,
|
|
80
|
+
"aria-label": n,
|
|
81
|
+
isDisabled: m,
|
|
82
|
+
onClick: h
|
|
83
|
+
})
|
|
84
|
+
]
|
|
85
|
+
}),
|
|
86
|
+
/* @__PURE__ */ c("div", {
|
|
87
|
+
className: "ds-asset-card__text ds-asset-tile__text",
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ s("span", {
|
|
90
|
+
className: "ds-asset-card__name ds-asset-tile__name",
|
|
91
|
+
children: n
|
|
92
|
+
}),
|
|
93
|
+
d ? /* @__PURE__ */ s("div", {
|
|
94
|
+
className: "ds-asset-card__meta ds-asset-tile__meta",
|
|
95
|
+
children: d
|
|
96
|
+
}) : null,
|
|
97
|
+
f ? /* @__PURE__ */ s("div", {
|
|
98
|
+
className: "ds-asset-card__description",
|
|
99
|
+
children: f
|
|
100
|
+
}) : null
|
|
101
|
+
]
|
|
102
|
+
}),
|
|
103
|
+
_ ? /* @__PURE__ */ s("div", {
|
|
104
|
+
className: "ds-asset-card__footer",
|
|
105
|
+
children: _
|
|
106
|
+
}) : null
|
|
107
|
+
]
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
function f({ index: e = 0, description: t = !1, footer: r = !1 }) {
|
|
111
|
+
let i = { animationDelay: `calc(var(--skeleton-stagger) * ${e})` };
|
|
112
|
+
return /* @__PURE__ */ c("div", {
|
|
113
|
+
className: "ds-asset-card ds-asset-tile",
|
|
114
|
+
"data-loading": "true",
|
|
115
|
+
"aria-hidden": "true",
|
|
116
|
+
children: [
|
|
117
|
+
/* @__PURE__ */ s(n, {
|
|
118
|
+
shape: "block",
|
|
119
|
+
className: "ds-asset-card__thumb ds-asset-tile__thumb",
|
|
120
|
+
style: i
|
|
121
|
+
}),
|
|
122
|
+
/* @__PURE__ */ c("div", {
|
|
123
|
+
className: "ds-asset-card__text ds-asset-tile__text",
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ s(n, {
|
|
126
|
+
shape: "text",
|
|
127
|
+
width: "80%",
|
|
128
|
+
style: i
|
|
129
|
+
}),
|
|
130
|
+
/* @__PURE__ */ s(n, {
|
|
131
|
+
shape: "text",
|
|
132
|
+
width: "45%",
|
|
133
|
+
style: i
|
|
134
|
+
}),
|
|
135
|
+
t && /* @__PURE__ */ s(n, {
|
|
136
|
+
shape: "text",
|
|
137
|
+
width: "65%",
|
|
138
|
+
style: i
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
}),
|
|
142
|
+
r && /* @__PURE__ */ s("div", {
|
|
143
|
+
className: "ds-asset-card__footer",
|
|
144
|
+
children: /* @__PURE__ */ s(n, {
|
|
145
|
+
shape: "block",
|
|
146
|
+
width: "45%",
|
|
147
|
+
style: {
|
|
148
|
+
...i,
|
|
149
|
+
blockSize: "var(--field-height-sm)"
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
]
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
//#endregion
|
|
157
|
+
export { d as AssetCard, f as AssetCardSkeleton };
|
|
158
|
+
|
|
159
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["_Fragment","Icon","Fragment$1","Placeholder","icon","label","AssetImage","status","setStatus","useState","ratio","setRatio","adopt","useCallback","image","imageRef","alt","Skeleton","event","AssetCard","forwardRef","rest","className","fit","isSelected","isPending","src","actions","onSelect","Button","name","meta","description","footer","AssetCardSkeleton","delay","index"],"sources":["../../../src/components/AssetCard/index.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { Button } from \"../Button\";\nimport { Icon } from \"../Icon\";\nimport type { IconName } from \"../Icon/icons\";\nimport { Skeleton } from \"../Skeleton\";\nimport \"./style.css\";\n\nexport interface AssetCardProps\n extends Omit<HTMLAttributes<HTMLDivElement>, \"onSelect\" | \"title\"> {\n /** File name or crop label, displayed in full. */\n name: string;\n /** Thumbnail source. Omit to display the fallback icon. */\n src?: string;\n /** Alternative text for the preview; empty when the image is decorative. */\n alt?: string;\n /** Fallback for assets without a thumbnail, such as videos and PDFs. */\n icon?: IconName;\n /** Fill the frame, or show the complete image on an inset preview stage. */\n fit?: \"cover\" | \"contain\";\n /** Dimensions, size, ratio, or other metadata below the name. */\n meta?: ReactNode;\n /** Supporting content below the metadata, such as a source file name. */\n description?: ReactNode;\n /** Paint the selection fill and rail without changing the card's size. */\n isSelected?: boolean;\n /** Show an uploading overlay and disable the thumbnail action. */\n isPending?: boolean;\n /** Makes the thumbnail a selection toggle, independent of overlay and footer controls. */\n onSelect?: () => void;\n /** Badges, buttons, or menus pinned across the top of the thumbnail. */\n actions?: ReactNode;\n /** Actions or content below the card's text. */\n footer?: ReactNode;\n}\n\nfunction Placeholder({ icon, label }: { icon: IconName; label?: string }) {\n return <span className=\"ds-asset-card__placeholder ds-asset-tile__placeholder\"><Icon name={icon} size={24} aria-label={label} /></span>;\n}\n\n/** Remount for each source so failed and loaded states cannot leak to another image. */\nfunction AssetImage({ src, alt }: { src: string; alt: string }) {\n const [status, setStatus] = useState<\"loading\" | \"loaded\" | \"failed\">(\"loading\");\n // The picture's own shape lets a contained preview fill the stage exactly.\n const [ratio, setRatio] = useState<number>();\n const adopt = useCallback((image: HTMLImageElement) => {\n setStatus(\"loaded\");\n if (image.naturalWidth && image.naturalHeight) setRatio(image.naturalWidth / image.naturalHeight);\n }, []);\n // A cached image can finish before onLoad is attached. Only success is read\n // here: an SVG without intrinsic size and a deferred lazy image also report\n // a zero naturalWidth, so failure is left to the error event.\n const imageRef = useCallback((image: HTMLImageElement | null) => {\n if (!image?.complete) return;\n if (image.naturalWidth > 0) adopt(image);\n else image.decode().then(() => adopt(image), () => {});\n }, [adopt]);\n\n if (status === \"failed\") {\n return <Placeholder icon=\"alert-triangle\" label={alt ? `${alt} (preview unavailable)` : \"Preview unavailable\"} />;\n }\n\n return <>\n {status === \"loading\" && <Skeleton shape=\"block\" className=\"ds-asset-card__thumb-skeleton ds-asset-tile__thumb-skeleton\" />}\n <img\n ref={imageRef}\n src={src}\n alt={alt}\n loading=\"lazy\"\n data-loaded={status === \"loaded\" || undefined}\n style={ratio ? ({ \"--asset-ratio\": ratio } as CSSProperties) : undefined}\n onLoad={(event) => adopt(event.currentTarget)}\n onError={() => setStatus(\"failed\")}\n />\n </>;\n}\n\n/** Shared presentation for assets, source files, and crop variants. */\nexport const AssetCard = forwardRef<HTMLDivElement, AssetCardProps>(function AssetCard(\n {\n name,\n src,\n alt = \"\",\n icon = \"image\",\n fit = \"cover\",\n meta,\n description,\n isSelected = false,\n isPending = false,\n onSelect,\n actions,\n footer,\n className,\n ...rest\n },\n ref,\n) {\n return (\n <div\n ref={ref}\n className={[\"ds-asset-card\", \"ds-asset-tile\", className].filter(Boolean).join(\" \")}\n data-fit={fit}\n data-selected={isSelected || undefined}\n data-pending={isPending || undefined}\n {...rest}\n >\n <div className=\"ds-asset-card__thumb ds-asset-tile__thumb\">\n {src ? <AssetImage key={src} src={src} alt={alt} /> : <Placeholder icon={icon} />}\n {isPending && (\n <span className=\"ds-asset-card__pending ds-asset-tile__pending\" role=\"status\">\n <Icon name=\"spinner\" size={20} className=\"ds-asset-card__spinner ds-asset-tile__spinner ds-icon--spin\" />\n <span className=\"ds-asset-card__pending-label ds-asset-tile__pending-label\">Uploading</span>\n </span>\n )}\n {/* Slots render only for truthy content, so `count && …` never leaves a stray 0. */}\n {actions ? <div className=\"ds-asset-card__actions ds-asset-tile__actions\">{actions}</div> : null}\n {onSelect && (\n <Button\n variant=\"simple\"\n className=\"ds-asset-card__hit ds-asset-tile__hit\"\n aria-pressed={isSelected}\n aria-label={name}\n isDisabled={isPending}\n onClick={onSelect}\n />\n )}\n </div>\n <div className=\"ds-asset-card__text ds-asset-tile__text\">\n <span className=\"ds-asset-card__name ds-asset-tile__name\">{name}</span>\n {meta ? <div className=\"ds-asset-card__meta ds-asset-tile__meta\">{meta}</div> : null}\n {description ? <div className=\"ds-asset-card__description\">{description}</div> : null}\n </div>\n {footer ? <div className=\"ds-asset-card__footer\">{footer}</div> : null}\n </div>\n );\n});\n\nexport interface AssetCardSkeletonProps {\n /** Position in the collection, used for the skeleton stagger. */\n index?: number;\n /** Reserve the description line, for cards that pass `description`. */\n description?: boolean;\n /** Reserve a footer row the height of a small Button, for cards that pass `footer`. */\n footer?: boolean;\n}\n\n/** A loading card. Match its slots to the real cards so nothing moves when they arrive. */\nexport function AssetCardSkeleton({ index = 0, description = false, footer = false }: AssetCardSkeletonProps) {\n const delay = { animationDelay: `calc(var(--skeleton-stagger) * ${index})` };\n return (\n <div className=\"ds-asset-card ds-asset-tile\" data-loading=\"true\" aria-hidden=\"true\">\n <Skeleton shape=\"block\" className=\"ds-asset-card__thumb ds-asset-tile__thumb\" style={delay} />\n <div className=\"ds-asset-card__text ds-asset-tile__text\">\n <Skeleton shape=\"text\" width=\"80%\" style={delay} />\n <Skeleton shape=\"text\" width=\"45%\" style={delay} />\n {description && <Skeleton shape=\"text\" width=\"65%\" style={delay} />}\n </div>\n {footer && (\n <div className=\"ds-asset-card__footer\">\n <Skeleton shape=\"block\" width=\"45%\" style={{ ...delay, blockSize: \"var(--field-height-sm)\" }} />\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
/* Rules that predate AssetCard also match the AssetTile class hooks, so
|
|
3
|
+
* hand-written tile markup keeps its styling. */
|
|
4
|
+
:is(.ds-asset-card, .ds-asset-tile) {
|
|
5
|
+
position: relative;
|
|
6
|
+
min-inline-size: 0;
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
gap: var(--space-3);
|
|
10
|
+
padding: var(--space-3);
|
|
11
|
+
background: var(--color-surface);
|
|
12
|
+
border: var(--control-border-width) solid var(--control-border-color);
|
|
13
|
+
border-radius: var(--radius-md);
|
|
14
|
+
/* The rail exists on every tile, so selecting one never shifts the grid. */
|
|
15
|
+
box-shadow: inset var(--rail-width) 0 0 0 transparent;
|
|
16
|
+
transition:
|
|
17
|
+
background-color var(--duration-fast) var(--ease-standard),
|
|
18
|
+
box-shadow var(--duration-fast) var(--ease-standard);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Loading placeholders are not interactive, so they never take the hover fill. */
|
|
22
|
+
:is(.ds-asset-card, .ds-asset-tile):hover:not([data-pending], [data-loading]) {
|
|
23
|
+
background: var(--field-hover);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
:is(.ds-asset-card, .ds-asset-tile)[data-selected] {
|
|
27
|
+
background: var(--color-primary-soft);
|
|
28
|
+
box-shadow: inset var(--rail-width) 0 0 0 var(--rail-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
:is(.ds-asset-card, .ds-asset-tile)[data-pending] {
|
|
32
|
+
opacity: 70%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:is(.ds-asset-card__thumb, .ds-asset-tile__thumb) {
|
|
36
|
+
position: relative;
|
|
37
|
+
aspect-ratio: var(--asset-thumb-aspect);
|
|
38
|
+
overflow: hidden;
|
|
39
|
+
border-radius: var(--field-radius);
|
|
40
|
+
background: var(--field-rest);
|
|
41
|
+
display: grid;
|
|
42
|
+
place-content: center;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* A loading card's thumbnail is a block Skeleton; keep the frame's shape
|
|
46
|
+
* rather than the Skeleton's fixed block height. */
|
|
47
|
+
:is(.ds-asset-card, .ds-asset-tile) > :is(.ds-asset-card__thumb, .ds-asset-tile__thumb).ds-skeleton {
|
|
48
|
+
block-size: auto;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Placeholder lines fill the line boxes of the text they stand in for. */
|
|
52
|
+
:is(.ds-asset-card, .ds-asset-tile)[data-loading] :is(.ds-asset-card__text, .ds-asset-tile__text) > .ds-skeleton {
|
|
53
|
+
block-size: calc(var(--font-size-xs) * var(--line-height-body));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
:is(.ds-asset-card, .ds-asset-tile)[data-loading] :is(.ds-asset-card__text, .ds-asset-tile__text) > .ds-skeleton:first-child {
|
|
57
|
+
block-size: calc(var(--font-size-sm) * var(--line-height-body));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Direct children only, so images inside overlay actions keep their own styling. */
|
|
61
|
+
:is(.ds-asset-card__thumb, .ds-asset-tile__thumb) > img {
|
|
62
|
+
position: absolute;
|
|
63
|
+
inset: 0;
|
|
64
|
+
inline-size: 100%;
|
|
65
|
+
block-size: 100%;
|
|
66
|
+
object-fit: cover;
|
|
67
|
+
opacity: 0;
|
|
68
|
+
transition: opacity var(--duration-base) var(--ease-standard);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
:is(.ds-asset-card__thumb, .ds-asset-tile__thumb) > img[data-loaded] {
|
|
72
|
+
opacity: 100%;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
:is(.ds-asset-card__thumb-skeleton, .ds-asset-tile__thumb-skeleton) {
|
|
76
|
+
position: absolute;
|
|
77
|
+
inset: 0;
|
|
78
|
+
block-size: 100%;
|
|
79
|
+
border-radius: 0;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
:is(.ds-asset-card__placeholder, .ds-asset-tile__placeholder) {
|
|
83
|
+
display: grid;
|
|
84
|
+
place-content: center;
|
|
85
|
+
color: var(--color-text-muted);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:is(.ds-asset-card__pending, .ds-asset-tile__pending) {
|
|
89
|
+
position: absolute;
|
|
90
|
+
inset: 0;
|
|
91
|
+
display: flex;
|
|
92
|
+
flex-direction: column;
|
|
93
|
+
align-items: center;
|
|
94
|
+
justify-content: center;
|
|
95
|
+
gap: var(--space-2);
|
|
96
|
+
background: color-mix(in srgb, var(--color-surface) 72%, transparent);
|
|
97
|
+
color: var(--color-text-muted);
|
|
98
|
+
font-size: var(--font-size-xs);
|
|
99
|
+
font-weight: var(--font-weight-bold);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
:is(.ds-asset-card__actions, .ds-asset-tile__actions) {
|
|
103
|
+
position: absolute;
|
|
104
|
+
inset-block-start: var(--space-2);
|
|
105
|
+
inset-inline: var(--space-2);
|
|
106
|
+
z-index: 1;
|
|
107
|
+
display: flex;
|
|
108
|
+
justify-content: space-between;
|
|
109
|
+
gap: var(--space-2);
|
|
110
|
+
flex-wrap: wrap;
|
|
111
|
+
pointer-events: none;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
:is(.ds-asset-card__actions, .ds-asset-tile__actions) > * {
|
|
115
|
+
pointer-events: auto;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* The whole thumbnail is the selection target; the name stays readable text
|
|
119
|
+
* underneath rather than being swallowed by the button. */
|
|
120
|
+
:is(.ds-asset-card, .ds-asset-tile) :is(.ds-asset-card__hit, .ds-asset-tile__hit).ds-button {
|
|
121
|
+
position: absolute;
|
|
122
|
+
inset: 0;
|
|
123
|
+
inline-size: 100%;
|
|
124
|
+
height: 100%;
|
|
125
|
+
padding: 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
:is(.ds-asset-card__hit, .ds-asset-tile__hit).ds-button:focus-visible {
|
|
129
|
+
outline-offset: -2px;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Selection reads on the tile, so Button's hover and pressed fills never
|
|
133
|
+
* paint over the thumbnail. */
|
|
134
|
+
:is(.ds-asset-card, .ds-asset-tile) :is(.ds-asset-card__hit, .ds-asset-tile__hit).ds-button:is(:hover, :active):not(:disabled) {
|
|
135
|
+
background: transparent;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
:is(.ds-asset-card__text, .ds-asset-tile__text) {
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
gap: var(--space-1);
|
|
142
|
+
min-inline-size: 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
:is(.ds-asset-card__name, .ds-asset-tile__name) {
|
|
146
|
+
font-size: var(--font-size-sm);
|
|
147
|
+
font-weight: var(--font-weight-bold);
|
|
148
|
+
line-height: var(--line-height-body);
|
|
149
|
+
overflow-wrap: anywhere;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
:is(.ds-asset-card__meta, .ds-asset-tile__meta) {
|
|
153
|
+
font-family: var(--font-mono);
|
|
154
|
+
font-size: var(--font-size-xs);
|
|
155
|
+
line-height: var(--line-height-body);
|
|
156
|
+
color: var(--color-text-muted);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.ds-asset-card__meta,
|
|
160
|
+
.ds-asset-card__description {
|
|
161
|
+
overflow-wrap: anywhere;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.ds-asset-card__description {
|
|
165
|
+
font-size: var(--font-size-xs);
|
|
166
|
+
line-height: var(--line-height-body);
|
|
167
|
+
color: var(--color-text-muted);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.ds-asset-card__footer {
|
|
171
|
+
margin-block-start: auto;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.ds-asset-card[data-fit="contain"] .ds-asset-card__thumb {
|
|
175
|
+
background: repeating-linear-gradient(135deg, var(--color-canvas) 0 12px, var(--color-surface) 12px 24px);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* The picture takes its own shape (`--asset-ratio`, set once it loads) at the
|
|
179
|
+
* largest size that fits inside the inset stage, scaling small renditions up.
|
|
180
|
+
* Equal logical insets with auto margins centre it in either direction. */
|
|
181
|
+
.ds-asset-card[data-fit="contain"] .ds-asset-card__thumb > img {
|
|
182
|
+
/* Sizing the content box lets the outline wrap the picture without a sliver. */
|
|
183
|
+
box-sizing: content-box;
|
|
184
|
+
inset: var(--space-3);
|
|
185
|
+
margin: auto;
|
|
186
|
+
inline-size: min(
|
|
187
|
+
100% - 2 * (var(--space-3) + var(--control-border-width)),
|
|
188
|
+
(100% / (var(--asset-thumb-aspect)) - 2 * (var(--space-3) + var(--control-border-width)))
|
|
189
|
+
* (var(--asset-ratio, var(--asset-thumb-aspect)))
|
|
190
|
+
);
|
|
191
|
+
block-size: auto;
|
|
192
|
+
aspect-ratio: var(--asset-ratio, var(--asset-thumb-aspect));
|
|
193
|
+
object-fit: contain;
|
|
194
|
+
border: var(--control-border-width) solid var(--color-text);
|
|
195
|
+
box-shadow: var(--shadow-md);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
@media (prefers-reduced-motion: reduce) {
|
|
199
|
+
:is(.ds-asset-card, .ds-asset-tile),
|
|
200
|
+
:is(.ds-asset-card__thumb, .ds-asset-tile__thumb) > img {
|
|
201
|
+
transition: none;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/Icon-CWsA1W83.cjs"),t=require("../
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../chunks/Icon-CWsA1W83.cjs"),t=require("../Grid/index.cjs"),n=require("../AssetCard/index.cjs");let r=require("react"),i=require("react/jsx-runtime");function a(...e){return e.filter(Boolean).join(` `)}var o=(0,r.forwardRef)(function({isLoading:e=!1,loadingCount:r=8,loadingCard:o,className:s,children:c,...l},u){return(0,i.jsx)(t.Grid,{ref:u,columns:`auto`,gap:`md`,minColumnWidth:`var(--asset-tile-min-width)`,className:a(`ds-asset-grid`,s),"aria-busy":e||void 0,...l,children:e?Array.from({length:r},(e,t)=>(0,i.jsx)(n.AssetCardSkeleton,{...o,index:t},t)):c})});function s({title:t,description:n,action:r}){return(0,i.jsxs)(`div`,{className:`ds-asset-empty`,children:[(0,i.jsx)(e.t,{name:`image`,size:24}),(0,i.jsx)(`span`,{className:`ds-asset-empty__title`,children:t}),n&&(0,i.jsx)(`span`,{className:`ds-asset-empty__description`,children:n}),r]})}exports.AssetGrid=o,exports.AssetGridEmpty=s,exports.AssetTile=n.AssetCard,exports.AssetTileSkeleton=n.AssetCardSkeleton;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["forwardRef","Grid","
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["forwardRef","Grid","AssetCardSkeleton","Icon","require_Icon","require_components_Grid_index","require_components_AssetCard_index","react","react_jsx_runtime","cx","parts","AssetGrid","rest","className","isLoading","loadingCount","loadingCard","i","children","AssetGridEmpty","title","description","action"],"sources":["../../../src/components/AssetGrid/index.tsx"],"sourcesContent":["import {\n forwardRef,\n type HTMLAttributes,\n type ReactNode,\n} from \"react\";\nimport { Grid } from \"../Grid\";\nimport { Icon } from \"../Icon\";\nimport { AssetCardSkeleton, type AssetCardSkeletonProps } from \"../AssetCard\";\nimport \"./style.css\";\n\nfunction cx(...parts: (string | undefined | false)[]) {\n return parts.filter(Boolean).join(\" \");\n}\n\nexport interface AssetGridProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Renders placeholder tiles instead of children. The grid keeps its\n * geometry, so nothing moves when the real assets arrive.\n */\n isLoading?: boolean;\n /** How many placeholder tiles to show while loading. */\n loadingCount?: number;\n /** Slots each placeholder reserves; match the cards that replace them. */\n loadingCard?: Omit<AssetCardSkeletonProps, \"index\">;\n children?: ReactNode;\n}\n\n/**\n * The media library surface: an auto-filling grid of asset tiles. Sits inside\n * a `TableFrame` when it is the page's collection, bare inside a drawer.\n */\nexport const AssetGrid = forwardRef<HTMLDivElement, AssetGridProps>(function AssetGrid(\n { isLoading = false, loadingCount = 8, loadingCard, className, children, ...rest },\n ref,\n) {\n return (\n <Grid\n ref={ref}\n columns=\"auto\"\n gap=\"md\"\n minColumnWidth=\"var(--asset-tile-min-width)\"\n className={cx(\"ds-asset-grid\", className)}\n aria-busy={isLoading || undefined}\n {...rest}\n >\n {isLoading\n ? Array.from({ length: loadingCount }, (_, i) => <AssetCardSkeleton key={i} {...loadingCard} index={i} />)\n : children}\n </Grid>\n );\n});\n\n// Existing entry points remain aliases to the shared card implementation.\nexport { AssetCard as AssetTile, AssetCardSkeleton as AssetTileSkeleton } from \"../AssetCard\";\nexport type { AssetCardProps as AssetTileProps, AssetCardSkeletonProps as AssetTileSkeletonProps } from \"../AssetCard\";\n\nexport interface AssetGridEmptyProps {\n title: string;\n description?: ReactNode;\n action?: ReactNode;\n}\n\n/** Nothing in the library yet — one action, the one that fills it. */\nexport function AssetGridEmpty({ title, description, action }: AssetGridEmptyProps) {\n return (\n <div className=\"ds-asset-empty\">\n <Icon name=\"image\" size={24} />\n <span className=\"ds-asset-empty__title\">{title}</span>\n {description && <span className=\"ds-asset-empty__description\">{description}</span>}\n {action}\n </div>\n );\n}\n"],"mappings":"A,8OAUA,SAASS,EAAG,GAAGC,EAAuC,CACpD,OAAOA,EAAM,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,CACvC,CAmBA,IAAaC,GAAA,EAAYX,EAAAA,WAAAA,CAA2C,SAClE,CAAE,YAAY,GAAO,eAAe,EAAG,cAAa,YAAW,WAAU,GAAGY,GAC5E,EACA,CACA,OACE,EAAAJ,EAAA,IAAA,CAACP,EAAAA,KAAD,CACO,MACL,QAAQ,OACR,IAAI,KACJ,eAAe,8BACf,UAAWQ,EAAG,gBAAiBI,CAAS,EACxC,YAAWC,GAAa,IAAA,GACxB,GAAIF,EAEH,SAAAE,EACG,MAAM,KAAK,CAAE,OAAQC,CAAa,GAAI,EAAG,KAAM,EAAAP,EAAA,IAAA,CAACN,EAAAA,kBAAD,CAA2B,GAAIc,EAAa,MAAOC,CAAI,EAA/BA,CAA+B,CAAC,EACvGC,CACA,CAAA,CAEV,CAAC,EAaD,SAAgBC,EAAe,CAAE,QAAO,cAAa,UAA+B,CAClF,OACE,EAAAX,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,iBAAf,SAAA,EACE,EAAAA,EAAA,IAAA,CAACL,EAAAA,EAAD,CAAM,KAAK,QAAQ,KAAM,EAAK,CAAA,GAC9B,EAAAK,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,wBAAyB,SAAAY,CAAY,CAAA,EACpDC,IAAe,EAAAb,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,8BAA+B,SAAAa,CAAkB,CAAA,EAChFC,CACE,C,EAET,C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type HTMLAttributes, type ReactNode } from "react";
|
|
2
|
-
import type
|
|
2
|
+
import { type AssetCardSkeletonProps } from "../AssetCard/index.cjs";
|
|
3
3
|
export interface AssetGridProps extends HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
/**
|
|
5
5
|
* Renders placeholder tiles instead of children. The grid keeps its
|
|
@@ -8,6 +8,8 @@ export interface AssetGridProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
8
8
|
isLoading?: boolean;
|
|
9
9
|
/** How many placeholder tiles to show while loading. */
|
|
10
10
|
loadingCount?: number;
|
|
11
|
+
/** Slots each placeholder reserves; match the cards that replace them. */
|
|
12
|
+
loadingCard?: Omit<AssetCardSkeletonProps, "index">;
|
|
11
13
|
children?: ReactNode;
|
|
12
14
|
}
|
|
13
15
|
/**
|
|
@@ -15,35 +17,8 @@ export interface AssetGridProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
15
17
|
* a `TableFrame` when it is the page's collection, bare inside a drawer.
|
|
16
18
|
*/
|
|
17
19
|
export declare const AssetGrid: import("react").ForwardRefExoticComponent<AssetGridProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
index?: number;
|
|
21
|
-
}
|
|
22
|
-
/** One loading tile: thumbnail block, name line, meta line. */
|
|
23
|
-
export declare function AssetTileSkeleton({ index }: AssetTileSkeletonProps): import("react").JSX.Element;
|
|
24
|
-
export interface AssetTileProps extends Omit<HTMLAttributes<HTMLDivElement>, "onSelect" | "title"> {
|
|
25
|
-
/** File name, shown in full — asset names are how people find things again. */
|
|
26
|
-
name: string;
|
|
27
|
-
/** Thumbnail source. Omit for a non-image asset and pass an `icon` instead. */
|
|
28
|
-
src?: string;
|
|
29
|
-
/** Glyph shown when there is no thumbnail, or while one fails to load. */
|
|
30
|
-
icon?: IconName;
|
|
31
|
-
/** Second line: dimensions, size, date — whatever the library sorts by. */
|
|
32
|
-
meta?: ReactNode;
|
|
33
|
-
/** Paints the soft fill and the solid rail. Never changes the tile's size. */
|
|
34
|
-
isSelected?: boolean;
|
|
35
|
-
/** The asset is still uploading or processing: dimmed, with a spinner. */
|
|
36
|
-
isPending?: boolean;
|
|
37
|
-
/** Makes the whole tile a selection target. */
|
|
38
|
-
onSelect?: () => void;
|
|
39
|
-
/** Badges or a menu, pinned to the top of the thumbnail. */
|
|
40
|
-
actions?: ReactNode;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* One asset in the library. Selection paints a fill and a rail exactly like a
|
|
44
|
-
* table row, so a grid and a list read as the same collection in two shapes.
|
|
45
|
-
*/
|
|
46
|
-
export declare const AssetTile: import("react").ForwardRefExoticComponent<AssetTileProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
20
|
+
export { AssetCard as AssetTile, AssetCardSkeleton as AssetTileSkeleton } from "../AssetCard/index.cjs";
|
|
21
|
+
export type { AssetCardProps as AssetTileProps, AssetCardSkeletonProps as AssetTileSkeletonProps } from "../AssetCard/index.cjs";
|
|
47
22
|
export interface AssetGridEmptyProps {
|
|
48
23
|
title: string;
|
|
49
24
|
description?: ReactNode;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/AssetGrid/index.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../../../src/components/AssetGrid/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAGf,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,aAAa,CAAC;AAMrB,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,cAAc,CAAC;IACpE;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;IACpD,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,2GAmBpB,CAAC;AAGH,OAAO,EAAE,SAAS,IAAI,SAAS,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC9F,YAAY,EAAE,cAAc,IAAI,cAAc,EAAE,sBAAsB,IAAI,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAEvH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,mBAAmB,+BASjF"}
|