[MM-67456] Allow OptionItem labels to wrap to two lines (#9504)
This commit is contained in:
parent
1757654882
commit
c3f83f9028
5 changed files with 49 additions and 1 deletions
|
|
@ -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',
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -29,6 +29,7 @@ const BaseOption = ({
|
||||||
destructive={isDestructive}
|
destructive={isDestructive}
|
||||||
icon={iconName}
|
icon={iconName}
|
||||||
label={intl.formatMessage(message)}
|
label={intl.formatMessage(message)}
|
||||||
|
labelNumberOfLines={1}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
type='default'
|
type='default'
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -132,6 +132,7 @@ export type OptionItemProps = {
|
||||||
value?: string;
|
value?: string;
|
||||||
onLayout?: (event: LayoutChangeEvent) => void;
|
onLayout?: (event: LayoutChangeEvent) => void;
|
||||||
descriptionNumberOfLines?: number;
|
descriptionNumberOfLines?: number;
|
||||||
|
labelNumberOfLines?: number;
|
||||||
longInfo?: boolean;
|
longInfo?: boolean;
|
||||||
nonDestructiveDescription?: boolean;
|
nonDestructiveDescription?: boolean;
|
||||||
isRadioCheckmark?: boolean;
|
isRadioCheckmark?: boolean;
|
||||||
|
|
@ -155,6 +156,7 @@ const OptionItem = ({
|
||||||
value,
|
value,
|
||||||
onLayout,
|
onLayout,
|
||||||
descriptionNumberOfLines,
|
descriptionNumberOfLines,
|
||||||
|
labelNumberOfLines = 2,
|
||||||
longInfo,
|
longInfo,
|
||||||
nonDestructiveDescription = false,
|
nonDestructiveDescription = false,
|
||||||
isRadioCheckmark = false,
|
isRadioCheckmark = false,
|
||||||
|
|
@ -326,7 +328,7 @@ const OptionItem = ({
|
||||||
<Text
|
<Text
|
||||||
style={labelTextStyle}
|
style={labelTextStyle}
|
||||||
testID={`${testID}.label`}
|
testID={`${testID}.label`}
|
||||||
numberOfLines={1}
|
numberOfLines={labelNumberOfLines}
|
||||||
>
|
>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ describe('OptionItem', () => {
|
||||||
const label = getByText('Test Option');
|
const label = getByText('Test Option');
|
||||||
expect(label).toBeTruthy();
|
expect(label).toBeTruthy();
|
||||||
expect(label).toHaveStyle({fontWeight: '400'});
|
expect(label).toHaveStyle({fontWeight: '400'});
|
||||||
|
expect(label.props.numberOfLines).toBe(2);
|
||||||
|
|
||||||
// No description
|
// No description
|
||||||
expect(queryByTestId('option-item.description')).toBeNull();
|
expect(queryByTestId('option-item.description')).toBeNull();
|
||||||
|
|
@ -65,6 +66,16 @@ describe('OptionItem', () => {
|
||||||
expect(queryByTestId('option-item.arrow.icon')).toBeNull();
|
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', () => {
|
it('renders with description when provided', () => {
|
||||||
const props = getBaseProps();
|
const props = getBaseProps();
|
||||||
props.description = 'Test description';
|
props.description = 'Test description';
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ const BindingOptionItem = ({binding, onPress}: {binding: AppBinding; onPress: (b
|
||||||
return (
|
return (
|
||||||
<OptionItem
|
<OptionItem
|
||||||
label={binding.label || ''}
|
label={binding.label || ''}
|
||||||
|
labelNumberOfLines={1}
|
||||||
icon={binding.icon}
|
icon={binding.icon}
|
||||||
action={handlePress}
|
action={handlePress}
|
||||||
type='default'
|
type='default'
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue