Table renderer
You can define how custom field values are displayed in the content table.
To enable custom table-cell rendering in your app, add FieldExtensionFeature.TableRenderer
to the features
array in the extension declaration.
import {FieldExtensionType,FieldExtensionFeature,} from '@graphcms/uix-react-sdk';const declaration = {extensionType: 'field',fieldType: FieldExtensionType.JSON,name: 'Custom JSON',features: [FieldExtensionFeature.FieldRenderer,FieldExtensionFeature.TableRenderer,],};
UI extensions declaration must be re-loaded every time the declaration changes.
The SDK provides a isTableCell
boolean that you can use to detect that the current extension instance is rendered in the content table:
How you handle table-cell rendering is up to you. Hygraph will only enforce a cell height of 60px in order to preserve other fields' functionality in the table layout.
Let's emulate a simple string field preview that conditionally displays the value in a paragraph:
#Multiple values
What happens if your extension supports lists? By combining the two features, FieldExtensionFeature.TableRenderer
and FieldExtensionFeature.ListRenderer
, you can determine how multiple-value fields should behave in content table.
Let us augment the previous example to account for list values:
import {Wrapper,useFieldExtension,FieldExtensionType,FieldExtensionFeature,} from '@graphcms/uix-react-sdk';const declaration = {extensionType: 'field',fieldType: FieldExtensionType.STRING,name: 'Custom string',features: [FieldExtensionFeature.FieldRenderer,FieldExtensionFeature.TableRenderer,FieldExtensionFeature.ListRenderer,],};const CustomStringInput = () => {const {value,onChange,isTableCell,field: { isList },} = useFieldExtension();if (isTableCell) {if (isList) {return (<div>{value.map((item) => (<p>{item}</p>))}</div>);}return <p>{value}</p>;}if (isList) {return (<inputvalue={value}onChange={({ target: { value: val } }) => onChange([...value, val])}/>);}return (<inputvalue={value}onChange={({ target: { value: val } }) => onChange(val)}/>);};const Extension = () => {return (<Wrapper declaration={declaration}><CustomStringInput /></Wrapper>);};
#Preview expansion
The example above would work for simple cases, but you'll likely need more space than a table cell allows.
For those cases, the SDK provides you with tools to display the content of a custom field in full-screen mode.
Extract the expand
handler that takes a boolean as an argument and isExpanded
prop by calling the useFieldExtension
hook:
const { isTableCell, expand, isExpanded } = useFieldExtension();
Instead of displaying the value directly in the table cell, you can now render a button that would expand the preview. A basic example would be something like this:
if (isTableCell) {if (isExpanded) {return (<div><p>{value}</p><button onClick={() => expand(false)}>Close</button><div>);} else {return (<button onClick={() => expand(true)}>Preview</button>);}}