From d7dc8a941429180057c10563d3f3c18421f8a063 Mon Sep 17 00:00:00 2001 From: radubrehar Date: Tue, 27 Aug 2024 14:27:54 +0300 Subject: [PATCH] add docs on disabled rows --- .cursorignore | 8 + ...ndering-for-disabled-rows-example.page.tsx | 89 ++++++++++ .../docs/learn/rows/disabled-rows.page.md | 78 +++++++++ .../initialRowDisabledState-example.page.tsx | 68 ++++++++ ...using-api-to-disable-rows-example.page.tsx | 125 ++++++++++++++ .../reference/datasource-api/index.page.md | 76 +++++++++ .../defaultRowDisabledState-example.page.tsx | 68 ++++++++ .../reference/datasource-props/index.page.md | 154 ++++++++++++++++++ .../rowDisabledState-example.page.tsx | 114 +++++++++++++ .../reference/infinite-table-props.page.md | 2 +- .../reference/type-definitions/index.page.md | 1 + www/src/components/MDX/Prop.tsx | 13 +- www/src/sidebarLearn.json | 4 + 13 files changed, 796 insertions(+), 4 deletions(-) create mode 100644 .cursorignore create mode 100644 www/content/docs/learn/rows/custom-rendering-for-disabled-rows-example.page.tsx create mode 100644 www/content/docs/learn/rows/disabled-rows.page.md create mode 100644 www/content/docs/learn/rows/initialRowDisabledState-example.page.tsx create mode 100644 www/content/docs/learn/rows/using-api-to-disable-rows-example.page.tsx create mode 100644 www/content/docs/reference/datasource-props/defaultRowDisabledState-example.page.tsx create mode 100644 www/content/docs/reference/datasource-props/rowDisabledState-example.page.tsx diff --git a/.cursorignore b/.cursorignore new file mode 100644 index 00000000..3132a4a1 --- /dev/null +++ b/.cursorignore @@ -0,0 +1,8 @@ +# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv) +node_modules +/www/dataserver/data +.next +.env.local +dist +out +.contentlayer \ No newline at end of file diff --git a/www/content/docs/learn/rows/custom-rendering-for-disabled-rows-example.page.tsx b/www/content/docs/learn/rows/custom-rendering-for-disabled-rows-example.page.tsx new file mode 100644 index 00000000..b0610d7a --- /dev/null +++ b/www/content/docs/learn/rows/custom-rendering-for-disabled-rows-example.page.tsx @@ -0,0 +1,89 @@ +import * as React from 'react'; + +import { + DataSource, + DataSourceApi, + DataSourceData, + InfiniteTable, + InfiniteTablePropColumns, +} from '@infinite-table/infinite-react'; + +type Developer = { + id: number; + firstName: string; + lastName: string; + + currency: string; + preferredLanguage: string; + stack: string; + canDesign: 'yes' | 'no'; + + salary: number; +}; + +const data: DataSourceData = () => { + return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`) + .then((r) => r.json()) + .then((data: Developer[]) => data); +}; + +const columns: InfiniteTablePropColumns = { + id: { + field: 'id', + type: 'number', + defaultWidth: 100, + }, + salary: { + defaultFilterable: true, + field: 'salary', + type: 'number', + }, + + firstName: { + field: 'firstName', + renderValue: ({ rowInfo, value }) => { + return `${value} ${rowInfo.rowDisabled ? '🚫' : ''}`; + }, + }, + stack: { field: 'stack' }, + currency: { field: 'currency' }, +}; + +export default () => { + const [dataSourceApi, setDataSourceApi] = + React.useState>(); + return ( + <> + + + + onReady={setDataSourceApi} + data={data} + primaryKey="id" + defaultRowDisabledState={{ + enabledRows: [1, 2, 3, 5], + disabledRows: true, + }} + > + + columnDefaultWidth={120} + columnMinWidth={50} + columns={columns} + keyboardNavigation="row" + /> + + + ); +}; diff --git a/www/content/docs/learn/rows/disabled-rows.page.md b/www/content/docs/learn/rows/disabled-rows.page.md new file mode 100644 index 00000000..f4659415 --- /dev/null +++ b/www/content/docs/learn/rows/disabled-rows.page.md @@ -0,0 +1,78 @@ +--- +title: Disabled Rows +--- + +Disabling rows allows you to have some rows that are not selectable, not clickable, not reacheable via keyboard navigation and other interactions. + +The `DataSource` manages the disabled state of rows, via the (uncontrolled) prop and (controlled) prop. + +```tsx + + idProperty="id" + data={[]} + defaultRowDisabledState={{ + enabledRows: true, + disabledRows: ['id1', 'id4', 'id5'] + }} +/> + + {/* ... */} + /> + +``` + + + +In addition to using the / props, you can also specify the function prop, which overrides those other props and ultimately determines whether a row is disabled or not. + + + + + +```tsx file="initialRowDisabledState-example.page.tsx" +``` + + + +## Using disabled rows while rendering + +When rendering a cell, you have access to the row disabled state - the type has a `rowDisabled` property which is true if the row is disabled. + + + + + This example uses custom rendering for the `firstName` column to render an emoji for disabled rows. + + +```tsx file="custom-rendering-for-disabled-rows-example.page.tsx" +``` + + + +## Using the API to enable/disable rows + +You can use the `DataSourceApi` to enable or disable rows programmatically. + + + +```tsx +dataSourceApi.setRowEnabled(rowId, enabled); + +``` + + + +```tsx +dataSourceApi.setRowEnabledAt(rowIndex, enabled); +``` + + + + +Use the context menu on each row to toggle the disabled state of the respective row. + + +```tsx file="using-api-to-disable-rows-example.page.tsx" +``` + + \ No newline at end of file diff --git a/www/content/docs/learn/rows/initialRowDisabledState-example.page.tsx b/www/content/docs/learn/rows/initialRowDisabledState-example.page.tsx new file mode 100644 index 00000000..b8114383 --- /dev/null +++ b/www/content/docs/learn/rows/initialRowDisabledState-example.page.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; + +import { + DataSource, + DataSourceData, + InfiniteTable, + InfiniteTablePropColumns, +} from '@infinite-table/infinite-react'; + +type Developer = { + id: number; + firstName: string; + lastName: string; + + currency: string; + preferredLanguage: string; + stack: string; + canDesign: 'yes' | 'no'; + + salary: number; +}; + +const data: DataSourceData = () => { + return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`) + .then((r) => r.json()) + .then((data: Developer[]) => data); +}; + +const columns: InfiniteTablePropColumns = { + id: { + field: 'id', + type: 'number', + defaultWidth: 100, + }, + salary: { + defaultFilterable: true, + field: 'salary', + type: 'number', + }, + + firstName: { + field: 'firstName', + }, + stack: { field: 'stack' }, + currency: { field: 'currency' }, +}; + +export default () => { + return ( + <> + + data={data} + primaryKey="id" + defaultRowDisabledState={{ + enabledRows: true, + disabledRows: [1, 3, 4, 5], + }} + > + + columnDefaultWidth={120} + columnMinWidth={50} + columns={columns} + keyboardNavigation="row" + /> + + + ); +}; diff --git a/www/content/docs/learn/rows/using-api-to-disable-rows-example.page.tsx b/www/content/docs/learn/rows/using-api-to-disable-rows-example.page.tsx new file mode 100644 index 00000000..505c0325 --- /dev/null +++ b/www/content/docs/learn/rows/using-api-to-disable-rows-example.page.tsx @@ -0,0 +1,125 @@ +import * as React from 'react'; + +import { + DataSource, + DataSourceApi, + DataSourceData, + InfiniteTable, + InfiniteTablePropColumns, +} from '@infinite-table/infinite-react'; + +type Developer = { + id: number; + firstName: string; + lastName: string; + + currency: string; + preferredLanguage: string; + stack: string; + canDesign: 'yes' | 'no'; + + salary: number; +}; + +const data: DataSourceData = () => { + return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`) + .then((r) => r.json()) + .then((data: Developer[]) => data); +}; + +const columns: InfiniteTablePropColumns = { + id: { + field: 'id', + type: 'number', + defaultWidth: 100, + }, + salary: { + defaultFilterable: true, + field: 'salary', + type: 'number', + }, + + firstName: { + field: 'firstName', + renderValue: ({ rowInfo, value }) => { + return `${value} ${rowInfo.rowDisabled ? '🚫' : ''}`; + }, + }, + stack: { field: 'stack' }, + currency: { field: 'currency' }, +}; + +export default () => { + const [dataSourceApi, setDataSourceApi] = + React.useState>(); + return ( + <> + + + + onReady={setDataSourceApi} + data={data} + primaryKey="id" + defaultRowDisabledState={{ + enabledRows: [1, 2, 3, 5], + disabledRows: true, + }} + > + + getCellContextMenuItems={({ rowInfo }, { dataSourceApi }) => { + return { + columns: [{ name: 'label' }], + items: [ + { + label: 'Disable row', + key: 'disable-row', + disabled: rowInfo.rowDisabled, + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabledAt(rowInfo.indexInAll, false); + hideMenu(); + }, + }, + { + label: 'Enable row', + key: 'enable-row', + disabled: !rowInfo.rowDisabled, + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabled(rowInfo.id, true); + hideMenu(); + }, + }, + { + label: 'Toggle row disable/enable', + key: 'toggle-row-disable-enable', + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabled( + rowInfo.id, + rowInfo.rowDisabled, + ); + hideMenu(); + }, + }, + ], + }; + }} + columnDefaultWidth={120} + columnMinWidth={50} + columns={columns} + keyboardNavigation="row" + /> + + + ); +}; diff --git a/www/content/docs/reference/datasource-api/index.page.md b/www/content/docs/reference/datasource-api/index.page.md index 033a52cc..38280ed2 100644 --- a/www/content/docs/reference/datasource-api/index.page.md +++ b/www/content/docs/reference/datasource-api/index.page.md @@ -34,6 +34,82 @@ For API on row/group selection, see the [Selection API page](/docs/reference/sel + + +> Returns `true` if the row at the specified index is disabled, `false` otherwise. + +See the prop for more information. + +For checking if a row is disabled by its primary key, see the method. + +For changing the enable/disable state for the row, see the . + + + +```ts file="../datasource-props/rowDisabledState-example.page.tsx" +``` + + + + + + + +> Returns `true` if the row with the specified primary key is disabled, `false` otherwise. + +See the prop for more information. + +For checking if a row is disabled by its index, see the method. + +For changing the enable/disable state for the row, see the . + + + +```ts file="../datasource-props/rowDisabledState-example.page.tsx" + +``` + + + + + + + +> Sets the enable/disable state for the row with the specified primary key. + +See the prop for more information. + +For setting the enable/disable state for a row by its index, see the method. + + + +```ts file="../datasource-props/rowDisabledState-example.page.tsx" + +``` + + + + + + + +> Sets the enable/disable state for the row at the specified index. + +See the prop for more information. + +For setting the enable/disable state for a row by its primary key, see the method. + + + +```ts file="../datasource-props/rowDisabledState-example.page.tsx" + +``` + + + + + + > Adds the specified data at the end of the data source. diff --git a/www/content/docs/reference/datasource-props/defaultRowDisabledState-example.page.tsx b/www/content/docs/reference/datasource-props/defaultRowDisabledState-example.page.tsx new file mode 100644 index 00000000..a56704a4 --- /dev/null +++ b/www/content/docs/reference/datasource-props/defaultRowDisabledState-example.page.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; + +import { + DataSource, + DataSourceData, + InfiniteTable, + InfiniteTablePropColumns, +} from '@infinite-table/infinite-react'; + +type Developer = { + id: number; + firstName: string; + lastName: string; + + currency: string; + preferredLanguage: string; + stack: string; + canDesign: 'yes' | 'no'; + + salary: number; +}; + +const data: DataSourceData = () => { + return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`) + .then((r) => r.json()) + .then((data: Developer[]) => data); +}; + +const columns: InfiniteTablePropColumns = { + id: { + field: 'id', + type: 'number', + defaultWidth: 100, + }, + salary: { + defaultFilterable: true, + field: 'salary', + type: 'number', + }, + + firstName: { + field: 'firstName', + }, + stack: { field: 'stack' }, + currency: { field: 'currency' }, +}; + +export default () => { + return ( + <> + + data={data} + primaryKey="id" + defaultRowDisabledState={{ + enabledRows: true, + disabledRows: [1, 3, 4, 5], + }} + > + + keyboardNavigation="row" + columnDefaultWidth={120} + columnMinWidth={50} + columns={columns} + /> + + + ); +}; diff --git a/www/content/docs/reference/datasource-props/index.page.md b/www/content/docs/reference/datasource-props/index.page.md index b4ea88b3..11652c4b 100644 --- a/www/content/docs/reference/datasource-props/index.page.md +++ b/www/content/docs/reference/datasource-props/index.page.md @@ -42,6 +42,160 @@ Using functions (for more dynamic primary keys) is supported, but hasn't been te + + +> This function ultimately decides the disabled state of a row. It overrides both / props. + +It's called with a single argument - the row info object for the row in question. + +It should return `true` if the row is disabled, and `false` otherwise. + + + +When this prop is used, will not be called. + + + + + + + + +> The uncontrolled prop for managing row enabled/disabled state. For the controlled version see . For listening to row disabled state changes, see . + +The value for this prop is an object with two properties: + +- `enabledRows` - either `true` or an array of row ids that are enabled. When `true` is passed, `disabledRows` should be an array of row ids that are disabled. +- `disabledRows` - either `true` or an array of row ids that are disabled. When `true` is passed, `enabledRows` should be an array of row ids that are enabled. + + + +The values in the `enabledRows`/`disabledRows` arrays are row ids, and not indexes. + + + + + + +This prop can be overriden by using the prop. + + + +Here's an example of how to use the `defaultRowDisabledState` prop: + + + + + +Rows with ids `1`, `3`, `4` and `5` are disabled. + + + +```ts file="defaultRowDisabledState-example.page.tsx" + +``` + + + + + + + +> Manages row enabled/disabled state. For the uncontrolled version see . For listening to row disabled state changes, see . + +The value for this prop is an object with two properties: + +- `enabledRows` - either `true` or an array of row ids that are enabled. When `true` is passed, `disabledRows` should be an array of row ids that are disabled. +- `disabledRows` - either `true` or an array of row ids that are disabled. When `true` is passed, `enabledRows` should be an array of row ids that are enabled. + + +When using this controlled prop, you will need to update the `rowDisabledState` prop by using the callback. + + + + +This prop can be overriden by using the prop. + + + + + + + +Rows with ids `1`, `3`, `4` and `5` are disabled initially. + +Right click rows and use the context menu to enable/disable rows. + + + +```ts file="rowDisabledState-example.page.tsx" + +``` + + + + + + + + + + +> Called when the row disabled state changes. + +It's called with just 1 argument (`rowDisabledState`), which is an instance of the `RowDisabledState` class. To get a literal object that represents the row disabled state, call the `rowDisabledState.getState()` method. + +```tsx {3,19} +import { + DataSource, + RowDisabledStateObject, +} from '@infinite-table/infinite-react'; +function App() { + const [rowDisabledState, setRowDisabledState] = React.useState< + RowDisabledStateObject + >({ + enabledRows: true, + disabledRows: [1, 3, 4, 5], + }); + return ( + <> + + data={data} + primaryKey="id" + rowDisabledState={rowDisabledState} + onRowDisabledStateChange={(rowState) => { + setRowDisabledState(rowState.getState()); + }} + /> + + ); +} +``` + + +When using the controlled prop, you will need to update the `rowDisabledState` by using this callback. + + + + + + +Rows with ids `1`, `3`, `4` and `5` are disabled initially. + +Right click rows and use the context menu to enable/disable rows. + + + +```ts file="rowDisabledState-example.page.tsx" + +``` + + + + + + + > Specifies the functions to use for aggregating data. The object is a map where the keys are ids for aggregations and values are object of the shape described below. diff --git a/www/content/docs/reference/datasource-props/rowDisabledState-example.page.tsx b/www/content/docs/reference/datasource-props/rowDisabledState-example.page.tsx new file mode 100644 index 00000000..bcf69912 --- /dev/null +++ b/www/content/docs/reference/datasource-props/rowDisabledState-example.page.tsx @@ -0,0 +1,114 @@ +import * as React from 'react'; + +import { + DataSource, + DataSourceData, + InfiniteTable, + InfiniteTablePropColumns, + RowDisabledStateObject, +} from '@infinite-table/infinite-react'; + +type Developer = { + id: number; + firstName: string; + lastName: string; + + currency: string; + preferredLanguage: string; + stack: string; + canDesign: 'yes' | 'no'; + + salary: number; +}; + +const data: DataSourceData = () => { + return fetch(process.env.NEXT_PUBLIC_BASE_URL + `/developers1k-sql?`) + .then((r) => r.json()) + .then((data: Developer[]) => data); +}; + +const columns: InfiniteTablePropColumns = { + id: { + field: 'id', + type: 'number', + defaultWidth: 100, + }, + salary: { + defaultFilterable: true, + field: 'salary', + type: 'number', + }, + + firstName: { + field: 'firstName', + }, + stack: { field: 'stack' }, + currency: { field: 'currency' }, +}; + +export default () => { + const [rowDisabledState, setRowDisabledState] = React.useState< + RowDisabledStateObject + >({ + enabledRows: true, + disabledRows: [1, 3, 4, 5], + }); + return ( + <> + + data={data} + primaryKey="id" + rowDisabledState={rowDisabledState} + onRowDisabledStateChange={(rowState) => { + setRowDisabledState(rowState.getState()); + }} + > + + getCellContextMenuItems={({ rowInfo }, { dataSourceApi }) => { + const rowDisabled = dataSourceApi.isRowDisabledAt( + rowInfo.indexInAll, + ); + return { + columns: [{ name: 'label' }], + items: [ + { + label: 'Disable row', + disabled: rowDisabled, + key: 'disable-row', + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabledAt(rowInfo.indexInAll, false); + hideMenu(); + }, + }, + { + label: 'Enable row', + disabled: !rowDisabled, + key: 'enable-row', + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabled(rowInfo.id, true); + hideMenu(); + }, + }, + { + label: 'Toggle row enable/disable', + key: 'toggle-row', + onAction: ({ hideMenu }) => { + dataSourceApi.setRowEnabled( + rowInfo.id, + dataSourceApi.isRowDisabled(rowInfo.id), + ); + hideMenu(); + }, + }, + ], + }; + }} + keyboardNavigation="row" + columnDefaultWidth={120} + columnMinWidth={50} + columns={columns} + /> + + + ); +}; diff --git a/www/content/docs/reference/infinite-table-props.page.md b/www/content/docs/reference/infinite-table-props.page.md index 304b687c..faf8f4b0 100644 --- a/www/content/docs/reference/infinite-table-props.page.md +++ b/www/content/docs/reference/infinite-table-props.page.md @@ -2449,7 +2449,7 @@ In addition, if you need to configure the context menu to have other columns rat ```tsx const getCellContextMenuItems = () => { return { - columns: [{ name: 'Label' }, { name: 'Icon' }], + columns: [{ name: 'label' }, { name: 'icon' }], items: [ { label: 'Welcome', diff --git a/www/content/docs/reference/type-definitions/index.page.md b/www/content/docs/reference/type-definitions/index.page.md index aef4f10b..03eaf31e 100644 --- a/www/content/docs/reference/type-definitions/index.page.md +++ b/www/content/docs/reference/type-definitions/index.page.md @@ -384,6 +384,7 @@ The common properties of the type (in all discriminated cases) are: - `id` - the primary key of the row, as retrieved using the prop. - `indexInAll` - the index in all currently visible rows. - `rowSelected` - whether the row is selected or not - `boolean | null`. +- `rowDisabled` - whether the row is disabled or not - `boolean`. ### InfiniteTable_NoGrouping_RowInfoNormal diff --git a/www/src/components/MDX/Prop.tsx b/www/src/components/MDX/Prop.tsx index 3e21c940..13595ffd 100644 --- a/www/src/components/MDX/Prop.tsx +++ b/www/src/components/MDX/Prop.tsx @@ -537,9 +537,8 @@ export function PropTable({ }, []); React.useLayoutEffect(() => { - const initialText = globalThis.location - ? globalThis.location.hash.slice(1).toLowerCase() - : ''; + const hash = globalThis.location ? globalThis.location.hash.slice(1) : ''; + const initialText = hash ? hash.toLowerCase() : ''; if (initialText) { const [search, value] = initialText.split('='); @@ -547,6 +546,7 @@ export function PropTable({ if (search === 'search' && value) { resetSearch(value); } + setHash(hash); } const onHashChange = debounce(function (_event: null | HashChangeEvent) { @@ -633,6 +633,13 @@ export function PropTable({ if (!hidden) { visibleCount++; } + if (highlight) { + console.log({ + highlight, + lowerName, + lowerHash, + }); + } return React.cloneElement(child, { //@ts-ignore hidden, diff --git a/www/src/sidebarLearn.json b/www/src/sidebarLearn.json index 0b631bd6..adf2b934 100644 --- a/www/src/sidebarLearn.json +++ b/www/src/sidebarLearn.json @@ -90,6 +90,10 @@ "path": "/docs/learn/rows/using-row-info", "title": "Using Rows at Runtime" }, + { + "path": "/docs/learn/rows/disabled-rows", + "title": "Disabled Rows" + }, { "path": "/docs/learn/selection/row-selection#", "title": "Selecting Rows"