-
-
Notifications
You must be signed in to change notification settings - Fork 2k
feat(toast): provide a way to close the toast itself within the endContent #5605
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
base: canary
Are you sure you want to change the base?
feat(toast): provide a way to close the toast itself within the endContent #5605
Conversation
🦋 Changeset detectedLatest commit: 41cda14 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@ChaserZ98 is attempting to deploy a commit to the HeroUI Inc Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughAdds function-based support for toast Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant EndContent as endContent(fn)
participant Toast
participant CloseBtn as CloseButton(onPress)
Note over Toast,EndContent: Toast renders CloseButton and endContent(fn)
User->>EndContent: Click custom action (calls onClose)
EndContent->>Toast: onClose()
Toast->>CloseBtn: invoke onPress (close flow)
CloseBtn-->>Toast: dismissal sequence
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
packages/components/toast/src/use-toast.ts (1)
68-71: Type expansion looks good; update the JSDoc to describe the function variantThe union is correct and non-breaking. Please update the JSDoc so consumers discover the new function form via IntelliSense.
Apply this diff to improve the comment:
/** - * Content to be displayed in the end side of the toast + * Content displayed at the end side of the toast. + * You can also provide a function that receives an `onClose` callback + * which, when called, will close this toast. */ endContent?: ReactNode | ((onClose: () => void) => ReactNode);Additionally, consider exposing a dedicated
close()callback from this hook (mirroring the close button behavior) to avoid downstream casting of event handlers. See my suggestion in toast.tsx.packages/components/toast/src/toast.tsx (2)
85-89: Avoid castingonPressto() => void; pass a dedicatedclosecallback insteadGrabbing
onPressfromgetCloseButtonProps()and casting to a no-arg function works at runtime but is type-unsafe and couples endContent to Button’s press event signature. Prefer exposing a zero-argclose()fromuseToastand passing that to the endContent function. This removes the cast, reduces re-computation, and decouples concerns.Apply this diff here (assuming
closeis returned fromuseToast):- const customEndContent = - typeof endContent === "function" - ? endContent((getCloseButtonProps() as ButtonProps).onPress as () => void) - : endContent; + const customEndContent = + typeof endContent === "function" ? endContent(close) : endContent;Outside the selected range (for context), add
closeinuseToast(packages/components/toast/src/use-toast.ts):// inside useToast(...) const close = useCallback(() => { setIsToastExiting(true); setTimeout(() => document.body.focus(), 0); onClose?.(); }, [onClose]); // include `close` in the returned object return { // ...existing close, };Optionally, simplify
getCloseButtonPropsto reuse the same logic:const getCloseButtonProps: PropGetter = useCallback( (props = {}) => ({ className: slots.closeButton({class: classNames?.closeButton}), "aria-label": "closeButton", "data-hidden": dataAttr(hideCloseButton), ...mergeProps(props, {onPress: close}), }), [close], );
112-112: Render order check: confirm intended tab order and semanticsPlacing
customEndContentafter the close button changes keyboard tab order. IfendContentcontains primary actions, consider placing it before the close button for better flow, or ensure focus order is intentional.packages/components/toast/stories/toast.stories.tsx (2)
146-146: Passingargs.endContentthrough is correct; type the template for safetyThis is fine. To keep stories type-safe with the new union, consider typing the template as
const WithEndContentTemplate = (args: ToastProps) => { ... }so Storybook args conform to the updatedToastProps.Outside the selected range:
const WithEndContentTemplate = (args: ToastProps) => { // ... };
451-466: Great example of the function form; add a quick type hint for clarityThis nicely demonstrates receiving
onCloseand wiring it to an action. For readability in examples, you could annotate the param type.Outside the selected range:
endContent: (onClose: () => void) => ( <> {/* ... */} </> )
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (4)
.changeset/grumpy-boxes-doubt.md(1 hunks)packages/components/toast/src/toast.tsx(2 hunks)packages/components/toast/src/use-toast.ts(1 hunks)packages/components/toast/stories/toast.stories.tsx(2 hunks)
🔇 Additional comments (2)
.changeset/grumpy-boxes-doubt.md (1)
1-6: Changelog entry reads well and matches the changePatch bump for @heroui/toast with a concise description. All good.
packages/components/toast/stories/toast.stories.tsx (1)
443-449: LGTM: static endContent exampleGood example demonstrating the ReactNode variant for endContent.
@heroui/accordion
@heroui/alert
@heroui/autocomplete
@heroui/avatar
@heroui/badge
@heroui/breadcrumbs
@heroui/button
@heroui/calendar
@heroui/card
@heroui/checkbox
@heroui/chip
@heroui/code
@heroui/date-input
@heroui/date-picker
@heroui/divider
@heroui/drawer
@heroui/dropdown
@heroui/form
@heroui/image
@heroui/input
@heroui/input-otp
@heroui/kbd
@heroui/link
@heroui/listbox
@heroui/menu
@heroui/modal
@heroui/navbar
@heroui/number-input
@heroui/pagination
@heroui/popover
@heroui/progress
@heroui/radio
@heroui/ripple
@heroui/scroll-shadow
@heroui/select
@heroui/skeleton
@heroui/slider
@heroui/snippet
@heroui/spacer
@heroui/spinner
@heroui/switch
@heroui/table
@heroui/tabs
@heroui/toast
@heroui/tooltip
@heroui/user
@heroui/react
@heroui/system
@heroui/system-rsc
@heroui/theme
@heroui/use-aria-accordion
@heroui/use-aria-accordion-item
@heroui/use-aria-button
@heroui/use-aria-link
@heroui/use-aria-modal-overlay
@heroui/use-aria-multiselect
@heroui/use-aria-overlay
@heroui/use-callback-ref
@heroui/use-clipboard
@heroui/use-data-scroll-overflow
@heroui/use-disclosure
@heroui/use-draggable
@heroui/use-form-reset
@heroui/use-image
@heroui/use-infinite-scroll
@heroui/use-intersection-observer
@heroui/use-is-mobile
@heroui/use-is-mounted
@heroui/use-measure
@heroui/use-pagination
@heroui/use-real-shape
@heroui/use-ref-state
@heroui/use-resize
@heroui/use-safe-layout-effect
@heroui/use-scroll-position
@heroui/use-ssr
@heroui/use-theme
@heroui/use-update-effect
@heroui/use-viewport-size
@heroui/aria-utils
@heroui/dom-animation
@heroui/framer-utils
@heroui/react-rsc-utils
@heroui/react-utils
@heroui/shared-icons
@heroui/shared-utils
@heroui/stories-utils
@heroui/test-utils
commit: |
wingkwong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not just use closeToast?
|
Because, like I mentioned, you need the toast id to close it and it won't be available until you call You might be able to implement it using a reference. It might be easy to manage the reference for one toast but when it comes to many toasts, that would be complicated. So exposing the |
wingkwong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please update doc part as well
e53d134 to
85e7897
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (8)
.changeset/grumpy-boxes-doubt.md(1 hunks)apps/docs/content/components/toast/custom-close-button-in-endContent.raw.jsx(1 hunks)apps/docs/content/components/toast/custom-close-button-in-endContent.ts(1 hunks)apps/docs/content/components/toast/index.ts(2 hunks)apps/docs/content/docs/components/toast.mdx(1 hunks)packages/components/toast/src/toast.tsx(2 hunks)packages/components/toast/src/use-toast.ts(1 hunks)packages/components/toast/stories/toast.stories.tsx(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- .changeset/grumpy-boxes-doubt.md
- packages/components/toast/src/toast.tsx
- packages/components/toast/src/use-toast.ts
- packages/components/toast/stories/toast.stories.tsx
🧰 Additional context used
🧬 Code graph analysis (1)
apps/docs/content/components/toast/custom-close-button-in-endContent.ts (2)
packages/utilities/shared-utils/scripts/postinstall.js (1)
react(28-28)apps/docs/content/components/toast/custom-close-button-in-endContent.raw.jsx (1)
App(3-21)
🔇 Additional comments (2)
apps/docs/content/components/toast/index.ts (1)
9-21: Docs wiring LGTMImporting and exposing customCloseButtonInEndContent in toastContent looks correct.
apps/docs/content/components/toast/custom-close-button-in-endContent.ts (1)
1-9: Mapping export looks goodThe raw example is correctly exposed for CodeDemo consumption.
📝 Description
This PR changes the
endContentattribute of theToastProps. It can now not only receive a variable of typeReactNode, but also a function with aonCloseparam and a return type ofReactNode. The functionality of theonClosefunction is the same as the toast's close button's onPress event. When users call theonClosefunction, it closes the toast just like clicking on the close button.With this PR, Users can now create customized close button in the
endContent.⛳️ Current behavior (updates)
There is no way to create a close button in
endContent. AlthoughcloseToastapi provides a way to programmtically close a toast, it requires the toast's id which users can only access it after the toast is created. Since the toast's id won't be available when the user defines theendContent, there is no way to utilize thecloseToastapi to close itself.🚀 New behavior
As mentioned in the description, users can now utilize the
onClosefunction to customize a close button or whatever ui effect they may want within theendContent.💣 Is this a breaking change (Yes/No):
No
📝 Additional Information
Please see the storybook example
With End Content Close Functionfor demo. I am not sure if a demo in the doc is required. If yes, let me know and I will add it.Summary by CodeRabbit
New Features
Documentation