diff --git a/packages/blade/CHANGELOG.md b/packages/blade/CHANGELOG.md
index b38d66eb4d3..b9d0dd0cddd 100644
--- a/packages/blade/CHANGELOG.md
+++ b/packages/blade/CHANGELOG.md
@@ -1,5 +1,13 @@
# @razorpay/blade
+## 11.24.1
+
+### Patch Changes
+
+- b38943c0: fix: table multiselect with pagination bug
+- 636952b6: feat: add multiselection-mode prop to Table
+- caee2688: fix: add button type button
+
## 11.24.0
### Minor Changes
diff --git a/packages/blade/package.json b/packages/blade/package.json
index eb3d8c64551..08ea1cc5dcc 100644
--- a/packages/blade/package.json
+++ b/packages/blade/package.json
@@ -1,7 +1,7 @@
{
"name": "@razorpay/blade",
"description": "The Design System that powers Razorpay",
- "version": "11.24.0",
+ "version": "11.24.1",
"license": "MIT",
"engines": {
"node": ">=18.12.1"
diff --git a/packages/blade/src/components/Accordion/AccordionButton.web.tsx b/packages/blade/src/components/Accordion/AccordionButton.web.tsx
index 41dbf2d150f..8b13f4376a4 100644
--- a/packages/blade/src/components/Accordion/AccordionButton.web.tsx
+++ b/packages/blade/src/components/Accordion/AccordionButton.web.tsx
@@ -53,6 +53,7 @@ const _AccordionButton = ({
width="100%"
>
should render Accordion on server 1`] = `"
You can use Razorpay Route from the Dashboard or using APIs to transfer money to customers. You may also check our docs for detailed instructions.
How can I setup QR Codes?
Just use Razorpay. You may also check our docs for detailed instructions. Please use the search functionality to ask your queries.
"`;
+exports[` should render Accordion on server 1`] = `"You can use Razorpay Route from the Dashboard or using APIs to transfer money to customers. You may also check our docs for detailed instructions.
How can I setup QR Codes?
Just use Razorpay. You may also check our docs for detailed instructions. Please use the search functionality to ask your queries.
"`;
exports[` should render Accordion on server 2`] = `
.c0.c0.c0.c0.c0 {
@@ -368,6 +368,7 @@ exports[` should render Accordion on server 2`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render Accordion on server 2`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
should render 1`] = `
aria-expanded="false"
class="c3"
data-blade-component="accordion-button"
+ type="button"
>
({
children,
data,
+ multiSelectTrigger = 'row',
selectionType = 'none',
onSelectionChange,
isHeaderSticky,
@@ -245,10 +250,11 @@ const _Table =
- ({
// Selection Logic
const onSelectChange: MiddlewareFunction = (action, state): void => {
- const selectedIDs: Identifier[] = state.id ? [state.id] : state.ids ?? [];
- setSelectedRows(selectedIDs);
+ const selectedIds: Identifier[] = state.id ? [state.id] : state.ids ?? [];
+ setSelectedRows(selectedIds);
onSelectionChange?.({
- values: data.nodes.filter((node) => selectedIDs.includes(node.id)),
+ selectedIds,
+ values: data.nodes.filter((node) => selectedIds.includes(node.id)),
});
};
@@ -258,6 +264,8 @@ const _Table =
- ({
onChange: onSelectChange,
},
{
+ clickType:
+ multiSelectTrigger === 'row' ? SelectClickTypes.RowClick : SelectClickTypes.ButtonClick,
rowSelect: selectionType !== 'none' ? rowSelectType[selectionType] : undefined,
},
);
diff --git a/packages/blade/src/components/Table/__tests__/Table.web.test.tsx b/packages/blade/src/components/Table/__tests__/Table.web.test.tsx
index 2f0be38fbfd..072c40c84ab 100644
--- a/packages/blade/src/components/Table/__tests__/Table.web.test.tsx
+++ b/packages/blade/src/components/Table/__tests__/Table.web.test.tsx
@@ -780,10 +780,10 @@ describe('', () => {
const firstSelectableRow = getByText('rzp01').closest('td');
if (firstSelectableRow) await user.click(firstSelectableRow);
- expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[0]] });
+ expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[0]], selectedIds: ['1'] });
const secondSelectableRow = getByText('rzp02').closest('td');
if (secondSelectableRow) await user.click(secondSelectableRow);
- expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[1]] });
+ expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[1]], selectedIds: ['2'] });
});
it('should render table with multi select', async () => {
@@ -831,14 +831,17 @@ describe('', () => {
expect(getAllByRole('checkbox')).toHaveLength(6);
const firstSelectableRow = getByText('rzp01').closest('td');
if (firstSelectableRow) await user.click(firstSelectableRow);
- expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[0]] });
+ expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[0]], selectedIds: ['1'] });
const secondSelectableRow = getByText('rzp02').closest('td');
if (secondSelectableRow) await user.click(secondSelectableRow);
- expect(onSelectionChange).toHaveBeenCalledWith({ values: [nodes[0], nodes[1]] });
+ expect(onSelectionChange).toHaveBeenCalledWith({
+ values: [nodes[0], nodes[1]],
+ selectedIds: ['1', '2'],
+ });
expect(getByText('2 Items Selected')).toBeInTheDocument();
const deselectButton = getByText('Deselect');
await user.click(deselectButton);
- expect(onSelectionChange).toHaveBeenCalledWith({ values: [] });
+ expect(onSelectionChange).toHaveBeenCalledWith({ values: [], selectedIds: [] });
});
it('should render table with client side pagination', async () => {
diff --git a/packages/blade/src/components/Table/docs/stories.ts b/packages/blade/src/components/Table/docs/stories.ts
index 831ee5b4d5f..68f7b7b9bf0 100644
--- a/packages/blade/src/components/Table/docs/stories.ts
+++ b/packages/blade/src/components/Table/docs/stories.ts
@@ -594,7 +594,9 @@ function App(): React.ReactElement {
setSelectedItems(values)}
+ onSelectionChange={({ selectedIds }) => {
+ setSelectedItems(data.nodes.filter((node) => selectedIds.includes(node.id)));
+ }}
toolbar={
= {
* The object should have an id property that is a unique identifier for the row.
*/
data: TableData- ;
+ /**
+ * Selection mode determines how the table rows can be selected.
+ * @default 'row'
+ **/
+ multiSelectTrigger?: 'checkbox' | 'row';
/**
* The selectionType prop determines the type of selection that is allowed on the table.
* The selectionType prop can be 'none', 'single' or 'multiple'.
@@ -83,7 +88,25 @@ type TableProps
- = {
* The onSelectionChange prop is a function that is called when the selection changes.
* The function is called with an object that has a values property that is an array of the selected rows.
**/
- onSelectionChange?: ({ values }: { values: TableNode
- [] }) => void;
+ onSelectionChange?: ({
+ values,
+ selectedIds,
+ }: {
+ /**
+ * Note: on server side paginated data, this prop will only contain the selected rows on the current page.
+ *
+ * Thus, it's recommended to use `selectedIds` for more consistent state management across server/client paginated data.
+ *
+ * *Deprecated:* Use `selectedIds` instead.
+ *
+ * @deprecated
+ */
+ values: TableNode
- [];
+ /**
+ * An array of selected row ids.
+ */
+ selectedIds: Identifier[];
+ }) => void;
/**
* The isHeaderSticky prop determines whether the table header is sticky or not.
* The default value is `false`.