-// Package imports.
-import classNames from 'classnames';
-import PropTypes from 'prop-types';
import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
-// This just renders a FontAwesome icon.
-export default function Icon ({
- className,
- fullwidth,
- icon,
-}) {
- const computedClass = classNames('icon', 'fa', { 'fa-fw': fullwidth }, `fa-${icon}`, className);
- return icon ? (
- <span
- aria-hidden='true'
- className={computedClass}
- />
- ) : null;
-}
+export default class Icon extends React.PureComponent {
-// Props.
-Icon.propTypes = {
- className: PropTypes.string,
- fullwidth: PropTypes.bool,
- icon: PropTypes.string,
-};
+ static propTypes = {
+ id: PropTypes.string.isRequired,
+ className: PropTypes.string,
+ fixedWidth: PropTypes.bool,
+ };
+
+ render () {
+ const { id, className, fixedWidth, ...other } = this.props;
+
+ return (
+ <i role='img' className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })} {...other} />
+ );
+ }
+
+}
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';
import classNames from 'classnames';
+import Icon from 'flavours/glitch/components/icon';
export default class IconButton extends React.PureComponent {
tabIndex={tabIndex}
disabled={disabled}
>
- <i className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
+ <Icon id={icon} fixedWidth aria-hidden='true' />
</button>
);
}
tabIndex={tabIndex}
disabled={disabled}
>
- <i style={{ transform: `rotate(${rotate}deg)` }} className={`fa fa-fw fa-${icon}`} aria-hidden='true' />
+ <Icon id={icon} style={{ transform: `rotate(${rotate}deg)` }} fixedWidth aria-hidden='true' />
{this.props.label}
</button>)
}
const IconWithBadge = ({ id, count, className }) => (
<i className='icon-with-badge'>
- <Icon icon={id} fixedWidth className={className} />
+ <Icon id={id} fixedWidth className={className} />
{count > 0 && <i className='icon-with-badge__badge'>{formatNumber(count)}</i>}
</i>
);
if (account.get('acct') !== account.get('username')) {
extraInfo = (
<div className='account__disclaimer'>
- <Icon icon='info-circle' fixedWidth /> <FormattedMessage
+ <Icon id='info-circle' fixedWidth /> <FormattedMessage
id='account.disclaimer_full'
defaultMessage="Information below may reflect the user's profile incompletely."
/>
}
if (account.get('locked')) {
- lockedIcon = <Icon icon='lock' title={intl.formatMessage(messages.account_locked)} />;
+ lockedIcon = <Icon id='lock' title={intl.formatMessage(messages.account_locked)} />;
}
if (account.get('id') !== me) {
<div className='account__header__tabs__buttons'>
{actionBtn}
- <DropdownMenuContainer items={menu} icon='ellipsis-v' size={24} direction='right' />
+ <DropdownMenuContainer items={menu} id='ellipsis-v' size={24} direction='right' />
</div>
</div>
<div className='video-player__controls active'>
<div className='video-player__buttons-bar'>
<div className='video-player__buttons left'>
- <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon icon={paused ? 'play' : 'pause'} fixedWidth /></button>
- <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon icon={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
+ <button type='button' aria-label={intl.formatMessage(paused ? messages.play : messages.pause)} onClick={this.togglePlay}><Icon id={paused ? 'play' : 'pause'} fixedWidth /></button>
+ <button type='button' aria-label={intl.formatMessage(muted ? messages.unmute : messages.mute)} onClick={this.toggleMute}><Icon id={muted ? 'volume-off' : 'volume-up'} fixedWidth /></button>
<div className='video-player__volume' onMouseDown={this.handleVolumeMouseDown} ref={this.setVolumeRef}>
<div className='video-player__volume__current' style={{ width: `${volumeWidth}px` }} />
if (on !== null && typeof on !== 'undefined') {
prefix = <Toggle checked={on} onChange={this.handleClick} />;
} else if (icon) {
- prefix = <Icon className='icon' fullwidth icon={icon} />
+ prefix = <Icon className='icon' fixedWidth id={icon} />
}
return (
aria-label={intl.formatMessage(messages.start)}
title={intl.formatMessage(messages.start)}
to='/getting-started'
- ><Icon icon='asterisk' /></Link>
+ ><Icon id='asterisk' /></Link>
{renderForColumn('HOME', (
<Link
aria-label={intl.formatMessage(messages.home_timeline)}
title={intl.formatMessage(messages.home_timeline)}
to='/timelines/home'
- ><Icon icon='home' /></Link>
+ ><Icon id='home' /></Link>
))}
{renderForColumn('NOTIFICATIONS', (
<Link
to='/notifications'
>
<span className='icon-badge-wrapper'>
- <Icon icon='bell' />
+ <Icon id='bell' />
{ showNotificationsBadge && unreadNotifications > 0 && <div className='icon-badge' />}
</span>
</Link>
aria-label={intl.formatMessage(messages.community)}
title={intl.formatMessage(messages.community)}
to='/timelines/public/local'
- ><Icon icon='users' /></Link>
+ ><Icon id='users' /></Link>
))}
{renderForColumn('PUBLIC', (
<Link
aria-label={intl.formatMessage(messages.public)}
title={intl.formatMessage(messages.public)}
to='/timelines/public'
- ><Icon icon='globe' /></Link>
+ ><Icon id='globe' /></Link>
))}
<a
aria-label={intl.formatMessage(messages.settings)}
onClick={onSettingsClick}
href='#'
title={intl.formatMessage(messages.settings)}
- ><Icon icon='cogs' /></a>
+ ><Icon id='cogs' /></a>
<a
aria-label={intl.formatMessage(messages.logout)}
onClick={this.handleLogoutClick}
href={ signOutLink }
title={intl.formatMessage(messages.logout)}
- ><Icon icon='sign-out' /></a>
+ ><Icon id='sign-out' /></a>
</nav>
);
};
</label>
<div className='poll__cancel'>
- <IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} icon='times' onClick={this.handleOptionRemove} />
+ <IconButton disabled={index <= 1} title={intl.formatMessage(messages.remove_option)} id='times' onClick={this.handleOptionRemove} />
</div>
</li>
);
{options.size < pollLimits.max_options && (
<label className='poll__text editable'>
<span className={classNames('poll__input')} style={{ opacity: 0 }} />
- <button className='button button-secondary' onClick={this.handleAddOption}><Icon icon='plus' /> <FormattedMessage {...messages.add_option} /></button>
+ <button className='button button-secondary' onClick={this.handleAddOption}><Icon id='plus' /> <FormattedMessage {...messages.add_option} /></button>
</label>
)}
</ul>
text={
<span>
<Icon
- icon={{
+ id={{
public: 'globe',
unlisted: 'unlock',
private: 'lock',
return (
<span>
<Icon
- icon={{
+ id={{
direct: 'envelope',
private: 'lock',
public: 'globe',
role='button'
tabIndex='0'
>
- <Icon icon='search' className={hasValue ? '' : 'active'} />
- <Icon icon='times-circle' className={hasValue ? 'active' : ''} />
+ <Icon id='search' className={hasValue ? '' : 'active'} />
+ <Icon id='times-circle' className={hasValue ? 'active' : ''} />
</div>
<Overlay show={expanded && !hasValue} placement='bottom' target={this}>
count += results.get('accounts').size;
accounts = (
<section>
- <h5><Icon icon='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
+ <h5><Icon id='users' fixedWidth /><FormattedMessage id='search_results.accounts' defaultMessage='People' /></h5>
{results.get('accounts').map(accountId => <AccountContainer id={accountId} key={accountId} />)}
count += results.get('statuses').size;
statuses = (
<section>
- <h5><Icon icon='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
+ <h5><Icon id='quote-right' fixedWidth /><FormattedMessage id='search_results.statuses' defaultMessage='Toots' /></h5>
{results.get('statuses').map(statusId => <StatusContainer id={statusId} key={statusId}/>)}
count += results.get('hashtags').size;
hashtags = (
<section>
- <h5><Icon icon='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
+ <h5><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
{results.get('hashtags').map(hashtag => <Hashtag key={hashtag.get('name')} hashtag={hashtag} />)}
return (
<div className='drawer--results'>
<header className='search-results__header'>
- <Icon icon='search' fixedWidth />
+ <Icon id='search' fixedWidth />
<FormattedMessage id='search_results.total' defaultMessage='{count, number} {count, plural, one {result} other {results}}' values={{ count }} />
</header>
title={intl.formatMessage(message)}
>
<Icon
- fullwidth
- icon={icon}
+ fixedWidth
+ id={icon}
/>
</span>
) : null
{({ scale }) => (
<div style={{ transform: `scale(${scale})`, backgroundImage: `url(${media.get('preview_url')})`, backgroundPosition: `${x}% ${y}%` }}>
<div className={classNames('composer--upload_form--actions', { active: true })}>
- <button className='icon-button' onClick={this.handleUndoClick}><Icon icon='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
+ <button className='icon-button' onClick={this.handleUndoClick}><Icon id='times' /> <FormattedMessage id='upload_form.undo' defaultMessage='Delete' /></button>
<button className='icon-button' onClick={this.handleFocalPointClick}><Icon id='pencil' /> <FormattedMessage id='upload_form.edit' defaultMessage='Edit' /></button>
</div>
</div>
return (
<div className='composer--upload_form--progress'>
- <Icon icon={icon} />
+ <Icon id={icon} />
<div className='message'>
{message}
return (
<Icon
className='icon'
- fullwidth
- icon={icon}
+ fixedWidth
+ id={icon}
/>
);
default:
<hr />
{lists.map(list => (
- <NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' icon='list-ul' fixedWidth />{list.get('title')}</NavLink>
+ <NavLink key={list.get('id')} className='column-link column-link--transparent' strict to={`/timelines/list/${list.get('id')}`}><Icon className='column-link__icon' id='list-ul' fixedWidth />{list.get('title')}</NavLink>
))}
</div>
);
const NavigationPanel = ({ onOpenSettings }) => (
<div className='navigation-panel'>
- <NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' icon='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/timelines/home' data-preview-title-id='column.home' data-preview-icon='home' ><Icon className='column-link__icon' id='home' fixedWidth /><FormattedMessage id='tabs_bar.home' defaultMessage='Home' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/notifications' data-preview-title-id='column.notifications' data-preview-icon='bell' ><NotificationsCounterIcon className='column-link__icon' /><FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' /></NavLink>
<FollowRequestsNavLink />
- <NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' icon='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
- <NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' icon='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
- <NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' icon='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
- <NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' icon='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
- {profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' icon='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
- <NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' icon='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/timelines/public/local' data-preview-title-id='column.community' data-preview-icon='users' ><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='tabs_bar.local_timeline' defaultMessage='Local' /></NavLink>
+ <NavLink className='column-link column-link--transparent' exact to='/timelines/public' data-preview-title-id='column.public' data-preview-icon='globe' ><Icon className='column-link__icon' id='globe' fixedWidth /><FormattedMessage id='tabs_bar.federated_timeline' defaultMessage='Federated' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/timelines/direct'><Icon className='column-link__icon' id='envelope' fixedWidth /><FormattedMessage id='navigation_bar.direct' defaultMessage='Direct messages' /></NavLink>
+ <NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
+ {profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
+ <NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
<ListPanel />
<hr />
- {!!preferencesLink && <a className='column-link column-link--transparent' href={preferencesLink} target='_blank'><Icon className='column-link__icon' icon='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>}
- <a className='column-link column-link--transparent' href='#' onClick={onOpenSettings}><Icon className='column-link__icon' icon='cogs' fixedWidth /><FormattedMessage id='navigation_bar.app_settings' defaultMessage='App settings' /></a>
- {!!relationshipsLink && <a className='column-link column-link--transparent' href={relationshipsLink} target='_blank'><Icon className='column-link__icon' icon='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>}
+ {!!preferencesLink && <a className='column-link column-link--transparent' href={preferencesLink} target='_blank'><Icon className='column-link__icon' id='cog' fixedWidth /><FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' /></a>}
+ <a className='column-link column-link--transparent' href='#' onClick={onOpenSettings}><Icon className='column-link__icon' id='cogs' fixedWidth /><FormattedMessage id='navigation_bar.app_settings' defaultMessage='App settings' /></a>
+ {!!relationshipsLink && <a className='column-link column-link--transparent' href={relationshipsLink} target='_blank'><Icon className='column-link__icon' id='users' fixedWidth /><FormattedMessage id='navigation_bar.follows_and_followers' defaultMessage='Follows and followers' /></a>}
{showTrends && <div className='flex-spacer' />}
{showTrends && <TrendsContainer />}