TinyBase logoTinyBase

SliceInHtmlTable

The SliceInHtmlTable component renders the contents of a Slice as an HTML

<table> element, and registers a listener so that any changes to that result will cause a re-render.
SliceInHtmlTable(props: SliceInHtmlTableProps & HtmlTableProps): ComponentReturnType
TypeDescription
propsSliceInHtmlTableProps & HtmlTableProps

The props for this component.

returnsComponentReturnType

A rendering of the Slice in a <table> element.

See the <SliceInHtmlTable /> demo for this component in action.

The component's props identify which Slice to render based on Index Id, Slice Id, and Indexes object (which is either the default context Indexes object, a named context Indexes object, or an explicit reference).

This component renders a Slice by iterating over its Row objects. By default the Cells are in turn rendered with the CellView component, but you can override this behavior by providing a component for each Cell in the customCells prop. You can pass additional props to that custom component with the getComponentProps callback. See the CustomCell type for more details.

This component uses the useSliceRowIds hook under the covers, which means that any changes to the structure of the Slice will cause a re-render.

You can use the headerRow and idColumn props to control whether labels and Ids appear in a <th> element at the top of the table, and the start of each row.

Examples

This example creates a Provider context into which a default Indexes object is provided. The SliceInHtmlTable component within it then renders the Slice in a <table> element with a CSS class.

const App = ({indexes}) => (
  <Provider indexes={indexes}>
    <Pane />
  </Provider>
);
const Pane = () => (
  <SliceInHtmlTable indexId="bySpecies" sliceId="dog" className="slice" />
);

const store = createStore().setTable('pets', {
  fido: {species: 'dog'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});
const indexes = createIndexes(store);
indexes.setIndexDefinition('bySpecies', 'pets', 'species');

const app = document.createElement('div');
ReactDOMClient.createRoot(app).render(<App indexes={indexes} />);
console.log(app.innerHTML);
// ->
`
<table class=\"slice\">
  <thead>
    <tr>
      <th>Id</th>
      <th>species</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>fido</th>
      <td>dog</td>
    </tr>
    <tr>
      <th>cujo</th>
      <td>dog</td>
    </tr>
  </tbody>
</table>
`;

This example creates a Provider context into which a default Indexes object is provided. The SliceInHtmlTable component within it then renders the Slice with a custom component and a custom props callback for the species Cell. The header row at the top of the table and the Id column at the start of each row is removed.

const App = ({indexes}) => (
  <Provider indexes={indexes}>
    <Pane />
  </Provider>
);
const Pane = () => (
  <SliceInHtmlTable
    indexId="bySpecies"
    sliceId="dog"
    customCells={customCells}
    headerRow={false}
    idColumn={false}
  />
);

const FormattedCellView = ({tableId, rowId, cellId, bold}) => (
  <>
    {bold ? <b>{rowId}</b> : rowId}:
    <CellView tableId={tableId} rowId={rowId} cellId={cellId} />
  </>
);
const customCells = {
  species: {
    component: FormattedCellView,
    getComponentProps: (rowId, cellId) => ({bold: rowId == 'fido'}),
  },
};

const store = createStore().setTable('pets', {
  fido: {species: 'dog', color: 'brown'},
  felix: {species: 'cat'},
  cujo: {species: 'dog'},
});
const indexes = createIndexes(store);
indexes.setIndexDefinition('bySpecies', 'pets', 'species');

const app = document.createElement('div');
ReactDOMClient.createRoot(app).render(<App indexes={indexes} />);
console.log(app.innerHTML);
// ->
`
<table>
  <tbody>
    <tr>
      <td><b>fido</b>:</td>
    </tr>
    <tr>
      <td>cujo:</td>
    </tr>
  </tbody>
</table>
`;

Since

v4.1.0