From 046d7ca6ab68ba419b0391d83242eb2aa07ee988 Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Thu, 28 Aug 2025 16:55:42 +0200 Subject: [PATCH 1/6] added readonly support form list --- src/layout/List/ListComponent.module.css | 29 ++++++ src/layout/List/ListComponent.test.tsx | 103 ++++++++++++++++++- src/layout/List/ListComponent.tsx | 123 ++++++++++++++--------- 3 files changed, 204 insertions(+), 51 deletions(-) diff --git a/src/layout/List/ListComponent.module.css b/src/layout/List/ListComponent.module.css index ab33046807..970fcc3595 100644 --- a/src/layout/List/ListComponent.module.css +++ b/src/layout/List/ListComponent.module.css @@ -100,3 +100,32 @@ margin-left: auto; min-width: unset; } + +/*.readOnlyRow {*/ +/* cursor: default;*/ +/*}*/ + +/*.readOnlyRow:hover {*/ +/* background-color: initial;*/ +/*}*/ + +/*.readOnlyCell {*/ +/* background-color: initial;*/ +/*}*/ + +/*.mobileContent {*/ +/* flex: 1;*/ +/* display: flex;*/ +/* flex-direction: column;*/ +/* gap: var(--ds-size-4);*/ +/*}*/ + +/*.mobileContent div {*/ +/* display: flex;*/ +/* flex-direction: column;*/ +/* gap: var(--ds-size-2);*/ +/*}*/ + +/*.mobileControl {*/ +/* flex-shrink: 0;*/ +/*}*/ diff --git a/src/layout/List/ListComponent.test.tsx b/src/layout/List/ListComponent.test.tsx index 02c1853cfc..ff462c05f4 100644 --- a/src/layout/List/ListComponent.test.tsx +++ b/src/layout/List/ListComponent.test.tsx @@ -211,8 +211,8 @@ describe('ListComponent', () => { await waitFor(() => expect(screen.getAllByRole('radio')).toHaveLength(6)); expect(screen.queryByRole('radio', { checked: true })).not.toBeInTheDocument(); - // Select the second row - const swedishRow = screen.getByRole('radio', { name: /sweden/i }); + // Select the second row - find by value since label is empty + const swedishRow = screen.getAllByRole('radio')[1]; await user.click(swedishRow); expect(formDataMethods.setMultiLeafValues).toHaveBeenCalledWith({ @@ -224,4 +224,103 @@ describe('ListComponent', () => { ], }); }); + + describe('readOnly mode', () => { + it('should not render radio buttons when readOnly is true', async () => { + await render({ component: { readOnly: true } }); + + // Wait for the data to load + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + + // No radio buttons should be present + expect(screen.queryByRole('radio')).not.toBeInTheDocument(); + }); + + it('should not render checkboxes when readOnly is true with group bindings', async () => { + await render({ + component: { + readOnly: true, + dataModelBindings: { + Name: { dataType: defaultDataTypeMock, field: 'CountryName' }, + Population: { dataType: defaultDataTypeMock, field: 'CountryPopulation' }, + HighestMountain: { dataType: defaultDataTypeMock, field: 'CountryHighestMountain' }, + group: { dataType: defaultDataTypeMock, field: 'Countries' }, + }, + }, + }); + + // Wait for the data to load + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + + // No checkboxes should be present + expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); + }); + + it('should not allow row selection when readOnly is true', async () => { + const user = userEvent.setup({ delay: null }); + const { formDataMethods } = await render({ component: { readOnly: true } }); + + // Wait for the data to load + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + + // Try to click a row + const norwegianRow = screen.getByRole('row', { name: /norway/i }); + await user.click(norwegianRow); + + // No data should be saved + expect(formDataMethods.setMultiLeafValues).not.toHaveBeenCalled(); + }); + + it('should not render controls in mobile view when readOnly is true', async () => { + jest.spyOn(useDeviceWidths, 'useIsMobile').mockReturnValue(true); + + await render({ + component: { + readOnly: true, + tableHeadersMobile: ['Name', 'FlagLink'], + }, + }); + + // Wait for the data to load + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + + // No radio buttons should be present + expect(screen.queryByRole('radio')).not.toBeInTheDocument(); + }); + + it('should not render checkbox controls in mobile view when readOnly is true with group bindings', async () => { + jest.spyOn(useDeviceWidths, 'useIsMobile').mockReturnValue(true); + + await render({ + component: { + readOnly: true, + dataModelBindings: { + Name: { dataType: defaultDataTypeMock, field: 'CountryName' }, + Population: { dataType: defaultDataTypeMock, field: 'CountryPopulation' }, + HighestMountain: { dataType: defaultDataTypeMock, field: 'CountryHighestMountain' }, + group: { dataType: defaultDataTypeMock, field: 'Countries' }, + }, + tableHeadersMobile: ['Name', 'FlagLink'], + }, + }); + + // Wait for the data to load + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + + // No checkboxes should be present + expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); + }); + + it('should still display table data when readOnly is true', async () => { + await render({ component: { readOnly: true } }); + + // All data should still be visible + await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); + expect(screen.getByText('Sweden')).toBeInTheDocument(); + expect(screen.getByText('Denmark')).toBeInTheDocument(); + expect(screen.getByText('Germany')).toBeInTheDocument(); + expect(screen.getByText('Spain')).toBeInTheDocument(); + expect(screen.getByText('France')).toBeInTheDocument(); + }); + }); }); diff --git a/src/layout/List/ListComponent.tsx b/src/layout/List/ListComponent.tsx index d780400a42..c3645faad4 100644 --- a/src/layout/List/ListComponent.tsx +++ b/src/layout/List/ListComponent.tsx @@ -49,6 +49,7 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li secure, dataListId, required, + readOnly, } = item; const [pageSize, setPageSize] = useState(pagination?.default ?? 0); @@ -96,6 +97,10 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li const description = item.textResourceBindings?.description; const handleRowClick = (row: Row) => { + if (readOnly) { + return; + } + if (enabled) { toggle(row); } else { @@ -171,15 +176,22 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li {data?.listItems.map((row) => ( - handleRowClick(row)} - value={JSON.stringify(row)} - checked={isChecked(row)} - label={renderListItems(row, tableHeaders)} - /> + > + {!readOnly && ( + handleRowClick(row)} + value={JSON.stringify(row)} + checked={isChecked(row)} + label='' + /> + )} +
{renderListItems(row, tableHeaders)}
+ ))} ) : ( @@ -200,14 +212,21 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li )} {data?.listItems.map((row) => ( - handleSelectedRadioRow({ selectedValue: row })} - label={renderListItems(row, tableHeaders)} - /> + className={cn(classes.mobile, { [classes.selectedRow]: isRowSelected(row) && !readOnly })} + > + {!readOnly && ( + handleSelectedRadioRow({ selectedValue: row })} + label='' + /> + )} +
{renderListItems(row, tableHeaders)}
+ ))} )} @@ -246,11 +265,13 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li )} - - - - - + {!readOnly && ( + + + + + + )} {Object.entries(tableHeaders).map(([key, value]) => { const isSortable = sortableColumns?.includes(key); let sort: AriaAttributes['aria-sort'] = undefined; @@ -273,41 +294,45 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li {data?.listItems.map((row) => ( handleRowClick(row)} + onClick={!readOnly ? () => handleRowClick(row) : undefined} + className={cn({ [classes.readOnlyRow]: readOnly })} > - - {enabled ? ( - {getRowLabel(row)}} - onChange={() => {}} - value={JSON.stringify(row)} - checked={isChecked(row)} - name={indexedId} - /> - ) : ( - { - handleSelectedRadioRow({ selectedValue: row }); - }} - value={JSON.stringify(row)} - checked={isRowSelected(row)} - name={indexedId} - /> - )} - + {!readOnly && ( + + {enabled ? ( + {getRowLabel(row)}} + onChange={() => {}} + value={JSON.stringify(row)} + checked={isChecked(row)} + name={indexedId} + /> + ) : ( + { + handleSelectedRadioRow({ selectedValue: row }); + }} + value={JSON.stringify(row)} + checked={isRowSelected(row)} + name={indexedId} + /> + )} + + )} {Object.keys(tableHeaders).map((key) => ( {typeof row[key] === 'string' ? : row[key]} From 7b1fa1a8a7659177166451f3a88af2a6580bfbef Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Fri, 29 Aug 2025 10:02:58 +0200 Subject: [PATCH 2/6] minor improvement --- src/layout/List/ListComponent.module.css | 40 ++++++++++++------------ src/layout/List/ListComponent.test.tsx | 2 +- src/layout/List/ListComponent.tsx | 17 +++++----- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/layout/List/ListComponent.module.css b/src/layout/List/ListComponent.module.css index 970fcc3595..96abbc9f0a 100644 --- a/src/layout/List/ListComponent.module.css +++ b/src/layout/List/ListComponent.module.css @@ -101,31 +101,31 @@ min-width: unset; } -/*.readOnlyRow {*/ -/* cursor: default;*/ -/*}*/ +.listTable tr.readOnlyRow { + cursor: default; +} /*.readOnlyRow:hover {*/ /* background-color: initial;*/ /*}*/ -/*.readOnlyCell {*/ -/* background-color: initial;*/ -/*}*/ +.readOnlyCell { + background-color: initial; +} -/*.mobileContent {*/ -/* flex: 1;*/ -/* display: flex;*/ -/* flex-direction: column;*/ -/* gap: var(--ds-size-4);*/ -/*}*/ +.mobileContent { + flex: 1; + display: flex; + flex-direction: column; + gap: var(--ds-size-4); +} -/*.mobileContent div {*/ -/* display: flex;*/ -/* flex-direction: column;*/ -/* gap: var(--ds-size-2);*/ -/*}*/ +.mobileContent div { + display: flex; + flex-direction: column; + gap: var(--ds-size-2); +} -/*.mobileControl {*/ -/* flex-shrink: 0;*/ -/*}*/ +.mobileControl { + flex-shrink: 0; +} diff --git a/src/layout/List/ListComponent.test.tsx b/src/layout/List/ListComponent.test.tsx index ff462c05f4..02c87fc6f1 100644 --- a/src/layout/List/ListComponent.test.tsx +++ b/src/layout/List/ListComponent.test.tsx @@ -212,7 +212,7 @@ describe('ListComponent', () => { expect(screen.queryByRole('radio', { checked: true })).not.toBeInTheDocument(); // Select the second row - find by value since label is empty - const swedishRow = screen.getAllByRole('radio')[1]; + const swedishRow = screen.getByRole('radio', { name: /sweden/i }); await user.click(swedishRow); expect(formDataMethods.setMultiLeafValues).toHaveBeenCalledWith({ diff --git a/src/layout/List/ListComponent.tsx b/src/layout/List/ListComponent.tsx index c3645faad4..9dad799f37 100644 --- a/src/layout/List/ListComponent.tsx +++ b/src/layout/List/ListComponent.tsx @@ -184,10 +184,10 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li handleRowClick(row)} + onChange={() => handleRowClick(row)} value={JSON.stringify(row)} checked={isChecked(row)} - label='' + label={{getRowLabel(row)}} /> )}
{renderListItems(row, tableHeaders)}
@@ -221,8 +221,8 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li {...getRadioProps({ value: JSON.stringify(row) })} value={JSON.stringify(row)} className={classes.mobileControl} - onClick={() => handleSelectedRadioRow({ selectedValue: row })} - label='' + onChange={() => handleSelectedRadioRow({ selectedValue: row })} + label={{getRowLabel(row)}} /> )}
{renderListItems(row, tableHeaders)}
@@ -301,14 +301,14 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li {enabled ? ( {getRowLabel(row)}} - onChange={() => {}} + onChange={() => toggle(row)} + onClick={(e) => e.stopPropagation()} value={JSON.stringify(row)} checked={isChecked(row)} name={indexedId} @@ -318,9 +318,8 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li className={classes.toggleControl} label={getRowLabel(row)} hideLabel - onChange={() => { - handleSelectedRadioRow({ selectedValue: row }); - }} + onChange={() => handleSelectedRadioRow({ selectedValue: row })} + onClick={(e) => e.stopPropagation()} value={JSON.stringify(row)} checked={isRowSelected(row)} name={indexedId} From 41675dc79f49a6ecf3230f213c689faace09ca71 Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Fri, 29 Aug 2025 10:36:02 +0200 Subject: [PATCH 3/6] cleanup --- src/layout/List/ListComponent.module.css | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/layout/List/ListComponent.module.css b/src/layout/List/ListComponent.module.css index 96abbc9f0a..92e0f22965 100644 --- a/src/layout/List/ListComponent.module.css +++ b/src/layout/List/ListComponent.module.css @@ -1,7 +1,3 @@ -.listTable { - width: 100%; -} - .listTable caption { text-align: left; padding-bottom: var(--ds-size-4); @@ -101,14 +97,14 @@ min-width: unset; } +.mobileControl { + flex-shrink: 0; +} + .listTable tr.readOnlyRow { cursor: default; } -/*.readOnlyRow:hover {*/ -/* background-color: initial;*/ -/*}*/ - .readOnlyCell { background-color: initial; } @@ -125,7 +121,3 @@ flex-direction: column; gap: var(--ds-size-2); } - -.mobileControl { - flex-shrink: 0; -} From 06f12bf68bad974d7e501f8fa5e0057f9fa14819 Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Fri, 29 Aug 2025 11:39:39 +0200 Subject: [PATCH 4/6] using lack of datamodelbindings to show readonly mode --- src/layout/List/ListComponent.test.tsx | 59 ++++++-------------------- src/layout/List/ListComponent.tsx | 31 ++++++++++---- 2 files changed, 36 insertions(+), 54 deletions(-) diff --git a/src/layout/List/ListComponent.test.tsx b/src/layout/List/ListComponent.test.tsx index 02c87fc6f1..f1d1f3f041 100644 --- a/src/layout/List/ListComponent.test.tsx +++ b/src/layout/List/ListComponent.test.tsx @@ -225,9 +225,9 @@ describe('ListComponent', () => { }); }); - describe('readOnly mode', () => { - it('should not render radio buttons when readOnly is true', async () => { - await render({ component: { readOnly: true } }); + describe('auto-readonly mode (no dataModelBindings)', () => { + it('should not render radio buttons when no dataModelBindings exist', async () => { + await render({ component: { dataModelBindings: undefined } }); // Wait for the data to load await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); @@ -236,29 +236,19 @@ describe('ListComponent', () => { expect(screen.queryByRole('radio')).not.toBeInTheDocument(); }); - it('should not render checkboxes when readOnly is true with group bindings', async () => { - await render({ - component: { - readOnly: true, - dataModelBindings: { - Name: { dataType: defaultDataTypeMock, field: 'CountryName' }, - Population: { dataType: defaultDataTypeMock, field: 'CountryPopulation' }, - HighestMountain: { dataType: defaultDataTypeMock, field: 'CountryHighestMountain' }, - group: { dataType: defaultDataTypeMock, field: 'Countries' }, - }, - }, - }); + it('should not render radio buttons when dataModelBindings is empty object', async () => { + await render({ component: { dataModelBindings: {} } }); // Wait for the data to load await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); - // No checkboxes should be present - expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); + // No radio buttons should be present + expect(screen.queryByRole('radio')).not.toBeInTheDocument(); }); - it('should not allow row selection when readOnly is true', async () => { + it('should not allow row selection when no dataModelBindings exist', async () => { const user = userEvent.setup({ delay: null }); - const { formDataMethods } = await render({ component: { readOnly: true } }); + const { formDataMethods } = await render({ component: { dataModelBindings: undefined } }); // Wait for the data to load await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); @@ -271,12 +261,12 @@ describe('ListComponent', () => { expect(formDataMethods.setMultiLeafValues).not.toHaveBeenCalled(); }); - it('should not render controls in mobile view when readOnly is true', async () => { + it('should not render controls in mobile view when no dataModelBindings exist', async () => { jest.spyOn(useDeviceWidths, 'useIsMobile').mockReturnValue(true); await render({ component: { - readOnly: true, + dataModelBindings: undefined, tableHeadersMobile: ['Name', 'FlagLink'], }, }); @@ -288,31 +278,8 @@ describe('ListComponent', () => { expect(screen.queryByRole('radio')).not.toBeInTheDocument(); }); - it('should not render checkbox controls in mobile view when readOnly is true with group bindings', async () => { - jest.spyOn(useDeviceWidths, 'useIsMobile').mockReturnValue(true); - - await render({ - component: { - readOnly: true, - dataModelBindings: { - Name: { dataType: defaultDataTypeMock, field: 'CountryName' }, - Population: { dataType: defaultDataTypeMock, field: 'CountryPopulation' }, - HighestMountain: { dataType: defaultDataTypeMock, field: 'CountryHighestMountain' }, - group: { dataType: defaultDataTypeMock, field: 'Countries' }, - }, - tableHeadersMobile: ['Name', 'FlagLink'], - }, - }); - - // Wait for the data to load - await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); - - // No checkboxes should be present - expect(screen.queryByRole('checkbox')).not.toBeInTheDocument(); - }); - - it('should still display table data when readOnly is true', async () => { - await render({ component: { readOnly: true } }); + it('should still display table data when no dataModelBindings exist', async () => { + await render({ component: { dataModelBindings: undefined } }); // All data should still be visible await waitFor(() => expect(screen.getByText('Norway')).toBeInTheDocument()); diff --git a/src/layout/List/ListComponent.tsx b/src/layout/List/ListComponent.tsx index 9dad799f37..a7fd40bab3 100644 --- a/src/layout/List/ListComponent.tsx +++ b/src/layout/List/ListComponent.tsx @@ -34,6 +34,17 @@ import type { PropsFromGenericComponent } from 'src/layout'; import type { IDataModelBindingsForList } from 'src/layout/List/config.generated'; type Row = Record; +type SelectionMode = 'readonly' | 'single' | 'multiple'; + +function getSelectionMode(bindings: IDataModelBindingsForList): SelectionMode { + const hasValidBindings = Object.keys(bindings).length > 0 && Object.values(bindings).some((b) => b !== undefined); + + if (!hasValidBindings) { + return 'readonly'; + } + + return bindings.group ? 'multiple' : 'single'; +} export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'List'>) => { const isMobile = useIsMobile(); @@ -49,7 +60,6 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li secure, dataListId, required, - readOnly, } = item; const [pageSize, setPageSize] = useState(pagination?.default ?? 0); @@ -67,14 +77,19 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li const { data } = useDataListQuery(filter, dataListId, secure, mapping, queryParameters); const bindings = item.dataModelBindings ?? ({} as IDataModelBindingsForList); + // Determine selection mode based on bindings + const selectionMode = getSelectionMode(bindings); + const readOnly = selectionMode === 'readonly'; + const isMultipleSelection = selectionMode === 'multiple'; + const { formData, setValues } = useDataModelBindings(bindings, DEFAULT_DEBOUNCE_TIMEOUT, 'raw'); - const { toggle, isChecked, enabled } = useSaveObjectToGroup(bindings); + const { toggle, isChecked } = useSaveObjectToGroup(bindings); const tableHeadersToShowInMobile = Object.keys(tableHeaders).filter( (key) => !tableHeadersMobile || tableHeadersMobile.includes(key), ); - const selectedRow = !enabled + const selectedRow = !isMultipleSelection ? (data?.listItems.find((row) => Object.keys(formData).every((key) => row[key] === formData[key])) ?? '') : ''; @@ -87,7 +102,7 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li } function isRowSelected(row: Row): boolean { - if (enabled) { + if (isMultipleSelection) { return isChecked(row); } return JSON.stringify(selectedRow) === JSON.stringify(row); @@ -101,7 +116,7 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li return; } - if (enabled) { + if (isMultipleSelection) { toggle(row); } else { handleSelectedRadioRow({ selectedValue: row }); @@ -156,10 +171,10 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li required, }); - if (isMobile) { + if (isMobile && !readOnly) { return ( - {enabled ? ( + {isMultipleSelection ? (
{description && ( @@ -303,7 +318,7 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li [classes.selectedRowCell]: isRowSelected(row) && !readOnly, })} > - {enabled ? ( + {isMultipleSelection ? ( {getRowLabel(row)}} From c24a58a4c4993f0ca13e62c352069b3541d0783e Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Tue, 2 Sep 2025 16:44:43 +0200 Subject: [PATCH 5/6] cleanup --- src/layout/List/ListComponent.module.css | 29 ++----------- src/layout/List/ListComponent.tsx | 52 +++++++++--------------- 2 files changed, 24 insertions(+), 57 deletions(-) diff --git a/src/layout/List/ListComponent.module.css b/src/layout/List/ListComponent.module.css index 92e0f22965..ab33046807 100644 --- a/src/layout/List/ListComponent.module.css +++ b/src/layout/List/ListComponent.module.css @@ -1,3 +1,7 @@ +.listTable { + width: 100%; +} + .listTable caption { text-align: left; padding-bottom: var(--ds-size-4); @@ -96,28 +100,3 @@ margin-left: auto; min-width: unset; } - -.mobileControl { - flex-shrink: 0; -} - -.listTable tr.readOnlyRow { - cursor: default; -} - -.readOnlyCell { - background-color: initial; -} - -.mobileContent { - flex: 1; - display: flex; - flex-direction: column; - gap: var(--ds-size-4); -} - -.mobileContent div { - display: flex; - flex-direction: column; - gap: var(--ds-size-2); -} diff --git a/src/layout/List/ListComponent.tsx b/src/layout/List/ListComponent.tsx index a7fd40bab3..90cd21c3b7 100644 --- a/src/layout/List/ListComponent.tsx +++ b/src/layout/List/ListComponent.tsx @@ -190,24 +190,19 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li - {data?.listItems.map((row) => ( -
- {!readOnly && ( - handleRowClick(row)} - value={JSON.stringify(row)} - checked={isChecked(row)} - label={{getRowLabel(row)}} - /> - )} -
{renderListItems(row, tableHeaders)}
-
- ))} +
+ {data?.listItems.map((row) => ( + handleRowClick(row)} + value={JSON.stringify(row)} + checked={isChecked(row)} + label={renderListItems(row, tableHeaders)} + /> + ))} +
) : (
@@ -227,21 +222,14 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li )} {data?.listItems.map((row) => ( -
- {!readOnly && ( - handleSelectedRadioRow({ selectedValue: row })} - label={{getRowLabel(row)}} - /> - )} -
{renderListItems(row, tableHeaders)}
-
+ {...getRadioProps({ value: JSON.stringify(row) })} + value={JSON.stringify(row)} + className={cn(classes.mobile, { [classes.selectedRow]: isRowSelected(row) })} + onClick={() => handleSelectedRadioRow({ selectedValue: row })} + label={renderListItems(row, tableHeaders)} + /> ))}
)} From f83f5d6bb13aa309d18e0adc90114cc1ed3309d3 Mon Sep 17 00:00:00 2001 From: Adam Haeger Date: Wed, 3 Sep 2025 08:25:04 +0200 Subject: [PATCH 6/6] nitpick --- src/layout/List/ListComponent.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/layout/List/ListComponent.tsx b/src/layout/List/ListComponent.tsx index 90cd21c3b7..a5e1a163d3 100644 --- a/src/layout/List/ListComponent.tsx +++ b/src/layout/List/ListComponent.tsx @@ -191,9 +191,9 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li
- {data?.listItems.map((row) => ( + {data?.listItems.map((row, idx) => ( handleRowClick(row)} @@ -221,9 +221,9 @@ export const ListComponent = ({ baseComponentId }: PropsFromGenericComponent<'Li )} - {data?.listItems.map((row) => ( + {data?.listItems.map((row, idx) => (