Skip to content

Commit

Permalink
Merge pull request #37074 from burczu/feature/35712-redesign-of-membe…
Browse files Browse the repository at this point in the history
…rs-list

Feature/35712 redesign of members list
  • Loading branch information
luacmartins authored Feb 22, 2024
2 parents 8783eb4 + 118ca71 commit 510d118
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 99 deletions.
2 changes: 2 additions & 0 deletions src/components/SelectionList/BaseListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {BaseListItemProps, ListItem} from './types';

function BaseListItem<TItem extends ListItem>({
item,
pressableStyle,
wrapperStyle,
selectMultipleStyle,
isDisabled = false,
Expand Down Expand Up @@ -59,6 +60,7 @@ function BaseListItem<TItem extends ListItem>({
dataSet={{[CONST.SELECTION_SCRAPER_HIDDEN_ELEMENT]: true}}
onMouseDown={shouldPreventDefaultFocusOnSelectRow ? (e) => e.preventDefault() : undefined}
nativeID={keyForList}
style={pressableStyle}
>
{({hovered}) => (
<>
Expand Down
13 changes: 9 additions & 4 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ function BaseSelectionList<TItem extends ListItem>(
rightHandSideComponent,
isLoadingNewOptions = false,
onLayout,
customListHeader,
listHeaderWrapperStyle,
}: BaseSelectionListProps<TItem>,
inputRef: ForwardedRef<RNTextInput>,
) {
Expand Down Expand Up @@ -428,7 +430,7 @@ function BaseSelectionList<TItem extends ListItem>(
<>
{!headerMessage && canSelectMultiple && shouldShowSelectAll && (
<PressableWithFeedback
style={[styles.peopleRow, styles.userSelectNone, styles.ph4, styles.pb3]}
style={[styles.peopleRow, styles.userSelectNone, styles.ph4, styles.pb3, listHeaderWrapperStyle]}
onPress={selectAllRow}
accessibilityLabel={translate('workspace.people.selectAll')}
role="button"
Expand All @@ -443,11 +445,14 @@ function BaseSelectionList<TItem extends ListItem>(
onPress={selectAllRow}
disabled={flattenedSections.allOptions.length === flattenedSections.disabledOptionsIndexes.length}
/>
<View style={[styles.flex1]}>
<Text style={[styles.textStrong, styles.ph3]}>{translate('workspace.people.selectAll')}</Text>
</View>
{customListHeader ?? (
<View style={[styles.flex1]}>
<Text style={[styles.textStrong, styles.ph3]}>{translate('workspace.people.selectAll')}</Text>
</View>
)}
</PressableWithFeedback>
)}
{!headerMessage && !canSelectMultiple && customListHeader}
<SectionList
ref={listRef}
sections={sections}
Expand Down
90 changes: 90 additions & 0 deletions src/components/SelectionList/TableListItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import React from 'react';
import {View} from 'react-native';
import MultipleAvatars from '@components/MultipleAvatars';
import TextWithTooltip from '@components/TextWithTooltip';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import BaseListItem from './BaseListItem';
import type {TableListItemProps} from './types';

function TableListItem({
item,
isFocused,
showTooltip,
isDisabled,
canSelectMultiple,
onSelectRow,
onDismissError,
shouldPreventDefaultFocusOnSelectRow,
rightHandSideComponent,
}: TableListItemProps) {
const styles = useThemeStyles();
const theme = useTheme();
const StyleUtils = useStyleUtils();

const focusedBackgroundColor = styles.sidebarLinkActive.backgroundColor;
const hoveredBackgroundColor = styles.sidebarLinkHover?.backgroundColor ? styles.sidebarLinkHover.backgroundColor : theme.sidebar;

return (
<BaseListItem
item={item}
pressableStyle={[[styles.selectionListPressableItemWrapper, isFocused && styles.activeComponentBG]]}
wrapperStyle={[styles.flexRow, styles.flex1, styles.justifyContentBetween, styles.userSelectNone, styles.alignItemsCenter, isFocused && styles.sidebarLinkActive]}
selectMultipleStyle={[StyleUtils.getCheckboxContainerStyle(20), StyleUtils.getMultiselectListStyles(!!item.isSelected, !!item.isDisabled)]}
isFocused={isFocused}
isDisabled={isDisabled}
showTooltip={showTooltip}
canSelectMultiple={canSelectMultiple}
onSelectRow={onSelectRow}
onDismissError={onDismissError}
shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow}
rightHandSideComponent={rightHandSideComponent}
errors={item.errors}
pendingAction={item.pendingAction}
keyForList={item.keyForList}
>
{(hovered) => (
<>
{!!item.icons && (
<MultipleAvatars
icons={item.icons ?? []}
shouldShowTooltip={showTooltip}
secondAvatarStyle={[
StyleUtils.getBackgroundAndBorderStyle(theme.sidebar),
isFocused ? StyleUtils.getBackgroundAndBorderStyle(focusedBackgroundColor) : undefined,
hovered && !isFocused ? StyleUtils.getBackgroundAndBorderStyle(hoveredBackgroundColor) : undefined,
]}
/>
)}
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsStretch]}>
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={item.text}
textStyles={[
styles.optionDisplayName,
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
styles.sidebarLinkTextBold,
styles.pre,
item.alternateText ? styles.mb1 : null,
styles.justifyContentCenter,
]}
/>
{!!item.alternateText && (
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={item.alternateText}
textStyles={[styles.textLabelSupporting, styles.lh16, styles.pre]}
/>
)}
</View>
{!!item.rightElement && item.rightElement}
</>
)}
</BaseListItem>
);
}

TableListItem.displayName = 'TableListItem';

export default TableListItem;
15 changes: 14 additions & 1 deletion src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {Errors, Icon, PendingAction} from '@src/types/onyx/OnyxCommon';
import type {ReceiptErrors} from '@src/types/onyx/Transaction';
import type ChildrenProps from '@src/types/utils/ChildrenProps';
import type RadioListItem from './RadioListItem';
import type TableListItem from './TableListItem';
import type UserListItem from './UserListItem';

type CommonListItemProps<TItem> = {
Expand All @@ -28,6 +29,9 @@ type CommonListItemProps<TItem> = {
/** Component to display on the right side */
rightHandSideComponent?: ((item: TItem) => ReactElement<TItem>) | ReactElement | null;

/** Styles for the pressable component */
pressableStyle?: StyleProp<ViewStyle>;

/** Styles for the wrapper view */
wrapperStyle?: StyleProp<ViewStyle>;

Expand Down Expand Up @@ -121,6 +125,8 @@ type UserListItemProps = ListItemProps & {

type RadioListItemProps = ListItemProps;

type TableListItemProps = ListItemProps;

type Section<TItem extends ListItem> = {
/** Title of the section */
title?: string;
Expand All @@ -143,7 +149,7 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
sections: Array<SectionListData<TItem, Section<TItem>>>;

/** Default renderer for every item in the list */
ListItem: typeof RadioListItem | typeof UserListItem;
ListItem: typeof RadioListItem | typeof UserListItem | typeof TableListItem;

/** Whether this is a multi-select list */
canSelectMultiple?: boolean;
Expand Down Expand Up @@ -246,6 +252,12 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {

/** Fired when the list is displayed with the items */
onLayout?: (event: LayoutChangeEvent) => void;

/** Custom header to show right above list */
customListHeader?: ReactNode;

/** Styles for the list header wrapper */
listHeaderWrapperStyle?: StyleProp<ViewStyle>;
};

type ItemLayout = {
Expand All @@ -272,6 +284,7 @@ export type {
BaseListItemProps,
UserListItemProps,
RadioListItemProps,
TableListItemProps,
ListItem,
ListItemProps,
FlattenedSectionsReturn,
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ export default {
iAcceptThe: 'I accept the ',
remove: 'Remove',
admin: 'Admin',
owner: 'Owner',
dateFormat: 'YYYY-MM-DD',
send: 'Send',
notifications: 'Notifications',
Expand Down Expand Up @@ -308,6 +309,8 @@ export default {
of: 'of',
default: 'Default',
update: 'Update',
member: 'Member',
role: 'Role',
},
location: {
useCurrent: 'Use current location',
Expand Down Expand Up @@ -1745,6 +1748,7 @@ export default {
},
addedWithPrimary: 'Some users were added with their primary logins.',
invitedBySecondaryLogin: ({secondaryLogin}) => `Added by secondary login ${secondaryLogin}.`,
membersListTitle: 'Directory of all workspace members.',
},
card: {
header: 'Unlock free Expensify Cards',
Expand Down
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export default {
iAcceptThe: 'Acepto los ',
remove: 'Eliminar',
admin: 'Administrador',
owner: 'Poseedor',
dateFormat: 'AAAA-MM-DD',
send: 'Enviar',
notifications: 'Notificaciones',
Expand Down Expand Up @@ -298,6 +299,8 @@ export default {
of: 'de',
default: 'Predeterminado',
update: 'Actualizar',
member: 'Miembro',
role: 'Role',
},
location: {
useCurrent: 'Usar ubicación actual',
Expand Down Expand Up @@ -1769,6 +1772,7 @@ export default {
},
addedWithPrimary: 'Se agregaron algunos usuarios con sus nombres de usuario principales.',
invitedBySecondaryLogin: ({secondaryLogin}) => `Agregado por nombre de usuario secundario ${secondaryLogin}.`,
membersListTitle: 'Directorio de todos los miembros del espacio de trabajo.',
},
card: {
header: 'Desbloquea Tarjetas Expensify gratis',
Expand Down
Loading

0 comments on commit 510d118

Please sign in to comment.