This commit is contained in:
mgabdev
2020-03-06 23:53:28 -05:00
parent da3d0c3462
commit 557c6470f5
41 changed files with 1181 additions and 1106 deletions

View File

@@ -10,6 +10,7 @@ export default class ComposeExtraButton extends PureComponent {
onClick: PropTypes.func,
icon: PropTypes.string,
small: PropTypes.bool,
active: PropTypes.bool,
}
state = {
@@ -25,7 +26,15 @@ export default class ComposeExtraButton extends PureComponent {
}
render() {
const { title, disabled, onClick, icon, children, small } = this.props
const {
title,
disabled,
onClick,
icon,
children,
small,
active
} = this.props
const { hovering } = this.state
const containerClasses = cx({
@@ -39,8 +48,10 @@ export default class ComposeExtraButton extends PureComponent {
circle: 1,
flexRow: 1,
cursorPointer: 1,
backgroundSubtle: !hovering,
backgroundSubtle2: hovering,
outlineNone: 1,
backgroundSubtle: !hovering && !active,
backgroundSubtle2: hovering && !active,
backgroundColorBrandLight: active,
paddingVertical10PX: !small,
paddingHorizontal10PX: !small,
paddingVertical5PX: small,
@@ -54,10 +65,16 @@ export default class ComposeExtraButton extends PureComponent {
lineHeight15: 1,
fontSize12PX: 1,
fontWeightMedium: 1,
colorSecondary: 1,
colorSecondary: !active,
colorWhite: active,
displayNone: !hovering,
})
const iconClasses = cx({
fillColorSecondary: !active,
fillColorWhite: active,
})
const iconSize = !!small ? '12px' : '18px'
return (
@@ -70,9 +87,9 @@ export default class ComposeExtraButton extends PureComponent {
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
<Icon id={icon} width={iconSize} height={iconSize} className={_s.fillColorSecondary} />
<Icon id={icon} width={iconSize} height={iconSize} className={iconClasses} />
{
!small &&
(!small && !!title) &&
<span className={titleClasses}>
{title}
</span>

View File

@@ -11,9 +11,9 @@ import PollButton from '../../components/poll_button';
import UploadButton from '../../components/upload_button';
import SpoilerButton from '../../components/spoiler_button';
import PrivacyDropdown from '../../components/privacy_dropdown';
import EmojiPickerButton from '../../components/emoji_picker_button'
import EmojiPickerDropdown from '../../containers/emoji_picker_dropdown_container';
import PollFormContainer from '../../containers/poll_form_container';
import WarningContainer from '../../containers/warning_container';
import SchedulePostDropdown from '../../components/schedule_post_dropdown';
import QuotedStatusPreviewContainer from '../../containers/quoted_status_preview_container';
import Icon from '../../../../components/icon';
@@ -228,7 +228,8 @@ class ComposeForm extends ImmutablePureComponent {
isModalOpen,
quoteOfId,
edit,
scheduledAt
scheduledAt,
spoiler
} = this.props
const condensed = shouldCondense && !this.props.text && !this.state.composeFocused;
const disabled = this.props.isSubmitting;
@@ -258,6 +259,15 @@ class ComposeForm extends ImmutablePureComponent {
marginTop5PX: shouldCondense,
})
const contentWarningClasses = cx({
default: 1,
paddingTop5PX: 1,
paddingBottom10PX: 1,
borderBottom1PX: 1,
borderColorSecondary: 1,
displayNone: !spoiler
})
const avatarSize = shouldCondense ? 28 : 46
return (
@@ -265,34 +275,32 @@ class ComposeForm extends ImmutablePureComponent {
<div className={avatarContainerClasses}>
<Avatar account={account} size={avatarSize} />
</div>
<div
className={containerClasses}
ref={this.setForm}
onClick={this.handleClick}
>
{ /* <WarningContainer /> */}
{ /* !shouldCondense && <ReplyIndicatorContainer /> */}
{ /*
<div className={`spoiler-input ${this.props.spoiler ? 'spoiler-input--visible' : ''}`}>
<AutosuggestTextbox
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
value={this.props.spoilerText}
onChange={this.handleChangeSpoilerText}
onKeyDown={this.handleKeyDown}
disabled={!this.props.spoiler}
ref={this.setSpoilerText}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSpoilerSuggestionSelected}
searchTokens={[':']}
id='cw-spoiler-input'
className='spoiler-input__input'
/>
</div>
*/ }
<div className={contentWarningClasses}>
<AutosuggestTextbox
placeholder={intl.formatMessage(messages.spoiler_placeholder)}
value={this.props.spoilerText}
onChange={this.handleChangeSpoilerText}
onKeyDown={this.handleKeyDown}
disabled={!this.props.spoiler}
ref={this.setSpoilerText}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSpoilerSuggestionSelected}
searchTokens={[':']}
id='cw-spoiler-input'
className='spoiler-input__input'
/>
</div>
{ /*
<div className='emoji-picker-wrapper'>
@@ -341,6 +349,7 @@ class ComposeForm extends ImmutablePureComponent {
}
<SpoilerButton small={shouldCondense} />
<SchedulePostDropdown small={shouldCondense} position={isModalOpen ? 'top' : undefined} />
<EmojiPickerButton />
</div>
<CharacterCounter max={maxPostCharacterCount} text={text} small={shouldCondense} />
{

View File

@@ -0,0 +1,56 @@
import { addPoll, removePoll } from '../../../actions/compose'
import ComposeExtraButton from './compose_extra_button'
const mapStateToProps = state => ({
// unavailable: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0),
// active: state.getIn(['compose', 'poll']) !== null,
})
const mapDispatchToProps = dispatch => ({
onClick() {
dispatch((_, getState) => {
if (getState().getIn(['compose', 'poll'])) {
dispatch(removePoll())
} else {
dispatch(addPoll())
}
})
},
})
export default
@connect(mapStateToProps, mapDispatchToProps)
class EmojiPickerButton extends PureComponent {
static propTypes = {
disabled: PropTypes.bool,
unavailable: PropTypes.bool,
active: PropTypes.bool,
onClick: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
small: PropTypes.bool,
}
handleClick = () => {
this.props.onClick()
}
render() {
const { active, unavailable, disabled, small } = this.props
if (unavailable) return null
return (
<ComposeExtraButton
disabled={disabled}
onClick={this.handleClick}
icon='happy'
small={small}
active={active}
/>
)
}
}

View File

@@ -1,31 +1,31 @@
import { defineMessages, injectIntl } from 'react-intl';
import { addPoll, removePoll } from '../../../actions/compose';
import { defineMessages, injectIntl } from 'react-intl'
import { addPoll, removePoll } from '../../../actions/compose'
import ComposeExtraButton from './compose_extra_button'
const messages = defineMessages({
add_poll: { id: 'poll_button.add_poll', defaultMessage: 'Add poll' },
title: { id: 'poll_button.title', defaultMessage: 'Poll' },
remove_poll: { id: 'poll_button.remove_poll', defaultMessage: 'Remove poll' },
});
})
const mapStateToProps = state => ({
unavailable: state.getIn(['compose', 'is_uploading']) || (state.getIn(['compose', 'media_attachments']).size > 0),
active: state.getIn(['compose', 'poll']) !== null,
});
})
const mapDispatchToProps = dispatch => ({
onClick() {
dispatch((_, getState) => {
if (getState().getIn(['compose', 'poll'])) {
dispatch(removePoll());
dispatch(removePoll())
} else {
dispatch(addPoll());
dispatch(addPoll())
}
});
})
},
});
})
export default
@connect(mapStateToProps, mapDispatchToProps)
@@ -39,16 +39,16 @@ class PollButton extends PureComponent {
onClick: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
small: PropTypes.bool,
};
}
handleClick = () => {
this.props.onClick();
this.props.onClick()
}
render() {
const { intl, active, unavailable, disabled, small } = this.props;
const { intl, active, unavailable, disabled, small } = this.props
if (unavailable) return null;
if (unavailable) return null
return (
<ComposeExtraButton
@@ -57,6 +57,7 @@ class PollButton extends PureComponent {
onClick={this.handleClick}
icon='poll'
small={small}
active={active}
/>
)
}

View File

@@ -0,0 +1,247 @@
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import classNames from 'classnames/bind'
import { defineMessages, injectIntl } from 'react-intl'
import Button from '../../../components/button'
import Text from '../../../components/text'
import Select from '../../../components/select'
import AutosuggestTextbox from '../../../components/autosuggest_textbox'
const cx = classNames.bind(_s)
const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
})
@injectIntl
class PollFormOption extends ImmutablePureComponent {
static propTypes = {
title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
isPollMultiple: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onToggleMultiple: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleOptionTitleChange = e => {
this.props.onChange(this.props.index, e.target.value);
};
handleOptionRemove = () => {
this.props.onRemove(this.props.index);
};
handleToggleMultiple = e => {
this.props.onToggleMultiple();
e.preventDefault();
e.stopPropagation();
};
onSuggestionsClearRequested = () => {
this.props.onClearSuggestions();
}
onSuggestionsFetchRequested = (token) => {
this.props.onFetchSuggestions(token);
}
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
}
render() {
const { isPollMultiple, title, index, intl } = this.props;
const toggleClasses = cx({
default: 1,
paddingHorizontal10PX: 1,
paddingVertical10PX: 1,
borderColorSecondary: 1,
border1PX: 1,
outlineNone: 1,
marginRight10PX: 1,
circle: !isPollMultiple,
})
return (
<li className={[_s.default, _s.flexRow, _s.marginBottom10PX].join(' ')}>
<label className={[_s.default, _s.flexRow, _s.flexGrow1, _s.alignItemsCenter].join(' ')}>
<span
className={toggleClasses}
onClick={this.handleToggleMultiple}
role='button'
tabIndex='0'
/>
<AutosuggestTextbox
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
maxLength={25}
value={title}
onChange={this.handleOptionTitleChange}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
/>
</label>
<Button
narrow
circle
backgroundColor='none'
className={[_s.marginLeft5PX, _s.justifyContentCenter].join(' ')}
icon='close'
iconWidth='8px'
iconHeight='8px'
iconClassName={_s.fillColorSecondary}
disabled={index <= 1}
title={intl.formatMessage(messages.remove_option)}
onClick={this.handleOptionRemove}
/>
</li>
);
}
}
export default
@injectIntl
class PollForm extends ImmutablePureComponent {
static propTypes = {
options: ImmutablePropTypes.list,
expiresIn: PropTypes.number,
isMultiple: PropTypes.bool,
onChangeOption: PropTypes.func.isRequired,
onAddOption: PropTypes.func.isRequired,
onRemoveOption: PropTypes.func.isRequired,
onChangeSettings: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleAddOption = () => {
this.props.onAddOption('');
};
handleSelectDuration = e => {
this.props.onChangeSettings(e.target.value, this.props.isMultiple);
};
handleToggleMultiple = () => {
this.props.onChangeSettings(this.props.expiresIn, !this.props.isMultiple);
};
render() {
const {
options,
expiresIn,
isMultiple,
onChangeOption,
onRemoveOption,
intl,
...otherProps
} = this.props;
if (!options) return null
return (
<div className={[_s.default, _s.paddingHorizontal10PX, _s.paddingVertical10PX, _s.borderColorSecondary, _s.border1PX, _s.radiusSmall].join(' ')}>
<ul className={[_s.default, _s.listStyleNone].join(' ')}>
{
options.map((title, i) => (
<PollFormOption
title={title}
key={`poll-form-option-${i}`}
index={i}
onChange={onChangeOption}
onRemove={onRemoveOption}
isPollMultiple={isMultiple}
onToggleMultiple={this.handleToggleMultiple}
{...otherProps}
/>
))
}
</ul>
<div className={[_s.default, _s.flexRow].join(' ')}>
{
options.size < 4 && (
<Button
outline
backgroundColor='none'
color='brand'
className={[_s.alignItemsCenter, _s.marginRight10PX].join(' ')}
onClick={this.handleAddOption}
icon='add'
iconWidth='14px'
iconHeight='14px'
iconClassName={[_s.fillColorBrand, _s.marginRight5PX].join(' ')}
>
<Text color='brand'>
{intl.formatMessage(messages.add_option)}
</Text>
</Button>
)
}
<div className={[_s.default, _s.flexGrow1].join(' ')}>
<Select
value={expiresIn}
onChange={this.handleSelectDuration}
options={[
{
value: 300,
title: intl.formatMessage(messages.minutes, { number: 5 }),
},
{
value: 1800,
title: intl.formatMessage(messages.minutes, { number: 30 }),
},
{
value: 3600,
title: intl.formatMessage(messages.hours, { number: 1 }),
},
{
value: 21600,
title: intl.formatMessage(messages.hours, { number: 6 }),
},
{
value: 86400,
title: intl.formatMessage(messages.days, { number: 1 }),
},
{
value: 259200,
title: intl.formatMessage(messages.days, { number: 3 }),
},
{
value: 604800,
title: intl.formatMessage(messages.days, { number: 7 }),
},
]}
/>
</div>
</div>
</div>
)
}
}

View File

@@ -1 +0,0 @@
export { default } from './poll_form'

View File

@@ -1,161 +0,0 @@
import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import IconButton from '../../../../components/icon_button';
import Icon from '../../../../components/icon';
import AutosuggestTextbox from '../../../../components/autosuggest_textbox';
const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Choice {number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add a choice' },
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this choice' },
poll_duration: { id: 'compose_form.poll.duration', defaultMessage: 'Poll duration' },
minutes: { id: 'intervals.full.minutes', defaultMessage: '{number, plural, one {# minute} other {# minutes}}' },
hours: { id: 'intervals.full.hours', defaultMessage: '{number, plural, one {# hour} other {# hours}}' },
days: { id: 'intervals.full.days', defaultMessage: '{number, plural, one {# day} other {# days}}' },
});
@injectIntl
class Option extends ImmutablePureComponent {
static propTypes = {
title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
isPollMultiple: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onToggleMultiple: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleOptionTitleChange = e => {
this.props.onChange(this.props.index, e.target.value);
};
handleOptionRemove = () => {
this.props.onRemove(this.props.index);
};
handleToggleMultiple = e => {
this.props.onToggleMultiple();
e.preventDefault();
e.stopPropagation();
};
onSuggestionsClearRequested = () => {
this.props.onClearSuggestions();
}
onSuggestionsFetchRequested = (token) => {
this.props.onFetchSuggestions(token);
}
onSuggestionSelected = (tokenStart, token, value) => {
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
}
render () {
const { isPollMultiple, title, index, intl } = this.props;
return (
<li>
<label className='poll__text editable'>
<span
className={classNames('poll__input', { checkbox: isPollMultiple })}
onClick={this.handleToggleMultiple}
role='button'
tabIndex='0'
/>
<AutosuggestTextbox
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
maxLength={25}
value={title}
onChange={this.handleOptionTitleChange}
suggestions={this.props.suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
/>
</label>
<div className='poll__cancel'>
<IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' onClick={this.handleOptionRemove} />
</div>
</li>
);
}
}
export default
@injectIntl
class PollForm extends ImmutablePureComponent {
static propTypes = {
options: ImmutablePropTypes.list,
expiresIn: PropTypes.number,
isMultiple: PropTypes.bool,
onChangeOption: PropTypes.func.isRequired,
onAddOption: PropTypes.func.isRequired,
onRemoveOption: PropTypes.func.isRequired,
onChangeSettings: PropTypes.func.isRequired,
suggestions: ImmutablePropTypes.list,
onClearSuggestions: PropTypes.func.isRequired,
onFetchSuggestions: PropTypes.func.isRequired,
onSuggestionSelected: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
handleAddOption = () => {
this.props.onAddOption('');
};
handleSelectDuration = e => {
this.props.onChangeSettings(e.target.value, this.props.isMultiple);
};
handleToggleMultiple = () => {
this.props.onChangeSettings(this.props.expiresIn, !this.props.isMultiple);
};
render () {
const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
if (!options) {
return null;
}
return (
<div className='compose-form__poll-wrapper'>
<ul>
{options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} {...other} />)}
</ul>
<div className='poll__footer'>
{options.size < 4 && (
<button className='button button--secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
)}
<select value={expiresIn} onChange={this.handleSelectDuration}>
<option value={300}>{intl.formatMessage(messages.minutes, { number: 5 })}</option>
<option value={1800}>{intl.formatMessage(messages.minutes, { number: 30 })}</option>
<option value={3600}>{intl.formatMessage(messages.hours, { number: 1 })}</option>
<option value={21600}>{intl.formatMessage(messages.hours, { number: 6 })}</option>
<option value={86400}>{intl.formatMessage(messages.days, { number: 1 })}</option>
<option value={259200}>{intl.formatMessage(messages.days, { number: 3 })}</option>
<option value={604800}>{intl.formatMessage(messages.days, { number: 7 })}</option>
</select>
</div>
</div>
);
}
}

View File

@@ -1,10 +0,0 @@
.poll-list-item {
display: flex;
align-items: center;
&__text {
flex: 0 0 auto;
width: calc(100% - (23px + 6px));
margin-right: 6px;
}
}

View File

@@ -45,6 +45,7 @@ class SpoilerButton extends PureComponent {
icon='warning'
onClick={this.handleClick}
small={small}
active={active}
/>
)
}

View File

@@ -2,9 +2,8 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { defineMessages, injectIntl } from 'react-intl'
import classNames from 'classnames'
import spring from 'react-motion/lib/spring'
import Motion from '../../../ui/util/optional_motion'
import Button from '../../../../components/button'
import Image from '../../../../components/image'
const messages = defineMessages({
description: { id: 'upload_form.description', defaultMessage: 'Describe for the visually impaired' },
@@ -72,7 +71,10 @@ class Upload extends ImmutablePureComponent {
handleInputBlur = () => {
const { dirtyDescription } = this.state
this.setState({ focused: false, dirtyDescription: null })
this.setState({
focused: false,
dirtyDescription: null,
})
if (dirtyDescription !== null) {
this.props.onDescriptionChange(this.props.media.get('id'), dirtyDescription)
@@ -90,37 +92,33 @@ class Upload extends ImmutablePureComponent {
return (
<div className='compose-form-upload' tabIndex='0' onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} onClick={this.handleClick} role='button'>
<Motion defaultStyle={{ scale: 0.8 }} style={{ scale: spring(1, { stiffness: 180, damping: 12 }) }}>
{({ scale }) => (
<div className='compose-form__upload-thumbnail' style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className={classNames('compose-form__upload__actions', { active })}>
<Button
title={intl.formatMessage(messages.delete)}
onClick={this.handleUndoClick}
icon='cancel'
/>
</div>
<div className='compose-form__upload-thumbnail' style={{ backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className={classNames('compose-form__upload__actions', { active })}>
<Button
title={intl.formatMessage(messages.delete)}
onClick={this.handleUndoClick}
icon='cancel'
/>
</div>
<div className={classNames('compose-form-upload__description', { active })}>
<label>
<span style={{ display: 'none' }}>
{intl.formatMessage(messages.description)}
</span>
<div className={classNames('compose-form-upload__description', { active })}>
<label>
<span style={{ display: 'none' }}>
{intl.formatMessage(messages.description)}
</span>
<textarea
placeholder={intl.formatMessage(messages.description)}
value={description}
maxLength={420}
onFocus={this.handleInputFocus}
onChange={this.handleInputChange}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
/>
</label>
</div>
</div>
)}
</Motion>
<textarea
placeholder={intl.formatMessage(messages.description)}
value={description}
maxLength={420}
onFocus={this.handleInputFocus}
onChange={this.handleInputChange}
onBlur={this.handleInputBlur}
onKeyDown={this.handleKeyDown}
/>
</label>
</div>
</div>
</div>
)
}

View File

@@ -1 +0,0 @@
export { default } from './warning'

View File

@@ -1,24 +0,0 @@
import Motion from '../../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
export default class Warning extends PureComponent {
static propTypes = {
message: PropTypes.node.isRequired,
};
render () {
const { message } = this.props;
return (
<Motion defaultStyle={{ opacity: 0, scaleX: 0.85, scaleY: 0.75 }} style={{ opacity: spring(1, { damping: 35, stiffness: 400 }), scaleX: spring(1, { damping: 35, stiffness: 400 }), scaleY: spring(1, { damping: 35, stiffness: 400 }) }}>
{({ opacity, scaleX, scaleY }) => (
<div className='compose-form-warning' style={{ opacity: opacity, transform: `scale(${scaleX}, ${scaleY})` }}>
{message}
</div>
)}
</Motion>
);
}
}

View File

@@ -1,33 +0,0 @@
.compose-form-warning {
color: $inverted-text-color;
margin-bottom: 10px;
background: $ui-primary-color;
box-shadow: 0 2px 6px rgba($base-shadow-color, 0.3);
padding: 8px 10px;
border-radius: 4px;
@include text-sizing(13px, 400);
strong {
color: $inverted-text-color;
font-weight: 500;
@each $lang in $cjk-langs {
&:lang(#{$lang}) {
font-weight: 700;
}
}
}
a {
color: $lighter-text-color;
font-weight: 500;
text-decoration: underline;
&:hover,
&:active,
&:focus {
text-decoration: none;
}
}
}