import React from 'react'; import { HTMLAttributes, ComponentClass } from 'react'; import styled from 'styled-components'; // AFP-2532 TODO: Fix automatic suppressions below // eslint-disable-next-line @atlassian/tangerine/import/entry-points import { fontSizeSmall } from '@atlaskit/theme'; import { N20, N800, N100 } from '@atlaskit/theme/colors'; import { relativeFontSizeToBase16 } from '@atlaskit/editor-shared-styles'; import { LinkSearchListItemData } from './types'; import formatDistance from 'date-fns/formatDistance'; import differenceInCalendarDays from 'date-fns/differenceInCalendarDays'; import format from 'date-fns/format'; import { injectIntl, InjectedIntlProps } from 'react-intl'; import messages from '../../messages'; interface ContainerProps { selected: boolean; } export const Container = styled.li` background-color: ${(props: ContainerProps) => props.selected ? N20 : 'transparent'}; padding: 8px 12px; cursor: pointer; display: flex; margin-top: 0; `; const NameWrapper: ComponentClass> = styled.span` overflow: hidden; `; export const Name: ComponentClass> = styled.div` color: ${N800}; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 20px; `; export const ContainerName: ComponentClass> = styled.div` color: ${N100}; line-height: 14px; font-size: ${relativeFontSizeToBase16(fontSizeSmall())}; `; const Icon: ComponentClass> = styled.span` min-width: 16px; margin-top: 3px; margin-right: 12px; img { max-width: 16px; } `; export interface Props { item: LinkSearchListItemData; selected: boolean; onSelect: (href: string, text: string) => void; onMouseMove?: (objectId: string) => void; onMouseEnter?: (objectId: string) => void; onMouseLeave?: (objectId: string) => void; } class LinkSearchListItem extends React.PureComponent< Props & InjectedIntlProps, {} > { handleSelect = (e: React.MouseEvent) => { e.preventDefault(); // don't let editor lose focus const { item, onSelect } = this.props; onSelect(item.url, item.name); }; handleMouseMove = () => { const { onMouseMove, item } = this.props; onMouseMove && onMouseMove(item.objectId); }; handleMouseEnter = () => { const { onMouseEnter, item } = this.props; onMouseEnter && onMouseEnter(item.objectId); }; handleMouseLeave = () => { const { onMouseLeave, item } = this.props; onMouseLeave && onMouseLeave(item.objectId); }; private renderIcon() { const { item: { icon, iconUrl }, } = this.props; if (icon) { return {icon}; } if (iconUrl) { return ( ); } return null; } renderWithSpaces( pageAction: string, dateString: string, timeSince: string = '', ) { return ( <>   •   {pageAction} {dateString} {timeSince} ); } renderAbsoluteOrRelativeDate( timeStamp: Date, pageAction: 'updated' | 'viewed', ) { const { intl } = this.props; let pageActionText: string = ''; switch (pageAction) { case 'updated': pageActionText = intl.formatMessage(messages.timeUpdated); break; case 'viewed': pageActionText = intl.formatMessage(messages.timeViewed); break; } if (differenceInCalendarDays(timeStamp, Date.now()) < -7) { return this.renderWithSpaces( pageActionText, format(timeStamp, 'MMMM dd, yyyy'), ); } return this.renderWithSpaces( pageActionText, formatDistance(timeStamp, Date.now()), intl.formatMessage(messages.timeAgo), ); } renderTimeStamp() { const { lastUpdatedDate, lastViewedDate } = this.props.item; if (lastViewedDate) { return this.renderAbsoluteOrRelativeDate(lastViewedDate, 'viewed'); } if (lastUpdatedDate) { return this.renderAbsoluteOrRelativeDate(lastUpdatedDate, 'updated'); } } render() { const { item, selected } = this.props; return ( {this.renderIcon()} {item.name} {item.container} {this.renderTimeStamp()} ); } } export default injectIntl(LinkSearchListItem);