import { ActionImpl } from "kbar"; import { ArrowIcon, BackIcon } from "outline-icons"; import * as React from "react"; import styled, { css, useTheme } from "styled-components"; import { s, ellipsis } from "@shared/styles"; import Flex from "~/components/Flex"; import Key from "~/components/Key"; import Text from "./Text"; type Props = { action: ActionImpl; active: boolean; currentRootActionId: string | null | undefined; }; function CommandBarItem( { action, active, currentRootActionId }: Props, ref: React.RefObject ) { const theme = useTheme(); const ancestors = React.useMemo(() => { if (!currentRootActionId) { return action.ancestors; } const index = action.ancestors.findIndex( (ancestor) => ancestor.id === currentRootActionId ); // +1 removes the currentRootAction; e.g. if we are on the "Set theme" // parent action, the UI should not display "Set theme… > Dark" but rather // just "Dark" return action.ancestors.slice(index + 1); }, [action.ancestors, currentRootActionId]); return ( {action.icon ? ( // @ts-expect-error no icon on ActionImpl React.cloneElement(action.icon, { size: 22, }) ) : ( )} {ancestors.map((ancestor) => ( {ancestor.name} ))} {action.name} {action.children?.length ? "…" : ""} {action.shortcut?.length ? ( {action.shortcut.map((sc: string, index) => ( {index > 0 ? ( <> {" "} then {" "} ) : ( "" )} {sc.split("+").map((s) => ( {s} ))} ))} ) : null} ); } const Shortcut = styled.div` display: grid; grid-auto-flow: column; gap: 4px; `; const Icon = styled(Flex)` align-items: center; justify-content: center; width: 24px; height: 24px; color: ${s("textSecondary")}; flex-shrink: 0; `; const Ancestor = styled.span` color: ${s("textSecondary")}; `; const Content = styled(Flex)` ${ellipsis()} flex-shrink: 1; `; const Item = styled.div<{ active?: boolean }>` font-size: 14px; padding: 9px 12px; margin: 0 8px; border-radius: 4px; background: ${(props) => props.active ? props.theme.menuItemSelected : "none"}; display: flex; align-items: center; justify-content: space-between; cursor: var(--pointer); ${ellipsis()} user-select: none; min-width: 0; ${(props) => props.active && css` ${Icon} { color: ${props.theme.text}; } `} `; const ForwardIcon = styled(BackIcon)` transform: rotate(180deg); flex-shrink: 0; `; export default React.forwardRef(CommandBarItem);