-
Notifications
You must be signed in to change notification settings - Fork 426
feat(astro): Add support for custom menu items #3969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
24 commits
Select commit
Hold shift + click to select a range
9ca6419
feat(astro): Add custom menu items
wobsoriano 5b0ec29
chore(astro): Add custom user profile page
wobsoriano c184539
chore(astro): Replace action prop with open
wobsoriano 909127e
chore(astro): Add changeset
wobsoriano b0727a8
chore(astro): Remove old component export
wobsoriano 4127d11
chore(astro): Select single element for user button
wobsoriano 74d1462
test(astro): Add custom menu item action test
wobsoriano 73cc657
chore(astro): Update changeset
wobsoriano 49b8488
test(astro): Add custom menu item link test
wobsoriano 147cda4
chore(astro): Add custom menu items reordering
wobsoriano cecb1bb
Merge branch 'main' into rob/eco-130-custom-menu-items-in-astro
wobsoriano dcd56d4
chore(astro): Make sure items are wrapped in parent menu items component
wobsoriano cc63e13
chore(astro): Add more description to parent wrappers
wobsoriano 3f5ce80
chore(astro): Update changeset
wobsoriano e8842f2
chore(astro): Add click handler to menu items
wobsoriano 2a7fbaa
chore(astro): Rename selector to clickIdentifier
wobsoriano f5755fa
test(astro): Add menu item reordering test
wobsoriano 6158081
chore(astro): formatting update
wobsoriano febe748
Merge branch 'main' into rob/eco-130-custom-menu-items-in-astro
wobsoriano bd90ce6
chore(astro): Make sure multiple user buttons are properly scoped
wobsoriano c43c401
chore(astro): Add clerk identifier to web component
wobsoriano 57313e1
chore(astro): Remove unused prop type
wobsoriano f89a32e
chore(astro): Update click event name
wobsoriano 7542e82
chore(astro): Update test preset
wobsoriano File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@clerk/astro": minor | ||
| --- | ||
|
|
||
| Add support for custom menu items in the `<UserButton />` Astro component. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
integration/templates/astro-node/src/components/CustomUserButton.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| --- | ||
| import { UserButton } from '@clerk/astro/components'; | ||
| --- | ||
|
|
||
| <UserButton afterSignOutUrl="/"> | ||
| <UserButton.MenuItems> | ||
| <UserButton.Action label="signOut" /> | ||
| <UserButton.Action label="manageAccount" /> | ||
| <UserButton.Link label="Custom link" href="/user"> | ||
| <div slot="label-icon">Icon</div> | ||
| </UserButton.Link> | ||
| <UserButton.Action label="Custom action" open="terms"> | ||
| <div slot="label-icon">Icon</div> | ||
| </UserButton.Action> | ||
| <UserButton.Action label="Custom click" clickIdentifier="custom_click"> | ||
| <div slot="label-icon">Icon</div> | ||
| </UserButton.Action> | ||
| </UserButton.MenuItems> | ||
| <UserButton.UserProfilePage label="Terms" url="terms"> | ||
| <div slot="label-icon">Icon</div> | ||
| <div> | ||
| <h1>Custom Terms Page</h1> | ||
| <p>This is the custom terms page</p> | ||
| </div> | ||
| </UserButton.UserProfilePage> | ||
| </UserButton> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5 changes: 3 additions & 2 deletions
5
packages/astro/src/astro-components/interactive/InternalUIComponentRenderer.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 0 additions & 8 deletions
8
packages/astro/src/astro-components/interactive/UserButton.astro
This file was deleted.
Oops, something went wrong.
83 changes: 83 additions & 0 deletions
83
packages/astro/src/astro-components/interactive/UserButton/MenuItemRenderer.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| --- | ||
| type Props = { | ||
| label: string | ||
| href?: string | ||
| open?: string | ||
| clickIdentifier?: string | ||
| parent?: string | ||
| } | ||
|
|
||
| const { label, href, open, clickIdentifier, parent } = Astro.props | ||
|
|
||
| let labelIcon = ''; | ||
|
|
||
| if (Astro.slots.has('label-icon')) { | ||
| labelIcon = await Astro.slots.render('label-icon'); | ||
| } | ||
|
|
||
| const isDevMode = import.meta.env.DEV; | ||
| --- | ||
|
|
||
| <script is:inline define:vars={{ label, href, open, clickIdentifier, labelIcon, isDevMode, parent }}> | ||
| const parentElement = document.currentScript.parentElement; | ||
|
|
||
| // We used a web component in the `<UserButton.MenuItems>` component. | ||
| const hasParentMenuItem = parentElement.tagName.toLowerCase() === 'clerk-user-button-menu-items'; | ||
| if (!hasParentMenuItem) { | ||
| if (isDevMode) { | ||
| throw new Error( | ||
| `Clerk: <UserButton.MenuItems /> component can only accept <UserButton.Action /> and <UserButton.Link /> as its children. Any other provided component will be ignored.` | ||
| ); | ||
| } | ||
| return | ||
| } | ||
|
|
||
| // Get the user button map from window that we set in the `<InternalUIComponentRenderer />`. | ||
| const userButtonComponentMap = window.__astro_clerk_component_props.get('user-button'); | ||
|
|
||
| let userButton | ||
| if (parent) { | ||
| userButton = document.querySelector(`[data-clerk-id="clerk-user-button-${parent}"]`); | ||
| } else { | ||
| userButton = document.querySelector('[data-clerk-id^="clerk-user-button"]'); | ||
| } | ||
|
|
||
| const safeId = userButton.getAttribute('data-clerk-id'); | ||
| const currentOptions = userButtonComponentMap.get(safeId); | ||
|
|
||
| const reorderItemsLabels = ['manageAccount', 'signOut']; | ||
| const isReorderItem = reorderItemsLabels.includes(label); | ||
|
|
||
| let newMenuItem = { | ||
| label, | ||
| } | ||
|
|
||
| if (!isReorderItem) { | ||
| newMenuItem = { | ||
| ...newMenuItem, | ||
| mountIcon: (el) => { | ||
| el.innerHTML = labelIcon | ||
| }, | ||
| unmountIcon: () => { /* What to clean up? */} | ||
| } | ||
|
|
||
| if (href) { | ||
| newMenuItem.href = href; | ||
| } else if (open) { | ||
| newMenuItem.open = open.startsWith('/') ? open : `/${open}`; | ||
| } else if (clickIdentifier) { | ||
| const clickEvent = new CustomEvent('clerk:menu-item-click', { detail: clickIdentifier }); | ||
| newMenuItem.onClick = () => { | ||
| document.dispatchEvent(clickEvent); | ||
LekoArts marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
| } | ||
|
|
||
| userButtonComponentMap.set(safeId, { | ||
| ...currentOptions, | ||
| customMenuItems: [ | ||
| ...(currentOptions?.customMenuItems ?? []), | ||
| newMenuItem, | ||
| ] | ||
| }) | ||
| </script> | ||
29 changes: 29 additions & 0 deletions
29
packages/astro/src/astro-components/interactive/UserButton/UserButton.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| --- | ||
| import type { UserButtonProps, UserProfileProps, Without } from "@clerk/types"; | ||
|
|
||
| type Props = Without<UserButtonProps, 'userProfileProps'> & { | ||
| userProfileProps?: Pick<UserProfileProps, 'additionalOAuthScopes' | 'appearance'>; | ||
| /** | ||
| * If you have more than one UserButton on a page, providing a custom ID is required | ||
| * to properly scope menu items to the correct button. | ||
| * | ||
| * Example usage: | ||
| * ```tsx | ||
| * <UserButton id="someId"> | ||
| * <UserButton.MenuItems> | ||
| * <UserButton.Link parent="someId" label="User" href="/user"> | ||
| * <Icon slot="label-icon" /> | ||
| * </UserButton.Link> | ||
| * </UserButton.MenuItems> | ||
| * </UserButton> | ||
| * ``` | ||
| */ | ||
| id?: string; | ||
| } | ||
|
|
||
| import InternalUIComponentRenderer from '../InternalUIComponentRenderer.astro' | ||
| --- | ||
|
|
||
| <InternalUIComponentRenderer {...Astro.props} component="user-button" /> | ||
|
|
||
| <slot /> |
24 changes: 24 additions & 0 deletions
24
packages/astro/src/astro-components/interactive/UserButton/UserButtonAction.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| --- | ||
| import MenuItemRenderer from './MenuItemRenderer.astro'; | ||
|
|
||
| type ReorderItemsLabels = 'manageAccount' | 'signOut' | ||
|
|
||
| type Props<Label extends string> = { | ||
| label: Label | ||
| parent?: string | ||
| } & (Label extends ReorderItemsLabels | ||
| ? { | ||
| open?: string | ||
| } | ||
| : ( | ||
| | { open: string; clickIdentifier?: string } | ||
| | { open?: string; clickIdentifier: string } | ||
| ) | ||
| ) | ||
|
|
||
| const { label, open, clickIdentifier, parent } = Astro.props | ||
| --- | ||
|
|
||
| <MenuItemRenderer label={label} open={open} clickIdentifier={clickIdentifier} parent={parent}> | ||
| <slot name="label-icon" slot="label-icon" /> | ||
| </MenuItemRenderer> |
15 changes: 15 additions & 0 deletions
15
packages/astro/src/astro-components/interactive/UserButton/UserButtonLink.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| --- | ||
| import MenuItemRenderer from './MenuItemRenderer.astro'; | ||
|
|
||
| interface Props { | ||
| label: string | ||
| href: string | ||
| parent?: string | ||
| } | ||
|
|
||
| const { label, href, parent } = Astro.props | ||
| --- | ||
|
|
||
| <MenuItemRenderer label={label} href={href} parent={parent}> | ||
| <slot name="label-icon" slot="label-icon" /> | ||
| </MenuItemRenderer> |
18 changes: 18 additions & 0 deletions
18
packages/astro/src/astro-components/interactive/UserButton/UserButtonMenuItems.astro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <clerk-user-button-menu-items> | ||
| <slot /> | ||
| </clerk-user-button-menu-items> | ||
|
|
||
| <script> | ||
| /** | ||
| * In the React version, menu items need to be wrapped in a `<UserButton.MenuItems>` component. | ||
| * We are trying to replicate that behavior here by adding a wrapper component | ||
| * and check if it exists inside the menu items components. | ||
| */ | ||
| class ClerkUserButtonMenuItems extends HTMLElement { | ||
| constructor() { | ||
| super(); | ||
| } | ||
| } | ||
|
|
||
| customElements.define('clerk-user-button-menu-items', ClerkUserButtonMenuItems); | ||
| </script> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.