Skip to content

Commit 2e878da

Browse files
docs(swingset): add user profile panel examples
1 parent 5177dd0 commit 2e878da

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

packages/swingset/src/components/DocsViewer.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ import { ViewSource } from './ViewSource';
1010
// MDX docs keyed by `group` slug → `component` slug. Group-aware so identically-named
1111
// entries (the headless `Dialog` primitive vs. the styled `Dialog` component) stay distinct.
1212
const docModules: Record<string, Record<string, React.ComponentType>> = {
13+
user: {
14+
'user-profile-profile-panel': dynamic(() => import('../stories/user-profile-profile-panel.mdx')),
15+
},
1316
organization: {
1417
'organization-profile': dynamic(() => import('../stories/organization-profile.mdx')),
1518
'organization-profile-general-panel': dynamic(() => import('../stories/organization-profile-general-panel.mdx')),

packages/swingset/src/lib/registry.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ import {
122122
} from '../stories/text-field.stories';
123123
import { meta as tooltipMeta } from '../stories/tooltip.stories';
124124
import { meta as useDataTableMeta } from '../stories/use-data-table.stories';
125+
import {
126+
Default as UserProfileProfilePanelDefault,
127+
meta as userProfileProfilePanelMeta,
128+
} from '../stories/user-profile-profile-panel.stories';
125129
import { toSlug } from './slug';
126130
import type { StoryModule } from './types';
127131

@@ -251,7 +255,14 @@ const scrollAreaModule: StoryModule = {
251255

252256
const useDataTableModule: StoryModule = { meta: useDataTableMeta };
253257

258+
const userProfileProfilePanelModule: StoryModule = {
259+
meta: userProfileProfilePanelMeta,
260+
Default: UserProfileProfilePanelDefault,
261+
};
262+
254263
export const registry: StoryModule[] = [
264+
// User
265+
userProfileProfilePanelModule,
255266
// Organization
256267
organizationProfileModule,
257268
organizationProfileGeneralPanelModule,
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as UserProfileProfilePanelStories from './user-profile-profile-panel.stories';
2+
3+
# UserProfileProfilePanel
4+
5+
The Profile panel from UserProfile, composed without the surrounding navigation shell. The
6+
presentational view renders account details, connected accounts, and the danger zone from props
7+
while its callbacks provide the seam for connected Clerk resources.
8+
9+
## Example
10+
11+
<Story
12+
name='Default'
13+
storyModule={UserProfileProfilePanelStories}
14+
/>
15+
16+
## Usage
17+
18+
```tsx
19+
import { UserProfileProfilePanelView } from '@clerk/ui/mosaic/user-profile/user-profile-profile-panel.view';
20+
21+
<UserProfileProfilePanelView
22+
imageUrl={user.imageUrl}
23+
name={user.fullName ?? ''}
24+
username={user.username ?? ''}
25+
emails={user.emailAddresses.map(email => ({
26+
id: email.id,
27+
value: email.emailAddress,
28+
isDefault: email.id === user.primaryEmailAddressId,
29+
}))}
30+
phones={user.phoneNumbers.map(phone => ({ id: phone.id, value: phone.phoneNumber }))}
31+
connectedAccounts={user.externalAccounts.map(account => ({
32+
id: account.id,
33+
provider: account.provider,
34+
identifier: account.emailAddress,
35+
connected: true,
36+
}))}
37+
onNameChange={setName}
38+
onUsernameChange={setUsername}
39+
/>
40+
```
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/** @jsxImportSource @emotion/react */
2+
import { UserProfileProfilePanelView } from '@clerk/ui/mosaic/user-profile/user-profile-profile-panel.view';
3+
import { useState } from 'react';
4+
5+
import type { StoryMeta } from '@/lib/types';
6+
7+
const providerIconUrl = (provider: string) => `https://img.clerk.com/static/${provider}.svg`;
8+
const profileImageUrl = 'https://avatars.githubusercontent.com/u/51144033?v=4';
9+
10+
export { default as __source } from './user-profile-profile-panel.stories?raw';
11+
12+
export const meta: StoryMeta = {
13+
group: 'User',
14+
title: 'UserProfileProfilePanel',
15+
source: 'packages/ui/src/mosaic/user-profile/user-profile-profile-panel.view.tsx',
16+
};
17+
18+
export function Default(_args: Record<string, unknown>) {
19+
const [name, setName] = useState('Preston Booth');
20+
const [username, setUsername] = useState('prestonxyz');
21+
22+
return (
23+
<UserProfileProfilePanelView
24+
emails={[
25+
{ id: 'email_1', value: 'item1@clerk.dev', isDefault: true },
26+
{ id: 'email_2', value: 'item2@clerk.dev' },
27+
]}
28+
connectedAccounts={[
29+
{
30+
id: 'google',
31+
provider: 'Google',
32+
identifier: 'test@google.com',
33+
iconUrl: providerIconUrl('google'),
34+
connected: true,
35+
},
36+
{ id: 'apple', provider: 'Apple', iconUrl: providerIconUrl('apple'), connected: false },
37+
]}
38+
imageUrl={profileImageUrl}
39+
name={name}
40+
phones={[{ id: 'phone_1', value: '+1 801-888-8181' }]}
41+
username={username}
42+
onAddEmail={() => undefined}
43+
onAddPhone={() => undefined}
44+
onConnectAccount={() => undefined}
45+
onDeleteAccount={() => undefined}
46+
onEditProfilePicture={() => undefined}
47+
onManageEmail={() => undefined}
48+
onManagePhone={() => undefined}
49+
onManageConnectedAccount={() => undefined}
50+
onNameChange={setName}
51+
onUsernameChange={setUsername}
52+
/>
53+
);
54+
}

0 commit comments

Comments
 (0)