From 9dddc847505501c9d269d6f3a8090203711cb0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?= <67428053+kakkokari-gtyih@users.noreply.github.com> Date: Sun, 6 Jul 2025 17:24:34 +0900 Subject: [PATCH] =?UTF-8?q?refactor(frontend):=20menu=E3=81=AE=E5=9E=8B?= =?UTF-8?q?=E5=AE=9A=E7=BE=A9=E3=81=AE=E5=8F=AF=E8=AA=AD=E6=80=A7=E5=90=91?= =?UTF-8?q?=E4=B8=8A=20(#16261)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/types/menu.ts | 117 ++++++++++++++++++++++++---- 1 file changed, 101 insertions(+), 16 deletions(-) diff --git a/packages/frontend/src/types/menu.ts b/packages/frontend/src/types/menu.ts index fae7370341..6f2f08cb6d 100644 --- a/packages/frontend/src/types/menu.ts +++ b/packages/frontend/src/types/menu.ts @@ -4,10 +4,10 @@ */ import * as Misskey from 'misskey-js'; -import type { Component, ComputedRef, Ref } from 'vue'; +import type { Component, ComputedRef, Ref, MaybeRef } from 'vue'; import type { ComponentProps as CP } from 'vue-component-type-helpers'; -type ComponentProps = { [K in keyof CP]: CP[K] | Ref[K]> }; +type ComponentProps = { [K in keyof CP]: MaybeRef[K]> }; type MenuRadioOptionsDef = Record; @@ -15,22 +15,107 @@ type Text = string | ComputedRef; export type MenuAction = (ev: MouseEvent) => void; -export type MenuDivider = { type: 'divider' }; -export type MenuNull = undefined; -export type MenuLabel = { type: 'label', text: Text, caption?: Text }; -export type MenuLink = { type: 'link', to: string, text: Text, caption?: Text, icon?: string, indicate?: boolean, avatar?: Misskey.entities.User }; -export type MenuA = { type: 'a', href: string, target?: string, download?: string, text: Text, caption?: Text, icon?: string, indicate?: boolean }; -export type MenuUser = { type: 'user', user: Misskey.entities.User, active?: boolean, indicate?: boolean, action: MenuAction }; -export type MenuSwitch = { type: 'switch', ref: Ref, text: Text, caption?: Text, icon?: string, disabled?: boolean | Ref }; -export type MenuButton = { type?: 'button', text: Text, caption?: Text, icon?: string, indicate?: boolean, danger?: boolean, active?: boolean | ComputedRef, avatar?: Misskey.entities.User; action: MenuAction }; -export type MenuRadio = { type: 'radio', text: Text, caption?: Text, icon?: string, ref: Ref, options: MenuRadioOptionsDef, disabled?: boolean | Ref }; -export type MenuRadioOption = { type: 'radioOption', text: Text, caption?: Text, action: MenuAction; active?: boolean | ComputedRef }; -export type MenuComponent = { type: 'component', component: T, props?: ComponentProps }; -export type MenuParent = { type: 'parent', text: Text, caption?: Text, icon?: string, children: MenuItem[] | (() => Promise | MenuItem[]) }; +export interface MenuButton { + type?: 'button'; + text: Text; + caption?: Text; + icon?: string; + indicate?: boolean; + danger?: boolean; + active?: boolean | ComputedRef; + avatar?: Misskey.entities.User; + action: MenuAction; +} -export type MenuPending = { type: 'pending' }; +interface MenuBase { + type: string; +} -type OuterMenuItem = MenuDivider | MenuNull | MenuLabel | MenuLink | MenuA | MenuUser | MenuSwitch | MenuButton | MenuRadio | MenuRadioOption | MenuComponent | MenuParent; +export interface MenuDivider extends MenuBase { + type: 'divider'; +} + +export interface MenuLabel extends MenuBase { + type: 'label'; + text: Text; + caption?: Text; +} + +export interface MenuLink extends MenuBase { + type: 'link'; + to: string; + text: Text; + caption?: Text; + icon?: string; + indicate?: boolean; + avatar?: Misskey.entities.User; +} + +export interface MenuA extends MenuBase { + type: 'a'; + href: string; + target?: string; + download?: string; + text: Text; + caption?: Text; + icon?: string; + indicate?: boolean; +} + +export interface MenuUser extends MenuBase { + type: 'user'; + user: Misskey.entities.User; + active?: boolean; + indicate?: boolean; + action: MenuAction; +} + +export interface MenuSwitch extends MenuBase { + type: 'switch'; + ref: Ref; + text: Text; + caption?: Text; + icon?: string; + disabled?: boolean | Ref; +} + +export interface MenuRadio extends MenuBase { + type: 'radio'; + text: Text; + caption?: Text; + icon?: string; + ref: Ref; + options: MenuRadioOptionsDef; + disabled?: boolean | Ref; +} + +export interface MenuRadioOption extends MenuBase { + type: 'radioOption'; + text: Text; + caption?: Text; + action: MenuAction; + active?: boolean | ComputedRef; +} + +export interface MenuComponent extends MenuBase { + type: 'component'; + component: T; + props?: ComponentProps; +} + +export interface MenuParent extends MenuBase { + type: 'parent'; + text: Text; + caption?: Text; + icon?: string; + children: MenuItem[] | (() => Promise | MenuItem[]); +} + +export interface MenuPending extends MenuBase { + type: 'pending'; +} + +type OuterMenuItem = MenuDivider | MenuLabel | MenuLink | MenuA | MenuUser | MenuSwitch | MenuButton | MenuRadio | MenuRadioOption | MenuComponent | MenuParent; type OuterPromiseMenuItem = Promise; export type MenuItem = OuterMenuItem | OuterPromiseMenuItem; export type InnerMenuItem = MenuDivider | MenuPending | MenuLabel | MenuLink | MenuA | MenuUser | MenuSwitch | MenuButton | MenuRadio | MenuRadioOption | MenuComponent | MenuParent;