ui: document table cell wrapper requirement
Added TSDoc comments to ColumnConfig.cell, RowRenderFn, CellProps, CellTextProps, and CellProfileProps making it explicit that cell render functions must return a cell component (Cell, CellText, or CellProfile) as the top-level element. Also added a Table Cell Requirement section to the package README with correct and incorrect usage examples. Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com> Made-with: Cursor
This commit is contained in:
@@ -17,6 +17,34 @@ yarn add @backstage/ui
|
||||
- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md)
|
||||
- [Backstage Documentation](https://backstage.io/docs)
|
||||
|
||||
## Table Cell Requirement
|
||||
|
||||
When using the `Table` component, every cell rendered via `ColumnConfig.cell` (or
|
||||
inside a custom `RowRenderFn`) **must** return a cell component as the top-level
|
||||
element. The available cell components are:
|
||||
|
||||
- **`CellText`** — displays a title with optional description and icon.
|
||||
- **`CellProfile`** — displays an avatar with a name and optional description.
|
||||
- **`Cell`** — a generic wrapper for fully custom cell content.
|
||||
|
||||
Returning bare text, React fragments, or other elements without wrapping them in
|
||||
one of these cell components will break the table layout.
|
||||
|
||||
```tsx
|
||||
// ✅ Correct — CellText is the top-level element
|
||||
cell: item => <CellText title={item.name} />;
|
||||
|
||||
// ✅ Correct — Cell wraps custom content
|
||||
cell: item => (
|
||||
<Cell>
|
||||
<MyCustomContent value={item.name} />
|
||||
</Cell>
|
||||
);
|
||||
|
||||
// ❌ Wrong — bare text without a cell wrapper
|
||||
cell: item => <span>{item.name}</span>;
|
||||
```
|
||||
|
||||
## Writing Changesets for Components
|
||||
|
||||
When creating changesets for component-specific changes, add component metadata to help maintain documentation:
|
||||
|
||||
@@ -766,7 +766,7 @@ export const Cell: {
|
||||
displayName: string;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CellOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
@@ -774,7 +774,7 @@ export type CellOwnProps = {
|
||||
// @public (undocumented)
|
||||
export const CellProfile: (props: CellProfileProps) => JSX_2.Element;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CellProfileOwnProps = {
|
||||
src?: string;
|
||||
name?: string;
|
||||
@@ -784,12 +784,12 @@ export type CellProfileOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface CellProfileProps
|
||||
extends CellProfileOwnProps,
|
||||
Omit<CellProps_2, keyof CellProfileOwnProps> {}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface CellProps
|
||||
extends CellOwnProps,
|
||||
Omit<CellProps_2, keyof CellOwnProps> {}
|
||||
@@ -800,7 +800,7 @@ export const CellText: {
|
||||
displayName: string;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type CellTextOwnProps = {
|
||||
title: string;
|
||||
description?: string;
|
||||
@@ -810,7 +810,7 @@ export type CellTextOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface CellTextProps
|
||||
extends CellTextOwnProps,
|
||||
Omit<CellProps_2, keyof CellTextOwnProps> {}
|
||||
@@ -849,9 +849,8 @@ export interface CheckboxProps
|
||||
// @public (undocumented)
|
||||
export const Column: (props: ColumnProps) => JSX_2.Element;
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export interface ColumnConfig<T extends TableItem> {
|
||||
// (undocumented)
|
||||
cell: (item: T) => ReactElement;
|
||||
// (undocumented)
|
||||
defaultWidth?: ColumnSize | null;
|
||||
@@ -2068,7 +2067,7 @@ export interface RowProps<T>
|
||||
extends RowOwnProps<T>,
|
||||
Omit<RowProps_2<T>, keyof RowOwnProps> {}
|
||||
|
||||
// @public (undocumented)
|
||||
// @public
|
||||
export type RowRenderFn<T extends TableItem> = (params: {
|
||||
item: T;
|
||||
index: number;
|
||||
|
||||
@@ -93,17 +93,35 @@ export interface ColumnProps
|
||||
extends ColumnOwnProps,
|
||||
Omit<ReactAriaColumnProps, keyof ColumnOwnProps> {}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Own props for the {@link Cell} component.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CellOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Props for the {@link Cell} component.
|
||||
*
|
||||
* `Cell` is a generic cell wrapper for custom cell content. When rendering
|
||||
* cells via {@link ColumnConfig.cell} or a custom {@link RowRenderFn}, the
|
||||
* returned element **must** be a cell component (`Cell`, `CellText`, or
|
||||
* `CellProfile`) at the top level. Returning bare text or other elements
|
||||
* without a cell wrapper will break the table layout.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CellProps
|
||||
extends CellOwnProps,
|
||||
Omit<ReactAriaCellProps, keyof CellOwnProps> {}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Own props for the {@link CellText} component.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CellTextOwnProps = {
|
||||
title: string;
|
||||
description?: string;
|
||||
@@ -113,12 +131,25 @@ export type CellTextOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Props for the {@link CellText} component.
|
||||
*
|
||||
* `CellText` renders a table cell with a title and optional description. It
|
||||
* is one of the cell components (`Cell`, `CellText`, `CellProfile`) that
|
||||
* **must** be used as the top-level element returned from
|
||||
* {@link ColumnConfig.cell} or a custom {@link RowRenderFn}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CellTextProps
|
||||
extends CellTextOwnProps,
|
||||
Omit<ReactAriaCellProps, keyof CellTextOwnProps> {}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Own props for the {@link CellProfile} component.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type CellProfileOwnProps = {
|
||||
src?: string;
|
||||
name?: string;
|
||||
@@ -128,7 +159,16 @@ export type CellProfileOwnProps = {
|
||||
className?: string;
|
||||
};
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Props for the {@link CellProfile} component.
|
||||
*
|
||||
* `CellProfile` renders a table cell with an avatar, name, and optional
|
||||
* description. It is one of the cell components (`Cell`, `CellText`,
|
||||
* `CellProfile`) that **must** be used as the top-level element returned
|
||||
* from {@link ColumnConfig.cell} or a custom {@link RowRenderFn}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface CellProfileProps
|
||||
extends CellProfileOwnProps,
|
||||
Omit<ReactAriaCellProps, keyof CellProfileOwnProps> {}
|
||||
@@ -151,10 +191,27 @@ export interface PagePagination extends TablePaginationProps {
|
||||
/** @public */
|
||||
export type TablePaginationType = NoPagination | PagePagination;
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Configuration for a single table column.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface ColumnConfig<T extends TableItem> {
|
||||
id: string;
|
||||
label: string;
|
||||
/**
|
||||
* Renders the cell content for this column.
|
||||
*
|
||||
* **Important:** The returned element **must** be a cell component at the
|
||||
* top level — either `Cell`, `CellText`, or `CellProfile`. Returning bare
|
||||
* text, fragments, or other elements without a cell wrapper will break the
|
||||
* table layout.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* cell: item => <CellText title={item.name} />
|
||||
* ```
|
||||
*/
|
||||
cell: (item: T) => ReactElement;
|
||||
header?: () => ReactElement;
|
||||
isSortable?: boolean;
|
||||
@@ -173,7 +230,16 @@ export interface RowConfig<T extends TableItem> {
|
||||
getIsDisabled?: (item: T) => boolean;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
/**
|
||||
* Custom render function for table rows.
|
||||
*
|
||||
* When using a custom row render function, each cell rendered inside the row
|
||||
* **must** use a cell component (`Cell`, `CellText`, or `CellProfile`) as
|
||||
* the top-level element. Returning bare text or other elements without a
|
||||
* cell wrapper will break the table layout.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type RowRenderFn<T extends TableItem> = (params: {
|
||||
item: T;
|
||||
index: number;
|
||||
|
||||
Reference in New Issue
Block a user