Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port upstream's icon changes #2568

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions app/javascript/flavours/glitch/components/attachment_list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import classNames from 'classnames';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';

import { Icon } from 'flavours/glitch/components/icon';
import { ReactComponent as LinkIcon } from '@material-symbols/svg-600/outlined/link.svg';

import { Icon } from 'flavours/glitch/components/icon';

const filename = url => url.split('/').pop().split('#')[0].split('?')[0];

Expand All @@ -25,7 +27,7 @@ export default class AttachmentList extends ImmutablePureComponent {
<div className={classNames('attachment-list', { compact })}>
{!compact && (
<div className='attachment-list__icon'>
<Icon id='link' />
<Icon id='link' icon={LinkIcon} />
</div>
)}

Expand All @@ -36,7 +38,7 @@ export default class AttachmentList extends ImmutablePureComponent {
return (
<li key={attachment.get('id')}>
<a href={displayUrl} target='_blank' rel='noopener noreferrer'>
{compact && <Icon id='link' />}
{compact && <Icon id='link' icon={LinkIcon} />}
{compact && ' ' }
{displayUrl ? filename(displayUrl) : <FormattedMessage id='attachments_list.unprocessed' defaultMessage='(unprocessed)' />}
</a>
Expand Down
13 changes: 0 additions & 13 deletions app/javascript/flavours/glitch/components/check.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { FormattedMessage } from 'react-intl';

import { withRouter } from 'react-router-dom';

import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg';

import { Icon } from 'flavours/glitch/components/icon';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';

Expand Down Expand Up @@ -34,7 +36,7 @@ export class ColumnBackButton extends PureComponent {

const component = (
<button onClick={this.handleClick} className='column-back-button'>
<Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</button>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { FormattedMessage } from 'react-intl';

import { withRouter } from 'react-router-dom';

import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg';

import { Icon } from 'flavours/glitch/components/icon';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';

Expand All @@ -29,7 +31,7 @@ class ColumnBackButtonSlim extends PureComponent {
return (
<div className='column-back-button--slim'>
<div role='button' tabIndex={0} onClick={this.handleClick} className='column-back-button column-back-button--slim-button'>
<Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</div>
</div>
Expand Down
26 changes: 17 additions & 9 deletions app/javascript/flavours/glitch/components/column_header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import classNames from 'classnames';
import { withRouter } from 'react-router-dom';

import { ReactComponent as AddIcon } from '@material-symbols/svg-600/outlined/add.svg';
import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg';
import { ReactComponent as ChevronLeftIcon } from '@material-symbols/svg-600/outlined/chevron_left.svg';
import { ReactComponent as ChevronRightIcon } from '@material-symbols/svg-600/outlined/chevron_right.svg';
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import { ReactComponent as TuneIcon } from '@material-symbols/svg-600/outlined/tune.svg';

import { Icon } from 'flavours/glitch/components/icon';
import { WithRouterPropTypes } from 'flavours/glitch/utils/react_router';

Expand All @@ -27,6 +34,7 @@ class ColumnHeader extends PureComponent {
intl: PropTypes.object.isRequired,
title: PropTypes.node,
icon: PropTypes.string,
iconComponent: PropTypes.func,
active: PropTypes.bool,
multiColumn: PropTypes.bool,
extraButton: PropTypes.node,
Expand Down Expand Up @@ -87,7 +95,7 @@ class ColumnHeader extends PureComponent {
};

render () {
const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props;
const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props;
const { collapsed, animating } = this.state;

const wrapperClassName = classNames('column-header__wrapper', {
Expand Down Expand Up @@ -118,22 +126,22 @@ class ColumnHeader extends PureComponent {
}

if (multiColumn && pinned) {
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='times' /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='times' icon={CloseIcon} /> <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' /></button>;

moveButtons = (
<div key='move-buttons' className='column-header__setting-arrows'>
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' /></button>
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' /></button>
<button title={formatMessage(messages.moveLeft)} aria-label={formatMessage(messages.moveLeft)} className='icon-button column-header__setting-btn' onClick={this.handleMoveLeft}><Icon id='chevron-left' icon={ChevronLeftIcon} /></button>
<button title={formatMessage(messages.moveRight)} aria-label={formatMessage(messages.moveRight)} className='icon-button column-header__setting-btn' onClick={this.handleMoveRight}><Icon id='chevron-right' icon={ChevronRightIcon} /></button>
</div>
);
} else if (multiColumn && this.props.onPin) {
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
pinButton = <button key='pin-button' className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
}

if (!pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) {
backButton = (
<button onClick={this.handleBackClick} className='column-header__back-button'>
<Icon id='chevron-left' className='column-back-button__icon' fixedWidth />
<Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
<FormattedMessage id='column_back_button.label' defaultMessage='Back' />
</button>
);
Expand All @@ -157,21 +165,21 @@ class ColumnHeader extends PureComponent {
onClick={this.handleToggleClick}
>
<i className='icon-with-badge'>
<Icon id='sliders' />
<Icon id='sliders' icon={TuneIcon} />
{collapseIssues && <i className='icon-with-badge__issue-badge' />}
</i>
</button>
);
}

const hasTitle = icon && title;
const hasTitle = (icon || iconComponent) && title;

const component = (
<div className={wrapperClassName}>
<h1 className={buttonClassName}>
{hasTitle && (
<button onClick={this.handleTitleClick}>
<Icon id={icon} fixedWidth className='column-header__icon' />
<Icon id={icon} icon={iconComponent} className='column-header__icon' />
{title}
</button>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { useCallback, useState, useEffect } from 'react';

import { defineMessages, useIntl } from 'react-intl';

import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';

import { changeSetting } from 'flavours/glitch/actions/settings';
import { bannerSettings } from 'flavours/glitch/settings';
import { useAppSelector, useAppDispatch } from 'flavours/glitch/store';
Expand Down Expand Up @@ -55,6 +57,7 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
<div className='dismissable-banner__action'>
<IconButton
icon='times'
iconComponent={CloseIcon}
title={intl.formatMessage(messages.dismiss)}
onClick={handleDismiss}
/>
Expand Down
3 changes: 3 additions & 0 deletions app/javascript/flavours/glitch/components/domain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { useCallback } from 'react';

import { defineMessages, useIntl } from 'react-intl';

import { ReactComponent as LockOpenIcon } from '@material-symbols/svg-600/outlined/lock_open.svg';

import { IconButton } from './icon_button';

const messages = defineMessages({
Expand Down Expand Up @@ -34,6 +36,7 @@ export const Domain: React.FC<Props> = ({ domain, onUnblockDomain }) => {
<IconButton
active
icon='unlock'
iconComponent={LockOpenIcon}
title={intl.formatMessage(messages.unblockDomain, { domain })}
onClick={handleDomainUnblock}
/>
Expand Down
15 changes: 10 additions & 5 deletions app/javascript/flavours/glitch/components/dropdown_menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { withRouter } from 'react-router-dom';

import ImmutablePropTypes from 'react-immutable-proptypes';

import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
import { supportsPassiveEvents } from 'detect-passive-events';
import Overlay from 'react-overlays/Overlay';

Expand Down Expand Up @@ -163,6 +164,7 @@ class Dropdown extends PureComponent {
static propTypes = {
children: PropTypes.node,
icon: PropTypes.string,
iconComponent: PropTypes.func,
items: PropTypes.oneOfType([PropTypes.array, ImmutablePropTypes.list]).isRequired,
loading: PropTypes.bool,
size: PropTypes.number,
Expand Down Expand Up @@ -255,7 +257,7 @@ class Dropdown extends PureComponent {
};

findTarget = () => {
return this.target;
return this.target?.buttonRef?.current ?? this.target;
};

componentWillUnmount = () => {
Expand All @@ -271,6 +273,7 @@ class Dropdown extends PureComponent {
render () {
const {
icon,
iconComponent,
items,
size,
title,
Expand All @@ -291,9 +294,11 @@ class Dropdown extends PureComponent {
onMouseDown: this.handleMouseDown,
onKeyDown: this.handleButtonKeyDown,
onKeyPress: this.handleKeyPress,
ref: this.setTargetRef,
}) : (
<IconButton
icon={icon}
icon={!open ? icon : 'close'}
iconComponent={!open ? iconComponent : CloseIcon}
title={title}
active={open}
disabled={disabled}
Expand All @@ -302,14 +307,14 @@ class Dropdown extends PureComponent {
onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown}
onKeyPress={this.handleKeyPress}
ref={this.setTargetRef}
/>
);

return (
<>
<span ref={this.setTargetRef}>
{button}
</span>
{button}

<Overlay show={open} offset={[5, 5]} placement={'bottom'} flip target={this.findTarget} popperConfig={{ strategy: 'fixed' }}>
{({ props, arrowProps, placement }) => (
<div {...props}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { FormattedMessage, injectIntl } from 'react-intl';

import { connect } from 'react-redux';

import { ReactComponent as ArrowDropDownIcon } from '@material-symbols/svg-600/outlined/arrow_drop_down.svg';

import { openModal } from 'flavours/glitch/actions/modal';
import { Icon } from 'flavours/glitch/components/icon';
import InlineAccount from 'flavours/glitch/components/inline_account';
Expand Down Expand Up @@ -66,7 +68,7 @@ class EditedTimestamp extends PureComponent {
return (
<DropdownMenu statusId={statusId} renderItem={this.renderItem} scrollable renderHeader={this.renderHeader} onItemClick={this.handleItemClick}>
<button className='dropdown-menu__text-button'>
<FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(timestamp, { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> <Icon id='caret-down' />
<FormattedMessage id='status.edited' defaultMessage='Edited {date}' values={{ date: intl.formatDate(timestamp, { hour12: false, month: 'short', day: '2-digit', hour: '2-digit', minute: '2-digit' }) }} /> <Icon id='caret-down' icon={ArrowDropDownIcon} />
</button>
</DropdownMenu>
);
Expand Down
54 changes: 43 additions & 11 deletions app/javascript/flavours/glitch/components/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,52 @@
import classNames from 'classnames';

interface Props extends React.HTMLAttributes<HTMLImageElement> {
id: string;
className?: string;
fixedWidth?: boolean;
import { ReactComponent as CheckBoxOutlineBlankIcon } from '@material-symbols/svg-600/outlined/check_box_outline_blank.svg';

interface SVGPropsWithTitle extends React.SVGProps<SVGSVGElement> {
title?: string;
}

export type IconProp = React.FC<SVGPropsWithTitle>;

interface Props extends React.SVGProps<SVGSVGElement> {
children?: never;
id: string;
icon: IconProp;
title?: string;
}

export const Icon: React.FC<Props> = ({
id,
icon: IconComponent,
className,
fixedWidth,
title: titleProp,
...other
}) => (
<i
className={classNames('fa', `fa-${id}`, className, { 'fa-fw': fixedWidth })}
{...other}
/>
);
}) => {
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (!IconComponent) {
if (process.env.NODE_ENV !== 'production') {
throw new Error(
`<Icon id="${id}" className="${className}"> is missing an "icon" prop.`,
);
}

IconComponent = CheckBoxOutlineBlankIcon;
}

const ariaHidden = titleProp ? undefined : true;
const role = !ariaHidden ? 'img' : undefined;

// Set the title to an empty string to remove the built-in SVG one if any
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
const title = titleProp || '';

return (
<IconComponent
className={classNames('icon', `icon-${id}`, className)}
title={title}
aria-hidden={ariaHidden}
role={role}
{...other}
/>
);
};
Loading
Loading