[MM-67456] Allow OptionItem labels to wrap to two lines (#9504)

This commit is contained in:
Guillermo Vayá 2026-02-24 18:17:04 +01:00 committed by GitHub
parent 1757654882
commit c3f83f9028
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 49 additions and 1 deletions

View file

@ -0,0 +1,33 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
import OptionItem from '@components/option_item';
import {renderWithIntlAndTheme} from '@test/intl-test-helper';
import BaseOption from './index';
jest.mock('@components/option_item');
jest.mocked(OptionItem).mockImplementation((props) => React.createElement('OptionItem', props));
describe('BaseOption', () => {
it('should force single line labels', () => {
renderWithIntlAndTheme(
<BaseOption
message={{id: 'test.base_option.label', defaultMessage: 'Option label'}}
iconName='icon-name'
onPress={jest.fn()}
testID='base-option'
/>,
);
expect(jest.mocked(OptionItem)).toHaveBeenCalled();
expect(jest.mocked(OptionItem).mock.calls[0][0]).toEqual(expect.objectContaining({
label: 'Option label',
labelNumberOfLines: 1,
type: 'default',
testID: 'base-option',
}));
});
});

View file

@ -29,6 +29,7 @@ const BaseOption = ({
destructive={isDestructive}
icon={iconName}
label={intl.formatMessage(message)}
labelNumberOfLines={1}
testID={testID}
type='default'
/>

View file

@ -132,6 +132,7 @@ export type OptionItemProps = {
value?: string;
onLayout?: (event: LayoutChangeEvent) => void;
descriptionNumberOfLines?: number;
labelNumberOfLines?: number;
longInfo?: boolean;
nonDestructiveDescription?: boolean;
isRadioCheckmark?: boolean;
@ -155,6 +156,7 @@ const OptionItem = ({
value,
onLayout,
descriptionNumberOfLines,
labelNumberOfLines = 2,
longInfo,
nonDestructiveDescription = false,
isRadioCheckmark = false,
@ -326,7 +328,7 @@ const OptionItem = ({
<Text
style={labelTextStyle}
testID={`${testID}.label`}
numberOfLines={1}
numberOfLines={labelNumberOfLines}
>
{label}
</Text>

View file

@ -40,6 +40,7 @@ describe('OptionItem', () => {
const label = getByText('Test Option');
expect(label).toBeTruthy();
expect(label).toHaveStyle({fontWeight: '400'});
expect(label.props.numberOfLines).toBe(2);
// No description
expect(queryByTestId('option-item.description')).toBeNull();
@ -65,6 +66,16 @@ describe('OptionItem', () => {
expect(queryByTestId('option-item.arrow.icon')).toBeNull();
});
it('respects custom label number of lines', () => {
const props = getBaseProps();
props.labelNumberOfLines = 1;
const {getByText} = renderWithIntlAndTheme(<OptionItem {...props}/>);
const label = getByText('Test Option');
expect(label.props.numberOfLines).toBe(1);
});
it('renders with description when provided', () => {
const props = getBaseProps();
props.description = 'Test description';

View file

@ -77,6 +77,7 @@ const BindingOptionItem = ({binding, onPress}: {binding: AppBinding; onPress: (b
return (
<OptionItem
label={binding.label || ''}
labelNumberOfLines={1}
icon={binding.icon}
action={handlePress}
type='default'