Skip to content

Commit e849468

Browse files
committed
Tooltip migration: editor + edit-post + edit-site consumers (2/5)
Migrates 7 consumer call sites in `@wordpress/editor`, `@wordpress/edit-post`, and `@wordpress/edit-site` from the legacy `Tooltip` exported by `@wordpress/components` to the compositional `Tooltip` exported by `@wordpress/ui` (built on top of base-ui under the hood): - editor/collab-sidebar/note-byline (non-interactive `<time>` trigger; visual-only on hover) - editor/collaborators-presence/avatar (non-interactive `<div role="img">` trigger; visual-only on hover) - editor/post-revisions-preview/diff-markers - editor/resizable-editor/resize-handle - editor/template-actions-panel/block-theme-content - edit-post/layout (resize separator) - edit-site/resizable-frame The mechanical rewrite was produced by the jscodeshift codemod landed in PR 1; import placement / ordering and a `jsx-a11y` disable directive that the codemod could not preserve were finished by hand. Also mounts a shell-level `<Tooltip.Provider>` inside `edit-post/layout` and `edit-site/layout`, so tooltips inside each editor coordinate as a group (e.g. once the first tooltip in a group has been shown, subsequent siblings open instantly). PR 5 will do the same for the new dashboard / `@wordpress/boot` shell. Avatar unit tests previously relied on the legacy `Ariakit.TooltipAnchor` adding `tabindex="0"` on a non-interactive trigger; they have been rewritten to verify tooltip *presence* by hovering the avatar and asserting the popup content becomes visible (wrapped in a `Tooltip.Provider` with `delay={ 0 }` so the assertion doesn't race the real-world hover delay). The `edit-post/layout/index.native.js` consumer is intentionally left on the legacy import: it uses `<WCTooltip.Slot>`, which is the SlotFill pattern of the legacy implementation and has no equivalent in the new compositional `Tooltip`.
1 parent 85c6808 commit e849468

9 files changed

Lines changed: 242 additions & 162 deletions

File tree

packages/edit-post/src/components/layout/index.js

Lines changed: 65 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import { store as coreStore } from '@wordpress/core-data';
4040
import {
4141
Icon as WCIcon,
4242
SlotFillProvider,
43-
Tooltip as WCTooltip,
4443
__unstableUseNavigateRegions as useNavigateRegions,
4544
privateApis as componentsPrivateApis,
4645
} from '@wordpress/components';
@@ -50,7 +49,7 @@ import {
5049
useRefEffect,
5150
useViewportMatch,
5251
} from '@wordpress/compose';
53-
import { VisuallyHidden } from '@wordpress/ui';
52+
import { Tooltip, VisuallyHidden } from '@wordpress/ui';
5453

5554
/**
5655
* Internal dependencies
@@ -328,16 +327,21 @@ function MetaBoxesMain( { isLegacy } ) {
328327
// The separator button that provides a11y for resizing.
329328
const separator = ! isShort && (
330329
<>
331-
<WCTooltip text={ __( 'Drag to resize' ) }>
332-
<button
333-
ref={ separatorRef }
334-
role="separator" // eslint-disable-line jsx-a11y/no-interactive-element-to-noninteractive-role
335-
aria-valuenow={ usedAriaValueNow }
336-
aria-label={ __( 'Drag to resize' ) }
337-
aria-describedby={ separatorHelpId }
338-
{ ...bindDragGesture() }
330+
<Tooltip.Root>
331+
<Tooltip.Trigger
332+
render={
333+
<button
334+
ref={ separatorRef }
335+
role="separator" // eslint-disable-line jsx-a11y/no-interactive-element-to-noninteractive-role
336+
aria-valuenow={ usedAriaValueNow }
337+
aria-label={ __( 'Drag to resize' ) }
338+
aria-describedby={ separatorHelpId }
339+
{ ...bindDragGesture() }
340+
/>
341+
}
339342
/>
340-
</WCTooltip>
343+
<Tooltip.Popup>{ __( 'Drag to resize' ) }</Tooltip.Popup>
344+
</Tooltip.Root>
341345
<VisuallyHidden id={ separatorHelpId }>
342346
{ __(
343347
'Use up and down arrow keys to resize the meta box pane.'
@@ -572,52 +576,56 @@ function Layout( {
572576

573577
return (
574578
<SlotFillProvider>
575-
<ErrorBoundary canCopyContent>
576-
<WelcomeGuide postType={ currentPostType } />
577-
<div { ...navigateRegionsProps }>
578-
<Editor
579-
settings={ editorSettings }
580-
initialEdits={ initialEdits }
581-
postType={ currentPostType }
582-
postId={ currentPostId }
583-
templateId={ templateId }
584-
className={ className }
585-
forceIsDirty={ hasActiveMetaboxes }
586-
disableIframe={ ! shouldIframe }
587-
// We should auto-focus the canvas (title) on load.
588-
// eslint-disable-next-line jsx-a11y/no-autofocus
589-
autoFocus={ ! isWelcomeGuideVisible }
590-
onActionPerformed={ onActionPerformed }
591-
extraSidebarPanels={
592-
showMetaBoxes && <MetaBoxes location="side" />
593-
}
594-
extraContent={
595-
! isDistractionFree &&
596-
showMetaBoxes && (
597-
<MetaBoxesMain isLegacy={ isDevicePreview } />
598-
)
599-
}
600-
>
601-
<PostLockedModal />
602-
<EditorInitialization />
603-
<FullscreenMode isActive={ isFullscreenActive } />
604-
<BrowserURL />
605-
<UnsavedChangesWarning />
606-
<AutosaveMonitor />
607-
<LocalAutosaveMonitor />
608-
<EditPostKeyboardShortcuts />
609-
<EditorKeyboardShortcutsRegister />
610-
<BlockKeyboardShortcuts />
611-
{ currentPostType === 'wp_block' && (
612-
<InitPatternModal />
613-
) }
614-
<PluginArea onError={ onPluginAreaError } />
615-
<PostEditorMoreMenu />
616-
{ backButton }
617-
<SnackbarNotices className="edit-post-layout__snackbar" />
618-
</Editor>
619-
</div>
620-
</ErrorBoundary>
579+
<Tooltip.Provider>
580+
<ErrorBoundary canCopyContent>
581+
<WelcomeGuide postType={ currentPostType } />
582+
<div { ...navigateRegionsProps }>
583+
<Editor
584+
settings={ editorSettings }
585+
initialEdits={ initialEdits }
586+
postType={ currentPostType }
587+
postId={ currentPostId }
588+
templateId={ templateId }
589+
className={ className }
590+
forceIsDirty={ hasActiveMetaboxes }
591+
disableIframe={ ! shouldIframe }
592+
// We should auto-focus the canvas (title) on load.
593+
// eslint-disable-next-line jsx-a11y/no-autofocus
594+
autoFocus={ ! isWelcomeGuideVisible }
595+
onActionPerformed={ onActionPerformed }
596+
extraSidebarPanels={
597+
showMetaBoxes && <MetaBoxes location="side" />
598+
}
599+
extraContent={
600+
! isDistractionFree &&
601+
showMetaBoxes && (
602+
<MetaBoxesMain
603+
isLegacy={ isDevicePreview }
604+
/>
605+
)
606+
}
607+
>
608+
<PostLockedModal />
609+
<EditorInitialization />
610+
<FullscreenMode isActive={ isFullscreenActive } />
611+
<BrowserURL />
612+
<UnsavedChangesWarning />
613+
<AutosaveMonitor />
614+
<LocalAutosaveMonitor />
615+
<EditPostKeyboardShortcuts />
616+
<EditorKeyboardShortcutsRegister />
617+
<BlockKeyboardShortcuts />
618+
{ currentPostType === 'wp_block' && (
619+
<InitPatternModal />
620+
) }
621+
<PluginArea onError={ onPluginAreaError } />
622+
<PostEditorMoreMenu />
623+
{ backButton }
624+
<SnackbarNotices className="edit-post-layout__snackbar" />
625+
</Editor>
626+
</div>
627+
</ErrorBoundary>
628+
</Tooltip.Provider>
621629
</SlotFillProvider>
622630
);
623631
}

packages/edit-site/src/components/layout/index.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { PluginArea } from '@wordpress/plugins';
3131
import { SnackbarNotices, store as noticesStore } from '@wordpress/notices';
3232
import { useDispatch, useSelect } from '@wordpress/data';
3333
import { store as preferencesStore } from '@wordpress/preferences';
34+
import { Tooltip } from '@wordpress/ui';
3435

3536
/**
3637
* Internal dependencies
@@ -275,9 +276,11 @@ export default function LayoutWithGlobalStylesProvider( props ) {
275276

276277
return (
277278
<SlotFillProvider>
278-
{ /** This needs to be within the SlotFillProvider */ }
279-
<PluginArea onError={ onPluginAreaError } />
280-
<Layout { ...props } />
279+
<Tooltip.Provider>
280+
{ /** This needs to be within the SlotFillProvider */ }
281+
<PluginArea onError={ onPluginAreaError } />
282+
<Layout { ...props } />
283+
</Tooltip.Provider>
281284
</SlotFillProvider>
282285
);
283286
}

