Skip to content

Commit 0cb3fac

Browse files
montezumekodiakhq[bot]
authored andcommitted
feat(rich-text-input): add expand icon (#1095)
* feat(rich-text-input): add expand icon * chore: fixup * chore: fix copy paste
1 parent 9d938dc commit 0cb3fac

File tree

7 files changed

+90
-19
lines changed

7 files changed

+90
-19
lines changed

src/components/inputs/rich-text-input/editor.js

+4
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ const Editor = props => {
6464
isDisabled={props.isDisabled}
6565
hasWarning={props.hasWarning}
6666
isReadOnly={props.isReadOnly}
67+
showExpandIcon={props.showExpandIcon}
68+
onClickExpand={props.onClickExpand}
6769
editor={props.editor}
6870
containerStyles={containerStyles}
6971
>
@@ -116,6 +118,8 @@ const renderEditor = (props, editor, next) => {
116118
isFocused: props.options.isFocused,
117119
horizontalConstraint: props.options.horizontalConstraint,
118120
defaultExpandMultilineText: props.options.defaultExpandMultilineText,
121+
showExpandIcon: props.options.showExpandIcon,
122+
onClickExpand: props.options.onClickExpand,
119123
hasError: props.options.hasError,
120124
hasWarning: props.options.hasWarning,
121125
isReadOnly: props.readOnly,

src/components/inputs/rich-text-input/rich-text-input.js

+5
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ class RichTextInput extends React.PureComponent {
8484
hasWarning: this.props.hasWarning,
8585
hasError: this.props.hasError,
8686
placeholder: this.props.placeholder,
87+
showExpandIcon: this.props.showExpandIcon,
88+
onClickExpand: this.props.onClickExpand,
8789
}}
8890
onChange={this.onValueChange}
8991
plugins={plugins}
@@ -97,6 +99,7 @@ RichTextInput.defaultProps = {
9799
defaultExpandMultilineText: false,
98100
horizontalConstraint: 'scale',
99101
placeholder: '',
102+
showExpandIcon: false,
100103
};
101104

102105
RichTextInput.displayName = 'RichTextInput';
@@ -121,6 +124,8 @@ RichTextInput.propTypes = {
121124
onFocus: PropTypes.func,
122125
onBlur: PropTypes.func,
123126
value: Types.value.isRequired,
127+
showExpandIcon: PropTypes.bool.isRequired,
128+
onClickExpand: requiredIf(PropTypes.func, props => props.showExpandIcon),
124129
};
125130

126131
export default RichTextInput;

src/components/inputs/rich-text-input/rich-text-input.story.js

+39-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
/* eslint-disable react/prop-types, react/display-name */
12
import React from 'react';
3+
import { Value } from 'react-value';
24
import { storiesOf } from '@storybook/react';
35
import { withKnobs, boolean, text } from '@storybook/addon-knobs/react';
46
import { action } from '@storybook/addon-actions';
@@ -7,52 +9,70 @@ import Spacings from '../../spacings';
79
import Section from '../../../../.storybook/decorators/section';
810
import RichTextInput from './rich-text-input';
911
import Readme from './README.md';
10-
import TextInput from '../text-input';
1112

1213
// Create our initial value...
1314

1415
const initialValue = RichTextInput.deserialize('');
16+
17+
const Input = props => {
18+
return (
19+
<Value
20+
defaultValue={initialValue}
21+
render={(value, onChange) => (
22+
<RichTextInput
23+
id={props.id}
24+
name={props.name}
25+
key={`rich-text-input-${props.defaultExpandMultilineText}`}
26+
onChange={event => onChange(event.target.value)}
27+
value={value}
28+
onBlur={props.onBlur}
29+
onFocus={props.onFocus}
30+
defaultExpandMultilineText={props.defaultExpandMultilineText}
31+
placeholder={props.placeholder}
32+
onClickExpand={props.onClickExpand}
33+
showExpandIcon={props.showExpandIcon}
34+
hasError={props.hasError}
35+
hasWarning={props.hasWarning}
36+
isDisabled={props.isDisabled}
37+
isReadOnly={props.isReadOnly}
38+
/>
39+
)}
40+
/>
41+
);
42+
};
43+
1544
storiesOf('Components|Inputs', module)
1645
.addDecorator(withKnobs)
1746
.addDecorator(withReadme(Readme))
1847
.add('RichTextInput', () => {
19-
const [value, setValue] = React.useState(initialValue);
20-
21-
const onChange = React.useCallback(event => setValue(event.target.value), [
22-
setValue,
23-
]);
24-
25-
const [textValue, setTextValue] = React.useState('');
48+
const onClickExpand = React.useCallback(() => {
49+
// eslint-disable-next-line no-alert
50+
alert('Expand');
51+
}, []);
2652

2753
const onBlur = React.useCallback(action('onBlur'), []);
2854
const onFocus = React.useCallback(action('onFocus'), []);
2955

3056
return (
3157
<Section>
3258
<Spacings.Stack scale="l">
33-
<RichTextInput
59+
<Input
3460
id={text('id', 'test-id')}
3561
name={text('name', 'test-name')}
36-
onChange={onChange}
62+
onBlur={onBlur}
63+
onFocus={onFocus}
3764
defaultExpandMultilineText={boolean(
3865
'defaultExpandMultilineText',
3966
false
4067
)}
41-
value={value}
42-
onBlur={onBlur}
43-
onFocus={onFocus}
4468
placeholder={text('placeholder', 'Placeholder')}
69+
showExpandIcon={boolean('showExpandIcon', false)}
70+
onClickExpand={onClickExpand}
4571
hasError={boolean('hasError', false)}
4672
hasWarning={boolean('hasWarning', false)}
4773
isDisabled={boolean('isDisabled', false)}
4874
isReadOnly={boolean('isReadOnly', false)}
4975
/>
50-
<TextInput
51-
id="text-input"
52-
name="text-input"
53-
onChange={evt => setTextValue(evt.target.value)}
54-
value={textValue}
55-
/>
5676
</Spacings.Stack>
5777
</Section>
5878
);

src/components/inputs/rich-text-input/rich-text-input.visualroute.js

+9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ const DefaultRoute = () => (
111111
horizontalConstraint="scale"
112112
/>
113113
</Spec>
114+
<Spec label="with expand button" omitPropsList>
115+
<RichTextInput
116+
onChange={() => {}}
117+
value={minimalValue}
118+
showExpandIcon={true}
119+
onClickExpand={() => {}}
120+
horizontalConstraint="scale"
121+
/>
122+
</Spec>
114123
</Suite>
115124
);
116125

src/components/internals/rich-text-body/icons/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import OrigSuperscriptIcon from './svg/superscript.react.svg';
1010
import OrigSubscriptIcon from './svg/subscript.react.svg';
1111
import OrigRedoIcon from './svg/redo.react.svg';
1212
import OrigUndoIcon from './svg/undo.react.svg';
13+
import OrigExpandIcon from './svg/expand.react.svg';
1314

1415
export const BoldIcon = createStyledIcon(OrigBoldIcon, 'BoldIcon');
16+
export const ExpandIcon = createStyledIcon(OrigExpandIcon, 'ExpandIcon');
1517
export const ItalicIcon = createStyledIcon(OrigItalicIcon, 'ItalicIcon');
1618
export const MoreStylesIcon = createStyledIcon(
1719
OrigMoreStylesIcon,

src/components/internals/rich-text-body/messages.js

+10
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ export default defineMessages({
1111
description: 'Title for the bold tooltip',
1212
defaultMessage: 'Bold',
1313
},
14+
expandButtonLabel: {
15+
id: 'UIKit.RichTextBody.expandButtonLabel',
16+
description: 'Label for the expand button',
17+
defaultMessage: 'Expand',
18+
},
19+
expandTooltipTitle: {
20+
id: 'UIKit.RichTextBody.expandTooltipTitle',
21+
description: 'Title for the expand tooltip',
22+
defaultMessage: 'Expand',
23+
},
1424
italicButtonLabel: {
1525
id: 'UIKit.RichTextBody.italicButtonLabel',
1626
description: 'Label for the italic button',

src/components/internals/rich-text-body/rich-text-body.js

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import { useIntl } from 'react-intl';
4+
import requiredIf from 'react-required-if';
45
import { css } from '@emotion/core';
56
import Tooltip from '../../tooltip';
67
import {
@@ -12,6 +13,7 @@ import {
1213
} from './rich-text-body.styles';
1314
import {
1415
BoldIcon,
16+
ExpandIcon,
1517
ItalicIcon,
1618
UnorderedListIcon,
1719
OrderedListIcon,
@@ -316,6 +318,23 @@ const RichTextEditorBody = React.forwardRef((props, ref) => {
316318
<RedoIcon size="medium" />
317319
</Button>
318320
</Tooltip>
321+
{props.showExpandIcon && (
322+
<React.Fragment>
323+
<Divider />
324+
<Tooltip
325+
title={intl.formatMessage(messages.expandTooltipTitle)}
326+
placement="bottom-end"
327+
>
328+
<Button
329+
isActive={false}
330+
label={intl.formatMessage(messages.expandButtonLabel)}
331+
onClick={props.onClickExpand}
332+
>
333+
<ExpandIcon size="medium" />
334+
</Button>
335+
</Tooltip>
336+
</React.Fragment>
337+
)}
319338
</ToolbarRightControls>
320339
</Toolbar>
321340
<div style={props.containerStyles}>
@@ -344,6 +363,8 @@ RichTextEditorBody.propTypes = {
344363
editor: PropTypes.any,
345364
children: PropTypes.node,
346365
containerStyles: PropTypes.any,
366+
showExpandIcon: PropTypes.bool.isRequired,
367+
onClickExpand: requiredIf(PropTypes.func, props => props.showExpandIcon),
347368
};
348369

349370
export default RichTextEditorBody;

0 commit comments

Comments
 (0)