Skip to content

Commit eafd146

Browse files
committed
feat(react): add showFields and hideFields props to UserProfile for field visibility control
1 parent 4e9a7c0 commit eafd146

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

packages/react/src/components/presentation/UserProfile/BaseUserProfile.tsx

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,14 @@ export interface BaseUserProfileProps {
6767
editable?: boolean;
6868
fallback?: ReactElement;
6969
flattenedProfile?: User;
70+
hideFields?: string[];
7071
mode?: 'inline' | 'popup';
7172
onOpenChange?: (open: boolean) => void;
7273
onUpdate?: (payload: any) => Promise<void>;
7374
open?: boolean;
7475
profile?: User;
7576
schemas?: Schema[];
77+
showFields?: string[];
7678
title?: string;
7779
error?: string | null;
7880
isLoading?: boolean;
@@ -119,12 +121,44 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
119121
open = false,
120122
error = null,
121123
isLoading = false,
124+
showFields = [],
125+
hideFields = [],
122126
}): ReactElement => {
123127
const {theme, colorScheme} = useTheme();
124128
const [editedUser, setEditedUser] = useState(flattenedProfile || profile);
125129
const [editingFields, setEditingFields] = useState<Record<string, boolean>>({});
126130
const {t} = useTranslation();
127131

132+
/**
133+
* Determines if a field should be visible based on showFields, hideFields, and fieldsToSkip arrays.
134+
* Priority order:
135+
* 1. fieldsToSkip (always hidden) - highest priority
136+
* 2. hideFields (explicitly hidden)
137+
* 3. showFields (explicitly shown, if array is not empty)
138+
* 4. Default behavior (show all fields not in fieldsToSkip)
139+
*/
140+
const shouldShowField = useCallback(
141+
(fieldName: string): boolean => {
142+
// Always skip fields in the hardcoded fieldsToSkip array
143+
if (fieldsToSkip.includes(fieldName)) {
144+
return false;
145+
}
146+
147+
// If hideFields is provided and contains this field, hide it
148+
if (hideFields.length > 0 && hideFields.includes(fieldName)) {
149+
return false;
150+
}
151+
152+
// If showFields is provided and not empty, only show fields in that array
153+
if (showFields.length > 0) {
154+
return showFields.includes(fieldName);
155+
}
156+
157+
return true;
158+
},
159+
[showFields, hideFields],
160+
);
161+
128162
const PencilIcon = () => (
129163
<svg
130164
width="16"
@@ -571,7 +605,7 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
571605

572606
const profileEntries = Object.entries(currentUser)
573607
.filter(([key, value]) => {
574-
if (fieldsToSkip.includes(key)) return false;
608+
if (!shouldShowField(key)) return false;
575609

576610
return value !== undefined && value !== '' && value !== null;
577611
})
@@ -612,7 +646,7 @@ const BaseUserProfile: FC<BaseUserProfileProps> = ({
612646
{schemas && schemas.length > 0
613647
? schemas
614648
.filter(schema => {
615-
if (fieldsToSkip.includes(schema.name)) return false;
649+
if (!schema.name || !shouldShowField(schema.name)) return false;
616650

617651
if (!editable) {
618652
const value = flattenedProfile && schema.name ? flattenedProfile[schema.name] : undefined;

packages/react/src/components/presentation/UserProfile/UserProfile.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,16 @@ export type UserProfileProps = Omit<BaseUserProfileProps, 'user' | 'profile' | '
5151
* cardLayout={true}
5252
* fallback={<div>Please sign in to view your profile</div>}
5353
* />
54+
*
55+
* // With field filtering - only show specific fields
56+
* <UserProfile
57+
* showFields={['name.givenName', 'name.familyName', 'emails']}
58+
* />
59+
*
60+
* // With field hiding - hide specific fields
61+
* <UserProfile
62+
* hideFields={['phoneNumbers', 'addresses']}
63+
* />
5464
* ```
5565
*/
5666
const UserProfile: FC<UserProfileProps> = ({...rest}: UserProfileProps): ReactElement => {

0 commit comments

Comments
 (0)