diff --git a/.changeset/context-menu-checked-item.md b/.changeset/context-menu-checked-item.md new file mode 100644 index 00000000..a712ae2c --- /dev/null +++ b/.changeset/context-menu-checked-item.md @@ -0,0 +1,8 @@ +--- +"@gouvfr-lasuite/ui-components": minor +--- + +✨(front) support checked items in ContextMenu + +Move `isChecked` to the shared `MenuItemAction` type so a ContextMenu item can +display the trailing checkmark already available in DropdownMenu. diff --git a/packages/ui-components/src/components/context-menu/ContextMenuProvider.tsx b/packages/ui-components/src/components/context-menu/ContextMenuProvider.tsx index 113103ed..b9bbf11f 100644 --- a/packages/ui-components/src/components/context-menu/ContextMenuProvider.tsx +++ b/packages/ui-components/src/components/context-menu/ContextMenuProvider.tsx @@ -198,6 +198,7 @@ export const ContextMenuProvider = ({ children }: PropsWithChildren) => { icon={item.icon} label={item.label} subText={item.subText} + isChecked={item.isChecked} /> ); diff --git a/packages/ui-components/src/components/context-menu/context-menu.stories.tsx b/packages/ui-components/src/components/context-menu/context-menu.stories.tsx index 9566e351..5504ad5a 100644 --- a/packages/ui-components/src/components/context-menu/context-menu.stories.tsx +++ b/packages/ui-components/src/components/context-menu/context-menu.stories.tsx @@ -77,6 +77,7 @@ import { MenuItem } from "./types"; * | `callback` | `() => void` | Callback on click | * | `isDisabled` | `boolean` | Disables the item | * | `isHidden` | `boolean` | Hides the item | + * | `isChecked` | `boolean` | Shows a trailing checkmark (selected/active item) | * | `variant` | `"default" \| "danger"` | Item style | * | `keepOpen` | `boolean` | Prevents menu from closing on click | * @@ -529,6 +530,72 @@ export const FocusHighlighting: Story = { ), }; +const SelectedOptionContent = () => { + const [sortBy, setSortBy] = useState("name"); + + const sortItems: MenuItem[] = [ + { label: "Sort by", isDisabled: true }, + { + label: "Name", + icon: sort_by_alpha, + isChecked: sortBy === "name", + callback: () => setSortBy("name"), + }, + { + label: "Date modified", + icon: schedule, + isChecked: sortBy === "date", + callback: () => setSortBy("date"), + }, + { + label: "Size", + icon: data_usage, + isChecked: sortBy === "size", + callback: () => setSortBy("size"), + }, + { type: "separator" }, + { + label: "Refresh", + icon: refresh, + callback: () => console.log("Refresh"), + }, + ]; + + return ( + + + Right-click here to pick a sort order + + Current sort: {sortBy} + + + + ); +}; + +/** + * Items with `isChecked: true` display a trailing checkmark, which marks the + * currently selected/active option (same rendering as `DropdownMenu`). + * + * Combine it with `keepOpen: true` if the user should be able to change the + * selection several times without reopening the menu. + */ +export const SelectedOption: Story = { + args: { + options: [], + children: null, + }, + render: () => , +}; + const WithModalContent = () => { const modal = useModal(); diff --git a/packages/ui-components/src/components/dropdown-menu/types.ts b/packages/ui-components/src/components/dropdown-menu/types.ts index 11642265..0edadb46 100644 --- a/packages/ui-components/src/components/dropdown-menu/types.ts +++ b/packages/ui-components/src/components/dropdown-menu/types.ts @@ -2,10 +2,9 @@ import { MenuItemAction, MenuItemSeparator } from "../menu/types"; /** * DropdownMenu option extending the shared MenuItemAction. - * Adds selection-specific props: isChecked, value. + * Adds the selection value used with `selectedValues` (`isChecked` is shared). */ export type DropdownMenuOption = MenuItemAction & { - isChecked?: boolean; value?: string; /** @deprecated Use MenuItem with { type: "separator" } instead */ showSeparator?: boolean; diff --git a/packages/ui-components/src/components/menu/types.ts b/packages/ui-components/src/components/menu/types.ts index 7b39978a..8a05d5a5 100644 --- a/packages/ui-components/src/components/menu/types.ts +++ b/packages/ui-components/src/components/menu/types.ts @@ -11,6 +11,8 @@ export type MenuItemAction = { callback?: () => void | Promise; isDisabled?: boolean; isHidden?: boolean; + /** Renders a trailing checkmark to mark the item as selected/active. */ + isChecked?: boolean; variant?: "default" | "danger"; keepOpen?: boolean; testId?: string;
Right-click here to pick a sort order
+ Current sort: {sortBy} +