import React, { useState } from 'react'; import styled from 'styled-components'; import type { JSX } from 'react'; import type { PageAction } from '@redocly/theme/core/types'; import { PageActionsMenuItem } from '@redocly/theme/components/PageActions/PageActionsMenuItem'; import { DropdownMenuItem } from '@redocly/theme/components/Dropdown/DropdownMenuItem'; import { Link } from '@redocly/theme/components/Link/Link'; import { ButtonGroup } from '@redocly/theme/components/Button/ButtonGroup'; import { Button } from '@redocly/theme/components/Button/Button'; import { Dropdown } from '@redocly/theme/components/Dropdown/Dropdown'; import { DropdownMenu } from '@redocly/theme/components/Dropdown/DropdownMenu'; import { Spinner } from '@redocly/theme/icons/Spinner/Spinner'; import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon'; import { PageActionType, usePageActions } from '@redocly/theme/core/hooks'; type ActionState = 'idle' | 'processing' | 'done'; type PageActionProps = { pageSlug?: string; mcpUrl?: string; actions?: PageActionType[]; }; const ACTION_DONE_DISPLAY_DURATION = 1000; export function PageActions(props: PageActionProps): JSX.Element | null { const { pageSlug, mcpUrl } = props; const actions = usePageActions(pageSlug || '/', mcpUrl, props.actions); const [actionState, setActionState] = useState('idle'); if (!actions.length) { return null; } const buttonAction = actions[0]; const handleActionClick = async (action: PageAction) => { if (!('onClick' in action)) { return; } setActionState('processing'); await action.onClick(); setActionState('done'); setTimeout(() => { setActionState('idle'); }, ACTION_DONE_DISPLAY_DURATION); }; const menuItems = actions.map((action, index) => { const key = `${action.title}-${index}`; const hasLink = 'link' in action; const content = hasLink ? ( ) : ( ); return ( handleActionClick(action)}> {content} ); }); return ( {actions.length > 1 ? ( } placement="bottom" alignment="end" > {menuItems} ) : null} ); } function renderIcon(buttonAction: PageAction, actionState: ActionState) { switch (actionState) { case 'processing': return ; case 'done': return ; default: return ; } } const PageActionsWrapper = styled.div` margin-left: auto; padding-left: var(--page-actions-padding-left); --button-color: var(--page-actions-button-text-color); .button-group-size-medium .button.button-size-medium { --button-icon-left-padding: var(--page-actions-button-padding); } `; const LinkMenuItem = styled(Link)` text-decoration: none; --link-decoration: none; --link-decoration-hover: none; `; const StyledDropdown = styled(Dropdown)` --dropdown-menu-z-index: calc(var(--z-index-raised) - 1); `; const StyledDropdownMenu = styled(DropdownMenu)` --dropdown-menu-max-height: var(--page-actions-dropdown-max-height); `; const StyledDropdownMenuItem = styled(DropdownMenuItem)` &:has(a) { padding: 0; & > a { display: inline-block; width: 100%; padding: var(--dropdown-menu-item-padding-vertical) var(--dropdown-menu-item-padding-horizontal); } } `;