hunk.code_window: 	menuGroup,
   	menuItem,
   	menuSubmenu,
   	showUiPaste,
   	useAllowGroup,
   	useAllowUngroup,
   } from './menuHelpers'
   import { useActions } from './useActions'
   import { useBreakpoint } from './useBreakpoint'
  
hunk.labels: keep keep keep replace keep keep keep keep keep
hunk.after_edit: 	showMenuPaste,
  
hunk.file_path: packages/ui/src/lib/hooks/useMenuSchema.tsx
hunk.type: replace
file: import { App, TLArrowShapeDef, useApp } from '@tldraw/editor'
  import { assert, exhaustiveSwitchError } from '@tldraw/utils'
  import { useValue } from 'signia-react'
  import { ActionItem } from './useActions'
  import { ToolItem } from './useTools'
  import { TLTranslationKey } from './useTranslation/TLTranslationKey'
  
  /** @public */
  export type MenuChild = MenuItem | SubMenu | MenuGroup | CustomMenuItem
  
  /** @public */
  export type CustomMenuItem = {
  	id: string
  	type: 'custom'
  	disabled: boolean
  	readonlyOk: boolean
  }
  
  /** @public */
  export type MenuItem = {
  	id: string
  	type: 'item'
  	readonlyOk: boolean
  	actionItem: ActionItem
  	disabled: boolean
  	checked: boolean
  }
  
  /** @public */
  export type MenuGroup = {
  	id: string
  	type: 'group'
  	checkbox: boolean
  	disabled: boolean
  	readonlyOk: boolean
  	children: MenuChild[]
  }
  
  /** @public */
  export type SubMenu = {
  	id: string
  	type: 'submenu'
  	label: TLTranslationKey
  	disabled: boolean
  	readonlyOk: boolean
  	children: MenuChild[]
  }
  
  /** @public */
  export type MenuSchema = (MenuGroup | MenuItem | CustomMenuItem)[]
  
  /** @public */
  export function compactMenuItems<T>(arr: T[]): Exclude<T, null | false | undefined>[] {
  	return arr.filter((i) => i !== undefined && i !== null && i !== false) as any
  }
  
  /** @public */
  export function menuGroup(id: string, ...children: (MenuChild | null | false)[]): MenuGroup | null {
  	const childItems = compactMenuItems(children)
  
  	if (childItems.length === 0) return null
  
  	return {
  		id,
  		type: 'group',
  		checkbox: childItems.every((child) => child.type === 'item' && child.actionItem.checkbox),
  		disabled: childItems.every((child) => child.disabled),
  		readonlyOk: childItems.some((child) => child.readonlyOk),
  		children: childItems,
  	}
  }
  
  /** @public */
  export function menuSubmenu(
  	id: string,
  	label: TLTranslationKey,
  	...children: (MenuChild | null | false)[]
  ): SubMenu | null {
  	const childItems = compactMenuItems(children)
  	if (childItems.length === 0) return null
  
  	return {
  		id,
  		type: 'submenu',
  		label,
  		children: childItems,
  		disabled: childItems.every((child) => child.disabled),
  		readonlyOk: childItems.some((child) => child.readonlyOk),
  	}
  }
  
  /** @public */
  export function menuCustom(
  	id: string,
  	opts = {} as Partial<{ readonlyOk: boolean; disabled: boolean }>
  ) {
  	const { readonlyOk = true, disabled = false } = opts
  	return {
  		id,
  		type: 'custom' as const,
  		disabled,
  		readonlyOk,
  	}
  }
  
  /** @public */
  export function menuItem(
  	actionItem: ActionItem | ToolItem,
  	opts = {} as Partial<{ checked: boolean; disabled: boolean }>
  ): MenuItem {
  	if (!actionItem) {
  		throw Error('No action item provided to menuItem')
  	}
  
  	if (!actionItem.label) {
  		throw Error("Trying to create menu item for action item that doesn't have a label")
  	}
  
  	const { checked = false, disabled = false } = opts
  
  	return {
  		id: actionItem.id,
  		type: 'item' as const,
  		actionItem,
  		disabled,
  		checked,
  		readonlyOk: actionItem.readonlyOk,
  	}
  }
  
  function shapesWithUnboundArrows(app: App) {
  	const { selectedIds } = app
  	const selectedShapes = selectedIds.map((id) => {
  		return app.getShapeById(id)
  	})
  
  	return selectedShapes.filter((shape) => {
  		if (!shape) return false
  		if (TLArrowShapeDef.is(shape) && shape.props.start.type === 'binding') {
  			return false
  		}
  		if (TLArrowShapeDef.is(shape) && shape.props.end.type === 'binding') {
  			return false
  		}
  		return true
  	})
  }
  
  /** @public */
  export const useThreeStackableItems = () => {
  	const app = useApp()
  	return useValue('threeStackableItems', () => shapesWithUnboundArrows(app).length > 2, [app])
  }
  
  /** @public */
  export const useAllowGroup = () => {
  	const app = useApp()
  	return useValue('allowGroup', () => shapesWithUnboundArrows(app).length > 1, [app])
  }
  
  /** @public */
  export const useAllowUngroup = () => {
  	const app = useApp()
  	return useValue(
  		'allowUngroup',
  		() => app.selectedIds.some((id) => app.getShapeById(id)?.type === 'group'),
  		[]
  	)
  }
  
  /** @public */
  export function findMenuItem(menu: MenuSchema, path: string[]) {
  	const item = _findMenuItem(menu, path)
  	assert(item, `Menu item ${path.join(' > ')} not found`)
  	return item
  }
  
  function _findMenuItem(menu: MenuSchema | MenuChild[], path: string[]): MenuChild | null {
  	const [next, ...rest] = path
  	if (!next) return null
  
  	const item = menu.find((item) => item.id === next)
  	if (!item) return null
  
  	switch (item.type) {
  		case 'group':
  		case 'submenu':
  			return rest.length === 0 ? item : _findMenuItem(item.children, rest)
  		case 'item':
  		case 'custom':
  			return rest.length === 0 ? item : null
  		default:
  			exhaustiveSwitchError(item, 'type')
  	}
  }
  
  export const showUiPaste =
  	typeof window !== 'undefined' &&
  	'navigator' in window &&
  	Boolean(navigator.clipboard) &&
  	Boolean(navigator.clipboard.read)
  