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`] = `"
"`; +exports[` should render Accordion on server 1`] = `"
"`; 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`.