Convert <ColumnHeader> to Typescript (#30849)
				
					
				
			This commit is contained in:
		
							parent
							
								
									e89317d4c1
								
							
						
					
					
						commit
						3939352e92
					
				@ -1,233 +0,0 @@
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import { PureComponent, useCallback } from 'react';
 | 
			
		||||
 | 
			
		||||
import { FormattedMessage, injectIntl, defineMessages, useIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
import { withRouter } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import AddIcon from '@/material-icons/400-24px/add.svg?react';
 | 
			
		||||
import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react';
 | 
			
		||||
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
 | 
			
		||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
 | 
			
		||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
 | 
			
		||||
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
 | 
			
		||||
import { Icon }  from 'mastodon/components/icon';
 | 
			
		||||
import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context';
 | 
			
		||||
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
 | 
			
		||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import { useAppHistory } from './router';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
 | 
			
		||||
  hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
 | 
			
		||||
  moveLeft: { id: 'column_header.moveLeft_settings', defaultMessage: 'Move column to the left' },
 | 
			
		||||
  moveRight: { id: 'column_header.moveRight_settings', defaultMessage: 'Move column to the right' },
 | 
			
		||||
  back: { id: 'column_back_button.label', defaultMessage: 'Back' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const BackButton = ({ onlyIcon }) => {
 | 
			
		||||
  const history = useAppHistory();
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
 | 
			
		||||
  const handleBackClick = useCallback(() => {
 | 
			
		||||
    if (history.location?.state?.fromMastodon) {
 | 
			
		||||
      history.goBack();
 | 
			
		||||
    } else {
 | 
			
		||||
      history.push('/');
 | 
			
		||||
    }
 | 
			
		||||
  }, [history]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <button onClick={handleBackClick} className={classNames('column-header__back-button', { 'compact': onlyIcon })} aria-label={intl.formatMessage(messages.back)}>
 | 
			
		||||
      <Icon id='chevron-left' icon={ArrowBackIcon} className='column-back-button__icon' />
 | 
			
		||||
      {!onlyIcon && <FormattedMessage id='column_back_button.label' defaultMessage='Back' />}
 | 
			
		||||
    </button>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
BackButton.propTypes = {
 | 
			
		||||
  onlyIcon: PropTypes.bool,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ColumnHeader extends PureComponent {
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    identity: identityContextPropShape,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    title: PropTypes.node,
 | 
			
		||||
    icon: PropTypes.string,
 | 
			
		||||
    iconComponent: PropTypes.func,
 | 
			
		||||
    active: PropTypes.bool,
 | 
			
		||||
    multiColumn: PropTypes.bool,
 | 
			
		||||
    extraButton: PropTypes.node,
 | 
			
		||||
    showBackButton: PropTypes.bool,
 | 
			
		||||
    children: PropTypes.node,
 | 
			
		||||
    pinned: PropTypes.bool,
 | 
			
		||||
    placeholder: PropTypes.bool,
 | 
			
		||||
    onPin: PropTypes.func,
 | 
			
		||||
    onMove: PropTypes.func,
 | 
			
		||||
    onClick: PropTypes.func,
 | 
			
		||||
    appendContent: PropTypes.node,
 | 
			
		||||
    collapseIssues: PropTypes.bool,
 | 
			
		||||
    ...WithRouterPropTypes,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  state = {
 | 
			
		||||
    collapsed: true,
 | 
			
		||||
    animating: false,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleToggleClick = (e) => {
 | 
			
		||||
    e.stopPropagation();
 | 
			
		||||
    this.setState({ collapsed: !this.state.collapsed, animating: true });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleTitleClick = () => {
 | 
			
		||||
    this.props.onClick?.();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMoveLeft = () => {
 | 
			
		||||
    this.props.onMove(-1);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleMoveRight = () => {
 | 
			
		||||
    this.props.onMove(1);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleTransitionEnd = () => {
 | 
			
		||||
    this.setState({ animating: false });
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handlePin = () => {
 | 
			
		||||
    if (!this.props.pinned) {
 | 
			
		||||
      this.props.history.replace('/');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.props.onPin();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    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', {
 | 
			
		||||
      'active': active,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const buttonClassName = classNames('column-header', {
 | 
			
		||||
      'active': active,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const collapsibleClassName = classNames('column-header__collapsible', {
 | 
			
		||||
      'collapsed': collapsed,
 | 
			
		||||
      'animating': animating,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    const collapsibleButtonClassName = classNames('column-header__button', {
 | 
			
		||||
      'active': !collapsed,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let extraContent, pinButton, moveButtons, backButton, collapseButton;
 | 
			
		||||
 | 
			
		||||
    if (children) {
 | 
			
		||||
      extraContent = (
 | 
			
		||||
        <div key='extra-content' className='column-header__collapsible__extra'>
 | 
			
		||||
          {children}
 | 
			
		||||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (multiColumn && pinned) {
 | 
			
		||||
      pinButton = <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 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' 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 className='text-btn column-header__setting-btn' onClick={this.handlePin}><Icon id='plus' icon={AddIcon} /> <FormattedMessage id='column_header.pin' defaultMessage='Pin' /></button>;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (history && !pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) {
 | 
			
		||||
      backButton = <BackButton onlyIcon={!!title} />;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const collapsedContent = [
 | 
			
		||||
      extraContent,
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    if (multiColumn) {
 | 
			
		||||
      collapsedContent.push(
 | 
			
		||||
        <div key='buttons' className='column-header__advanced-buttons'>
 | 
			
		||||
          {pinButton}
 | 
			
		||||
          {moveButtons}
 | 
			
		||||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (this.props.identity.signedIn && (children || (multiColumn && this.props.onPin))) {
 | 
			
		||||
      collapseButton = (
 | 
			
		||||
        <button
 | 
			
		||||
          className={collapsibleButtonClassName}
 | 
			
		||||
          title={formatMessage(collapsed ? messages.show : messages.hide)}
 | 
			
		||||
          aria-label={formatMessage(collapsed ? messages.show : messages.hide)}
 | 
			
		||||
          onClick={this.handleToggleClick}
 | 
			
		||||
        >
 | 
			
		||||
          <i className='icon-with-badge'>
 | 
			
		||||
            <Icon id='sliders' icon={SettingsIcon} />
 | 
			
		||||
            {collapseIssues && <i className='icon-with-badge__issue-badge' />}
 | 
			
		||||
          </i>
 | 
			
		||||
        </button>
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const hasTitle = (icon || iconComponent) && title;
 | 
			
		||||
 | 
			
		||||
    const component = (
 | 
			
		||||
      <div className={wrapperClassName}>
 | 
			
		||||
        <h1 className={buttonClassName}>
 | 
			
		||||
          {hasTitle && (
 | 
			
		||||
            <>
 | 
			
		||||
              {backButton}
 | 
			
		||||
 | 
			
		||||
              <button onClick={this.handleTitleClick} className='column-header__title'>
 | 
			
		||||
                {!backButton && <Icon id={icon} icon={iconComponent} className='column-header__icon' />}
 | 
			
		||||
                {title}
 | 
			
		||||
              </button>
 | 
			
		||||
            </>
 | 
			
		||||
          )}
 | 
			
		||||
 | 
			
		||||
          {!hasTitle && backButton}
 | 
			
		||||
 | 
			
		||||
          <div className='column-header__buttons'>
 | 
			
		||||
            {extraButton}
 | 
			
		||||
            {collapseButton}
 | 
			
		||||
          </div>
 | 
			
		||||
        </h1>
 | 
			
		||||
 | 
			
		||||
        <div className={collapsibleClassName} tabIndex={collapsed ? -1 : null} onTransitionEnd={this.handleTransitionEnd}>
 | 
			
		||||
          <div className='column-header__collapsible-inner'>
 | 
			
		||||
            {(!collapsed || animating) && collapsedContent}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        {appendContent}
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (placeholder) {
 | 
			
		||||
      return component;
 | 
			
		||||
    } else {
 | 
			
		||||
      return (<ButtonInTabsBar>
 | 
			
		||||
        {component}
 | 
			
		||||
      </ButtonInTabsBar>);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default injectIntl(withIdentity(withRouter(ColumnHeader)));
 | 
			
		||||
							
								
								
									
										301
									
								
								app/javascript/mastodon/components/column_header.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										301
									
								
								app/javascript/mastodon/components/column_header.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,301 @@
 | 
			
		||||
import { useCallback, useState } from 'react';
 | 
			
		||||
 | 
			
		||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
import classNames from 'classnames';
 | 
			
		||||
 | 
			
		||||
import AddIcon from '@/material-icons/400-24px/add.svg?react';
 | 
			
		||||
import ArrowBackIcon from '@/material-icons/400-24px/arrow_back.svg?react';
 | 
			
		||||
import ChevronLeftIcon from '@/material-icons/400-24px/chevron_left.svg?react';
 | 
			
		||||
import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react';
 | 
			
		||||
import CloseIcon from '@/material-icons/400-24px/close.svg?react';
 | 
			
		||||
import SettingsIcon from '@/material-icons/400-24px/settings.svg?react';
 | 
			
		||||
import type { IconProp } from 'mastodon/components/icon';
 | 
			
		||||
import { Icon } from 'mastodon/components/icon';
 | 
			
		||||
import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context';
 | 
			
		||||
import { useIdentity } from 'mastodon/identity_context';
 | 
			
		||||
 | 
			
		||||
import { useAppHistory } from './router';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
 | 
			
		||||
  hide: { id: 'column_header.hide_settings', defaultMessage: 'Hide settings' },
 | 
			
		||||
  moveLeft: {
 | 
			
		||||
    id: 'column_header.moveLeft_settings',
 | 
			
		||||
    defaultMessage: 'Move column to the left',
 | 
			
		||||
  },
 | 
			
		||||
  moveRight: {
 | 
			
		||||
    id: 'column_header.moveRight_settings',
 | 
			
		||||
    defaultMessage: 'Move column to the right',
 | 
			
		||||
  },
 | 
			
		||||
  back: { id: 'column_back_button.label', defaultMessage: 'Back' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const BackButton: React.FC<{
 | 
			
		||||
  onlyIcon: boolean;
 | 
			
		||||
}> = ({ onlyIcon }) => {
 | 
			
		||||
  const history = useAppHistory();
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
 | 
			
		||||
  const handleBackClick = useCallback(() => {
 | 
			
		||||
    if (history.location.state?.fromMastodon) {
 | 
			
		||||
      history.goBack();
 | 
			
		||||
    } else {
 | 
			
		||||
      history.push('/');
 | 
			
		||||
    }
 | 
			
		||||
  }, [history]);
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <button
 | 
			
		||||
      onClick={handleBackClick}
 | 
			
		||||
      className={classNames('column-header__back-button', {
 | 
			
		||||
        compact: onlyIcon,
 | 
			
		||||
      })}
 | 
			
		||||
      aria-label={intl.formatMessage(messages.back)}
 | 
			
		||||
    >
 | 
			
		||||
      <Icon
 | 
			
		||||
        id='chevron-left'
 | 
			
		||||
        icon={ArrowBackIcon}
 | 
			
		||||
        className='column-back-button__icon'
 | 
			
		||||
      />
 | 
			
		||||
      {!onlyIcon && (
 | 
			
		||||
        <FormattedMessage id='column_back_button.label' defaultMessage='Back' />
 | 
			
		||||
      )}
 | 
			
		||||
    </button>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export interface Props {
 | 
			
		||||
  title?: string;
 | 
			
		||||
  icon?: string;
 | 
			
		||||
  iconComponent?: IconProp;
 | 
			
		||||
  active?: boolean;
 | 
			
		||||
  children?: React.ReactNode;
 | 
			
		||||
  pinned?: boolean;
 | 
			
		||||
  multiColumn?: boolean;
 | 
			
		||||
  extraButton?: React.ReactNode;
 | 
			
		||||
  showBackButton?: boolean;
 | 
			
		||||
  placeholder?: boolean;
 | 
			
		||||
  appendContent?: React.ReactNode;
 | 
			
		||||
  collapseIssues?: boolean;
 | 
			
		||||
  onClick?: () => void;
 | 
			
		||||
  onMove?: (arg0: number) => void;
 | 
			
		||||
  onPin?: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ColumnHeader: React.FC<Props> = ({
 | 
			
		||||
  title,
 | 
			
		||||
  icon,
 | 
			
		||||
  iconComponent,
 | 
			
		||||
  active,
 | 
			
		||||
  children,
 | 
			
		||||
  pinned,
 | 
			
		||||
  multiColumn,
 | 
			
		||||
  extraButton,
 | 
			
		||||
  showBackButton,
 | 
			
		||||
  placeholder,
 | 
			
		||||
  appendContent,
 | 
			
		||||
  collapseIssues,
 | 
			
		||||
  onClick,
 | 
			
		||||
  onMove,
 | 
			
		||||
  onPin,
 | 
			
		||||
}) => {
 | 
			
		||||
  const intl = useIntl();
 | 
			
		||||
  const { signedIn } = useIdentity();
 | 
			
		||||
  const history = useAppHistory();
 | 
			
		||||
  const [collapsed, setCollapsed] = useState(true);
 | 
			
		||||
  const [animating, setAnimating] = useState(false);
 | 
			
		||||
 | 
			
		||||
  const handleToggleClick = useCallback(
 | 
			
		||||
    (e: React.MouseEvent) => {
 | 
			
		||||
      e.stopPropagation();
 | 
			
		||||
      setCollapsed((value) => !value);
 | 
			
		||||
      setAnimating(true);
 | 
			
		||||
    },
 | 
			
		||||
    [setCollapsed, setAnimating],
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const handleTitleClick = useCallback(() => {
 | 
			
		||||
    onClick?.();
 | 
			
		||||
  }, [onClick]);
 | 
			
		||||
 | 
			
		||||
  const handleMoveLeft = useCallback(() => {
 | 
			
		||||
    onMove?.(-1);
 | 
			
		||||
  }, [onMove]);
 | 
			
		||||
 | 
			
		||||
  const handleMoveRight = useCallback(() => {
 | 
			
		||||
    onMove?.(1);
 | 
			
		||||
  }, [onMove]);
 | 
			
		||||
 | 
			
		||||
  const handleTransitionEnd = useCallback(() => {
 | 
			
		||||
    setAnimating(false);
 | 
			
		||||
  }, [setAnimating]);
 | 
			
		||||
 | 
			
		||||
  const handlePin = useCallback(() => {
 | 
			
		||||
    if (!pinned) {
 | 
			
		||||
      history.replace('/');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    onPin?.();
 | 
			
		||||
  }, [history, pinned, onPin]);
 | 
			
		||||
 | 
			
		||||
  const wrapperClassName = classNames('column-header__wrapper', {
 | 
			
		||||
    active,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const buttonClassName = classNames('column-header', {
 | 
			
		||||
    active,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const collapsibleClassName = classNames('column-header__collapsible', {
 | 
			
		||||
    collapsed,
 | 
			
		||||
    animating,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const collapsibleButtonClassName = classNames('column-header__button', {
 | 
			
		||||
    active: !collapsed,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  let extraContent, pinButton, moveButtons, backButton, collapseButton;
 | 
			
		||||
 | 
			
		||||
  if (children) {
 | 
			
		||||
    extraContent = (
 | 
			
		||||
      <div key='extra-content' className='column-header__collapsible__extra'>
 | 
			
		||||
        {children}
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (multiColumn && pinned) {
 | 
			
		||||
    pinButton = (
 | 
			
		||||
      <button
 | 
			
		||||
        className='text-btn column-header__setting-btn'
 | 
			
		||||
        onClick={handlePin}
 | 
			
		||||
      >
 | 
			
		||||
        <Icon id='times' icon={CloseIcon} />{' '}
 | 
			
		||||
        <FormattedMessage id='column_header.unpin' defaultMessage='Unpin' />
 | 
			
		||||
      </button>
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    moveButtons = (
 | 
			
		||||
      <div className='column-header__setting-arrows'>
 | 
			
		||||
        <button
 | 
			
		||||
          title={intl.formatMessage(messages.moveLeft)}
 | 
			
		||||
          aria-label={intl.formatMessage(messages.moveLeft)}
 | 
			
		||||
          className='icon-button column-header__setting-btn'
 | 
			
		||||
          onClick={handleMoveLeft}
 | 
			
		||||
        >
 | 
			
		||||
          <Icon id='chevron-left' icon={ChevronLeftIcon} />
 | 
			
		||||
        </button>
 | 
			
		||||
        <button
 | 
			
		||||
          title={intl.formatMessage(messages.moveRight)}
 | 
			
		||||
          aria-label={intl.formatMessage(messages.moveRight)}
 | 
			
		||||
          className='icon-button column-header__setting-btn'
 | 
			
		||||
          onClick={handleMoveRight}
 | 
			
		||||
        >
 | 
			
		||||
          <Icon id='chevron-right' icon={ChevronRightIcon} />
 | 
			
		||||
        </button>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  } else if (multiColumn && onPin) {
 | 
			
		||||
    pinButton = (
 | 
			
		||||
      <button
 | 
			
		||||
        className='text-btn column-header__setting-btn'
 | 
			
		||||
        onClick={handlePin}
 | 
			
		||||
      >
 | 
			
		||||
        <Icon id='plus' icon={AddIcon} />{' '}
 | 
			
		||||
        <FormattedMessage id='column_header.pin' defaultMessage='Pin' />
 | 
			
		||||
      </button>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    !pinned &&
 | 
			
		||||
    ((multiColumn && history.location.state?.fromMastodon) || showBackButton)
 | 
			
		||||
  ) {
 | 
			
		||||
    backButton = <BackButton onlyIcon={!!title} />;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const collapsedContent = [extraContent];
 | 
			
		||||
 | 
			
		||||
  if (multiColumn) {
 | 
			
		||||
    collapsedContent.push(
 | 
			
		||||
      <div key='buttons' className='column-header__advanced-buttons'>
 | 
			
		||||
        {pinButton}
 | 
			
		||||
        {moveButtons}
 | 
			
		||||
      </div>,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (signedIn && (children || (multiColumn && onPin))) {
 | 
			
		||||
    collapseButton = (
 | 
			
		||||
      <button
 | 
			
		||||
        className={collapsibleButtonClassName}
 | 
			
		||||
        title={intl.formatMessage(collapsed ? messages.show : messages.hide)}
 | 
			
		||||
        aria-label={intl.formatMessage(
 | 
			
		||||
          collapsed ? messages.show : messages.hide,
 | 
			
		||||
        )}
 | 
			
		||||
        onClick={handleToggleClick}
 | 
			
		||||
      >
 | 
			
		||||
        <i className='icon-with-badge'>
 | 
			
		||||
          <Icon id='sliders' icon={SettingsIcon} />
 | 
			
		||||
          {collapseIssues && <i className='icon-with-badge__issue-badge' />}
 | 
			
		||||
        </i>
 | 
			
		||||
      </button>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const hasIcon = icon && iconComponent;
 | 
			
		||||
  const hasTitle = hasIcon && title;
 | 
			
		||||
 | 
			
		||||
  const component = (
 | 
			
		||||
    <div className={wrapperClassName}>
 | 
			
		||||
      <h1 className={buttonClassName}>
 | 
			
		||||
        {hasTitle && (
 | 
			
		||||
          <>
 | 
			
		||||
            {backButton}
 | 
			
		||||
 | 
			
		||||
            <button onClick={handleTitleClick} className='column-header__title'>
 | 
			
		||||
              {!backButton && (
 | 
			
		||||
                <Icon
 | 
			
		||||
                  id={icon}
 | 
			
		||||
                  icon={iconComponent}
 | 
			
		||||
                  className='column-header__icon'
 | 
			
		||||
                />
 | 
			
		||||
              )}
 | 
			
		||||
              {title}
 | 
			
		||||
            </button>
 | 
			
		||||
          </>
 | 
			
		||||
        )}
 | 
			
		||||
 | 
			
		||||
        {!hasTitle && backButton}
 | 
			
		||||
 | 
			
		||||
        <div className='column-header__buttons'>
 | 
			
		||||
          {extraButton}
 | 
			
		||||
          {collapseButton}
 | 
			
		||||
        </div>
 | 
			
		||||
      </h1>
 | 
			
		||||
 | 
			
		||||
      <div
 | 
			
		||||
        className={collapsibleClassName}
 | 
			
		||||
        tabIndex={collapsed ? -1 : undefined}
 | 
			
		||||
        onTransitionEnd={handleTransitionEnd}
 | 
			
		||||
      >
 | 
			
		||||
        <div className='column-header__collapsible-inner'>
 | 
			
		||||
          {(!collapsed || animating) && collapsedContent}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      {appendContent}
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  if (placeholder) {
 | 
			
		||||
    return component;
 | 
			
		||||
  } else {
 | 
			
		||||
    return <ButtonInTabsBar>{component}</ButtonInTabsBar>;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line import/no-default-export
 | 
			
		||||
export default ColumnHeader;
 | 
			
		||||
@ -16,7 +16,7 @@ import {
 | 
			
		||||
} from 'mastodon/actions/columns';
 | 
			
		||||
import { fetchDirectory, expandDirectory } from 'mastodon/actions/directory';
 | 
			
		||||
import Column from 'mastodon/components/column';
 | 
			
		||||
import ColumnHeader from 'mastodon/components/column_header';
 | 
			
		||||
import { ColumnHeader } from 'mastodon/components/column_header';
 | 
			
		||||
import { LoadMore } from 'mastodon/components/load_more';
 | 
			
		||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
 | 
			
		||||
import { RadioButton } from 'mastodon/components/radio_button';
 | 
			
		||||
@ -86,7 +86,7 @@ export const Directory: React.FC<{
 | 
			
		||||
  }, [dispatch, order, local]);
 | 
			
		||||
 | 
			
		||||
  const handleMove = useCallback(
 | 
			
		||||
    (dir: string) => {
 | 
			
		||||
    (dir: number) => {
 | 
			
		||||
      dispatch(moveColumn(columnId, dir));
 | 
			
		||||
    },
 | 
			
		||||
    [dispatch, columnId],
 | 
			
		||||
@ -185,7 +185,6 @@ export const Directory: React.FC<{
 | 
			
		||||
      label={intl.formatMessage(messages.title)}
 | 
			
		||||
    >
 | 
			
		||||
      <ColumnHeader
 | 
			
		||||
        // @ts-expect-error ColumnHeader is not properly typed yet
 | 
			
		||||
        icon='address-book-o'
 | 
			
		||||
        iconComponent={PeopleIcon}
 | 
			
		||||
        title={intl.formatMessage(messages.title)}
 | 
			
		||||
 | 
			
		||||
@ -1,11 +1,8 @@
 | 
			
		||||
import Column from '../../../components/column';
 | 
			
		||||
import ColumnHeader from '../../../components/column_header';
 | 
			
		||||
import Column from 'mastodon/components/column';
 | 
			
		||||
import { ColumnHeader } from 'mastodon/components/column_header';
 | 
			
		||||
import type { Props as ColumnHeaderProps } from 'mastodon/components/column_header';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  multiColumn?: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ColumnLoading: React.FC<Props> = (otherProps) => (
 | 
			
		||||
export const ColumnLoading: React.FC<ColumnHeaderProps> = (otherProps) => (
 | 
			
		||||
  <Column>
 | 
			
		||||
    <ColumnHeader {...otherProps} />
 | 
			
		||||
    <div className='scrollable' />
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user