diff --git a/packages/keystatic/src/app/CollectionPage.tsx b/packages/keystatic/src/app/CollectionPage.tsx
index 2d086dd03..8cfbbe0a8 100644
--- a/packages/keystatic/src/app/CollectionPage.tsx
+++ b/packages/keystatic/src/app/CollectionPage.tsx
@@ -565,17 +565,42 @@ function CollectionTable(
...(hideStatusColumn ? [] : [statusCell]),
nameCell,
...collection.columns.map(column => {
- let val;
- val = item.data?.[column];
+ const raw = item.data?.[column];
+ const field = collection.schema[column];
+ const FieldCell =
+ field &&
+ 'kind' in field &&
+ field.kind === 'form' &&
+ 'Cell' in field &&
+ field.Cell;
+
+ if (raw == null) {
+ return (
+ |
+ {undefined}
+ |
+ );
+ }
- if (val == null) {
- val = undefined;
- } else {
- val = val + '';
+ const strVal = raw + '';
+
+ if (FieldCell) {
+ return (
+
+
+ |
+ );
}
+
return (
-
- {val}
+ |
+ {strVal}
|
);
}),
@@ -597,6 +622,7 @@ function CollectionTable(
);
}
+
function getItemPath(
basePath: string,
collection: string,
diff --git a/packages/keystatic/src/form/api.tsx b/packages/keystatic/src/form/api.tsx
index 4b87714cf..cfa876f03 100644
--- a/packages/keystatic/src/form/api.tsx
+++ b/packages/keystatic/src/form/api.tsx
@@ -1,4 +1,4 @@
-import { ReactElement, ReactNode } from 'react';
+import { ReactElement, ReactNode, ComponentType } from 'react';
import { Glob } from '../config';
import { ChildField } from './fields/child';
@@ -48,6 +48,7 @@ export type BasicFormField<
parse(value: FormFieldStoredValue): ReaderValue;
};
label?: string;
+ Cell?: ComponentType<{ value: any }>;
};
export type SlugFormField<
@@ -85,6 +86,7 @@ export type SlugFormField<
): ReaderValueAsSlugField;
};
label?: string;
+ Cell?: ComponentType<{ value: any }>;
};
export type AssetFormField<
@@ -127,6 +129,7 @@ export type AssetFormField<
parse(value: FormFieldStoredValue): ReaderValue;
};
label?: string;
+ Cell?: ComponentType<{ value: any }>;
};
export type AssetsFormField<
diff --git a/packages/keystatic/src/form/fields/empty-field-ui.tsx b/packages/keystatic/src/form/fields/empty-field-ui.tsx
index 0289efad7..7b9caf710 100644
--- a/packages/keystatic/src/form/fields/empty-field-ui.tsx
+++ b/packages/keystatic/src/form/fields/empty-field-ui.tsx
@@ -19,6 +19,7 @@ export let SlugFieldInput = empty,
IntegerFieldInput = empty,
NumberFieldInput = empty,
ImageFieldInput = empty,
+ ImageCell = empty,
FileFieldInput = empty,
DatetimeFieldInput = empty,
DateFieldInput = empty,
diff --git a/packages/keystatic/src/form/fields/image/index.tsx b/packages/keystatic/src/form/fields/image/index.tsx
index 759e534f2..2c8bb43dc 100644
--- a/packages/keystatic/src/form/fields/image/index.tsx
+++ b/packages/keystatic/src/form/fields/image/index.tsx
@@ -3,7 +3,7 @@ import { AssetFormField } from '../../api';
import { FieldDataError } from '../error';
import { RequiredValidation, assertRequired } from '../utils';
import { getSrcPrefix } from './getSrcPrefix';
-import { ImageFieldInput } from '#field-ui/image';
+import { ImageFieldInput, ImageCell } from '#field-ui/image';
export function image({
label,
@@ -34,6 +34,7 @@ export function image({
kind: 'form',
formKind: 'asset',
label,
+ Cell: ImageCell,
Input(props) {
return (
);
}
+
+export function ImageCell({ value }: { value: string | null }) {
+ const [errored, setErrored] = useState(false);
+ if (!value) return null;
+ if (errored) {
+ return (
+
+ {value}
+
+ );
+ }
+ return (
+ setErrored(true)}
+ className={css({
+ width: tokenSchema.size.scale[400],
+ height: tokenSchema.size.scale[400],
+ objectFit: 'cover',
+ borderRadius: tokenSchema.size.radius.small,
+ flexShrink: 0,
+ })}
+ />
+ );
+}
|