// Copyright 2025 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import type { FC } from 'react'; import React, { createContext, memo, useContext } from 'react'; import type { AxoBaseMenu } from './_internal/AxoBaseMenu.js'; import { assert, unreachable } from './_internal/assert.js'; import { AxoDropdownMenu } from './AxoDropdownMenu.js'; import { AxoContextMenu } from './AxoContextMenu.js'; const Namespace = 'AxoMenuBuilder'; export namespace AxoMenuBuilder { export type Renderer = 'AxoDropdownMenu' | 'AxoContextMenu'; const MenuBuilderContext = createContext(null); // eslint-disable-next-line no-inner-declarations function useMenuBuilderContext(): Renderer { const context = useContext(MenuBuilderContext); return assert(context, `Must be wrapped with <${Namespace}.Root>`); } export type RootProps = AxoBaseMenu.MenuRootProps & Readonly<{ renderer: Renderer; }>; export const Root: FC = memo(props => { const { renderer, ...rest } = props; let child: JSX.Element; if (renderer === 'AxoDropdownMenu') { child = ; } else if (renderer === 'AxoContextMenu') { child = ; } else { unreachable(renderer); } return ( {child} ); }); Root.displayName = `${Namespace}.Root`; export const Trigger: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Trigger.displayName = `${Namespace}.Trigger`; export const Content: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Content.displayName = `${Namespace}.Content`; export const Item: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Item.displayName = `${Namespace}.Item`; export const Group: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Group.displayName = `${Namespace}.Group`; export const Label: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Label.displayName = `${Namespace}.Label`; export const Separator: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Separator.displayName = `${Namespace}.Separator`; export const CheckboxItem: FC = memo( props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); } ); CheckboxItem.displayName = `${Namespace}.CheckboxItem`; export const RadioGroup: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); RadioGroup.displayName = `${Namespace}.RadioGroup`; export const RadioItem: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); RadioItem.displayName = `${Namespace}.RadioItem`; export const Sub: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); Sub.displayName = `${Namespace}.Sub`; export const SubTrigger: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); SubTrigger.displayName = `${Namespace}.SubTrigger`; export const SubContent: FC = memo(props => { const renderer = useMenuBuilderContext(); if (renderer === 'AxoDropdownMenu') { return ; } if (renderer === 'AxoContextMenu') { return ; } unreachable(renderer); }); SubContent.displayName = `${Namespace}.SubContent`; }