mirror of
https://github.com/modrinth/code.git
synced 2026-08-26 01:26:23 +00:00
* fix: fixed height on modal * fix: conditional auto padding being applied on user avatars * feat: allow ungrouped to be dragged * feat: add drag handle to resize num items in jump in * qa * feat: add context menu submenus * feat: hook up icon editing in sub menu * fix: breadcrumb and sidebar not matching * fix: bring back signal icon for ping and players online * feat: add compact mode for library * smaller checkmark * pnpm prepr * feat: bring back loader/game version sort * add loader symbols * refactor: compact mode with sync'd app settings * pnpm prepr * move loaders up * qa * feat: exclude loaders from randomizing
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import type {
|
|
ContextMenuAction,
|
|
ContextMenuDivider,
|
|
ContextMenuOption,
|
|
ContextMenuParentAction,
|
|
Point,
|
|
} from './types'
|
|
|
|
export function isAction(option: ContextMenuOption): option is ContextMenuAction {
|
|
return 'name' in option
|
|
}
|
|
|
|
export function isDivider(option: ContextMenuOption): option is ContextMenuDivider {
|
|
return 'type' in option && option.type === 'divider'
|
|
}
|
|
|
|
export function hasChildren(option: ContextMenuOption): option is ContextMenuParentAction {
|
|
return isAction(option) && Boolean(option.children?.length)
|
|
}
|
|
|
|
export function isInstanceLink(value: unknown) {
|
|
if (!value || typeof value !== 'object') return false
|
|
|
|
if ('instance' in value) {
|
|
const instance = value.instance
|
|
return Boolean(instance && typeof instance === 'object' && 'link' in instance && instance.link)
|
|
}
|
|
|
|
return 'link' in value && Boolean(value.link)
|
|
}
|
|
|
|
export function getFocusableButtons(buttonRefs: Map<number, HTMLElement>) {
|
|
return [...buttonRefs.entries()]
|
|
.sort(([left], [right]) => left - right)
|
|
.map(([, button]) => button)
|
|
.filter((button) => button.offsetParent !== null)
|
|
}
|
|
|
|
export function focusRelativeButton(buttons: HTMLElement[], direction: 1 | -1) {
|
|
if (!buttons.length) return
|
|
|
|
const currentIndex = buttons.indexOf(document.activeElement as HTMLElement)
|
|
const nextIndex =
|
|
currentIndex === -1 ? (direction === 1 ? 0 : buttons.length - 1) : currentIndex + direction
|
|
buttons[(nextIndex + buttons.length) % buttons.length]?.focus()
|
|
}
|
|
|
|
export function isPointInTriangle(point: Point, a: Point, b: Point, c: Point) {
|
|
const area = triangleArea(a, b, c)
|
|
const area1 = triangleArea(point, b, c)
|
|
const area2 = triangleArea(a, point, c)
|
|
const area3 = triangleArea(a, b, point)
|
|
|
|
return Math.abs(area - (area1 + area2 + area3)) < 0.5
|
|
}
|
|
|
|
function triangleArea(a: Point, b: Point, c: Point) {
|
|
return Math.abs((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2)
|
|
}
|