/**
* The ui-react-inspector module of the TinyBase project provides a component to
* help debug the state of your TinyBase stores and other objects.
*
* The component in this module uses the react-dom module and so is not
* appropriate for environments like React Native.
* @see demo
* @packageDocumentation
* @module ui-react-inspector
* @since v5.0.0
*/
import type {
CellIdFromSchema,
TableIdFromSchema,
} from '../../_internal/store/with-schemas/index.d.ts';
import type {
CellProps,
CellPropsForTableIdAndCellId,
ComponentReturnType,
ExtraProps,
IndexesOrIndexesId,
QueriesOrQueriesId,
RelationshipsOrRelationshipsId,
ResultCellProps,
StoreOrStoreId,
ValueProps,
} from '../../_internal/ui-react/with-schemas/index.d.ts';
import type {Id, Ids} from '../../common/with-schemas/index.d.ts';
import type {ComponentType} from 'react';
import type {NoSchemas} from '../../store/index.d.ts';
import type {OptionalSchemas} from '../../store/with-schemas/index.d.ts';
/**
* The CustomCell object is used to configure custom cell rendering in an HTML
* table.
* @category Configuration
* @since v4.1.0
*/
export type CustomCell<
Schemas extends OptionalSchemas,
TableId extends TableIdFromSchema,
CellId extends CellIdFromSchema,
> = {
/**
* An optional string that will be used as the label at the top of the table
* column for this Cell.
* @category Prop
* @since v4.1.0
*/
label?: string;
/**
* An optional custom component for rendering each Cell in the Table (to
* override the default CellView component).
* @category Prop
* @since v4.1.0
*/
component?: ComponentType<
CellPropsForTableIdAndCellId
>;
/**
* An optional function for generating extra props for each custom Cell
* component based on Row and Cell Id.
* @category Prop
* @since v4.1.0
*/
getComponentProps?: (rowId: Id, cellId: CellId) => ExtraProps;
};
/**
* The CustomResultCell object is used to configure custom cell rendering for
* query results in an HTML table.
* @category Configuration
* @since v4.1.0
*/
export type CustomResultCell = {
/**
* An optional string that will be used as the label at the top of the table
* column for this Cell.
* @category Prop
* @since v4.1.0
*/
label?: string;
/**
* An optional custom component for rendering each Cell in the ResultTable (to
* override the default ResultCellView component).
* @category Prop
* @since v4.1.0
*/
component?: ComponentType>;
/**
* An optional function for generating extra props for each custom Cell
* component based on Row and Cell Id.
* @category Prop
* @since v4.1.0
*/
getComponentProps?: (rowId: Id, cellId: Id) => ExtraProps;
};
/**
* HtmlTableProps props are used for components that will render in an HTML
* table, such as the TableInHtmlTable component or SortedTableInHtmlTable
* component.
* @category Props
* @since v4.1.0
*/
export type HtmlTableProps = {
/**
* A string className to use on the root of the resulting element.
* @category Prop
* @since v4.1.0
*/
readonly className?: string;
/**
* Whether a header row should be rendered at the top of the table, defaulting
* to `true`.
* @category Prop
* @since v4.1.0
*/
readonly headerRow?: boolean;
/**
* Whether an Id column should be rendered on the left of the table,
* defaulting to `true`.
* @category Prop
* @since v4.1.0
*/
readonly idColumn?: boolean;
};
/**
* TableInHtmlTableProps props are used for components that will render a Table
* in an HTML table, such as the TableInHtmlTable component.
* @category Props
* @since v4.1.0
*/
export type TableInHtmlTableProps<
Schemas extends OptionalSchemas,
TableIds extends TableIdFromSchema = TableIdFromSchema<
Schemas[0]
>,
> = TableIds extends infer TableId
? TableId extends TableIdFromSchema
? {
/**
* The Id of the Table in the Store to be rendered.
* @category Prop
* @since v4.1.0
*/
readonly tableId: TableId;
/**
* The Store to be accessed: omit for the default context Store, provide an Id
* for a named context Store, or provide an explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly store?: StoreOrStoreId;
/**
* Whether the Cells should be editable. This affects the default CellView
* component (to use the EditableCellView component instead) but of course
* will not affect custom Cell components if you have set them.
* @category Prop
* @since v4.1.0
*/
readonly editable?: boolean;
/**
* An optional list of Cell Ids to use for rendering a prescribed set of the
* Table's Cells in a given order. This can also be an object with the desired
* Cell Ids as keys, and with a value that can either be a string label to
* show in the column header, or a CustomCell object to further configure the
* column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| CellIdFromSchema[]
| {
[CellId in CellIdFromSchema]?:
| string
| CustomCell;
};
}
: never
: never;
/**
* SortedTableInHtmlTableProps props are used for components that will render a
* sorted Table in an HTML table, such as the SortedTableInHtmlTable component.
* @category Props
* @since v4.1.0
*/
export type SortedTableInHtmlTableProps<
Schemas extends OptionalSchemas,
TableIds extends TableIdFromSchema = TableIdFromSchema<
Schemas[0]
>,
> = TableIds extends infer TableId
? TableId extends TableIdFromSchema
? {
/**
* The Id of the Table in the Store to be rendered.
* @category Prop
* @since v4.1.0
*/
readonly tableId: TableId;
/**
* The Id of the Cell whose values are used for the sorting. If omitted, the
* view will sort the Row Id itself.
* @category Prop
* @since v4.1.0
*/
readonly cellId?: CellIdFromSchema;
/**
* Whether the sorting should be in descending order.
* @category Prop
* @since v4.1.0
*/
readonly descending?: boolean;
/**
* The number of Row Ids to skip for pagination purposes.
* @category Prop
* @since v4.1.0
*/
readonly offset?: number;
/**
* The maximum number of Row Ids to return.
* @category Prop
* @since v4.1.0
*/
readonly limit?: number;
/**
* The Store to be accessed: omit for the default context Store, provide an Id
* for a named context Store, or provide an explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly store?: StoreOrStoreId;
/**
* Whether the Cells should be editable. This affects the default CellView
* component (to use the EditableCellView component instead) but of course
* will not affect custom Cell components if you have set them.
* @category Prop
* @since v4.1.0
*/
readonly editable?: boolean;
/**
* An optional list of Cell Ids to use for rendering a prescribed set of the
* Table's Cells in a given order. This can also be an object with the desired
* Cell Ids as keys, and with a value that can either be a string label to
* show in the column header, or a CustomCell object to further configure the
* column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| CellIdFromSchema[]
| {
[CellId in CellIdFromSchema]?:
| string
| CustomCell;
};
/**
* Whether the table should be interactive such that clicking a header changes
* the sorting and/or direction.
* @category Prop
* @since v4.1.0
*/
readonly sortOnClick?: boolean;
/**
* Either `true` to show the default SortedTablePaginator for the Table, or
* provide your own paginator component that takes SortedTablePaginatorProps.
* @category Prop
* @since v4.1.0
*/
readonly paginator?: boolean | ComponentType;
/**
* A function that is called whenever the sorting or pagination of the Table
* is changed by the user, invoked with the sorted Cell Id, whether descending
* or not, and the offset of the pagination.
* @category Prop
* @since v4.1.0
*/
readonly onChange?: (
sortAndOffset: [
cellId: CellIdFromSchema | undefined,
descending: boolean,
offset: number,
],
) => void;
}
: never
: never;
/**
* ValuesInHtmlTableProps props are used for components that will render Values
* in an HTML table, such as the ValuesInHtmlTable component.
* @category Props
* @since v4.1.0
*/
export type ValuesInHtmlTableProps = {
/**
* The Store to be accessed: omit for the default context Store, provide an Id
* for a named context Store, or provide an explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly store?: StoreOrStoreId;
/**
* Whether the Values should be editable. This affects the default ValueView
* component (to use the EditableValueView component instead) but of course
* will not affect a custom valueComponent if you have set one.
* @category Prop
* @since v4.1.0
*/
readonly editable?: boolean;
/**
* A custom component for rendering each Value in the Store (to override the
* default ValueView component).
* @category Prop
* @since v4.1.0
*/
readonly valueComponent?: ComponentType>;
/**
* A function for generating extra props for each custom Value component based
* on its Id.
* @category Prop
* @since v4.1.0
*/
readonly getValueComponentProps?: (valueId: Id) => ExtraProps;
};
/**
* SliceInHtmlTableProps props are used for components that will render an Index
* Slice in an HTML table, such as the SliceInHtmlTable component.
* @category Props
* @since v4.1.0
*/
export type SliceInHtmlTableProps = {
/**
* The Id of the Index in the Indexes object.
* @category Prop
* @since v4.1.0
*/
readonly indexId: Id;
/**
* The Id of the Slice in the Index to be rendered.
* @category Prop
* @since v4.1.0
*/
readonly sliceId: Id;
/**
* The Indexes object to be accessed: omit for the default context Indexes
* object, provide an Id for a named context Indexes object, or provide an
* explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly indexes?: IndexesOrIndexesId;
/**
* Whether the Cells should be editable. This affects the default CellView
* component (to use the EditableCellView component instead) but of course
* will not affect custom Cell components if you have set them.
* @category Prop
* @since v4.1.0
*/
readonly editable?: boolean;
/**
* An optional list of Cell Ids to use for rendering a prescribed set of the
* Slice's Cells in a given order. This can also be an object with the desired
* Cell Ids as keys, and with a value that can either be a string label to
* show in the column header, or a CustomCell object to further configure the
* column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| Ids
| {[cellId: Id]: string | CustomCell};
};
/**
* RelationshipInHtmlTableProps props are used for components that will render
* the contents of the two Tables linked by a Relationship as an HTML table,
* such as the RelationshipInHtmlTable component.
*
* Note the use of dotted 'tableId.cellId' string pairs when specifying custom
* rendering for the cells in this table, since Cells from both the
* relationship's 'local' and 'remote' Table objects can be rendered and need to
* be distinguished.
* @category Props
* @since v4.1.0
*/
export type RelationshipInHtmlTableProps = {
/**
* The Id of the relationship in the Relationships object for which the
* relationship Table Rows will be rendered.
* @category Prop
* @since v4.1.0
*/
readonly relationshipId: Id;
/**
* The Relationships object to be accessed: omit for the default context
* Relationships object, provide an Id for a named context Relationships
* object, or provide an explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly relationships?: RelationshipsOrRelationshipsId;
/**
* Whether the Cells should be editable. This affects the default CellView
* component (to use the EditableCellView component instead) but of course
* will not affect custom Cell components if you have set them.
* @category Prop
* @since v4.1.0
*/
readonly editable?: boolean;
/**
* An optional list of dotted 'tableId.cellId' string pairs to use for
* rendering a prescribed set of the relationship Tables' Cells in a given
* order. This can also be an object with the desired 'tableId.cellId' string
* pairs as keys, and with a value that can either be a string label to show
* in the column header, or a CustomCell object to further configure the
* column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| Ids
| {[cellId: Id]: string | CustomCell};
};
/**
* ResultTableInHtmlTableProps props are used for components that will render a
* ResultTable in an HTML table, such as the ResultTableInHtmlTable component.
* @category Props
* @since v4.1.0
*/
export type ResultTableInHtmlTableProps = {
/**
* The Id of the query in the Queries object for which the ResultTable will be
* rendered.
* @category Prop
* @since v4.1.0
*/
readonly queryId: Id;
/**
* The Queries object to be accessed: omit for the default context Queries
* object, provide an Id for a named context Queries object, or provide an
* explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly queries?: QueriesOrQueriesId;
/**
* An optional list of Cell Ids to use for rendering a prescribed set of the
* ResultTable's Cells in a given order. This can also be an object with the
* desired Cell Ids as keys, and with a value that can either be a string
* label to show in the column header, or a ResultCustomCell object to further
* configure the column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| Ids
| {[cellId: Id]: string | CustomResultCell};
};
/**
* ResultSortedTableInHtmlTableProps props are used for components that will
* render a sorted Table in an HTML table, such as the SortedTableInHtmlTable
* component.
* @category Props
* @since v4.1.0
*/
export type ResultSortedTableInHtmlTableProps =
{
/**
* The Id of the query in the Queries object for which the ResultTable will be
* rendered.
* @category Prop
* @since v4.1.0
*/
readonly queryId: Id;
/**
* The Id of the Cell whose values are used for the sorting. If omitted, the
* view will sort the Row Id itself.
* @category Prop
* @since v4.1.0
*/
readonly cellId?: Id;
/**
* Whether the sorting should be in descending order.
* @category Prop
* @since v4.1.0
*/
readonly descending?: boolean;
/**
* The number of Row Ids to skip for pagination purposes.
* @category Prop
* @since v4.1.0
*/
readonly offset?: number;
/**
* The maximum number of Row Ids to return.
* @category Prop
* @since v4.1.0
*/
readonly limit?: number;
/**
* The Queries object to be accessed: omit for the default context Queries
* object, provide an Id for a named context Queries object, or provide an
* explicit reference.
* @category Prop
* @since v4.1.0
*/
readonly queries?: QueriesOrQueriesId;
/**
* An optional list of Cell Ids to use for rendering a prescribed set of the
* ResultTable's Cells in a given order. This can also be an object with the
* desired Cell Ids as keys, and with a value that can either be a string
* label to show in the column header, or a ResultCustomCell object to further
* configure the column.
* @category Prop
* @since v4.1.0
*/
readonly customCells?:
| Ids
| {[cellId: Id]: string | CustomResultCell};
/**
* Whether the table should be interactive such that clicking a header changes
* the sorting and/or direction.
* @category Prop
* @since v4.1.0
*/
readonly sortOnClick?: boolean;
/**
* Either `true` to show the default SortedTablePaginator for the ResultTable,
* or provide your own paginator component that takes
* SortedTablePaginatorProps.
* @category Prop
* @since v4.1.0
*/
readonly paginator?: boolean | ComponentType;
/**
* A function that is called whenever the sorting or pagination of the
* ResultTable is changed by the user, invoked with the sorted Cell Id,
* whether descending or not, and the offset of the pagination.
* @category Prop
* @since v4.1.0
*/
readonly onChange?: (
sortAndOffset: [
cellId: Id | undefined,
descending: boolean,
offset: number,
],
) => void;
};
/**
* SortedTablePaginatorProps props are used for components that will be used as
* a table paginator, such as the SortedTablePaginator component.
* @category Props
* @since v4.1.0
*/
export type SortedTablePaginatorProps = {
/**
* An event that will fire when the offset is updated, called with the new
* offset.
* @category Prop
* @since v4.1.0
*/
readonly onChange: (offset: number) => void;
/**
* The number of Row Ids to skip for pagination.
* @category Prop
* @since v4.1.0
*/
readonly offset?: number;
/**
* The maximum number of Row Ids being returned.
* @category Prop
* @since v4.1.0
*/
readonly limit?: number;
/**
* The total number of Row Ids in the paginated table.
* @category Prop
* @since v4.1.0
*/
readonly total: number;
/**
* A noun to use in the pagination label for a single row, defaulting to
* 'row'.
* @category Prop
* @since v4.1.0
*/
readonly singular?: string;
/**
* A noun to use in the pagination label for multiple rows, defaulting to the
* value of the singular noun suffixed with the letter 's'.
* @category Prop
* @since v4.1.0
*/
readonly plural?: string;
};
/**
* InspectorProps props are used to configure the Inspector component.
* @category Props
* @since v5.0.0
*/
export type InspectorProps = {
/**
* An optional string to indicate where you want the inspector to first
* appear.
* @category Prop
* @since v5.0.0
*/
readonly position?: 'top' | 'right' | 'bottom' | 'left' | 'full';
/**
* An optional boolean to indicate whether the inspector should start in the
* opened state.
* @category Prop
* @since v5.0.0
*/
readonly open?: boolean;
};
export type WithSchemas = {
/**
* The TableInHtmlTable component renders the contents of a single Table in a
* Store as an HTML
element, and registers a listener so that any
* changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Table to render based on Table Id, and
* Store (which is either the default context Store, a named context Store, or
* by explicit reference).
*
* This component renders a Table 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 useRowIds hook under the covers, which means that any
* changes to the structure of the Table will cause a re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether the Ids
* appear in a
element at the top of the table, and the start of each row.
* @param props The props for this component.
* @returns A rendering of the Table in a
element.
* @example
* This example creates a Provider context into which a default Store is
* provided. The TableInHtmlTable component within it then renders the Table in
* a
element with a CSS class.
*
* ```jsx
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {TableInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => ;
*
* const store = createStore().setTable('pets', {
* fido: {species: 'dog'},
* felix: {species: 'cat'},
* });
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
Id
*
species
*
*
*
*
*
fido
*
dog
*
*
*
felix
*
cat
*
*
*
* `;
* ```
* @example
* This example creates a Provider context into which a default Store is
* provided. The TableInHtmlTable component within it then renders the Table
* 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.
*
* ```jsx
* import {CellView, Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {TableInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const FormattedCellView = ({tableId, rowId, cellId, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* species: {
* component: FormattedCellView,
* getComponentProps: (rowId) => ({bold: rowId == 'fido'}),
* },
* };
*
* const store = createStore().setTable('pets', {
* fido: {species: 'dog'},
* felix: {species: 'cat'},
* });
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
fido:dog
*
*
*
felix:cat
*
*
*
* `;
* ```
* @category Store components
* @since v4.1.0
*/
TableInHtmlTable: (
props: TableInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The SortedTableInHtmlTable component renders the contents of a single sorted
* Table in a Store, as an HTML
element, and registers a listener so
* that any changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Table to render based on Table Id, and
* Store (which is either the default context Store, a named context Store, or
* by explicit reference). It also takes a Cell Id to sort by and a boolean to
* indicate that the sorting should be in descending order. The `offset` and
* `limit` props are used to paginate results, but default to `0` and
* `undefined` to return all available Row Ids if not specified.
*
* This component renders a ResultTable by iterating over its Row objects, in
* the order dictated by the sort parameters. 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 useSortedRowIds hook under the covers, which means
* that any changes to the structure or sorting of the Table will cause a
* re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether the Ids
* appear in a
element at the top of the table, and the start of each row.
*
* The `sortOnClick` prop makes the table's sorting interactive such that the
* user can click on a column heading to sort by that column. The style classes
* `sorted` and `ascending` (or `descending`) are added so that you can provide
* hints to the user how the sorting is being applied.
*
* Provide a paginator component for the Table with the `paginator` prop. Set to
* `true` to use the default SortedTablePaginator, or provide your own component
* that accepts SortedTablePaginatorProps.
*
* Finally, the `onChange` prop lets you listen to a user's changes to the
* Table's sorting or pagination.
* @param props The props for this component.
* @returns A rendering of the Table in a
element.
* @example
* This example creates a Provider context into which a default Store is
* provided. The SortedTableInHtmlTable component within it then renders the
* Table in a
* `;
* ```
* @example
* This example creates a Provider context into which a default Store is
* provided. The SortedTableInHtmlTable component within it then renders the
* Table 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.
*
* ```jsx
* import {CellView, Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {SortedTableInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
*
* const Pane = () => (
*
* );
*
* const FormattedCellView = ({tableId, rowId, cellId, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* species: {
* component: FormattedCellView,
* getComponentProps: (rowId) => ({bold: rowId == 'fido'}),
* },
* };
*
* const store = createStore().setTables({
* pets: {
* fido: {species: 'dog'},
* felix: {species: 'cat'},
* },
* });
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
felix:cat
*
*
*
fido:dog
*
*
*
* `;
* ```
* @category Store components
* @since v4.1.0
*/
SortedTableInHtmlTable: (
props: SortedTableInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The ValuesInHtmlTable component renders the keyed value contents of a Store
* as an HTML
element, and registers a listener so that any changes to
* that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Row to render based on Table Id, Row Id,
* and Store (which is either the default context Store, a named context Store,
* or an explicit reference).
*
* This component renders a Store by iterating over its Value objects. By
* default the Values are in turn rendered with the ValueView component, but you
* can override this behavior by providing a `valueComponent` prop, a custom
* component of your own that will render a Value based on ValueProps. You can
* also pass additional props to your custom component with the
* `getValueComponentProps` callback prop.
*
* This component uses the useValueIds hook under the covers, which means that
* any changes to the structure of the Values in the Store will cause a
* re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether labels
* and Ids appear in a
element at the top of the table, and the start of
* each row.
* @param props The props for this component.
* @returns A rendering of the Values in a
element.
* @example
* This example creates a Provider context into which a default Store is
* provided. The ValuesInHtmlTable component within it then renders the Values
* in a
element with a CSS class.
*
* ```jsx
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {ValuesInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => ;
*
* const store = createStore().setValues({open: true, employees: 3});
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
Id
*
Value
*
*
*
*
*
open
*
true
*
*
*
employees
*
3
*
*
*
* `;
* ```
* @example
* This example creates a Provider context into which a default Store is
* provided. The ValuesInHtmlTable component within it then renders the Row
* with a custom Cell component and a custom props callback. The header row at
* the top of the table and the Id column at the start of each row is removed.
*
* ```jsx
* import {Provider, ValueView} from 'tinybase/ui-react';
* import React from 'react';
* import {ValuesInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const getBoldProp = (valueId) => ({bold: valueId == 'open'});
* const Pane = () => (
*
* );
* const FormattedValueView = ({valueId, bold}) => (
* <>
* {bold ? {valueId} : valueId}
* {': '}
*
* >
* );
*
* const store = createStore().setValues({open: true, employees: 3});
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
open: true
*
employees: 3
*
*
* `;
* ```
* @category Store components
* @since v4.1.0
*/
ValuesInHtmlTable: (
props: ValuesInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The SliceInHtmlTable component renders the contents of a Slice as an HTML
*
element, and registers a listener so that any changes to that result
* will cause a re-render.
*
* See the 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
element at the top of the table, and the start of
* each row.
* @param props The props for this component.
* @returns A rendering of the Slice in a
element.
* @example
* 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
* `;
* ```
* @example
* 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.
*
* ```jsx
* import {CellView, Provider} from 'tinybase/ui-react';
* import {createIndexes, createStore} from 'tinybase';
* import React from 'react';
* import {SliceInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
*
* const App = ({indexes}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const FormattedCellView = ({tableId, rowId, cellId, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* species: {
* component: FormattedCellView,
* getComponentProps: (rowId) => ({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');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
fido:
*
*
*
cujo:
*
*
*
* `;
* ```
* @category Indexes components
* @since v4.1.0
*/
SliceInHtmlTable: (
props: SliceInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The RelationshipInHtmlTable component renders the contents of the two Tables
* linked by a Relationship as an HTML
element, and registers a listener
* so that any changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Relationship to render based on
* Relationship Id and Relationships object (which is either the default context
* Relationships object, a named context Relationships object, or an explicit
* reference).
*
* This component renders the two Table objects by iterating over their related
* 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.
*
* Note the use of dotted 'tableId.cellId' string pairs when specifying custom
* rendering for the cells in this table, since Cells from both the
* relationship's 'local' and 'remote' Table objects can be rendered and need to
* be distinguished.
*
* This component uses the useRowIds and useRemoteRowId hooks under the covers,
* which means that any changes to the structure of either Table resulting in a
* change to the relationship will cause a re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether labels
* and Ids appear in a
element at the top of the table, and the start of
* each row.
* @param props The props for this component.
* @returns A rendering of the two Tables linked by a Relationship in a
*
element.
* @example
* This example creates a Provider context into which a default Relationships
* object is provided. The RelationshipInHtmlTable component within it then
* renders the two Tables linked by a relationship in a
element with a
* CSS class. Note the dotted pairs that are used as column headings.
*
* ```jsx
* import {createRelationships, createStore} from 'tinybase';
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {RelationshipInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
*
* const App = ({relationships}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const relationships = createRelationships(
* createStore()
* .setTable('pets', {fido: {species: 'dog'}, cujo: {species: 'dog'}})
* .setTable('species', {wolf: {price: 10}, dog: {price: 5}}),
* ).setRelationshipDefinition('petSpecies', 'pets', 'species', 'species');
*
* const app = document.createElement('div');
* const root = createRoot(app);
* root.render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
pets.Id
*
species.Id
*
pets.species
*
species.price
*
*
*
*
*
fido
*
dog
*
dog
*
5
*
*
*
cujo
*
dog
*
dog
*
5
*
*
*
* `;
* ```
* @example
* This example creates a Provider context into which a default Relationships
* object is provided. The RelationshipInHtmlTable component within it then
* renders the two Tables linked by a relationship 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.
*
* ```jsx
* import {CellView, Provider} from 'tinybase/ui-react';
* import {createRelationships, createStore} from 'tinybase';
* import React from 'react';
* import {RelationshipInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
*
* const App = ({relationships}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const FormattedCellView = ({tableId, rowId, cellId, store, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* 'species.price': {
* component: FormattedCellView,
* getComponentProps: (rowId) => ({bold: rowId == 'dog'}),
* },
* };
*
* const relationships = createRelationships(
* createStore()
* .setTable('pets', {fido: {species: 'dog'}, cujo: {species: 'wolf'}})
* .setTable('species', {wolf: {price: 10}, dog: {price: 5}}),
* ).setRelationshipDefinition('petSpecies', 'pets', 'species', 'species');
*
* const app = document.createElement('div');
* const root = createRoot(app);
* root.render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
dog:5
*
*
*
wolf:10
*
*
*
* `;
* ```
* @category Relationships components
* @since v4.1.0
*/
RelationshipInHtmlTable: (
props: RelationshipInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The ResultTableInHtmlTable component renders the contents of a single query's
* ResultTable in a Queries object as an HTML
element, and registers a
* listener so that any changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which ResultTable to render based on query Id,
* and Queries object (which is either the default context Queries object, a
* named context Queries object, or by explicit reference).
*
* This component renders a ResultTable 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 ResultCustomCell type for more
* details.
*
* This component uses the useRowIds hook under the covers, which means that any
* changes to the structure of the Table will cause a re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether the Ids
* appear in a
element at the top of the table, and the start of each row.
* @param props The props for this component.
* @returns A rendering of the ResultTable in a
element.
* @example
* This example creates a Provider context into which a default Queries object
* is provided. The ResultTableInHtmlTable component within it then renders the
* ResultTable in a
* `;
* ```
* @example
* This example creates a Provider context into which a default Queries object
* is provided. The ResultTableInHtmlTable component within it then renders the
* ResultTable with a custom component and a custom props callback for the
* `color` Cell. The header row at the top of the table and the Id column at
* the start of each row is removed.
*
* ```jsx
* import {Provider, ResultCellView} from 'tinybase/ui-react';
* import {createQueries, createStore} from 'tinybase';
* import React from 'react';
* import {ResultTableInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
*
* const App = ({queries}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const FormattedResultCellView = ({queryId, rowId, cellId, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* color: {
* component: FormattedResultCellView,
* getComponentProps: (rowId) => ({bold: rowId == 'fido'}),
* },
* };
*
* const queries = createQueries(
* createStore().setTable('pets', {
* fido: {species: 'dog', color: 'brown'},
* felix: {species: 'cat', color: 'black'},
* }),
* ).setQueryDefinition('petColors', 'pets', ({select}) => select('color'));
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
fido:brown
*
*
*
felix:black
*
*
*
* `;
* ```
* @category Queries components
* @since v4.1.0
*/
ResultTableInHtmlTable: (
props: ResultTableInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The SortedTableInHtmlTable component renders the contents of a single query's
* sorted ResultTable in a Queries object as an HTML
element, and
* registers a listener so that any changes to that result will cause a
* re-render.
*
* See the demo for this component in action.
*
* The component's props identify which ResultTable to render based on query Id,
* and Queries object (which is either the default context Queries object, a
* named context Queries object, or by explicit reference). It also takes a Cell
* Id to sort by and a boolean to indicate that the sorting should be in
* descending order. The `offset` and `limit` props are used to paginate
* results, but default to `0` and `undefined` to return all available Row Ids
* if not specified.
*
* This component renders a ResultTable by iterating over its Row objects, in
* the order dictated by the sort parameters. 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 ResultCustomCell type for more details.
*
* This component uses the useSortedRowIds hook under the covers, which means
* that any changes to the structure or sorting of the ResultTable will cause a
* re-render.
*
* You can use the `headerRow` and `idColumn` props to control whether the Ids
* appear in a
element at the top of the table, and the start of each row.
*
* The `sortOnClick` prop makes the table's sorting interactive such that the
* user can click on a column heading to sort by that column. The style classes
* `sorted` and `ascending` (or `descending`) are added so that you can provide
* hints to the user how the sorting is being applied.
*
* Provide a paginator component for the ResultTable with the `paginator` prop.
* Set to `true` to use the default SortedTablePaginator, or provide your own
* component that accepts SortedTablePaginatorProps.
*
* Finally, the `onChange` prop lets you listen to a user's changes to the
* ResultTable's sorting or pagination.
* @param props The props for this component.
* @returns A rendering of the ResultTable in a
element.
* @example
* This example creates a Provider context into which a default Queries object
* is provided. The ResultSortedTableInHtmlTable component within it then
* renders the ResultTable in a
* `;
* ```
* @example
* This example creates a Provider context into which a default Queries object
* is provided. The ResultSortedTableInHtmlTable component within it then
* renders the ResultTable with a custom component and a custom props callback
* for the `color` Cell. The header row at the top of the table and the Id
* column at the start of each row is removed.
*
* ```jsx
* import {Provider, ResultCellView} from 'tinybase/ui-react';
* import {createQueries, createStore} from 'tinybase';
* import React from 'react';
* import {ResultSortedTableInHtmlTable} from 'tinybase/ui-react-dom';
* import {createRoot} from 'react-dom/client';
*
* const App = ({queries}) => (
*
*
*
* );
*
* const Pane = () => (
*
* );
*
* const FormattedResultCellView = ({queryId, rowId, cellId, bold}) => (
* <>
* {bold ? {rowId} : rowId}:
*
* >
* );
* const customCells = {
* color: {
* component: FormattedResultCellView,
* getComponentProps: (rowId) => ({bold: rowId == 'fido'}),
* },
* };
*
* const queries = createQueries(
* createStore().setTable('pets', {
* fido: {species: 'dog', color: 'brown'},
* felix: {species: 'cat', color: 'black'},
* }),
* ).setQueryDefinition('petColors', 'pets', ({select}) => select('color'));
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
felix:black
*
*
*
fido:brown
*
*
*
* `;
* ```
* @category Queries components
* @since v4.1.0
*/
ResultSortedTableInHtmlTable: (
props: ResultSortedTableInHtmlTableProps & HtmlTableProps,
) => ComponentReturnType;
/**
* The EditableCellView component renders the value of a single Cell in a way
* that can be edited in a web browser, and registers a listener so that any
* changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Cell to render based on Table Id, Row
* Id, Cell Id, and Store (which is either the default context Store, a named
* context Store, or an explicit reference).
*
* A Cell contains a string, number, or boolean, so the value is rendered in an
* appropriate tag and a button lets the user change type, if possible.
*
* Set the `showType` prop to false to remove the ability for the user to see or
* change the Cell type. They will also not be able to change the type if there
* is a TablesSchema applied to the Store.
*
* This component uses the useCell hook under the covers, which means that any
* changes to the specified Cell outside of this component will cause a
* re-render.
*
* You can provide a custom className prop which well be used on the root of the
* resulting element. If omitted the element's class will be `editableCell`. The
* debugIds prop has no effect on this component.
* @param props The props for this component.
* @returns An editable rendering of the Cell.
* @example
* This example creates a Provider context into which a default Store is
* provided. The EditableCellView component within it then renders an editable
* Cell.
*
* ```jsx
* import {EditableCellView} from 'tinybase/ui-react-dom';
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => (
*
* );
*
* const store = createStore().setCell('pets', 'fido', 'color', 'brown');
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
* `;
* ```
* @category Store components
* @since v4.1.0
*/
EditableCellView: (
props: CellProps & {
className?: string;
readonly showType?: boolean;
},
) => ComponentReturnType;
/**
* The EditableValueView component renders the value of a single Value in a way
* that can be edited in a web browser, and registers a listener so that any
* changes to that result will cause a re-render.
*
* See the demo for this component in action.
*
* The component's props identify which Value to render based on Table Id, Row
* Id, Value Id, and Store (which is either the default context Store, a named
* context Store, or an explicit reference).
*
* A Value contains a string, number, or boolean, so the value is rendered in an
* appropriate tag and a button lets the user change type, if possible.
*
* Set the `showType` prop to false to remove the ability for the user to see or
* change the Value type. They will also not be able to change the type if there
* is a ValuesSchema applied to the Store.
*
* This component uses the useValue hook under the covers, which means that any
* changes to the specified Value outside of this component will cause a
* re-render.
*
* You can provide a custom className prop which well be used on the root of the
* resulting element. If omitted the element's class will be `editableValue`.
* The debugIds prop has no effect on this component.
* @param props The props for this component.
* @returns An editable rendering of the Value.
* @example
* This example creates a Provider context into which a default Store is
* provided. The EditableValueView component within it then renders an editable
* Value.
*
* ```jsx
* import {EditableValueView} from 'tinybase/ui-react-dom';
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => ;
*
* const store = createStore().setValue('employees', 3);
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* console.log(app.innerHTML);
* // ->
* `
*
*
*
*
* `;
* ```
* @category Store components
* @since v4.1.0
*/
EditableValueView: (
props: ValueProps & {
className?: string;
readonly showType?: boolean;
},
) => ComponentReturnType;
/**
* The SortedTablePaginator component renders a paginator for a sorted table.
*
* See the demo for this component in action.
*
* The component displays 'previous' and 'next' buttons for paging through the
* Table if there are more Row Ids than fit in each page. The component will
* also display a label that shows which Row Ids are being displayed.
*
* The component's props identify initial pagination settings, and it will fire
* an event when the pagination changes.
* @param props The props for this component.
* @returns The rendering of a paginator control with a label, and next and
* previous buttons, where appropriate.
* @example
* This example creates a Provider context into which a default Store is
* provided. The SortedTableInHtmlTable component within it then renders the
* Table in a
* `;
* ```
* @category Store components
* @since v4.1.0
*/
SortedTablePaginator: (
props: SortedTablePaginatorProps,
) => ComponentReturnType;
/**
* The Inspector component renders a tool which allows you to view and edit the
* content of a Store in a debug web environment.
*
* See the demo for this component in action.
*
* The component displays a nub in the corner of the screen which you may then
* click to interact with all the Store objects in the Provider component
* context.
*
* The component's props identify the nub's initial location and panel state,
* though subsequent user changes to that will be preserved on each reload.
* @param props The props for this component.
* @returns The rendering of the inspector tool.
* @example
* This example creates a Provider context into which a default Store is
* provided. The Inspector component within it then renders the inspector
* tool.
*
* ```jsx
* import {Inspector} from 'tinybase/ui-react-inspector';
* import {Provider} from 'tinybase/ui-react';
* import React from 'react';
* import {createRoot} from 'react-dom/client';
* import {createStore} from 'tinybase';
*
* const App = ({store}) => (
*
*
*
* );
* const Pane = () => ;
*
* const store = createStore().setTables({pets: {fido: {species: 'dog'}}});
* const app = document.createElement('div');
* createRoot(app).render(); // !act
* // ... // !act
* console.log(app.innerHTML.substring(0, 30));
* // -> '