packages/edit-site/src/components/resizable-frame/index.js

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import clsx from 'clsx';
99
import { useState, useRef } from '@wordpress/element';
1010
import {
1111
ResizableBox,
12-
Tooltip as WCTooltip,
1312
__unstableMotion as motion,
1413
} from '@wordpress/components';
1514
import { useInstanceId, useReducedMotion } from '@wordpress/compose';
@@ -18,6 +17,7 @@ import { privateApis as routerPrivateApis } from '@wordpress/router';
1817
import { useSelect } from '@wordpress/data';
1918
import { store as coreStore } from '@wordpress/core-data';
2019
import { addQueryArgs } from '@wordpress/url';
20+
import { Tooltip } from '@wordpress/ui';
2121

2222
/**
2323
* Internal dependencies
@@ -294,34 +294,44 @@ function ResizableFrame( {
294294
handleComponent={ {
295295
[ isRTL() ? 'right' : 'left' ]: canvas === 'view' && (
296296
<>
297-
<WCTooltip text={ __( 'Drag to resize' ) }>
298-
{ /* Disable reason: role="separator" does in fact support aria-valuenow */ }
299-
{ /* eslint-disable-next-line jsx-a11y/role-supports-aria-props */ }
300-
<motion.button
301-
key="handle"
302-
role="separator"
303-
aria-orientation="vertical"
304-
className={ clsx(
305-
'edit-site-resizable-frame__handle',
306-
{ 'is-resizing': isResizing }
307-
) }
308-
variants={ resizeHandleVariants }
309-
animate={ currentResizeHandleVariant }
310-
aria-label={ __( 'Drag to resize' ) }
311-
aria-describedby={ resizableHandleHelpId }
312-
aria-valuenow={
313-
frameRef.current?.resizable?.offsetWidth ||
314-
undefined
297+
<Tooltip.Root>
298+
<Tooltip.Trigger
299+
render={
300+
/* role="separator" does in fact support aria-valuenow */
301+
<motion.button
302+
key="handle"
303+
role="separator"
304+
aria-orientation="vertical"
305+
className={ clsx(
306+
'edit-site-resizable-frame__handle',
307+
{ 'is-resizing': isResizing }
308+
) }
309+
variants={ resizeHandleVariants }
310+
animate={ currentResizeHandleVariant }
311+
aria-label={ __( 'Drag to resize' ) }
312+
aria-describedby={
313+
resizableHandleHelpId
314+
}
315+
aria-valuenow={
316+
frameRef.current?.resizable
317+
?.offsetWidth || undefined
318+
}
319+
aria-valuemin={ FRAME_MIN_WIDTH }
320+
aria-valuemax={ defaultSize.width }
321+
onKeyDown={
322+
handleResizableHandleKeyDown
323+
}
324+
initial="hidden"
325+
exit="hidden"
326+
whileFocus="active"
327+
whileHover="active"
328+
/>
315329
}
316-
aria-valuemin={ FRAME_MIN_WIDTH }
317-
aria-valuemax={ defaultSize.width }
318-
onKeyDown={ handleResizableHandleKeyDown }
319-
initial="hidden"
320-
exit="hidden"
321-
whileFocus="active"
322-
whileHover="active"
323330
/>
324-
</WCTooltip>
331+
<Tooltip.Popup>
332+
{ __( 'Drag to resize' ) }
333+
</Tooltip.Popup>
334+
</Tooltip.Root>
325335
<div hidden id={ resizableHandleHelpId }>
326336
{ __(
327337
'Use left and right arrow keys to resize the canvas. Hold shift to resize in larger increments.'

packages/editor/src/components/collab-sidebar/note-byline.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/**
22
* WordPress dependencies
33
*/
4-
import { Tooltip as WCTooltip } from '@wordpress/components';
5-
import { Stack } from '@wordpress/ui';
4+
import { Stack, Tooltip } from '@wordpress/ui';
65
import { __, _x } from '@wordpress/i18n';
76
import {
87
dateI18n,
@@ -95,14 +94,19 @@ export function NoteByline( { avatar, name, date, userId } ) {
9594
{ name ?? currentUserName }
9695
</span>
9796
{ date && (
98-
<WCTooltip text={ tooltipText }>
99-
<time
100-
dateTime={ commentDateTime }
101-
className="editor-collab-sidebar-panel__user-time"
102-
>
103-
{ commentDateText }
104-
</time>
105-
</WCTooltip>
97+
<Tooltip.Root>
98+
<Tooltip.Trigger
99+
render={
100+
<time
101+
dateTime={ commentDateTime }
102+
className="editor-collab-sidebar-panel__user-time"
103+
>
104+
{ commentDateText }
105+
</time>
106+
}
107+
/>
108+
<Tooltip.Popup>{ tooltipText }</Tooltip.Popup>
109+
</Tooltip.Root>
106110
) }
107111
</Stack>
108112
</>

packages/editor/src/components/collaborators-presence/avatar/component.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ extend( [ a11yPlugin ] );
1010
/**
1111
* WordPress dependencies
1212
*/
13-
import { Icon as WCIcon, Tooltip as WCTooltip } from '@wordpress/components';
13+
import { Icon as WCIcon } from '@wordpress/components';
1414
import { useMemo } from '@wordpress/element';
15+
import { Tooltip } from '@wordpress/ui';
1516

1617
/**
1718
* Internal dependencies
@@ -114,7 +115,12 @@ function Avatar( {
114115
);
115116

116117
if ( name && ( ! showBadge || label ) ) {
117-
return <WCTooltip text={ name }>{ avatar }</WCTooltip>;
118+
return (
119+
<Tooltip.Root>
120+
<Tooltip.Trigger render={ avatar } />
121+
<Tooltip.Popup>{ name }</Tooltip.Popup>
122+
</Tooltip.Root>
123+
);
118124
}
119125

120126
return avatar;

0 commit comments

Comments
 (0)