mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 23:55:20 +00:00
Fix MCP/Markdown copy confirmation closing dropdown instantly (#4579)
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Fix the page-actions dropdown closing before the "Copied" confirmation could be shown when copying the MCP server URL, an MCP install command, or the page as Markdown.
|
||||
@@ -98,9 +98,14 @@ const createCopiedStateStore = () => {
|
||||
set({ copied: true });
|
||||
|
||||
timeoutRef = setTimeout(() => {
|
||||
set({ copied: false });
|
||||
onSuccess?.();
|
||||
timeoutRef = null;
|
||||
|
||||
// Delay resetting the label past the dropdown's closing animation (`scaleOut`,
|
||||
// 200ms) so the "Copied" label doesn't flip back while still visible mid-fade.
|
||||
timeoutRef = setTimeout(() => {
|
||||
set({ copied: false });
|
||||
timeoutRef = null;
|
||||
}, 200);
|
||||
}, 1500);
|
||||
},
|
||||
}));
|
||||
@@ -153,13 +158,7 @@ export function ActionCopyMarkdown(props: {
|
||||
return result;
|
||||
};
|
||||
|
||||
const onClick = async (e: React.MouseEvent) => {
|
||||
// Prevent default behavior for non-default actions to avoid closing the dropdown.
|
||||
// This allows showing transient UI (e.g., a "copied" state) inside the menu item.
|
||||
if (!isDefaultAction) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
const onClick = async () => {
|
||||
copy(markdownCache.get(markdownPageURL) || (await fetchMarkdown()), {
|
||||
onSuccess: () => {
|
||||
// We close the dropdown menu if the action is a dropdown menu item and not the default action.
|
||||
@@ -179,6 +178,7 @@ export function ActionCopyMarkdown(props: {
|
||||
description={tString(language, 'copy_page_markdown')}
|
||||
onClick={onClick}
|
||||
loading={loading}
|
||||
closeOnClick={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -421,9 +421,7 @@ export function CopyToClipboard(props: {
|
||||
icon={copied ? 'check' : icon}
|
||||
label={copied ? tString(language, 'code_copied') : label}
|
||||
description={description}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
|
||||
onClick={() => {
|
||||
copy(data, {
|
||||
onSuccess: () => {
|
||||
if (type === 'dropdown-menu-item') {
|
||||
@@ -432,6 +430,7 @@ export function CopyToClipboard(props: {
|
||||
},
|
||||
});
|
||||
}}
|
||||
closeOnClick={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@@ -453,6 +452,7 @@ function PageActionWrapper(props: {
|
||||
target?: React.HTMLAttributeAnchorTarget;
|
||||
disabled?: boolean;
|
||||
loading?: boolean;
|
||||
closeOnClick?: boolean;
|
||||
}) {
|
||||
const {
|
||||
type,
|
||||
@@ -465,6 +465,7 @@ function PageActionWrapper(props: {
|
||||
description,
|
||||
disabled,
|
||||
loading,
|
||||
closeOnClick,
|
||||
} = props;
|
||||
|
||||
if (type === 'button') {
|
||||
@@ -498,6 +499,7 @@ function PageActionWrapper(props: {
|
||||
target={target}
|
||||
onClick={onClick}
|
||||
disabled={disabled || loading}
|
||||
closeOnClick={closeOnClick}
|
||||
>
|
||||
<div className="flex size-5 items-center justify-center text-tint">
|
||||
{loading ? (
|
||||
|
||||
Reference in New Issue
Block a user