Skip to content

Commit

Permalink
feat(reply): Integrate collaborators endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingze Xiao committed May 13, 2020
1 parent 56331b9 commit 228ae85
Show file tree
Hide file tree
Showing 13 changed files with 311 additions and 42 deletions.
1 change: 1 addition & 0 deletions src/components/Popups/Popper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import unionBy from 'lodash/unionBy';

export type Instance = popper.Instance;
export type Options = popper.Options;
export type State = popper.State;
export type VirtualElement = popper.VirtualElement;

export type PopupReference = Element | VirtualElement;
Expand Down
7 changes: 7 additions & 0 deletions src/components/Popups/ReplyField/DefaultItemRow.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@import '~box-ui-elements/es/styles/variables';

.ba-DefaultItemRow-email {
color: $bdl-gray-62;
font-size: 11px;
line-height: 13px;
}
25 changes: 25 additions & 0 deletions src/components/Popups/ReplyField/DefaultItemRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import DatalistItem from 'box-ui-elements/es/components/datalist-item';
import { UserMini, GroupMini } from '../../../@types';
import './DefaultItemRow.scss';

export type Props = {
id?: string;
item?: UserMini | GroupMini;
name?: string;
};

const DefaultItemRow = ({ item, ...rest }: Props): JSX.Element | null => {
if (!item || !item.name) {
return null;
}

return (
<DatalistItem {...rest}>
<div className="ba-DefaultItemRow-name">{item.name}</div>
{'email' in item && <div className="ba-DefaultItemRow-email">{item.email}</div>}
</DatalistItem>
);
};

export default DefaultItemRow;
5 changes: 5 additions & 0 deletions src/components/Popups/ReplyField/ItemList.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.ba {
.ba-ItemList-row {
padding: 5px 30px 5px 15px;
}
}
52 changes: 52 additions & 0 deletions src/components/Popups/ReplyField/ItemList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { SyntheticEvent } from 'react';
import noop from 'lodash/noop';
import DefaultItemRow from './DefaultItemRow';
import { Collaborator } from '../../../@types';
import './ItemList.scss';

export type Props = {
activeItemIndex?: number;
filterString?: string;
itemRow?: JSX.Element;
items: Collaborator[];
onSelect: (index: number, event: React.SyntheticEvent) => void;
setActiveItemIndex?: (index: number) => void;
};

const ItemList = ({
activeItemIndex = 0,
itemRow = <DefaultItemRow />,
items,
onSelect,
setActiveItemIndex = noop,
...rest
}: Props): JSX.Element => {
return (
<ul role="listbox" {...rest}>
{items.map((item, index) => {
if (!item) {
return null;
}

return React.cloneElement(itemRow, {
...item,
key: item.id,
className: 'ba-ItemList-row',
isActive: index === activeItemIndex,
onClick: (event: SyntheticEvent) => {
onSelect(index, event);
},
/* preventDefault on mousedown so blur doesn't happen before click */
onMouseDown: (event: SyntheticEvent) => {
event.preventDefault();
},
onMouseEnter: () => {
setActiveItemIndex(index);
},
});
})}
</ul>
);
};

export default ItemList;
5 changes: 5 additions & 0 deletions src/components/Popups/ReplyField/MentionItem.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@import '~box-ui-elements/es/styles/variables';

.ba-MentionItem-link {
color: $bdl-box-blue;
}
22 changes: 22 additions & 0 deletions src/components/Popups/ReplyField/MentionItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import * as React from 'react';
import { ContentState } from 'draft-js';
import './MentionItem.scss';

type Props = {
children: React.ReactNode;
contentState: ContentState;
decoratedText: string;
entityKey?: string;
};

const MentionItem = ({ contentState, entityKey, children }: Props): JSX.Element => {
const id = entityKey ? contentState.getEntity(entityKey).getData().id : '';

return (
<a className="ba-MentionItem-link" href={`/profile/${id}`}>
{children}
</a>
);
};

export default MentionItem;
6 changes: 1 addition & 5 deletions src/components/Popups/ReplyField/PopupList.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, .05);
}

.ba-PopupList-item {
padding: 10px;
}

.ba-PopupList-prompt {
padding-top: 0;
padding: 0 10px 10px;
}
}
34 changes: 24 additions & 10 deletions src/components/Popups/ReplyField/PopupList.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import * as React from 'react';
import React from 'react';
import isEmpty from 'lodash/isEmpty';
import { FormattedMessage } from 'react-intl';
import ItemList from './ItemList';
import messages from '../messages';
import PopupBase from '../PopupBase';
import { Collaborator } from '../../../@types';
import { Options, PopupReference } from '../Popper';

import './PopupList.scss';

export type Props = {
activeItemIndex?: number;
itemRow?: JSX.Element;
items: Collaborator[];
onSelect: (index: number, event: React.SyntheticEvent) => void;
options?: Partial<Options>;
reference: PopupReference;
setActiveItemIndex?: (index: number) => void;
};

const options: Partial<Options> = {
const defaultOptions: Partial<Options> = {
modifiers: [
{
name: 'offset',
Expand All @@ -28,12 +36,18 @@ const options: Partial<Options> = {
placement: 'bottom-start',
};

const PopupList = ({ reference, ...rest }: Props): JSX.Element => (
<PopupBase className="ba-PopupList" options={options} reference={reference} {...rest}>
<div className="ba-PopupList-prompt ba-PopupList-item">
<FormattedMessage {...messages.popupListPrompt} />
</div>
</PopupBase>
);
const PopupList = ({ items, reference, options, ...rest }: Props): JSX.Element => {
return (
<PopupBase className="ba-PopupList" options={{ ...defaultOptions, ...options }} reference={reference}>
{isEmpty(items) ? (
<div className="ba-PopupList-prompt">
<FormattedMessage {...messages.popupListPrompt} />
</div>
) : (
<ItemList items={items} {...rest} />
)}
</PopupBase>
);
};

export default PopupList;
Loading

0 comments on commit 228ae85

Please sign in to comment.