-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
chore: Refactor FeedbackButton to accept all the feedback options #103794
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
Changes from all commits
9a189b1
5600686
e381eaa
8bbbe60
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
This file was deleted.
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this was moved into |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| import {useRef} from 'react'; | ||
|
|
||
| import {Button, type ButtonProps} from 'sentry/components/core/button'; | ||
| import {type UseFeedbackOptions} from 'sentry/components/feedbackButton/useFeedbackSDKIntegration'; | ||
| import {IconMegaphone} from 'sentry/icons/iconMegaphone'; | ||
| import {t} from 'sentry/locale'; | ||
| import {useFeedbackForm} from 'sentry/utils/useFeedbackForm'; | ||
|
|
||
| interface Props extends Omit<ButtonProps, 'icon'> { | ||
| feedbackOptions?: UseFeedbackOptions; | ||
| } | ||
|
|
||
| /** | ||
| * A button component that opens the Sentry feedback widget when clicked. | ||
| * | ||
| * Use this component to embed a feedback collection button anywhere in the UI where users | ||
| * might want to submit feedback, report issues, or share suggestions with your team. | ||
| * | ||
| * The feedback form will stay open even if the button itself it removed from the | ||
| * DOM. So you can add buttons inside of Dropdowns or Tooltips for example. | ||
| * | ||
| * The component will return null when the Feedback SDK integration is not enabled, | ||
| * like in self-hosted environments. | ||
| * | ||
| * It's strongly recommended to add the tags: `feedback.source` and `feedback.owner` | ||
| * and then setup an alert rule to notify you when feedback is submitted. | ||
| * | ||
| * @example | ||
| * // Mix of Button and Feedback props | ||
| * <FeedbackButton | ||
| * priority="primary" | ||
| * size="lg" | ||
| * feedbackOptions={{ | ||
| * messagePlaceholder: 'Tell us what you think...', | ||
| * tags: { | ||
| * ['feedback.source']: 'issue-details' | ||
| * ['feedback.owner']: 'issues' | ||
| * } | ||
| * }} | ||
| * /> | ||
ryan953 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * | ||
| * @param feedbackOptions - Optional configuration to customize the feedback widget behavior, | ||
| * such as form labels, tags, or user metadata | ||
| * | ||
| * @param children - The content to display inside the button. If not provided, the default label 'Give Feedback' will be used. | ||
| * | ||
| * @param * - All standard Button props except `icon` (icon is fixed to megaphone). | ||
| * Includes size, priority, disabled, onClick handlers, etc. | ||
| * | ||
| * @returns A Button that opens the feedback widget on click, or null if feedback is not enabled | ||
| */ | ||
| export default function FeedbackButton({ | ||
| feedbackOptions, | ||
| children, | ||
| ...buttonProps | ||
| }: Props) { | ||
| const buttonRef = useRef<HTMLButtonElement>(null); | ||
| const openForm = useFeedbackForm(); | ||
|
|
||
| // Do not show button if Feedback integration is not enabled | ||
| if (!openForm) { | ||
| return null; | ||
| } | ||
|
|
||
| return ( | ||
| <Button | ||
| ref={buttonRef} | ||
| size="sm" | ||
| {...buttonProps} | ||
| icon={<IconMegaphone />} | ||
| onClick={e => { | ||
| openForm?.(feedbackOptions); | ||
| buttonProps.onClick?.(e); | ||
| }} | ||
| > | ||
| {children || t('Give Feedback')} | ||
| </Button> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import {useEffect} from 'react'; | ||
| import {css, Global, useTheme} from '@emotion/react'; | ||
|
|
||
| import {useFeedbackSDKIntegration} from 'sentry/components/feedbackButton/useFeedbackSDKIntegration'; | ||
|
|
||
| /** | ||
| * `<FloatingFeedbackButton /> renders a 'Give Feedback' button that floats in | ||
| * the bottom right corner of the page. | ||
| * | ||
| * This button can float overtop of content, but can also be helpful because it | ||
| * allows users to scroll anywhere and still be able to trigger the Feedback form | ||
| * which allows taking screenshots of what's visible on the page. | ||
| */ | ||
| export default function FloatingFeedbackButton() { | ||
| const theme = useTheme(); | ||
| const {feedback, defaultOptions} = useFeedbackSDKIntegration(); | ||
|
|
||
| useEffect(() => { | ||
| if (!feedback) { | ||
| return undefined; | ||
| } | ||
|
|
||
| const widget = feedback.createWidget(defaultOptions); | ||
| return () => { | ||
| widget.removeFromDom(); | ||
| }; | ||
| }, [feedback, defaultOptions]); | ||
|
|
||
| if (!feedback) { | ||
| return null; | ||
| } | ||
|
|
||
| // z-index needs to be below our indicators which is 10001 | ||
| return ( | ||
| <Global | ||
| styles={css` | ||
| #sentry-feedback { | ||
| --z-index: ${theme.zIndex.toast - 1}; | ||
| } | ||
| `} | ||
| /> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import type {RefObject} from 'react'; | ||
| import {useEffect} from 'react'; | ||
|
|
||
| import {useFeedbackSDKIntegration} from 'sentry/components/feedbackButton/useFeedbackSDKIntegration'; | ||
|
|
||
| interface Props { | ||
| buttonRef?: RefObject<HTMLButtonElement | null> | RefObject<HTMLAnchorElement | null>; | ||
| } | ||
|
|
||
| /** | ||
| * @deprecated This layer isn't needed. Call `useFeedbackSDKIntegration` or use `<FeedbackButton/>` or `<FloatingFeedbackButton/>` | ||
| */ | ||
ryan953 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| export default function useFeedbackWidget({buttonRef}: Props) { | ||
|
Comment on lines
+10
to
+13
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is deprecated now. it's a layer that isn't providing a lot of value. I've already inlined bits into FeedbackButton and FloatingFeedbackButton, |
||
| const {feedback, defaultOptions} = useFeedbackSDKIntegration(); | ||
|
|
||
| useEffect(() => { | ||
| if (!feedback) { | ||
| return undefined; | ||
| } | ||
|
|
||
| if (buttonRef) { | ||
| if (buttonRef.current) { | ||
| return feedback.attachTo(buttonRef.current, defaultOptions); | ||
| } | ||
| } else { | ||
| const widget = feedback.createWidget(defaultOptions); | ||
| return () => { | ||
| widget.removeFromDom(); | ||
| }; | ||
| } | ||
|
|
||
| return undefined; | ||
| }, [buttonRef, feedback, defaultOptions]); | ||
|
|
||
| return feedback; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
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.
this was moved into
feedbackButton/floatingFeedbackButton.tsxand got parts ofuseFeedbackWidgetinserted into it along with a big docstring, which means git isn't tracking it as a move anymore.