From e5ffe6f25d2458c22be86fd0429ac3e7282c66e3 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 21 Sep 2026 17:49:18 -0400 Subject: [PATCH 1/6] ref(a11y): Migrate disabled Button tooltips to tooltipProps --- .../autofix/v3/prIterationFeedbackForm.tsx | 19 ++- .../debugImageDetails/candidate/actions.tsx | 19 ++- .../feedback/feedbackItem/feedbackActions.tsx | 28 ++-- .../modals/dataWidgetViewerModal.tsx | 45 +++--- .../replays/table/deleteReplays.tsx | 144 +++++++++--------- .../authLogin/components/organizationAuth.tsx | 23 ++- .../automations/components/disabledAlert.tsx | 22 ++- .../components/details/common/actions.tsx | 22 ++- .../components/detectorListTable/actions.tsx | 77 +++++----- static/app/views/discover/results.tsx | 28 ++-- .../replays/list/replayOnboardingPanel.tsx | 67 ++++---- static/app/views/explore/tables/index.tsx | 24 +-- .../tagsDistributionDrawer.tsx | 11 +- .../views/projectInstall/createProject.tsx | 51 +++---- .../featureFlags/changeTracking/index.tsx | 23 ++- .../addIntegrationButton.tsx | 110 ++++++------- .../directEnableButton.tsx | 25 ++- .../installedIntegration.tsx | 36 +++-- .../integrationDetailedView.tsx | 16 +- .../organizationTeams/teamProjects.tsx | 33 ++-- .../project/tempest/addCredentialsButton.tsx | 39 +++-- 21 files changed, 402 insertions(+), 460 deletions(-) diff --git a/static/app/components/events/autofix/v3/prIterationFeedbackForm.tsx b/static/app/components/events/autofix/v3/prIterationFeedbackForm.tsx index 1b6757b54766..ed246a2b36f4 100644 --- a/static/app/components/events/autofix/v3/prIterationFeedbackForm.tsx +++ b/static/app/components/events/autofix/v3/prIterationFeedbackForm.tsx @@ -120,16 +120,15 @@ export function PrIterationFeedbackForm({ {onClose && ( - + ); diff --git a/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidate/actions.tsx b/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidate/actions.tsx index 60d4b6e0030d..19a25ddf63ae 100644 --- a/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidate/actions.tsx +++ b/static/app/components/events/interfaces/debugMeta/debugImageDetails/candidate/actions.tsx @@ -54,16 +54,15 @@ export function Actions({ {({hasAccess}) => ( - - } - href={downloadUrl} - disabled={!hasRole} - > - {t('Download')} - - + } + href={downloadUrl} + disabled={!hasRole} + tooltipProps={{title: noPermissionToDownloadDebugFilesInfo}} + > + {t('Download')} + {isSpam ? t('Move to Inbox') : t('Mark as Spam')} - - - + {hasSeen ? t('Mark Unread') : t('Mark Read')} + - + {t('Delete')} + ); } diff --git a/static/app/components/modals/dataWidgetViewerModal.tsx b/static/app/components/modals/dataWidgetViewerModal.tsx index 195748b323f3..098096bf3c20 100644 --- a/static/app/components/modals/dataWidgetViewerModal.tsx +++ b/static/app/components/modals/dataWidgetViewerModal.tsx @@ -828,13 +828,15 @@ function OpenButton({ !widgetTypeSupportsExploreMultiQuery(widget.widgetType); if (multiQueryUnsupported) { return ( - - - + {openLabel} + ); } path = getWidgetExploreUrl(widget, dashboardFilters, selection, organization)!; @@ -861,22 +863,21 @@ function OpenButton({ } return ( - - { - trackAnalytics('dashboards_views.widget_viewer.open_source', { - organization, - widget_type: widget.widgetType ?? WidgetType.ERRORS, - display_type: widget.displayType, - }); - }} - > - {openLabel} - - + { + trackAnalytics('dashboards_views.widget_viewer.open_source', { + organization, + widget_type: widget.widgetType ?? WidgetType.ERRORS, + display_type: widget.displayType, + }); + }} + > + {openLabel} + ); } diff --git a/static/app/components/replays/table/deleteReplays.tsx b/static/app/components/replays/table/deleteReplays.tsx index 6784e297ab05..32b6f6291ecc 100644 --- a/static/app/components/replays/table/deleteReplays.tsx +++ b/static/app/components/replays/table/deleteReplays.tsx @@ -10,7 +10,6 @@ import {Flex} from '@sentry/scraps/layout'; import {Link} from '@sentry/scraps/link'; import type {TableColumnConfig} from '@sentry/scraps/table'; import {Text} from '@sentry/scraps/text'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {useAnalyticsArea} from 'sentry/components/analyticsArea'; @@ -87,81 +86,76 @@ export function DeleteReplays({selectedIds, replays, queryOptions}: Props) { }; return ( - - - - ), - onConfirm: () => { - bulkDelete([deletePayload], { - onSuccess: () => { - addSuccessMessage( - tct('Replays are being deleted. [settings:View progress]', { - settings: , - }) - ); - // TODO: get the list to refetch - refetchAuditLog(); - }, - onError: error => { - const count = - selectedIds === 'all' - ? Number.MAX_SAFE_INTEGER - : selectedIds.length; - const reason = getBulkDeleteErrorReason(error); - addErrorMessage( - reason - ? tn( - 'Failed to delete replay: %2$s', - 'Failed to delete replays: %2$s', - count, - reason - ) - : tn('Failed to delete replay', 'Failed to delete replays', count) - ); - }, - onSettled: () => {}, - }); + + ), + onConfirm: () => { + bulkDelete([deletePayload], { + onSuccess: () => { + addSuccessMessage( + tct('Replays are being deleted. [settings:View progress]', { + settings: , + }) + ); + // TODO: get the list to refetch + refetchAuditLog(); + }, + onError: error => { + const count = + selectedIds === 'all' ? Number.MAX_SAFE_INTEGER : selectedIds.length; + const reason = getBulkDeleteErrorReason(error); + addErrorMessage( + reason + ? tn( + 'Failed to delete replay: %2$s', + 'Failed to delete replays: %2$s', + count, + reason + ) + : tn('Failed to delete replay', 'Failed to delete replays', count) + ); }, - }) - } - size="xs" - > - {t('Delete')} - - - + onSettled: () => {}, + }); + }, + }) + } + size="xs" + > + {t('Delete')} + ); } diff --git a/static/app/views/authV2/authLogin/components/organizationAuth.tsx b/static/app/views/authV2/authLogin/components/organizationAuth.tsx index 8da3bc5b4036..0d567bf88048 100644 --- a/static/app/views/authV2/authLogin/components/organizationAuth.tsx +++ b/static/app/views/authV2/authLogin/components/organizationAuth.tsx @@ -6,7 +6,6 @@ import {Avatar} from '@sentry/scraps/avatar'; import {Button, LinkButton} from '@sentry/scraps/button'; import {Flex, Stack} from '@sentry/scraps/layout'; import {Text} from '@sentry/scraps/text'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {IconClose, IconMegaphone} from 'sentry/icons'; import {IdentityIcon} from 'sentry/icons/identityIcon'; @@ -65,19 +64,17 @@ export function OrganizationAuth({
setIsSubmitting(true)}> - - - + {t('SSO')} +
); diff --git a/static/app/views/automations/components/disabledAlert.tsx b/static/app/views/automations/components/disabledAlert.tsx index a1fd2852e525..1dbbe997e7a4 100644 --- a/static/app/views/automations/components/disabledAlert.tsx +++ b/static/app/views/automations/components/disabledAlert.tsx @@ -1,6 +1,5 @@ import {Alert} from '@sentry/scraps/alert'; import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {IconPlay} from 'sentry/icons'; import {t} from 'sentry/locale'; @@ -44,17 +43,16 @@ export function DisabledAlert({automation}: DisabledAlertProps) { - -
+ } > {t('This alert is disabled and will not send notifications.')} diff --git a/static/app/views/detectors/components/details/common/actions.tsx b/static/app/views/detectors/components/details/common/actions.tsx index fc8402dac39a..3cd7f7b4c739 100644 --- a/static/app/views/detectors/components/details/common/actions.tsx +++ b/static/app/views/detectors/components/details/common/actions.tsx @@ -1,5 +1,4 @@ import {Button, LinkButton} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addSuccessMessage} from 'sentry/actionCreators/indicator'; import {openConfirmModal} from 'sentry/components/confirm'; @@ -74,17 +73,16 @@ export function EditDetectorAction({ : getManagedBySentryMonitorEditTooltip(); return ( - - } - size="sm" - disabled={!canEdit} - > - {t('Edit')} - - + } + size="sm" + disabled={!canEdit} + tooltipProps={{title: canEdit ? undefined : permissionTooltipText}} + > + {t('Edit')} + ); } diff --git a/static/app/views/detectors/components/detectorListTable/actions.tsx b/static/app/views/detectors/components/detectorListTable/actions.tsx index 32c5a4485d31..ba1ec8ce83d9 100644 --- a/static/app/views/detectors/components/detectorListTable/actions.tsx +++ b/static/app/views/detectors/components/detectorListTable/actions.tsx @@ -5,7 +5,6 @@ import {Alert} from '@sentry/scraps/alert'; import {Button} from '@sentry/scraps/button'; import {Checkbox} from '@sentry/scraps/checkbox'; import {Flex} from '@sentry/scraps/layout'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {openConfirmModal} from 'sentry/components/confirm'; import {usePageFilters} from 'sentry/components/pageFilters/usePageFilters'; @@ -145,56 +144,50 @@ export function DetectorsTableActions({ }} /> {showEnable && ( - handleUpdate({enabled: true})} + disabled={isUpdating || !canEdit || detectorLimitReached} + tooltipProps={{ + title: canEdit ? detectorLimitReached ? "You've reached your plan's limit on metric monitors." - : '' - : 'You do not have permission to modify the selected monitors.' - } - disabled={canEdit && !detectorLimitReached} + : undefined + : 'You do not have permission to modify the selected monitors.', + }} > - - + {t('Enable')} + )} {showDisable && ( - - - - )} - - + )} + diff --git a/static/app/views/discover/results.tsx b/static/app/views/discover/results.tsx index eb341a75429c..271a96f2298f 100644 --- a/static/app/views/discover/results.tsx +++ b/static/app/views/discover/results.tsx @@ -1365,22 +1365,20 @@ function SaveQueryButton({ if (!isNewQuery && isEditingQuery) { return ( - - - + + {t('Save Changes')} + - {t('Select a supported project from the projects dropdown.')} - - } - disabled={!disabled} // we only want to show the tooltip when the button is disabled + - + {t('Set Up Replays')} + ) : ( - - {t('You do not have permission to create a project.')} - - } - disabled={!disabled} + + {t('You do not have permission to create a project.')} + + ), + }} > - - {t('Create Project')} - - + {t('Create Project')} + ); return ( diff --git a/static/app/views/explore/tables/index.tsx b/static/app/views/explore/tables/index.tsx index ec152e77f2bf..c02e9b738e82 100644 --- a/static/app/views/explore/tables/index.tsx +++ b/static/app/views/explore/tables/index.tsx @@ -5,7 +5,6 @@ import {Button} from '@sentry/scraps/button'; import {Flex} from '@sentry/scraps/layout'; import {useModal} from '@sentry/scraps/modal'; import {TabList, Tabs} from '@sentry/scraps/tabs'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {IconEdit} from 'sentry/icons/iconEdit'; import {t} from 'sentry/locale'; @@ -150,17 +149,20 @@ export function ExploreTables(props: ExploreTablesProps) { {t('Edit Table')} ) : ( - } + size="sm" + tooltipProps={{ + title: + tab === Tab.TRACE + ? t('Editing columns is available for span samples only') + : t('Use the Group By and Visualize controls to change table columns'), + }} > - - + {t('Edit Table')} + )} {tab === Tab.SPAN && ( diff --git a/static/app/views/issueDetails/groupDistributions/tagsDistributionDrawer.tsx b/static/app/views/issueDetails/groupDistributions/tagsDistributionDrawer.tsx index 20d88598125f..bdbf4520470a 100644 --- a/static/app/views/issueDetails/groupDistributions/tagsDistributionDrawer.tsx +++ b/static/app/views/issueDetails/groupDistributions/tagsDistributionDrawer.tsx @@ -2,7 +2,6 @@ import {Fragment, useState} from 'react'; import {Button} from '@sentry/scraps/button'; import {Grid} from '@sentry/scraps/layout'; -import {Tooltip} from '@sentry/scraps/tooltip'; import { EventDrawerBody, @@ -79,9 +78,13 @@ export function TagsDistributionDrawer({ }} /> {includeFeatureFlagsTab ? ( - - - + {t('Create Project')} +
{!isModalVisible && ( diff --git a/static/app/views/settings/featureFlags/changeTracking/index.tsx b/static/app/views/settings/featureFlags/changeTracking/index.tsx index afb10545e2c3..57cc2a1a18b2 100644 --- a/static/app/views/settings/featureFlags/changeTracking/index.tsx +++ b/static/app/views/settings/featureFlags/changeTracking/index.tsx @@ -6,7 +6,6 @@ import {LinkButton} from '@sentry/scraps/button'; import {Flex} from '@sentry/scraps/layout'; import {ExternalLink} from '@sentry/scraps/link'; import type {TableColumnConfig} from '@sentry/scraps/table'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {hasEveryAccess} from 'sentry/components/acl/access'; @@ -83,20 +82,16 @@ function AddNewProvider({ organizationSlug: string; }) { return ( - - - {t('Add New Provider')} - - + {t('Add New Provider')} + ); } diff --git a/static/app/views/settings/organizationIntegrations/addIntegrationButton.tsx b/static/app/views/settings/organizationIntegrations/addIntegrationButton.tsx index f6a4b70a76e5..b4e508b30cbb 100644 --- a/static/app/views/settings/organizationIntegrations/addIntegrationButton.tsx +++ b/static/app/views/settings/organizationIntegrations/addIntegrationButton.tsx @@ -1,51 +1,39 @@ -import type {ButtonProps} from '@sentry/scraps/button'; -import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; - import {t} from 'sentry/locale'; import type {IntegrationWithConfig} from 'sentry/types/integrations'; import {trackAnalytics} from 'sentry/utils/analytics'; -import type {AddIntegrationParams} from 'sentry/utils/integrations/useAddIntegration'; -import {useAddIntegration} from 'sentry/utils/integrations/useAddIntegration'; -import {useAutoOpenInstallModal} from 'sentry/utils/integrations/useAutoOpenInstallModal'; +import useOrganization from 'sentry/utils/useOrganization'; -interface AddIntegrationButtonProps - extends - Omit, - Pick< - AddIntegrationParams, - | 'provider' - | 'organization' - | 'analyticsParams' - | 'suppressSuccessMessage' - | 'onCancel' - | 'onError' - > { - onAddIntegration: (data: IntegrationWithConfig) => void; - buttonText?: string; - installStatus?: string; -} +import {Button} from '@sentry/scraps/button'; + +import {useIntegrationInstallFlow} from './integrationInstallFlow'; + +type AddIntegrationButtonProps = { + provider: IntegrationWithConfig['provider']; + analyticsParams?: { + already_installed: boolean; + view: 'integrations_directory_integration_detail' | 'onboarding'; + }; + buttonProps?: React.ComponentProps; + label?: React.ReactNode; + onAddIntegration?: () => void; + onCancel?: () => void; + onError?: () => void; + suppressSuccessMessage?: boolean; +}; export function AddIntegrationButton({ provider, - buttonText, - onAddIntegration, - organization, analyticsParams, - installStatus, + onAddIntegration, + buttonProps, suppressSuccessMessage, onCancel, onError, - ...buttonProps + label = t('Add Integration'), }: AddIntegrationButtonProps) { - const label = - buttonText ?? - (installStatus === 'Disabled' ? t('Reinstall') : t('Add %s', provider.metadata.noun)); - - const {startFlow} = useAddIntegration(); + const organization = useOrganization(); - // This is hooked to the button since the button is only rendered when all the flags/plan checks pass. - useAutoOpenInstallModal({ + const {startFlow} = useIntegrationInstallFlow({ provider, organization, onInstall: onAddIntegration, @@ -55,34 +43,32 @@ export function AddIntegrationButton({ }); return ( - - - + } + startFlow({ + provider, + organization, + onInstall: onAddIntegration, + analyticsParams, + suppressSuccessMessage, + onCancel, + onError, + }); + }} + aria-label={t('Add integration')} + > + {label} + ); } diff --git a/static/app/views/settings/organizationIntegrations/directEnableButton.tsx b/static/app/views/settings/organizationIntegrations/directEnableButton.tsx index b95a61cbf060..939a4c227e8c 100644 --- a/static/app/views/settings/organizationIntegrations/directEnableButton.tsx +++ b/static/app/views/settings/organizationIntegrations/directEnableButton.tsx @@ -1,7 +1,6 @@ import {useMutation, useQueryClient} from '@tanstack/react-query'; import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addErrorMessage} from 'sentry/actionCreators/indicator'; import {t} from 'sentry/locale'; @@ -58,18 +57,18 @@ export function DirectEnableButton({ }); return ( - enable()} > - - + {t('Enable Integration')} + ); } diff --git a/static/app/views/settings/organizationIntegrations/installedIntegration.tsx b/static/app/views/settings/organizationIntegrations/installedIntegration.tsx index 666ccc0e5dbb..2214740cc889 100644 --- a/static/app/views/settings/organizationIntegrations/installedIntegration.tsx +++ b/static/app/views/settings/organizationIntegrations/installedIntegration.tsx @@ -199,28 +199,26 @@ export class InstalledIntegration extends Component { )}
- - } + data-test-id="integration-remove-button" + tooltipProps={{ + title: t( + 'You must be an organization owner, manager or admin to uninstall' + ), + }} > - - - + {t('Uninstall')} + +
- - + ); } diff --git a/static/app/views/settings/organizationTeams/teamProjects.tsx b/static/app/views/settings/organizationTeams/teamProjects.tsx index 0e6efd719678..100a92c9ea8e 100644 --- a/static/app/views/settings/organizationTeams/teamProjects.tsx +++ b/static/app/views/settings/organizationTeams/teamProjects.tsx @@ -7,7 +7,6 @@ import {Button} from '@sentry/scraps/button'; import {CompactSelect, type SelectOption} from '@sentry/scraps/compactSelect'; import {OverlayTrigger} from '@sentry/scraps/overlayTrigger'; import {Pagination} from '@sentry/scraps/pagination'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {hasEveryAccess} from 'sentry/components/acl/access'; @@ -167,24 +166,22 @@ export default function TeamProjects() { sortProjects(linkedProjects).map(project => ( - } + aria-label={t('Remove')} + tooltipProps={{ + title: t( + 'You do not have enough permission to change project association.' + ), + }} + onClick={() => { + handleLinkProject(project, 'remove'); + }} > - - + {t('Remove')} + )) ) : linkedProjectsLoading ? null : ( diff --git a/static/app/views/settings/project/tempest/addCredentialsButton.tsx b/static/app/views/settings/project/tempest/addCredentialsButton.tsx index 409a014da46c..95f12926ad67 100644 --- a/static/app/views/settings/project/tempest/addCredentialsButton.tsx +++ b/static/app/views/settings/project/tempest/addCredentialsButton.tsx @@ -1,5 +1,4 @@ import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {openAddTempestCredentialsModal} from 'sentry/actionCreators/modal'; import {IconAdd} from 'sentry/icons/iconAdd'; @@ -19,27 +18,23 @@ export function AddCredentialsButton({project, origin}: AddCredentialsButtonProp const hasWriteAccess = useHasTempestWriteAccess(project); return ( - } + tooltipProps={{title: t('You do not have permission to add new credentials.')}} + onClick={() => { + openAddTempestCredentialsModal({organization, project, origin}); + trackAnalytics('tempest.credentials.add_modal_opened', { + organization, + project_slug: project.slug, + origin, + }); + }} > - - + {t('Add Credentials')} + ); } From 6b11411f5262f068203eb291e2f01d9fd4fa8a59 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 21 Sep 2026 17:50:23 -0400 Subject: [PATCH 2/6] ref(a11y): Remove tooltip wrapper spans on disabled buttons --- .../preprod/preprodBuildsTableCommon.tsx | 30 ++++++++----------- .../transactionEvents/eventsTable.tsx | 12 ++------ 2 files changed, 16 insertions(+), 26 deletions(-) diff --git a/static/app/components/preprod/preprodBuildsTableCommon.tsx b/static/app/components/preprod/preprodBuildsTableCommon.tsx index 3bc994adabcf..4797807409c7 100644 --- a/static/app/components/preprod/preprodBuildsTableCommon.tsx +++ b/static/app/components/preprod/preprodBuildsTableCommon.tsx @@ -100,23 +100,19 @@ export function PreprodBuildsRowCells({ variant="icon" /> ) : ( - - - - - + {t('Remove')} + + ); diff --git a/static/app/views/settings/organizationAuthTokens/authTokenRow.tsx b/static/app/views/settings/organizationAuthTokens/authTokenRow.tsx index 3a0ba8ab6ca1..a49e83f84cc8 100644 --- a/static/app/views/settings/organizationAuthTokens/authTokenRow.tsx +++ b/static/app/views/settings/organizationAuthTokens/authTokenRow.tsx @@ -3,7 +3,6 @@ import styled from '@emotion/styled'; import {Button} from '@sentry/scraps/button'; import {Link} from '@sentry/scraps/link'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {Confirm} from 'sentry/components/confirm'; import {Placeholder} from 'sentry/components/placeholder'; @@ -119,28 +118,28 @@ export function OrganizationAuthTokensAuthTokenRow({ - revokeToken(token) : undefined} + message={t( + 'Are you sure you want to revoke %s token? It will not be usable anymore, and this cannot be undone.', + tokenPreview(token.tokenLastCharacters || '', 'sntrys_') + )} > - revokeToken(token) : undefined} - message={t( - 'Are you sure you want to revoke %s token? It will not be usable anymore, and this cannot be undone.', - tokenPreview(token.tokenLastCharacters || '', 'sntrys_') - )} + - - + {t('Revoke')} + + ); diff --git a/static/app/views/settings/organizationTeams/teamNotifications.tsx b/static/app/views/settings/organizationTeams/teamNotifications.tsx index 7d9a56f6edc9..bffa56ac27bb 100644 --- a/static/app/views/settings/organizationTeams/teamNotifications.tsx +++ b/static/app/views/settings/organizationTeams/teamNotifications.tsx @@ -4,7 +4,6 @@ import styled from '@emotion/styled'; import {Button} from '@sentry/scraps/button'; import {Flex} from '@sentry/scraps/layout'; import {ExternalLink} from '@sentry/scraps/link'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {addErrorMessage, addSuccessMessage} from 'sentry/actionCreators/indicator'; import {hasEveryAccess} from 'sentry/components/acl/access'; @@ -125,22 +124,23 @@ function TeamNotificationSettingsPanel({ /> - onDelete(externalTeam)} + message={t('Are you sure you want to remove this Slack team link?')} > - } disabled={!hasWriteAccess} - onConfirm={() => onDelete(externalTeam)} - message={t('Are you sure you want to remove this Slack team link?')} + tooltipProps={{ + title: t( + 'You must be an organization owner, manager or admin to remove a Slack team link' + ), + }} > - - - + {t('Unlink')} + + )); diff --git a/static/app/views/settings/project/tempest/CredentialRow.tsx b/static/app/views/settings/project/tempest/CredentialRow.tsx index 70d56e3efdbc..5ecf5550c1fb 100644 --- a/static/app/views/settings/project/tempest/CredentialRow.tsx +++ b/static/app/views/settings/project/tempest/CredentialRow.tsx @@ -37,27 +37,27 @@ export function CredentialRow({ - removeCredential({id: credential.id}) : undefined + } + disabled={isRemoving || !removeCredential} > - removeCredential({id: credential.id}) : undefined - } + - - + {t('Remove')} + + ); diff --git a/static/app/views/settings/projectSourceMaps/debugIdBundleDeleteButton.tsx b/static/app/views/settings/projectSourceMaps/debugIdBundleDeleteButton.tsx index 0820905d8d80..182cc15b9d97 100644 --- a/static/app/views/settings/projectSourceMaps/debugIdBundleDeleteButton.tsx +++ b/static/app/views/settings/projectSourceMaps/debugIdBundleDeleteButton.tsx @@ -1,6 +1,5 @@ import type {ButtonProps} from '@sentry/scraps/button'; import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {Access} from 'sentry/components/acl/access'; import {Confirm} from 'sentry/components/confirm'; @@ -19,20 +18,22 @@ export function DebugIdBundleDeleteButton({ return ( {({hasAccess}) => ( - - } + size={size} disabled={!hasAccess} + tooltipProps={{ + title: t('You do not have permission to delete source maps.'), + }} > - - - + {t('Delete Source Maps')} + + )} ); From 9424822b8e808c214716f023cc1d4d98b4d26f78 Mon Sep 17 00:00:00 2001 From: Nate Moore Date: Mon, 21 Sep 2026 17:59:42 -0400 Subject: [PATCH 4/6] ref(a11y): Clean up remaining disabled button tooltip workarounds --- .../views/dashboards/widgetCard/toolbar.tsx | 49 +++++++------------ static/app/views/explore/logs/logsTab.tsx | 22 +++------ 2 files changed, 27 insertions(+), 44 deletions(-) diff --git a/static/app/views/dashboards/widgetCard/toolbar.tsx b/static/app/views/dashboards/widgetCard/toolbar.tsx index 8aca4af9a3ad..891fdf05ac4d 100644 --- a/static/app/views/dashboards/widgetCard/toolbar.tsx +++ b/static/app/views/dashboards/widgetCard/toolbar.tsx @@ -3,7 +3,6 @@ import styled from '@emotion/styled'; import color from 'color'; import {Button} from '@sentry/scraps/button'; -import {Tooltip} from '@sentry/scraps/tooltip'; import {IconCopy, IconDelete, IconEdit, IconGrabbable} from 'sentry/icons'; import {t} from 'sentry/locale'; @@ -41,37 +40,27 @@ export function Toolbar({ /> )} {onEdit && ( - -