mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2025-12-20 02:08:57 +00:00
206 lines
6.3 KiB
TypeScript
206 lines
6.3 KiB
TypeScript
// Copyright 2025 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
import type { FC } from 'react';
|
|
import React, { memo } from 'react';
|
|
import type { AxoBaseMenu } from './_internal/AxoBaseMenu.dom.js';
|
|
import { unreachable } from './_internal/assert.dom.js';
|
|
import { AxoDropdownMenu } from './AxoDropdownMenu.dom.js';
|
|
import { AxoContextMenu } from './AxoContextMenu.dom.js';
|
|
import {
|
|
createStrictContext,
|
|
useStrictContext,
|
|
} from './_internal/StrictContext.dom.js';
|
|
|
|
const Namespace = 'AxoMenuBuilder';
|
|
|
|
export namespace AxoMenuBuilder {
|
|
export type Renderer = 'AxoDropdownMenu' | 'AxoContextMenu';
|
|
|
|
const MenuBuilderContext = createStrictContext<Renderer>(`${Namespace}.Root`);
|
|
|
|
export type RootProps = AxoBaseMenu.MenuRootProps &
|
|
Readonly<{
|
|
renderer: Renderer;
|
|
}>;
|
|
|
|
export const Root: FC<RootProps> = memo(props => {
|
|
const { renderer, ...rest } = props;
|
|
|
|
let child: JSX.Element;
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
child = <AxoDropdownMenu.Root {...rest} />;
|
|
} else if (renderer === 'AxoContextMenu') {
|
|
child = <AxoContextMenu.Root {...rest} />;
|
|
} else {
|
|
unreachable(renderer);
|
|
}
|
|
|
|
return (
|
|
<MenuBuilderContext.Provider value={props.renderer}>
|
|
{child}
|
|
</MenuBuilderContext.Provider>
|
|
);
|
|
});
|
|
|
|
Root.displayName = `${Namespace}.Root`;
|
|
|
|
export const Trigger: FC<AxoBaseMenu.MenuTriggerProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Trigger {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Trigger {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Trigger.displayName = `${Namespace}.Trigger`;
|
|
|
|
export const Content: FC<AxoBaseMenu.MenuContentProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Content {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Content {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Content.displayName = `${Namespace}.Content`;
|
|
|
|
export const Item: FC<AxoBaseMenu.MenuItemProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Item {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Item {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Item.displayName = `${Namespace}.Item`;
|
|
|
|
export const Group: FC<AxoBaseMenu.MenuGroupProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Group {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Group {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Group.displayName = `${Namespace}.Group`;
|
|
|
|
export const Label: FC<AxoBaseMenu.MenuLabelProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Label {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Label {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Label.displayName = `${Namespace}.Label`;
|
|
|
|
export const Separator: FC<AxoBaseMenu.MenuSeparatorProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Separator {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Separator {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Separator.displayName = `${Namespace}.Separator`;
|
|
|
|
export const CheckboxItem: FC<AxoBaseMenu.MenuCheckboxItemProps> = memo(
|
|
props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.CheckboxItem {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.CheckboxItem {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
}
|
|
);
|
|
|
|
CheckboxItem.displayName = `${Namespace}.CheckboxItem`;
|
|
|
|
export const RadioGroup: FC<AxoBaseMenu.MenuRadioGroupProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.RadioGroup {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.RadioGroup {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
RadioGroup.displayName = `${Namespace}.RadioGroup`;
|
|
|
|
export const RadioItem: FC<AxoBaseMenu.MenuRadioItemProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.RadioItem {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.RadioItem {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
RadioItem.displayName = `${Namespace}.RadioItem`;
|
|
|
|
export const Sub: FC<AxoBaseMenu.MenuSubProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.Sub {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.Sub {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
Sub.displayName = `${Namespace}.Sub`;
|
|
|
|
export const SubTrigger: FC<AxoBaseMenu.MenuSubTriggerProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.SubTrigger {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.SubTrigger {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
SubTrigger.displayName = `${Namespace}.SubTrigger`;
|
|
|
|
export const SubContent: FC<AxoBaseMenu.MenuSubContentProps> = memo(props => {
|
|
const renderer = useStrictContext(MenuBuilderContext);
|
|
if (renderer === 'AxoDropdownMenu') {
|
|
return <AxoDropdownMenu.SubContent {...props} />;
|
|
}
|
|
if (renderer === 'AxoContextMenu') {
|
|
return <AxoContextMenu.SubContent {...props} />;
|
|
}
|
|
unreachable(renderer);
|
|
});
|
|
|
|
SubContent.displayName = `${Namespace}.SubContent`;
|
|
}
|