Updated ad placeholder graphics, update Modrinth App sidebar to mockup designs (#4584)

* Update ad placeholders to new green graphic

* Remove rounded corners from app ad frame

* Improve web ad placeholder styling

* Revamp app sidebar to match mockups more closely, greatly improve friends UX, fix up context menus and typify shit

* only show overflow on hover

* lint

* intl:extract

* clean up the inline code in FriendsSection
This commit is contained in:
Prospector
2025-10-19 16:26:17 -07:00
committed by GitHub
parent e58456eed4
commit 6a70acef25
19 changed files with 745 additions and 340 deletions

View File

@@ -3,12 +3,13 @@
<button
v-if="!!slots.title"
:class="buttonClass ?? 'flex flex-col gap-2 bg-transparent m-0 p-0 border-none'"
@click="() => (isOpen ? close() : open())"
@click="() => (forceOpen ? undefined : toggledOpen ? close() : open())"
>
<slot name="button" :open="isOpen">
<div class="flex items-center gap-1 w-full">
<slot name="title" />
<DropdownIcon
v-if="!forceOpen"
class="ml-auto size-5 transition-transform duration-300 shrink-0"
:class="{ 'rotate-180': isOpen }"
/>
@@ -28,7 +29,7 @@
<script setup lang="ts">
import { DropdownIcon } from '@modrinth/assets'
import { ref, useSlots } from 'vue'
import { computed, ref, useSlots } from 'vue'
const props = withDefaults(
defineProps<{
@@ -37,6 +38,7 @@ const props = withDefaults(
buttonClass?: string
contentClass?: string
titleWrapperClass?: string
forceOpen?: boolean
}>(),
{
type: 'standard',
@@ -44,27 +46,29 @@ const props = withDefaults(
buttonClass: null,
contentClass: null,
titleWrapperClass: null,
forceOpen: false,
},
)
const isOpen = ref(props.openByDefault)
const toggledOpen = ref(props.openByDefault)
const isOpen = computed(() => toggledOpen.value || props.forceOpen)
const emit = defineEmits(['onOpen', 'onClose'])
const slots = useSlots()
function open() {
isOpen.value = true
toggledOpen.value = true
emit('onOpen')
}
function close() {
isOpen.value = false
toggledOpen.value = false
emit('onClose')
}
defineExpose({
open,
close,
isOpen,
isOpen: toggledOpen,
})
defineOptions({

View File

@@ -5,9 +5,11 @@
:disabled="disabled"
:dropdown-id="dropdownId"
:tooltip="tooltip"
:placement="placement"
>
<slot></slot>
<template #menu>
<slot name="menu-header" />
<template v-for="(option, index) in options.filter((x) => x.shown === undefined || x.shown)">
<div
v-if="isDivider(option)"
@@ -96,12 +98,14 @@ withDefaults(
disabled?: boolean
dropdownId?: string
tooltip?: string
placement?: string
}>(),
{
options: () => [],
disabled: false,
dropdownId: undefined,
tooltip: undefined,
placement: 'bottom-end',
},
)

View File

@@ -3,7 +3,7 @@
ref="dropdown"
no-auto-focus
:aria-id="dropdownId || null"
placement="bottom-end"
:placement="placement"
:class="dropdownClass"
@apply-hide="focusTrigger"
@apply-show="focusMenuChild"
@@ -45,6 +45,11 @@ defineProps({
default: null,
required: false,
},
placement: {
type: String,
default: 'bottom-end',
required: false,
},
})
function focusMenuChild() {

View File

@@ -17,6 +17,9 @@
"button.cancel": {
"defaultMessage": "Cancel"
},
"button.clear": {
"defaultMessage": "Clear"
},
"button.close": {
"defaultMessage": "Close"
},

View File

@@ -25,6 +25,10 @@ export const commonMessages = defineMessages({
id: 'button.cancel',
defaultMessage: 'Cancel',
},
clearButton: {
id: 'button.clear',
defaultMessage: 'Clear',
},
closeButton: {
id: 'button.close',
defaultMessage: 'Close',