mirror of
https://github.com/modrinth/code.git
synced 2026-08-29 02:54:51 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
107e0f73a9 | ||
|
|
6a88091d3d | ||
|
|
acab02878a | ||
|
|
b9a65175a0 | ||
|
|
ee60b1adbc |
@@ -9,11 +9,10 @@ import {
|
||||
WrenchIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, Collapsible, injectNotificationManager } from '@modrinth/ui'
|
||||
import { ButtonStyled, Collapsible, injectNotificationManager, Modal } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { ChatIcon } from '@/assets/icons'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { login as login_flow, set_default_user } from '@/helpers/auth.js'
|
||||
import { install_existing_instance } from '@/helpers/install'
|
||||
@@ -151,7 +150,7 @@ async function copyToClipboard(text) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper ref="errorModal" :header="title" :closable="closable">
|
||||
<Modal ref="errorModal" :header="title" :closable="closable">
|
||||
<div class="modal-body max-w-[550px]">
|
||||
<div class="markdown-body">
|
||||
<template v-if="errorType === 'minecraft_auth'">
|
||||
@@ -323,7 +322,7 @@ async function copyToClipboard(text) {
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
defineMessages,
|
||||
FileTreeSelect,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -233,7 +233,7 @@ function isExportCandidateDisabled(path) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="exportModal"
|
||||
:header="formatMessage(messages.header)"
|
||||
scrollable
|
||||
@@ -300,5 +300,5 @@ function isExportCandidateDisabled(path) {
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<template>
|
||||
<ModalWrapper
|
||||
ref="detectJavaModal"
|
||||
:header="formatMessage(messages.title)"
|
||||
:show-ad-on-close="false"
|
||||
>
|
||||
<Modal ref="detectJavaModal" :header="formatMessage(messages.title)">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Table :columns="javaInstallColumns" :data="chosenInstallOptions" row-key="path">
|
||||
<template #cell-version="{ value }">
|
||||
@@ -46,7 +42,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckIcon, PlusIcon, XIcon } from '@modrinth/assets'
|
||||
@@ -54,12 +50,12 @@ import {
|
||||
ButtonStyled,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
Modal,
|
||||
Table,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { find_filtered_jres } from '@/helpers/jre.js'
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
<script setup>
|
||||
import { CheckIcon } from '@modrinth/assets'
|
||||
import { Badge, ButtonStyled } from '@modrinth/ui'
|
||||
import { Badge, ButtonStyled, Modal } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { SwapIcon } from '@/assets/icons/index.js'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { update_managed_modrinth_version } from '@/helpers/instance'
|
||||
import { releaseColor } from '@/helpers/utils'
|
||||
|
||||
@@ -52,7 +51,7 @@ const onHide = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper
|
||||
<Modal
|
||||
ref="modpackVersionModal"
|
||||
class="modpack-version-modal"
|
||||
header="Change modpack version"
|
||||
@@ -123,7 +122,7 @@ const onHide = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script setup>
|
||||
import { ButtonStyled, injectNotificationManager, ProjectCard } from '@modrinth/ui'
|
||||
import { ButtonStyled, injectNotificationManager, Modal, ProjectCard } from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { get_project_v3, get_version } from '@/helpers/cache.js'
|
||||
import { injectContentInstall } from '@/providers/content-install'
|
||||
|
||||
@@ -45,7 +44,7 @@ async function install() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper ref="confirmModal" :header="`Install ${project?.name}`">
|
||||
<Modal ref="confirmModal" :header="`Install ${project?.name}`">
|
||||
<div class="modal-body">
|
||||
<ProjectCard
|
||||
:title="project.name"
|
||||
@@ -75,7 +74,7 @@ async function install() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useRelativeTime,
|
||||
useVIntl,
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import FriendsSection from '@/components/ui/friends/FriendsSection.vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { useFriends } from '@/composables/use-friends'
|
||||
import type { FriendWithUserData } from '@/helpers/friends.ts'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
@@ -176,7 +176,7 @@ const messages = defineMessages({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper ref="friendInvitesModal" header="View friend requests">
|
||||
<Modal ref="friendInvitesModal" header="View friend requests">
|
||||
<p v-if="incomingRequests.length === 0">You have no pending friend requests :C</p>
|
||||
<div v-else class="flex flex-col gap-4 min-w-[40rem]">
|
||||
<div v-for="friend in incomingRequests" :key="friend.username" class="flex gap-2">
|
||||
@@ -222,8 +222,8 @@ const messages = defineMessages({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
<ModalWrapper ref="addFriendModal" :header="formatMessage(messages.addingAFriend)">
|
||||
</Modal>
|
||||
<Modal ref="addFriendModal" :header="formatMessage(messages.addingAFriend)">
|
||||
<div class="min-w-[30rem]">
|
||||
<h2 class="m-0 text-base font-medium text-primary">
|
||||
{{ formatMessage(messages.usernameTitle) }}
|
||||
@@ -248,7 +248,7 @@ const messages = defineMessages({
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
<div v-if="userCredentials && !loading" class="flex gap-1 items-center mb-3 -ml-1">
|
||||
<template v-if="sortedFriends.length > 0">
|
||||
<ButtonStyled circular type="transparent">
|
||||
|
||||
@@ -5,13 +5,13 @@ import {
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
injectNotificationManager,
|
||||
Modal,
|
||||
StyledInput,
|
||||
} from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { list } from '@/helpers/instance'
|
||||
import { add_server_to_instance, get_instance_worlds } from '@/helpers/worlds.ts'
|
||||
@@ -82,7 +82,7 @@ async function addServer(instance) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ModalWrapper ref="modal" header="Add server to instance">
|
||||
<Modal ref="modal" header="Add server to instance">
|
||||
<div class="flex flex-col gap-4 min-w-[350px]">
|
||||
<Admonition type="warning" body="This server may not be compatible with all instances." />
|
||||
<StyledInput
|
||||
@@ -124,5 +124,5 @@ async function addServer(instance) {
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
+4
-4
@@ -7,7 +7,7 @@ import {
|
||||
MessagesSquareIcon,
|
||||
WrenchIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Admonition, ButtonStyled, Collapsible, NewModal } from '@modrinth/ui'
|
||||
import { Admonition, ButtonStyled, Collapsible, Modal } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import { hide_ads_window, show_ads_window } from '@/helpers/ads.js'
|
||||
@@ -16,7 +16,7 @@ import { handleSevereError } from '@/store/error.js'
|
||||
|
||||
import { findMinecraftAuthError, type MinecraftAuthError } from './minecraft-auth-errors'
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const rawError = ref<string>('')
|
||||
const matchedError = ref<MinecraftAuthError | null>(null)
|
||||
const debugCollapsed = ref(true)
|
||||
@@ -74,7 +74,7 @@ async function copyToClipboard(text: string) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal ref="modal" header="Sign in Failed" :max-width="'548px'" @hide="onModalHide">
|
||||
<Modal ref="modal" header="Sign in Failed" :max-width="'548px'" @hide="onModalHide">
|
||||
<div class="flex flex-col gap-6">
|
||||
<Admonition
|
||||
type="warning"
|
||||
@@ -191,5 +191,5 @@ async function copyToClipboard(text: string) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" max-width="544px" no-padding>
|
||||
<Modal ref="modal" :header="formatMessage(messages.header)" max-width="544px" no-padding>
|
||||
<div class="grid grid-cols-[1fr_auto] gap-2.5 h-[154px] px-7 pt-4 pb-1 pr-9">
|
||||
<div class="flex flex-col gap-2.5 items-start justify-center h-min mt-5">
|
||||
<div class="font-semibold text-xl text-contrast">
|
||||
@@ -64,12 +64,12 @@
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { MessagesSquareIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, defineMessages, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { ButtonStyled, defineMessages, Modal, useVIntl } from '@modrinth/ui'
|
||||
import { inject, type Ref, ref } from 'vue'
|
||||
|
||||
import steveImage from '@/assets/steve-look-up-left.webp'
|
||||
@@ -113,7 +113,7 @@ const messages = defineMessages({
|
||||
},
|
||||
})
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const loadingSignIn = ref(false)
|
||||
|
||||
function show() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" fade="danger" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(messages.header)" fade="danger" max-width="500px">
|
||||
<Admonition type="critical" :header="formatMessage(messages.admonitionHeader)">
|
||||
{{ formatMessage(messages.admonitionBody) }}
|
||||
</Admonition>
|
||||
@@ -20,7 +20,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
@@ -61,7 +61,7 @@ const emit = defineEmits<{
|
||||
(e: 'delete'): void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
function show() {
|
||||
modal.value?.show()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.installToPlay)"
|
||||
:closable="true"
|
||||
@@ -151,7 +151,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<ModpackContentModal
|
||||
ref="modpackContentModal"
|
||||
@@ -171,8 +171,8 @@ import {
|
||||
type ContentItem,
|
||||
defineMessages,
|
||||
formatLoader,
|
||||
Modal,
|
||||
ModpackContentModal,
|
||||
NewModal,
|
||||
Table,
|
||||
type TableColumn,
|
||||
useScrollIndicator,
|
||||
@@ -191,7 +191,7 @@ type ExternalFileRow = {
|
||||
name: string
|
||||
}
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const modpackVersionId = ref<string | null>(null)
|
||||
const modpackVersion = ref<Labrinth.Versions.v2.Version | null>(null)
|
||||
const project = ref<Labrinth.Projects.v3.Project | null>(null)
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
<!-- @deprecated Use NewModal from @modrinth/ui directly. Ads/noblur now handled by injectModalBehavior. -->
|
||||
<script setup lang="ts">
|
||||
import { NewModal as Modal } from '@modrinth/ui'
|
||||
import { useTemplateRef } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
header: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
hideHeader: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
closable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
onHide: {
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {}
|
||||
},
|
||||
},
|
||||
/** @deprecated No longer used — ads are handled by provideModalBehavior */
|
||||
showAdOnClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
})
|
||||
const modal = useTemplateRef('modal')
|
||||
|
||||
defineExpose({
|
||||
show: (e?: MouseEvent) => {
|
||||
modal.value?.show(e)
|
||||
},
|
||||
hide: () => {
|
||||
modal.value?.hide()
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="header"
|
||||
:closable="closable"
|
||||
:hide-header="hideHeader"
|
||||
:on-hide="() => props.onHide?.()"
|
||||
>
|
||||
<template #title>
|
||||
<slot name="title" />
|
||||
</template>
|
||||
<slot />
|
||||
</Modal>
|
||||
</template>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" fade="warning" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(messages.header)" fade="warning" max-width="500px">
|
||||
<p class="m-0 text-secondary">
|
||||
<IntlFormatted :message-id="messages.body" :values="{ instanceName }">
|
||||
<template #bold="{ children }">
|
||||
@@ -30,7 +30,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
@@ -72,7 +72,7 @@ const emit = defineEmits<{
|
||||
(e: 'create-anyway'): void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const instanceName = ref('')
|
||||
const instanceId = ref('')
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="formatMessage(authenticating ? messages.signingInHeader : messages.header)"
|
||||
:on-hide="handleHide"
|
||||
@@ -103,12 +103,12 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LogInIcon, RefreshCwIcon, SpinnerIcon, UserPlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, defineMessages, IntlFormatted, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { ButtonStyled, defineMessages, IntlFormatted, Modal, useVIntl } from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { ref } from 'vue'
|
||||
|
||||
@@ -119,7 +119,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const authenticating = ref<ModrinthAuthFlow | null>(null)
|
||||
const reopeningBrowser = ref(false)
|
||||
let resolveShow: ((signedIn: boolean) => void) | undefined
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" fade="danger" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(messages.header)" fade="danger" max-width="500px">
|
||||
<Admonition type="critical" :header="formatMessage(messages.admonitionHeader)">
|
||||
<IntlFormatted :message-id="messages.admonitionBody" :values="{ code: inviteCode }">
|
||||
<template #monospace="{ children }">
|
||||
@@ -24,7 +24,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -35,13 +35,13 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const inviteCode = ref('')
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" fade="warning" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(messages.header)" fade="warning" max-width="500px">
|
||||
<p class="m-0 text-secondary">
|
||||
<IntlFormatted :message-id="messages.body" :values="{ instanceName }">
|
||||
<template #bold="{ children }">
|
||||
@@ -30,7 +30,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -40,7 +40,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
@@ -71,7 +71,7 @@ const emit = defineEmits<{
|
||||
(e: 'cancel' | 'go-to-instance' | 'install-anyway'): void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const instanceName = ref('')
|
||||
|
||||
function show(name: string) {
|
||||
|
||||
+7
-7
@@ -28,7 +28,7 @@
|
||||
<span class="text-primary">{{ formatMessage(messages.unlinkDescription) }}</span>
|
||||
</div>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="unpublishModal"
|
||||
:header="formatMessage(messages.unpublishModalHeader)"
|
||||
fade="warning"
|
||||
@@ -50,8 +50,8 @@
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
</Modal>
|
||||
<Modal
|
||||
ref="unlinkModal"
|
||||
:header="formatMessage(messages.unlinkModalHeader)"
|
||||
fade="warning"
|
||||
@@ -81,7 +81,7 @@
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -92,7 +92,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
InlineBackupCreator,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
@@ -117,8 +117,8 @@ const props = withDefaults(
|
||||
},
|
||||
)
|
||||
const { formatMessage } = useVIntl()
|
||||
const unpublishModal = ref<InstanceType<typeof NewModal>>()
|
||||
const unlinkModal = ref<InstanceType<typeof NewModal>>()
|
||||
const unpublishModal = ref<InstanceType<typeof Modal>>()
|
||||
const unlinkModal = ref<InstanceType<typeof Modal>>()
|
||||
const backupCreator = ref<InstanceType<typeof InlineBackupCreator>>()
|
||||
const backupBusy = ref(false)
|
||||
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="
|
||||
reportMode
|
||||
@@ -242,7 +242,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<ModpackContentModal
|
||||
ref="contentModal"
|
||||
:header="formatMessage(messages.sharedInstanceContent)"
|
||||
@@ -270,8 +270,8 @@ import {
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
MarkdownEditor,
|
||||
Modal,
|
||||
ModpackContentModal,
|
||||
NewModal,
|
||||
Table,
|
||||
type TableColumn,
|
||||
useScrollIndicator,
|
||||
@@ -302,7 +302,7 @@ type SharedInstanceCreator = {
|
||||
avatarUrl: string | null
|
||||
}
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const contentModal = ref<InstanceType<typeof ModpackContentModal>>()
|
||||
const externalFileTable = ref<HTMLElement | null>(null)
|
||||
const preview = ref<SharedInstanceInstallPreview | null>(null)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :on-hide="handleModalHide">
|
||||
<Modal ref="modal" :on-hide="handleModalHide">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">
|
||||
{{ formatMessage(mode === 'edit' ? messages.editSkinTitle : messages.addSkinTitle) }}
|
||||
@@ -127,7 +127,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -139,7 +139,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
RadioButtons,
|
||||
SkinPreviewRenderer,
|
||||
useScrollIndicator,
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
@@ -29,7 +29,7 @@ const props = defineProps<{
|
||||
instance: GameInstance
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const name = ref('')
|
||||
const address = ref('')
|
||||
@@ -88,7 +88,7 @@ const messages = defineMessages({
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.title)" width="500px" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(messages.title)" width="500px" max-width="500px">
|
||||
<ServerModalBody
|
||||
v-model:name="name"
|
||||
v-model:address="address"
|
||||
@@ -116,5 +116,5 @@ defineExpose({ show, hide })
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
@@ -59,7 +59,7 @@ const messages = defineMessages({
|
||||
},
|
||||
})
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const isServer = computed(() => props.world?.type === 'server')
|
||||
const isSingleplayer = computed(() => props.world?.type === 'singleplayer')
|
||||
@@ -94,7 +94,7 @@ defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(titleMessage)" fade="danger" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(titleMessage)" fade="danger" max-width="500px">
|
||||
<div class="flex flex-col gap-4">
|
||||
<Admonition
|
||||
type="critical"
|
||||
@@ -120,5 +120,5 @@ defineExpose({ show, hide })
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessage,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
@@ -32,7 +32,7 @@ const props = defineProps<{
|
||||
instance: GameInstance
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const name = ref<string>('')
|
||||
const address = ref<string>('')
|
||||
@@ -96,7 +96,7 @@ const titleMessage = defineMessage({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(titleMessage)" width="500px" max-width="500px">
|
||||
<Modal ref="modal" :header="formatMessage(titleMessage)" width="500px" max-width="500px">
|
||||
<ServerModalBody
|
||||
v-model:name="name"
|
||||
v-model:address="address"
|
||||
@@ -119,5 +119,5 @@ const titleMessage = defineMessage({
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -6,12 +6,12 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import HideFromHomeOption from '@/components/ui/world/modal/HideFromHomeOption.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import type { DisplayStatus, SingleplayerWorld } from '@/helpers/worlds.ts'
|
||||
@@ -94,7 +94,7 @@ const messages = defineMessages({
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<ModalWrapper ref="modal">
|
||||
<Modal ref="modal">
|
||||
<template #title>
|
||||
<Avatar :src="removeIcon || !icon ? undefined : icon" size="24px" />
|
||||
{{ instance.name }} <ChevronRightIcon />
|
||||
@@ -132,5 +132,5 @@ const messages = defineMessages({
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</ModalWrapper>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.header)"
|
||||
max-width="470px"
|
||||
@@ -44,7 +44,7 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -55,7 +55,7 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
@@ -64,7 +64,7 @@ import { methodLabels, type ShareRow } from './shared-instance-share-types'
|
||||
|
||||
const props = defineProps<{ row: ShareRow | null; memberCount: number }>()
|
||||
const emit = defineEmits<{ confirm: [row: ShareRow]; clear: [] }>()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const username = computed(() => props.row?.username ?? '')
|
||||
const messages = defineMessages({
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="formatMessage(analyticsChartMessages.renderLimitHeader, { count: tableProjectCount })"
|
||||
fade="warning"
|
||||
@@ -24,11 +24,11 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { ButtonStyled, Modal, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import { analyticsChartMessages } from '../../analytics-messages'
|
||||
|
||||
@@ -41,7 +41,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const modal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const modal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
|
||||
function show(event: MouseEvent) {
|
||||
modal.value?.show(event)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" fade="warning" width="550px">
|
||||
<Modal ref="modal" fade="warning" width="550px">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-lg font-extrabold text-contrast">Transfer</span>
|
||||
@@ -71,12 +71,12 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RightArrowIcon, TransferIcon, XIcon } from '@modrinth/assets'
|
||||
import { Admonition, Avatar, ButtonStyled, NewModal, StyledInput } from '@modrinth/ui'
|
||||
import { Admonition, Avatar, ButtonStyled, Modal, StyledInput } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -86,7 +86,7 @@ const props = defineProps<{
|
||||
onConfirm: () => void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const confirmationText = ref('')
|
||||
|
||||
const isConfirmEnabled = computed(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" fade="warning" width="550px">
|
||||
<Modal ref="modal" fade="warning" width="550px">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="text-lg font-extrabold text-contrast">Transfer</span>
|
||||
@@ -78,12 +78,12 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { RightArrowIcon, TransferIcon, XIcon } from '@modrinth/assets'
|
||||
import { Admonition, Avatar, ButtonStyled, NewModal, StyledInput } from '@modrinth/ui'
|
||||
import { Admonition, Avatar, ButtonStyled, Modal, StyledInput } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -98,7 +98,7 @@ const props = defineProps<{
|
||||
onConfirm: () => void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const confirmationText = ref('')
|
||||
|
||||
const isConfirmEnabled = computed(
|
||||
|
||||
@@ -1,156 +0,0 @@
|
||||
<template>
|
||||
<div v-if="shown">
|
||||
<div
|
||||
:class="{
|
||||
shown: actuallyShown,
|
||||
noblur: !$orElse(cosmetics.advancedRendering, true),
|
||||
}"
|
||||
class="modal-overlay"
|
||||
@click="hide"
|
||||
/>
|
||||
<div class="modal-container" :class="{ shown: actuallyShown }">
|
||||
<div class="modal-body">
|
||||
<div v-if="header" class="header">
|
||||
<strong>{{ header }}</strong>
|
||||
<ButtonStyled circular type="transparent">
|
||||
<button @click="hide">
|
||||
<XIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled } from '@modrinth/ui'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ButtonStyled,
|
||||
XIcon,
|
||||
},
|
||||
props: {
|
||||
header: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
},
|
||||
setup() {
|
||||
const cosmetics = useCosmetics()
|
||||
|
||||
return { cosmetics }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shown: false,
|
||||
actuallyShown: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
show() {
|
||||
this.shown = true
|
||||
setTimeout(() => {
|
||||
this.actuallyShown = true
|
||||
}, 50)
|
||||
},
|
||||
hide() {
|
||||
this.actuallyShown = false
|
||||
setTimeout(() => {
|
||||
this.shown = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.modal-overlay {
|
||||
visibility: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 20;
|
||||
transition: all 0.3s ease-in-out;
|
||||
|
||||
&.shown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
background: hsla(0, 0%, 0%, 0.5);
|
||||
backdrop-filter: blur(3px);
|
||||
}
|
||||
|
||||
&.noblur {
|
||||
backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 21;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
|
||||
&.shown {
|
||||
visibility: visible;
|
||||
|
||||
.modal-body {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
position: fixed;
|
||||
box-shadow: var(--shadow-raised), var(--shadow-inset);
|
||||
border-radius: var(--size-rounded-lg);
|
||||
max-height: calc(100% - 2 * var(--spacing-card-bg));
|
||||
overflow-y: auto;
|
||||
width: 600px;
|
||||
pointer-events: auto;
|
||||
outline: 3px solid transparent;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: var(--color-bg);
|
||||
padding: var(--spacing-card-md) var(--spacing-card-lg);
|
||||
|
||||
strong {
|
||||
font-size: 1.25rem;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: var(--color-raised-bg);
|
||||
}
|
||||
|
||||
transform: translateY(50vh);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.25s ease-in-out;
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
width: calc(100% - 2 * var(--spacing-card-bg));
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalOpen"
|
||||
:header="formatMessage(messages.transferProjectsTitle)"
|
||||
no-padding
|
||||
@@ -83,7 +83,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<ButtonStyled>
|
||||
<button @click="show($event)">
|
||||
<TransferIcon />
|
||||
@@ -101,7 +101,7 @@ import {
|
||||
commonMessages,
|
||||
CopyCode,
|
||||
defineMessages,
|
||||
NewModal,
|
||||
Modal,
|
||||
Table,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :on-show="onShow" :on-hide="onHide" width="544px" actions-divider>
|
||||
<Modal ref="modal" :on-show="onShow" :on-hide="onHide" width="544px" actions-divider>
|
||||
<template #title>
|
||||
<template v-if="project">
|
||||
<Avatar :src="project.icon_url" :alt="project.title" class="icon" size="32px" />
|
||||
@@ -87,7 +87,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -102,7 +102,7 @@ import {
|
||||
injectNotificationManager,
|
||||
type JoinedButtonAction,
|
||||
JoinedButtons,
|
||||
NewModal,
|
||||
Modal,
|
||||
ServersPromo,
|
||||
truncatedTooltip,
|
||||
useDebugLogger,
|
||||
@@ -146,7 +146,7 @@ type DownloadedFile = DownloadableFile & {
|
||||
|
||||
type DownloadActionType = 'zip' | 'dependencies' | 'recommended'
|
||||
|
||||
type NewModalRef = {
|
||||
type ModalRef = {
|
||||
show: (event?: MouseEvent) => void
|
||||
hide: () => void
|
||||
}
|
||||
@@ -191,7 +191,7 @@ const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
const debug = useDebugLogger('DownloadModal')
|
||||
|
||||
const modal = ref<NewModalRef | null>(null)
|
||||
const modal = ref<ModalRef | null>(null)
|
||||
const downloadTitleRef = ref<HTMLElement | null>(null)
|
||||
const modalOpening = ref(false)
|
||||
const modalOpen = ref(false)
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
ButtonStyled,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
ServerNotice,
|
||||
StyledInput,
|
||||
TagItem,
|
||||
@@ -18,7 +18,7 @@ const client = injectModrinthClient()
|
||||
|
||||
type ServerNoticeType = Archon.Notices.v0.ListedNotice
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void
|
||||
@@ -107,7 +107,7 @@ function hide() {
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
<template>
|
||||
<NewModal ref="modal" :on-hide="() => emit('close')">
|
||||
<Modal ref="modal" :on-hide="() => emit('close')">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">
|
||||
Editing assignments of notice #{{ notice?.id }}
|
||||
@@ -202,5 +202,5 @@ defineExpose({ show, hide })
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal">
|
||||
<Modal ref="modal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">Batch credit</span>
|
||||
</template>
|
||||
@@ -125,7 +125,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -135,7 +135,7 @@ import {
|
||||
Combobox,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
TagItem,
|
||||
Toggle,
|
||||
@@ -148,7 +148,7 @@ import { useBaseFetch } from '#imports'
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const days = ref(1)
|
||||
const sendEmail = ref(true)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal">
|
||||
<Modal ref="modal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">Schedule transfer</span>
|
||||
</template>
|
||||
@@ -189,7 +189,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -200,7 +200,7 @@ import {
|
||||
Combobox,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
TagItem,
|
||||
Toggle,
|
||||
@@ -215,7 +215,7 @@ const emit = defineEmits<{
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const client = injectModrinthClient()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
const modeOptions = [
|
||||
{ value: 'servers', label: 'Servers' },
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@proceed="removePasskey()"
|
||||
/>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="managePasskeyModal"
|
||||
width="600px"
|
||||
:header="formatMessage(messages.managePasskeyTitle)"
|
||||
@@ -99,9 +99,9 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="addPasskeyModal"
|
||||
width="500px"
|
||||
:header="formatMessage(messages.passkeyAddModalTitle)"
|
||||
@@ -138,9 +138,9 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="renamePasskeyModal"
|
||||
width="500px"
|
||||
:header="formatMessage(messages.renamePasskeyModalHeader)"
|
||||
@@ -177,7 +177,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<div class="adjacent-input mb-0">
|
||||
<label for="manage-passkeys">
|
||||
@@ -215,7 +215,7 @@ import {
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useFormatDateTime,
|
||||
useRelativeTime,
|
||||
@@ -316,9 +316,9 @@ const messages = defineMessages({
|
||||
})
|
||||
|
||||
const removePasskeyModal = useTemplateRef<InstanceType<typeof ConfirmModal>>('removePasskeyModal')
|
||||
const managePasskeyModal = useTemplateRef<InstanceType<typeof NewModal>>('managePasskeyModal')
|
||||
const addPasskeyModal = useTemplateRef<InstanceType<typeof NewModal>>('addPasskeyModal')
|
||||
const renamePasskeyModal = useTemplateRef<InstanceType<typeof NewModal>>('renamePasskeyModal')
|
||||
const managePasskeyModal = useTemplateRef<InstanceType<typeof Modal>>('managePasskeyModal')
|
||||
const addPasskeyModal = useTemplateRef<InstanceType<typeof Modal>>('addPasskeyModal')
|
||||
const renamePasskeyModal = useTemplateRef<InstanceType<typeof Modal>>('renamePasskeyModal')
|
||||
|
||||
const pendingPasskey = ref<Labrinth.Auth.v2.PasskeyRegisterFinishRequest | null>(null)
|
||||
const passkeyToRemove = ref<Labrinth.Auth.v2.Passkey | null>(null)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.title)">
|
||||
<Modal ref="modal" :header="formatMessage(messages.title)">
|
||||
<div class="min-w-md flex max-w-md flex-col gap-3">
|
||||
<CreateLimitAlert v-model="hasHitLimit" type="collection" />
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -52,7 +52,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
<script setup>
|
||||
import { PlusIcon, XIcon } from '@modrinth/assets'
|
||||
@@ -61,7 +61,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.title)">
|
||||
<Modal ref="modal" :header="formatMessage(messages.title)">
|
||||
<div class="min-w-md flex max-w-md flex-col gap-3">
|
||||
<CreateLimitAlert v-model="hasHitLimit" type="org" />
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -73,7 +73,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -83,7 +83,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -142,7 +142,7 @@ const slug = ref<string>('')
|
||||
const description = ref<string>('')
|
||||
const manualSlug = ref<boolean>(false)
|
||||
const hasHitLimit = ref<boolean>(false)
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
|
||||
async function createOrganization(): Promise<void> {
|
||||
startLoading()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:header="
|
||||
projectType === 'server'
|
||||
@@ -125,7 +125,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -140,7 +140,7 @@ import {
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -264,7 +264,7 @@ const props = defineProps<{
|
||||
organizationId?: string | null
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
const hasHitLimit = ref(false)
|
||||
|
||||
const name = ref('')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="taxFormModal"
|
||||
:header="formatMessage(messages.taxFormHeader)"
|
||||
:hide-header="currentStage === 'download-confirmation'"
|
||||
@@ -151,7 +151,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -171,7 +171,7 @@ import {
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
normalizeChildren,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -191,7 +191,7 @@ const props = withDefaults(
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
const taxFormModal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const taxFormModal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
|
||||
type ModalStage = 'form-selection' | 'download-confirmation'
|
||||
const currentStage = ref<ModalStage>('form-selection')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="withdrawModal"
|
||||
:closable="currentStage !== 'completion'"
|
||||
:hide-header="currentStage === 'completion'"
|
||||
@@ -93,7 +93,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<CreatorTaxFormModal
|
||||
ref="taxFormModal"
|
||||
:close-button-text="formatMessage(commonMessages.continueButton)"
|
||||
@@ -118,7 +118,7 @@ import {
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, nextTick, onMounted, ref, useTemplateRef, watch } from 'vue'
|
||||
@@ -151,7 +151,7 @@ const emit = defineEmits<{
|
||||
(e: 'refresh-data' | 'hide'): void
|
||||
}>()
|
||||
|
||||
const withdrawModal = useTemplateRef<InstanceType<typeof NewModal>>('withdrawModal')
|
||||
const withdrawModal = useTemplateRef<InstanceType<typeof Modal>>('withdrawModal')
|
||||
const taxFormModal = ref<InstanceType<typeof CreatorTaxFormModal> | null>(null)
|
||||
const isSubmitting = ref(false)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { ClipboardCopyIcon, DownloadIcon, LoaderCircleIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, CopyCode, NewModal, useDebugLogger } from '@modrinth/ui'
|
||||
import { ButtonStyled, CopyCode, Modal, useDebugLogger } from '@modrinth/ui'
|
||||
import { ref, useTemplateRef } from 'vue'
|
||||
|
||||
export type UnsafeFile = {
|
||||
@@ -18,7 +18,7 @@ const props = defineProps<{
|
||||
|
||||
const debug = useDebugLogger('MaliciousSummaryModal')
|
||||
|
||||
const modalRef = useTemplateRef<InstanceType<typeof NewModal>>('modalRef')
|
||||
const modalRef = useTemplateRef<InstanceType<typeof Modal>>('modalRef')
|
||||
|
||||
const versionDataCache = ref<
|
||||
Map<
|
||||
@@ -96,7 +96,7 @@ defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalRef"
|
||||
header="Malicious file(s) summary"
|
||||
:close-on-click-outside="false"
|
||||
@@ -182,5 +182,5 @@ defineExpose({ show, hide })
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
Table,
|
||||
type TableColumn,
|
||||
useVIntl,
|
||||
@@ -136,7 +136,7 @@ const props = defineProps<{
|
||||
const client = injectModrinthClient()
|
||||
const queryClient = useQueryClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const modalRef = useTemplateRef<InstanceType<typeof NewModal>>('modalRef')
|
||||
const modalRef = useTemplateRef<InstanceType<typeof Modal>>('modalRef')
|
||||
const clearModalRef = useTemplateRef<InstanceType<typeof ConfirmModal>>('clearModalRef')
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -373,7 +373,7 @@ defineExpose({ show, hide })
|
||||
@proceed="clearAllGroups"
|
||||
/>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalRef"
|
||||
width="60vw"
|
||||
:close-on-click-outside="false"
|
||||
@@ -517,5 +517,5 @@ defineExpose({ show, hide })
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalSubmit"
|
||||
:header="
|
||||
formatMessage(
|
||||
@@ -56,8 +56,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal ref="modalReply" :header="formatMessage(messages.replyModalHeader)">
|
||||
</Modal>
|
||||
<Modal ref="modalReply" :header="formatMessage(messages.replyModalHeader)">
|
||||
<div class="flex max-w-[45rem] flex-col gap-3">
|
||||
<p class="m-0">{{ formatMessage(messages.replyModalDescription) }}</p>
|
||||
<p class="m-0">
|
||||
@@ -98,7 +98,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<div v-if="flags.developerMode" class="mx-4 mb-3 font-semibold">
|
||||
Thread ID:
|
||||
<CopyCode :text="thread.id" />
|
||||
@@ -430,7 +430,7 @@ import {
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
MarkdownEditor,
|
||||
NewModal,
|
||||
Modal,
|
||||
OverflowMenu,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
@@ -2744,24 +2744,15 @@
|
||||
"settings.applications.about": {
|
||||
"message": "O"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Zrušit"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Vytvořit aplikaci"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Smazat"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Upravit"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nová aplikace"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Uložit změny"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Nahrát ikonu"
|
||||
},
|
||||
|
||||
@@ -2945,24 +2945,15 @@
|
||||
"settings.applications.button.add-more": {
|
||||
"message": "Tilføj mere"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Annuller"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Opret app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Slet"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Rediger"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Ny applikation"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Gem ændringer"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Upload ikon"
|
||||
},
|
||||
|
||||
@@ -4679,24 +4679,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Weiterleitungs-URI hinzufügen"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Abbrechen"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "App erstellen"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Löschen"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Bearbeiten"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Neue Anwendung"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Änderungen speichern"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Icon hochladen"
|
||||
},
|
||||
|
||||
@@ -4679,24 +4679,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Weiterleitungs-URI hinzufügen"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Abbrechen"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Anwendung erstellen"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Löschen"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Bearbeiten"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Neue Anwendung"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Änderungen speichern"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Icon hochladen"
|
||||
},
|
||||
|
||||
@@ -4709,24 +4709,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Add a redirect URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Cancel"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Create app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Delete"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Edit"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "New application"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Save changes"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Upload icon"
|
||||
},
|
||||
|
||||
@@ -4187,24 +4187,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Agregar un URI de redirección"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Cancelar"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Crear aplicación"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Borrar"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Editar"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nueva aplicación"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Guardar cambios"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Cargar icono"
|
||||
},
|
||||
|
||||
@@ -3860,24 +3860,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Añadir una URI de redirección"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Cancelar"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Crear aplicación"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Eliminar"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Editar"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nueva aplicación"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Guardar cambios"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Subir icono"
|
||||
},
|
||||
|
||||
@@ -2840,24 +2840,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Magdagdag ng redirect URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Kanselahin"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Lumikha ng app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Tanggalin"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Baguhin"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Bagong aplikasyon"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "I-save ang mga pagbabago"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "I-upload ang ikono"
|
||||
},
|
||||
|
||||
@@ -4667,24 +4667,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Ajouter une URI de redirection"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Annuler"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Créer une appli"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Supprimer"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Modifier"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nouvelle application"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Sauvegarder les changements"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Charger une icône"
|
||||
},
|
||||
|
||||
@@ -2282,9 +2282,6 @@
|
||||
"settings.account.data-export.description": {
|
||||
"message": "תבקש עותק של כל הדאטה האישי שהעלית ל-Modrinth. זה יכול לקחת כמה דקות."
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "ערוך"
|
||||
},
|
||||
"settings.applications.field.name": {
|
||||
"message": "שם"
|
||||
},
|
||||
|
||||
@@ -4130,24 +4130,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Átírányítás URI hozzáadása"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Mégse"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Alkalmazás létrehozása"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Törlés"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Szerkesztés"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Új alkalmazás"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Módosítások mentése"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Ikon feltöltése"
|
||||
},
|
||||
|
||||
@@ -2918,24 +2918,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Tambah URI pengarahan ulang"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Batal"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Buat aplikasi"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Hapus"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Sunting"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Aplikasi baru"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Simpan perubahan"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Unggah ikon"
|
||||
},
|
||||
|
||||
@@ -4667,24 +4667,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Aggiungi reindirizzamento"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Annulla"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Crea app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Elimina"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Modifica"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nuova applicazione"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Salva modifiche"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Carica icona"
|
||||
},
|
||||
|
||||
@@ -3620,24 +3620,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "リダイレクトURIを追加"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "キャンセル"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "アプリを作成する"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "削除"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "編集"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "新規アプリケーション"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "変更を保存する"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "アイコンをアップロード"
|
||||
},
|
||||
|
||||
@@ -4631,24 +4631,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "리디렉션 URI 를 추가하세요"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "취소"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "앱 만들기"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "지우기"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "편집"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "새 애플리케이션"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "변경사항 저장"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "아이콘 업로드"
|
||||
},
|
||||
|
||||
@@ -3653,24 +3653,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Tambah URI pengubah hala"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Batal"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Cipta aplikasi"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Padam"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Sunting"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Aplikasi baharu"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Simpan perubahan"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Muat naik ikon"
|
||||
},
|
||||
|
||||
@@ -4706,24 +4706,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Voeg een URI toe"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Annuleren"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Maak nieuwe"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Verwijder"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Bewerk"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nieuw project"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Wijzigingen opslaan"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Pictogram uploaden"
|
||||
},
|
||||
|
||||
@@ -3539,24 +3539,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Legg til en omdirings-URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Avbryt"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Lag app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Slett"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Regiser"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Ny søknad"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Lagre endringer"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Last opp ikon"
|
||||
},
|
||||
|
||||
@@ -4622,24 +4622,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Dodaj URI przekierowywania"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Anuluj"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Stwórz aplikację"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Usuń"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Edytuj"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nowa aplikacja"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Zapisz zmiany"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Prześlij ikonę"
|
||||
},
|
||||
|
||||
@@ -4709,24 +4709,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Adicionar URI de redirecionamento"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Cancelar"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Criar app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Excluir"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Editar"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Novo aplicativo"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Salvar alterações"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Enviar ícone"
|
||||
},
|
||||
|
||||
@@ -3350,24 +3350,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Adicionar um endereço de redirecionamento"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Cancelar"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Criar app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Apagar"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Editar"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Nova aplicação"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Guardar alterações"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Carregar ícone"
|
||||
},
|
||||
|
||||
@@ -1814,21 +1814,12 @@
|
||||
"settings.applications.about": {
|
||||
"message": "Despre"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Anuleaza"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Creaza aplicația"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Sterge"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Editeaza"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Salvează schimbările"
|
||||
},
|
||||
"settings.applications.client-id": {
|
||||
"message": "ID Client"
|
||||
},
|
||||
|
||||
@@ -4655,24 +4655,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Добавить адрес перенаправления"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Отмена"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Создать приложение"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Удалить"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Изменить"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Новое приложение"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Сохранить изменения"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Загрузить иконку"
|
||||
},
|
||||
|
||||
@@ -3713,24 +3713,15 @@
|
||||
"settings.applications.button.add-more": {
|
||||
"message": "Lägg till mer"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Avbryt"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Skapa app"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Ta bort"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Redigera"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Ny applikation"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Spara ändringar"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Ladda upp ikon"
|
||||
},
|
||||
|
||||
@@ -4118,24 +4118,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Yönlendirme URI'ları ekle"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "İptal"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Uygulama oluştur"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Sil"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Düzenle"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Yeni uygulama"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Değişiklikleri kaydet"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Simge yükle"
|
||||
},
|
||||
|
||||
@@ -4631,24 +4631,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Додати переадресацію URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Скасувати"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Створити застосунок"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Видалити"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Редагувати"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Новий застосунок"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Зберегти зміни"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Завантажити значок"
|
||||
},
|
||||
|
||||
@@ -3818,24 +3818,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "Thêm URI chuyển hướng"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "Huỷ"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "Tạo ứng dụng"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "Xoá"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "Chỉnh sửa"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "Ứng dụng mới"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "Lưu thay đổi"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "Tải lên biểu tượng"
|
||||
},
|
||||
|
||||
@@ -4709,24 +4709,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "添加重定向 URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "取消"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "新建 App"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "删除"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "编辑"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "新建应用程序"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "保存更改"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "上传图标"
|
||||
},
|
||||
|
||||
@@ -4709,24 +4709,15 @@
|
||||
"settings.applications.button.add-redirect-uri": {
|
||||
"message": "新增重新導向 URI"
|
||||
},
|
||||
"settings.applications.button.cancel": {
|
||||
"message": "取消"
|
||||
},
|
||||
"settings.applications.button.create": {
|
||||
"message": "建立應用程式"
|
||||
},
|
||||
"settings.applications.button.delete": {
|
||||
"message": "刪除"
|
||||
},
|
||||
"settings.applications.button.edit": {
|
||||
"message": "編輯"
|
||||
},
|
||||
"settings.applications.button.new": {
|
||||
"message": "新的應用程式"
|
||||
},
|
||||
"settings.applications.button.save-changes": {
|
||||
"message": "儲存變更"
|
||||
},
|
||||
"settings.applications.button.upload-icon": {
|
||||
"message": "上傳圖示"
|
||||
},
|
||||
|
||||
@@ -305,7 +305,7 @@ import {
|
||||
DropArea,
|
||||
FileInput,
|
||||
injectProjectPageContext,
|
||||
NewModal as Modal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useFormatDateTime,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
@@ -295,7 +295,7 @@ import {
|
||||
DropArea,
|
||||
FileInput,
|
||||
injectProjectPageContext,
|
||||
NewModal as Modal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useFormatDateTime,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
:proceed-label="formatMessage(messages.proceedDeletion)"
|
||||
@proceed="deleteVersion()"
|
||||
/>
|
||||
<NewModal
|
||||
<Modal
|
||||
v-if="auth.user && currentMember"
|
||||
ref="packageModal"
|
||||
:header="formatMessage(messages.packageDataPackHeader)"
|
||||
@@ -79,7 +79,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<ProjectDownloadModal
|
||||
ref="dependencyDownloadModal"
|
||||
download-reason="dependency"
|
||||
@@ -513,8 +513,8 @@ import {
|
||||
injectNotificationManager,
|
||||
injectProjectPageContext,
|
||||
IntlFormatted,
|
||||
Modal,
|
||||
MultiSelect,
|
||||
NewModal,
|
||||
OverflowMenu,
|
||||
useFormatBytes,
|
||||
useFormatDateTime,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
@proceed="confirmDeleteEvent"
|
||||
/>
|
||||
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="eventModal"
|
||||
:header="modalMode === 'create' ? 'New event' : 'Edit event'"
|
||||
width="480px"
|
||||
@@ -121,7 +121,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<div class="normal-page no-sidebar">
|
||||
<div class="normal-page__content flex flex-col gap-4">
|
||||
@@ -245,9 +245,9 @@ import {
|
||||
DatePicker,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
Modal,
|
||||
MultiSelect,
|
||||
type MultiSelectOption,
|
||||
NewModal,
|
||||
type SortDirection,
|
||||
StyledInput,
|
||||
Table,
|
||||
@@ -318,7 +318,7 @@ const metricKindOptions: MultiSelectOption<AnalyticsEventMetricKind>[] = [
|
||||
const allMetricKinds = metricKindOptions.map((option) => option.value)
|
||||
|
||||
const deleteEventModal = ref<InstanceType<typeof ConfirmModal> | null>(null)
|
||||
const eventModal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const eventModal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
const titleInput = ref<InstanceType<typeof StyledInput> | null>(null)
|
||||
const searchQuery = ref('')
|
||||
const sortColumn = ref<EventColumnKey | undefined>('date')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="refundModal">
|
||||
<Modal ref="refundModal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">Refund charge</span>
|
||||
</template>
|
||||
@@ -57,8 +57,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal ref="modifyModal">
|
||||
</Modal>
|
||||
<Modal ref="modifyModal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">Modify charge</span>
|
||||
</template>
|
||||
@@ -96,8 +96,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal ref="creditModal">
|
||||
</Modal>
|
||||
<Modal ref="creditModal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">Credit subscription</span>
|
||||
</template>
|
||||
@@ -131,7 +131,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<div class="page">
|
||||
<div
|
||||
class="mb-4 flex items-center justify-between border-0 border-b border-solid border-divider pb-4"
|
||||
@@ -232,7 +232,7 @@ import {
|
||||
DropdownSelect,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
Toggle,
|
||||
useFormatDateTime,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { CopyIcon, LibraryIcon, PlayIcon, SearchIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, NewModal, StyledInput } from '@modrinth/ui'
|
||||
import { ButtonStyled, Modal, StyledInput } from '@modrinth/ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
|
||||
import emails from '~/templates/emails'
|
||||
@@ -126,7 +126,7 @@ onMounted(() => {
|
||||
<template>
|
||||
<div class="normal-page no-sidebar">
|
||||
<h1 class="mb-4 text-3xl font-extrabold text-heading">Email templates</h1>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="previewModal"
|
||||
header="Preview email"
|
||||
width="min(92vw, 1000px)"
|
||||
@@ -188,7 +188,7 @@ onMounted(() => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<div class="normal-page__content">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<StyledInput
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="createNoticeModal">
|
||||
<Modal ref="createNoticeModal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">{{
|
||||
editingNotice ? `Editing notice #${editingNotice?.id}` : 'Creating a notice'
|
||||
@@ -118,7 +118,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<AssignNoticeModal ref="assignNoticeModal" @close="refreshNotices" />
|
||||
<div class="page">
|
||||
<div
|
||||
@@ -270,7 +270,7 @@ import {
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
NewModal,
|
||||
Modal,
|
||||
ServerNotice,
|
||||
StyledInput,
|
||||
TagItem,
|
||||
@@ -301,7 +301,7 @@ const formatDateTimeShortMonth = useFormatDateTime({
|
||||
type ServerNoticeType = Archon.Notices.v0.ListedNotice
|
||||
|
||||
const notices = ref<ServerNoticeType[]>([])
|
||||
const createNoticeModal = ref<InstanceType<typeof NewModal>>()
|
||||
const createNoticeModal = ref<InstanceType<typeof Modal>>()
|
||||
const assignNoticeModal = ref<InstanceType<typeof AssignNoticeModal>>()
|
||||
|
||||
await refreshNotices()
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
:proceed-label="formatMessage(commonMessages.deleteLabel)"
|
||||
@proceed="deleteCollection()"
|
||||
/>
|
||||
<NewModal v-if="canEdit" ref="editModal" :header="formatMessage(messages.editingCollection)">
|
||||
<Modal v-if="canEdit" ref="editModal" :header="formatMessage(messages.editingCollection)">
|
||||
<div class="flex w-[30rem] flex-col gap-3">
|
||||
<div class="flow-root">
|
||||
<div class="group relative float-end ml-4">
|
||||
@@ -136,7 +136,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<NormalPage :sidebar="cosmetics.leftContentLayout ? 'left' : 'right'">
|
||||
<template #header>
|
||||
<div class="flex flex-col gap-4">
|
||||
@@ -413,8 +413,8 @@ import {
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
Modal,
|
||||
NavTabs,
|
||||
NewModal,
|
||||
normalizeChildren,
|
||||
NormalPage,
|
||||
OverflowMenu,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<NewModal ref="editLinksModal" :header="formatMessage(messages.editLinksHeader)">
|
||||
<Modal ref="editLinksModal" :header="formatMessage(messages.editLinksHeader)">
|
||||
<div class="universal-modal links-modal !p-0">
|
||||
<p>{{ formatMessage(messages.editLinksDescription) }}</p>
|
||||
<section class="links">
|
||||
@@ -155,7 +155,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<ModalCreation ref="modal_creation" />
|
||||
<section class="relative overflow-hidden rounded-2xl">
|
||||
<Table
|
||||
@@ -365,7 +365,7 @@ import {
|
||||
FloatingActionBar,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
ProjectStatusBadge,
|
||||
StyledInput,
|
||||
Table,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="editModal" header="Edit external project">
|
||||
<Modal ref="editModal" header="Edit external project">
|
||||
<form class="flex flex-col gap-2" @submit.prevent="saveExternalProjectEdit">
|
||||
<label class="font-semibold text-contrast" for="edit-form-title">Title</label>
|
||||
<StyledInput id="edit-form-title" v-model="editForm.title" type="text" />
|
||||
@@ -47,7 +47,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</form>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<div>
|
||||
<form class="flex gap-2" @submit.prevent="executeSearch">
|
||||
<StyledInput
|
||||
@@ -139,7 +139,7 @@ import {
|
||||
externalProjectLicenseStatusMessages,
|
||||
ExternalProjectLookupCard,
|
||||
injectModrinthClient,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
@@ -150,7 +150,7 @@ const query = ref('')
|
||||
const isLoading = ref(false)
|
||||
const isSavingEdit = ref(false)
|
||||
const client = injectModrinthClient()
|
||||
const editModal = useTemplateRef<InstanceType<typeof NewModal>>('editModal')
|
||||
const editModal = useTemplateRef<InstanceType<typeof Modal>>('editModal')
|
||||
|
||||
useHead({ title: 'External projects - Modrinth' })
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div>
|
||||
<NewModal ref="editLinksModal" :header="formatMessage(messages.editLinksHeader)">
|
||||
<Modal ref="editLinksModal" :header="formatMessage(messages.editLinksHeader)">
|
||||
<div class="universal-modal links-modal !p-0">
|
||||
<p>{{ formatMessage(messages.editLinksDescription) }}</p>
|
||||
<section class="links">
|
||||
@@ -155,7 +155,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<ModalCreation ref="modal_creation" :organization-id="organization.id" />
|
||||
<section class="relative overflow-hidden rounded-2xl">
|
||||
<Table
|
||||
@@ -366,7 +366,7 @@ import {
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
ProjectStatusBadge,
|
||||
StyledInput,
|
||||
Table,
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
:has-to-type="true"
|
||||
@proceed="deleteAccount"
|
||||
/>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="changeEmailModal"
|
||||
width="500px"
|
||||
:header="`${auth.user.email ? formatMessage(messages.changeEmailHeaderChange) : formatMessage(messages.changeEmailHeaderAdd)}`"
|
||||
@@ -48,8 +48,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
</Modal>
|
||||
<Modal
|
||||
ref="managePasswordModal"
|
||||
width="600px"
|
||||
:header="`${
|
||||
@@ -169,8 +169,8 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
</Modal>
|
||||
<Modal
|
||||
ref="manageTwoFactorModal"
|
||||
width="500px"
|
||||
:header="
|
||||
@@ -307,8 +307,8 @@
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
</Modal>
|
||||
<Modal
|
||||
ref="manageProvidersModal"
|
||||
width="500px"
|
||||
:header="formatMessage(messages.manageProvidersModalHeader)"
|
||||
@@ -343,7 +343,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<section class="universal-card">
|
||||
<h2 class="text-2xl">{{ formatMessage(messages.accountSecurityTitle) }}</h2>
|
||||
|
||||
@@ -500,7 +500,7 @@ import {
|
||||
defineMessages,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
Table,
|
||||
useVIntl,
|
||||
|
||||
@@ -7,10 +7,10 @@
|
||||
:proceed-label="formatMessage(messages.deleteConfirmButton)"
|
||||
@proceed="removeApp(editingId)"
|
||||
/>
|
||||
<Modal ref="appModal" :header="formatMessage(messages.modalHeader)">
|
||||
<div class="universal-modal">
|
||||
<label for="app-name"
|
||||
><span class="label__title">{{ formatMessage(messages.nameLabel) }}</span>
|
||||
<Modal ref="appModal" :header="formatMessage(messages.modalHeader)" width="40rem" scrollable>
|
||||
<div class="flex flex-col">
|
||||
<label for="app-name" class="m-0 mb-2 text-lg font-semibold text-contrast">
|
||||
{{ formatMessage(messages.nameLabel) }}
|
||||
</label>
|
||||
<StyledInput
|
||||
id="app-name"
|
||||
@@ -19,8 +19,12 @@
|
||||
autocomplete="off"
|
||||
:placeholder="formatMessage(messages.namePlaceholder)"
|
||||
/>
|
||||
<label v-if="editingId" for="app-icon"
|
||||
><span class="label__title">{{ formatMessage(messages.iconLabel) }}</span>
|
||||
<label
|
||||
v-if="editingId"
|
||||
for="app-icon"
|
||||
class="mb-2 mt-4 text-lg font-semibold text-contrast"
|
||||
>
|
||||
{{ formatMessage(messages.iconLabel) }}
|
||||
</label>
|
||||
<div v-if="editingId" class="icon-submission">
|
||||
<Avatar size="md" :src="icon" />
|
||||
@@ -36,8 +40,8 @@
|
||||
</FileInput>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<label v-if="editingId" for="app-url">
|
||||
<span class="label__title">{{ formatMessage(messages.urlLabel) }}</span>
|
||||
<label v-if="editingId" for="app-url" class="mb-2 mt-4 text-lg font-semibold text-contrast">
|
||||
{{ formatMessage(messages.urlLabel) }}
|
||||
</label>
|
||||
<StyledInput
|
||||
v-if="editingId"
|
||||
@@ -48,8 +52,12 @@
|
||||
autocomplete="off"
|
||||
:placeholder="formatMessage(messages.urlPlaceholder)"
|
||||
/>
|
||||
<label v-if="editingId" for="app-description">
|
||||
<span class="label__title">{{ formatMessage(messages.descriptionLabel) }}</span>
|
||||
<label
|
||||
v-if="editingId"
|
||||
for="app-description"
|
||||
class="mb-2 mt-4 text-lg font-semibold text-contrast"
|
||||
>
|
||||
{{ formatMessage(messages.descriptionLabel) }}
|
||||
</label>
|
||||
<StyledInput
|
||||
v-if="editingId"
|
||||
@@ -61,15 +69,12 @@
|
||||
:placeholder="formatMessage(messages.descriptionPlaceholder)"
|
||||
input-class="h-24 resize-y"
|
||||
/>
|
||||
<label for="app-scopes"
|
||||
><span class="label__title">{{ formatMessage(messages.scopesLabel) }}</span>
|
||||
<label for="app-scopes" class="mb-2 mt-4 text-lg font-semibold text-contrast">
|
||||
{{ formatMessage(messages.scopesLabel) }}
|
||||
</label>
|
||||
<div
|
||||
id="app-scopes"
|
||||
class="scope-items mt-2 grid grid-cols-1 gap-x-6 gap-y-4 min-[600px]:grid-cols-2"
|
||||
>
|
||||
<div id="app-scopes" class="scope-items grid grid-cols-1 gap-6 min-[600px]:grid-cols-2">
|
||||
<div v-for="category in scopeCategories" :key="category.name" class="flex flex-col gap-2">
|
||||
<h4 class="m-0 border-b border-divider pb-1 text-base font-bold text-contrast">
|
||||
<h4 class="m-0 text-base font-medium text-primary">
|
||||
{{ category.name }}
|
||||
</h4>
|
||||
<div class="flex flex-col gap-2">
|
||||
@@ -83,8 +88,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<label for="app-redirect-uris" class="mt-4"
|
||||
><span class="label__title">{{ formatMessage(messages.redirectUrisLabel) }}</span>
|
||||
<label for="app-redirect-uris" class="mb-2 mt-4 text-lg font-semibold text-contrast">
|
||||
{{ formatMessage(messages.redirectUrisLabel) }}
|
||||
</label>
|
||||
<div class="uri-input-list">
|
||||
<div v-for="(_, index) in redirectUris" :key="index">
|
||||
@@ -93,6 +98,7 @@
|
||||
v-model="redirectUris[index]"
|
||||
:maxlength="2048"
|
||||
type="url"
|
||||
class="w-80"
|
||||
autocomplete="off"
|
||||
:placeholder="formatMessage(messages.redirectUriPlaceholder)"
|
||||
/>
|
||||
@@ -116,18 +122,20 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="submit-row input-group push-right">
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2 p-2">
|
||||
<ButtonStyled>
|
||||
<button @click="$refs.appModal.hide()">
|
||||
<XIcon />
|
||||
{{ formatMessage(messages.cancel) }}
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-if="editingId" color="brand">
|
||||
<button :disabled="!canSubmit" @click="editApp">
|
||||
<SaveIcon />
|
||||
{{ formatMessage(messages.saveChanges) }}
|
||||
{{ formatMessage(commonMessages.saveChangesButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else color="brand">
|
||||
@@ -137,7 +145,7 @@
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Modal>
|
||||
|
||||
<div class="header__row">
|
||||
@@ -220,7 +228,7 @@
|
||||
"
|
||||
>
|
||||
<EditIcon />
|
||||
{{ formatMessage(messages.edit) }}
|
||||
{{ formatMessage(commonMessages.editButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="red">
|
||||
@@ -255,6 +263,7 @@ import {
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
Modal,
|
||||
normalizeChildren,
|
||||
StyledInput,
|
||||
useFormatDateTime,
|
||||
@@ -262,7 +271,6 @@ import {
|
||||
} from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
import {
|
||||
getScopeValue,
|
||||
hasScope,
|
||||
@@ -355,14 +363,6 @@ const messages = defineMessages({
|
||||
id: 'settings.applications.button.add-redirect-uri',
|
||||
defaultMessage: 'Add a redirect URI',
|
||||
},
|
||||
cancel: {
|
||||
id: 'settings.applications.button.cancel',
|
||||
defaultMessage: 'Cancel',
|
||||
},
|
||||
saveChanges: {
|
||||
id: 'settings.applications.button.save-changes',
|
||||
defaultMessage: 'Save changes',
|
||||
},
|
||||
createApp: {
|
||||
id: 'settings.applications.button.create',
|
||||
defaultMessage: 'Create app',
|
||||
@@ -396,10 +396,6 @@ const messages = defineMessages({
|
||||
id: 'settings.applications.created-on',
|
||||
defaultMessage: 'Created on {date}',
|
||||
},
|
||||
edit: {
|
||||
id: 'settings.applications.button.edit',
|
||||
defaultMessage: 'Edit',
|
||||
},
|
||||
delete: {
|
||||
id: 'settings.applications.button.delete',
|
||||
defaultMessage: 'Delete',
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:proceed-label="formatMessage(deleteModalMessages.action)"
|
||||
@proceed="removePat(deletePatIndex)"
|
||||
/>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="patModal"
|
||||
:header="
|
||||
editPatId !== null
|
||||
@@ -86,7 +86,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
|
||||
<div class="header__row">
|
||||
<div class="header__title">
|
||||
@@ -211,7 +211,7 @@ import {
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
useFormatDateTime,
|
||||
useRelativeTime,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.createHeader)">
|
||||
<Modal ref="modal" :header="formatMessage(messages.createHeader)">
|
||||
<div class="flex flex-col">
|
||||
<label v-if="showUserField" class="contents" for="create-affiliate-user-input">
|
||||
<span class="text-lg font-semibold text-contrast mb-1">
|
||||
@@ -55,7 +55,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
<script lang="ts"></script>
|
||||
<script setup lang="ts">
|
||||
@@ -64,7 +64,7 @@ import { computed, ref, useTemplateRef } from 'vue'
|
||||
|
||||
import { defineMessages, useVIntl } from '../../composables/i18n'
|
||||
import { commonMessages } from '../../utils/common-messages'
|
||||
import { AutoBrandIcon, ButtonStyled, NewModal, StyledInput } from '../index'
|
||||
import { AutoBrandIcon, ButtonStyled, Modal, StyledInput } from '../index'
|
||||
export type CreateAffiliateProps = { sourceName: string; username?: string }
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -82,7 +82,7 @@ const emit = defineEmits<{
|
||||
(e: 'create', data: CreateAffiliateProps): void
|
||||
}>()
|
||||
|
||||
const modal = useTemplateRef<typeof NewModal>('modal')
|
||||
const modal = useTemplateRef<typeof Modal>('modal')
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const affiliateLinkTitle = ref('')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="linkModal" :header="formatMessage(messages.linkModalHeader)" class="!w-[40rem]">
|
||||
<Modal ref="linkModal" :header="formatMessage(messages.linkModalHeader)" class="!w-[40rem]">
|
||||
<div class="modal-insert">
|
||||
<label class="label" for="insert-link-label">
|
||||
<span class="label__title">{{ formatMessage(messages.linkModalLabelFieldTitle) }}</span>
|
||||
@@ -66,8 +66,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal ref="imageModal" :header="formatMessage(messages.imageModalHeader)" class="!w-[40rem]">
|
||||
</Modal>
|
||||
<Modal ref="imageModal" :header="formatMessage(messages.imageModalHeader)" class="!w-[40rem]">
|
||||
<div class="modal-insert">
|
||||
<label class="label" for="insert-image-alt">
|
||||
<span class="label__title">
|
||||
@@ -164,8 +164,8 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
<NewModal ref="videoModal" :header="formatMessage(messages.videoModalHeader)" class="!w-[40rem]">
|
||||
</Modal>
|
||||
<Modal ref="videoModal" :header="formatMessage(messages.videoModalHeader)" class="!w-[40rem]">
|
||||
<div class="modal-insert">
|
||||
<label class="label" for="insert-video-url">
|
||||
<span class="label__title">
|
||||
@@ -224,7 +224,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
<div class="block grow w-full">
|
||||
<div class="editor-action-row w-full">
|
||||
<div class="w-full flex justify-between items-center flex-wrap gap-2">
|
||||
@@ -335,7 +335,7 @@ import { type Component, computed, onBeforeUnmount, onMounted, ref, toRef, watch
|
||||
|
||||
import { defineMessages, type MessageDescriptor, useVIntl } from '../../composables/i18n'
|
||||
import { commonMessages } from '../../utils/common-messages.ts'
|
||||
import NewModal from '../modal/NewModal.vue'
|
||||
import Modal from '../modal/Modal.vue'
|
||||
import ButtonStyled from './ButtonStyled.vue'
|
||||
import Chips from './Chips.vue'
|
||||
import FileInput from './FileInput.vue'
|
||||
@@ -1042,9 +1042,9 @@ const videoMarkdown = computed(() => {
|
||||
return ''
|
||||
})
|
||||
|
||||
const linkModal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const imageModal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const videoModal = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const linkModal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
const imageModal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
const videoModal = ref<InstanceType<typeof Modal> | null>(null)
|
||||
|
||||
function resetModalStates() {
|
||||
linkText.value = ''
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modal"
|
||||
:scrollable="true"
|
||||
max-content-height="72vh"
|
||||
@@ -114,12 +114,12 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ChevronRightIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, NewModal } from '@modrinth/ui'
|
||||
import { ButtonStyled, Modal } from '@modrinth/ui'
|
||||
import type { Component } from 'vue'
|
||||
import { computed, nextTick, ref, useTemplateRef, watch } from 'vue'
|
||||
|
||||
@@ -175,7 +175,7 @@ const props = withDefaults(
|
||||
},
|
||||
)
|
||||
|
||||
const modal = useTemplateRef<InstanceType<typeof NewModal>>('modal')
|
||||
const modal = useTemplateRef<InstanceType<typeof Modal>>('modal')
|
||||
const currentStageIndex = ref<number>(0)
|
||||
|
||||
function show() {
|
||||
|
||||
@@ -5,13 +5,13 @@ import { nextTick, ref, useTemplateRef } from 'vue'
|
||||
|
||||
import { defineMessages, useVIntl } from '../../composables/i18n'
|
||||
import { commonMessages } from '../../utils'
|
||||
import { ButtonStyled, NewModal } from '../index'
|
||||
import { ButtonStyled, Modal } from '../index'
|
||||
import type { AddPaymentMethodProps } from './AddPaymentMethod.vue'
|
||||
import AddPaymentMethod from './AddPaymentMethod.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const modal = useTemplateRef<InstanceType<typeof NewModal>>('modal')
|
||||
const modal = useTemplateRef<InstanceType<typeof Modal>>('modal')
|
||||
const addPaymentMethod = useTemplateRef<InstanceType<typeof AddPaymentMethod>>('addPaymentMethod')
|
||||
|
||||
const props = defineProps<AddPaymentMethodProps>()
|
||||
@@ -40,7 +40,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal ref="modal">
|
||||
<Modal ref="modal">
|
||||
<template #title>
|
||||
<span class="text-lg font-extrabold text-contrast">
|
||||
{{ formatMessage(messages.addingPaymentMethod) }}
|
||||
@@ -71,5 +71,5 @@ defineExpose({
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -18,8 +18,8 @@ import { defineMessage, type MessageDescriptor, useVIntl } from '../../composabl
|
||||
import { useStripe } from '../../composables/stripe'
|
||||
import { commonMessages } from '../../utils'
|
||||
import { ButtonStyled } from '../index'
|
||||
import Modal from '../modal/Modal.vue'
|
||||
import ModalLoadingIndicator from '../modal/ModalLoadingIndicator.vue'
|
||||
import NewModal from '../modal/NewModal.vue'
|
||||
import PlanSelector from './ServersPurchase0Plan.vue'
|
||||
import RegionSelector from './ServersPurchase1Region.vue'
|
||||
import PaymentMethodSelector from './ServersPurchase2PaymentMethod.vue'
|
||||
@@ -65,7 +65,7 @@ const props = defineProps<{
|
||||
affiliateCode?: string | null
|
||||
}>()
|
||||
|
||||
const modal = useTemplateRef<InstanceType<typeof NewModal>>('modal')
|
||||
const modal = useTemplateRef<InstanceType<typeof Modal>>('modal')
|
||||
const selectedPlan = ref<Labrinth.Billing.Internal.Product>()
|
||||
const selectedInterval = ref<ServerBillingInterval>('quarterly')
|
||||
const loading = ref(false)
|
||||
@@ -448,7 +448,7 @@ function goToBreadcrumbStep(id: string) {
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<NewModal ref="modal" @hide="handleHide">
|
||||
<Modal ref="modal" @hide="handleHide">
|
||||
<template #title>
|
||||
<div class="flex items-center gap-1 font-bold text-secondary">
|
||||
<template v-for="(step, index) in visibleSteps" :key="step">
|
||||
@@ -601,5 +601,5 @@ function goToBreadcrumbStep(id: string) {
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="purchaseModal">
|
||||
<Modal ref="purchaseModal">
|
||||
<template #title>
|
||||
<span class="text-contrast text-xl font-extrabold">
|
||||
<template v-if="productType === 'midas'">Subscribe to Modrinth+!</template>
|
||||
@@ -446,7 +446,7 @@
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -479,7 +479,7 @@ import Combobox from '../base/Combobox.vue'
|
||||
import Slider from '../base/Slider.vue'
|
||||
import StyledInput from '../base/StyledInput.vue'
|
||||
import AnimatedLogo from '../brand/AnimatedLogo.vue'
|
||||
import NewModal from '../modal/NewModal.vue'
|
||||
import Modal from '../modal/Modal.vue'
|
||||
import LoaderIcon from '../servers/icons/LoaderIcon.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" max-width="550px">
|
||||
<Modal ref="modal" max-width="550px">
|
||||
<template #title>
|
||||
<div class="text-2xl font-semibold text-contrast">{{ formatMessage(messages.title) }}</div>
|
||||
</template>
|
||||
@@ -92,7 +92,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -105,7 +105,7 @@ import { injectNotificationManager } from '#ui/providers/web-notifications.ts'
|
||||
import { useFormatDateTime, useFormatPrice } from '../../composables'
|
||||
import { defineMessages, useVIntl } from '../../composables/i18n'
|
||||
import IntlFormatted from '../base/IntlFormatted.vue'
|
||||
import { ButtonStyled, NewModal } from '../index'
|
||||
import { ButtonStyled, Modal } from '../index'
|
||||
|
||||
const { addNotification } = injectNotificationManager()
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -148,7 +148,7 @@ const emit = defineEmits<{
|
||||
const formatDate = useFormatDateTime({ dateStyle: 'long' })
|
||||
const formatPrice = useFormatPrice()
|
||||
|
||||
const modal = useTemplateRef<InstanceType<typeof NewModal>>('modal')
|
||||
const modal = useTemplateRef<InstanceType<typeof Modal>>('modal')
|
||||
|
||||
const modalData = ref<ResubscribeModalState | null>(null)
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ChevronRightIcon, ExternalIcon, XIcon } from '@modrinth/assets'
|
||||
import { computed, ref, useTemplateRef } from 'vue'
|
||||
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
import NewModal from '../modal/NewModal.vue'
|
||||
import Modal from '../modal/Modal.vue'
|
||||
import type { ServerBillingInterval } from './ModrinthServersPurchaseModal.vue'
|
||||
import PlanSelector from './ServersPurchase0Plan.vue'
|
||||
|
||||
@@ -23,7 +23,7 @@ const emit = defineEmits<{
|
||||
(e: 'continue', payload: { interval: ServerBillingInterval; planId: string | null }): void
|
||||
}>()
|
||||
|
||||
const modal = useTemplateRef<InstanceType<typeof NewModal>>('modal')
|
||||
const modal = useTemplateRef<InstanceType<typeof Modal>>('modal')
|
||||
|
||||
const selectedPlan = ref<Labrinth.Billing.Internal.Product>()
|
||||
const selectedInterval = ref<ServerBillingInterval>('quarterly')
|
||||
@@ -91,7 +91,7 @@ defineExpose({
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal ref="modal" :on-hide="handleModalHide" no-padding>
|
||||
<Modal ref="modal" :on-hide="handleModalHide" no-padding>
|
||||
<template #title>
|
||||
<div class="flex items-center gap-1 font-bold text-secondary">
|
||||
<span class="text-contrast">Plan</span>
|
||||
@@ -165,5 +165,5 @@ defineExpose({
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Labrinth } from '@modrinth/api-client'
|
||||
import { CheckIcon, PlusIcon, SearchIcon, SpinnerIcon, XIcon } from '@modrinth/assets'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
|
||||
import { ButtonStyled, NewModal, StyledInput } from '#ui/components'
|
||||
import { ButtonStyled, Modal, StyledInput } from '#ui/components'
|
||||
import { commonMessages } from '#ui/utils'
|
||||
|
||||
import { defineMessages, useVIntl } from '../../composables/i18n'
|
||||
@@ -60,7 +60,7 @@ type AssignableFileEntry = {
|
||||
sourceLabel: string
|
||||
}
|
||||
|
||||
const modalRef = ref<InstanceType<typeof NewModal> | null>(null)
|
||||
const modalRef = ref<InstanceType<typeof Modal> | null>(null)
|
||||
const assignableEntries = ref<AssignableFileEntry[]>([])
|
||||
const searchQuery = ref('')
|
||||
const searchInputRef = ref<{ focus: () => void } | null>(null)
|
||||
@@ -176,7 +176,7 @@ defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalRef"
|
||||
:header="formatMessage(messages.addFilesModalTitle)"
|
||||
max-width="560px"
|
||||
@@ -283,5 +283,5 @@ defineExpose({ show, hide })
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { PlusIcon, SearchIcon, SpinnerIcon, XIcon } from '@modrinth/assets'
|
||||
import { useMutation } from '@tanstack/vue-query'
|
||||
import { computed, ref, useTemplateRef } from 'vue'
|
||||
|
||||
import { Accordion, ButtonStyled, NewModal, StyledInput } from '#ui/components'
|
||||
import { Accordion, ButtonStyled, Modal, StyledInput } from '#ui/components'
|
||||
|
||||
import { injectModrinthClient, injectNotificationManager } from '../../providers'
|
||||
import AttributionGroupFilePicker from './AttributionGroupFilePicker.vue'
|
||||
@@ -41,7 +41,7 @@ type ExternalProject = {
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
const modalRef = useTemplateRef<InstanceType<typeof NewModal>>('modalRef')
|
||||
const modalRef = useTemplateRef<InstanceType<typeof Modal>>('modalRef')
|
||||
const searchAccordionRef = useTemplateRef<InstanceType<typeof Accordion>>('searchAccordionRef')
|
||||
const filesAccordionRef = useTemplateRef<InstanceType<typeof Accordion>>('filesAccordionRef')
|
||||
const searchInputRef = useTemplateRef<InstanceType<typeof StyledInput>>('searchInputRef')
|
||||
@@ -185,7 +185,7 @@ defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalRef"
|
||||
header="Add to existing entry"
|
||||
max-width="720px"
|
||||
@@ -324,5 +324,5 @@ defineExpose({ show, hide })
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
ButtonStyled,
|
||||
Combobox,
|
||||
type ComboboxOption,
|
||||
NewModal,
|
||||
Modal,
|
||||
StyledInput,
|
||||
} from '#ui/components'
|
||||
|
||||
@@ -35,7 +35,7 @@ const emit = defineEmits<{
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
const modalRef = useTemplateRef<InstanceType<typeof NewModal>>('modalRef')
|
||||
const modalRef = useTemplateRef<InstanceType<typeof Modal>>('modalRef')
|
||||
|
||||
const statusOptions: ComboboxOption<ExternalLicenseStatus>[] = [
|
||||
{ value: 'yes', label: 'Yes' },
|
||||
@@ -140,7 +140,7 @@ defineExpose({ show, hide })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NewModal
|
||||
<Modal
|
||||
ref="modalRef"
|
||||
header="Adding to global permissions database"
|
||||
max-width="640px"
|
||||
@@ -241,5 +241,5 @@ defineExpose({ show, hide })
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="localizeIfPossible(title)" fade="warning" max-width="500px">
|
||||
<Modal ref="modal" :header="localizeIfPossible(title)" fade="warning" max-width="500px">
|
||||
<div class="flex flex-col gap-6">
|
||||
<Admonition :type="admonitionType" :header="localizeIfPossible(header)">
|
||||
{{ localizeIfPossible(body) }}
|
||||
@@ -22,7 +22,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -33,7 +33,7 @@ import Admonition from '#ui/components/base/Admonition.vue'
|
||||
import ButtonStyled from '#ui/components/base/ButtonStyled.vue'
|
||||
import { defineMessage, type MessageDescriptor, useVIntl } from '#ui/composables/i18n'
|
||||
|
||||
import NewModal from './NewModal.vue'
|
||||
import Modal from './Modal.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@@ -80,7 +80,7 @@ function localizeIfPossible(message: MessageDescriptor | string) {
|
||||
return typeof message === 'string' ? message : formatMessage(message)
|
||||
}
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const modal = ref<InstanceType<typeof Modal>>()
|
||||
let resolvePromise: ((value: boolean) => void) | null = null
|
||||
|
||||
function prompt(): Promise<boolean> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :noblur="noblur" :danger="danger" :on-hide="onHide" max-width="550px">
|
||||
<Modal ref="modal" :noblur="noblur" :danger="danger" :on-hide="onHide" max-width="550px">
|
||||
<template #title>
|
||||
<slot name="title">
|
||||
<span class="font-extrabold text-contrast text-lg">{{ title }}</span>
|
||||
@@ -45,7 +45,7 @@
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@@ -55,7 +55,7 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
import StyledInput from '../base/StyledInput.vue'
|
||||
import NewModal from './NewModal.vue'
|
||||
import Modal from './Modal.vue'
|
||||
|
||||
const props = defineProps({
|
||||
confirmationText: {
|
||||
|
||||
@@ -1,82 +1,403 @@
|
||||
<template>
|
||||
<div v-if="shown">
|
||||
<div
|
||||
:class="{ shown: actuallyShown }"
|
||||
class="tauri-overlay"
|
||||
data-tauri-drag-region
|
||||
@click="() => (closable ? hide() : {})"
|
||||
/>
|
||||
<div
|
||||
:class="{
|
||||
shown: actuallyShown,
|
||||
noblur: props.noblur,
|
||||
}"
|
||||
class="modal-overlay"
|
||||
@click="() => (closable ? hide() : {})"
|
||||
/>
|
||||
<div class="modal-container" :class="{ shown: actuallyShown }">
|
||||
<div class="modal-body">
|
||||
<div v-if="props.header" class="header">
|
||||
<h1>{{ props.header }}</h1>
|
||||
<button v-if="closable" class="btn icon-only transparent" @click="hide">
|
||||
<XIcon />
|
||||
</button>
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot />
|
||||
<Teleport to="body">
|
||||
<div v-if="open" class="modal-root">
|
||||
<div
|
||||
:class="{ shown: visible }"
|
||||
class="tauri-overlay"
|
||||
data-tauri-drag-region
|
||||
@click="() => (closeOnClickOutside && closable ? hide() : {})"
|
||||
/>
|
||||
<div
|
||||
:class="[
|
||||
'modal-overlay',
|
||||
{
|
||||
shown: visible,
|
||||
noblur: effectiveNoblur,
|
||||
},
|
||||
computedFade,
|
||||
]"
|
||||
@click="() => (closeOnClickOutside && closable ? hide() : {})"
|
||||
/>
|
||||
<div class="modal-container" :class="{ shown: visible }">
|
||||
<div
|
||||
ref="modalBodyRef"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
:aria-labelledby="headerId"
|
||||
class="modal-body flex flex-col bg-bg-raised rounded-2xl border border-solid border-surface-5"
|
||||
v-bind="$attrs"
|
||||
@keydown="handleKeyDown"
|
||||
>
|
||||
<div
|
||||
v-if="!hideHeader"
|
||||
data-tauri-drag-region
|
||||
class="grid grid-cols-[1fr_auto] items-center gap-4 p-6 border-solid border-0 border-b-[1px] border-surface-5 max-w-full"
|
||||
>
|
||||
<div class="flex text-wrap break-words items-center gap-3 min-w-0">
|
||||
<slot name="title">
|
||||
<span v-if="header" :id="headerId" class="text-2xl font-semibold text-contrast">
|
||||
{{ header }}
|
||||
</span>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<slot name="header-actions" />
|
||||
<ButtonStyled v-if="closable" circular>
|
||||
<button
|
||||
v-tooltip="closeLabel"
|
||||
:aria-label="closeLabel"
|
||||
:disabled="disableClose"
|
||||
@click="hide"
|
||||
>
|
||||
<XIcon aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ButtonStyled
|
||||
v-if="props.mergeHeader && closable"
|
||||
class="absolute top-4 right-4 z-10"
|
||||
circular
|
||||
>
|
||||
<button
|
||||
v-tooltip="closeLabel"
|
||||
:aria-label="closeLabel"
|
||||
:disabled="disableClose"
|
||||
@click="hide"
|
||||
>
|
||||
<XIcon aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<div v-if="scrollable" class="relative flex-1 min-h-0 flex flex-col">
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-6"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-6"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTopFade"
|
||||
class="pointer-events-none absolute left-0 right-0 top-0 z-10 h-6 bg-gradient-to-b from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
<div
|
||||
ref="scrollContainer"
|
||||
data-modal-content
|
||||
:class="[
|
||||
'flex-1 min-h-0 overflow-y-auto',
|
||||
props.noPadding ? '' : 'p-6 !pb-1 sm:pb-6',
|
||||
{ 'pt-12': props.mergeHeader && closable && !props.noPadding },
|
||||
]"
|
||||
:style="{ maxHeight: maxContentHeight }"
|
||||
@scroll="checkScrollState"
|
||||
>
|
||||
<slot> You just lost the game.</slot>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-6"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-6"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showBottomFade"
|
||||
class="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-6 bg-gradient-to-t from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
data-modal-content
|
||||
:class="[
|
||||
'min-h-0',
|
||||
props.noPadding ? '' : 'overflow-y-auto p-6',
|
||||
{ 'pt-12': props.mergeHeader && closable && !props.noPadding },
|
||||
]"
|
||||
>
|
||||
<slot> You just lost the game.</slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.actions"
|
||||
:class="{ 'pt-4 border-0 border-t border-solid border-surface-5': actionsDivider }"
|
||||
class="p-4"
|
||||
>
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else></div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { XIcon } from '@modrinth/assets'
|
||||
import { ref } from 'vue'
|
||||
import { computed, nextTick, onUnmounted, ref } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
header: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
noblur: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
closable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
onHide: {
|
||||
type: Function,
|
||||
default() {
|
||||
return () => {}
|
||||
},
|
||||
import { useVIntl } from '../../composables/i18n'
|
||||
import { useModalStack } from '../../composables/modal-stack'
|
||||
import { useScrollIndicator } from '../../composables/scroll-indicator'
|
||||
import { injectModalBehavior } from '../../providers'
|
||||
import { commonMessages } from '../../utils/common-messages'
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const modalBehavior = injectModalBehavior(null)
|
||||
const {
|
||||
push: pushModal,
|
||||
pop: popModal,
|
||||
isTopmost: isTopmostModal,
|
||||
stackSize: modalStackSize,
|
||||
} = useModalStack()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
noblur?: boolean
|
||||
closable?: boolean
|
||||
/** @deprecated Use `fade="danger"` instead */
|
||||
danger?: boolean
|
||||
fade?: 'standard' | 'warning' | 'danger'
|
||||
closeOnEsc?: boolean
|
||||
closeOnClickOutside?: boolean
|
||||
warnOnClose?: boolean
|
||||
header?: string
|
||||
hideHeader?: boolean
|
||||
onHide?: () => void
|
||||
onAfterHide?: () => void
|
||||
onShow?: () => void
|
||||
beforeHide?: () => boolean
|
||||
mergeHeader?: boolean
|
||||
scrollable?: boolean
|
||||
maxContentHeight?: string
|
||||
/** Removes padding from the content area. Useful for edge-to-edge layouts. */
|
||||
noPadding?: boolean
|
||||
/** Max width for the modal (e.g., '460px', '600px'). Defaults to '60rem'. */
|
||||
maxWidth?: string
|
||||
/** Width for the modal body (e.g., '460px', '600px'). */
|
||||
width?: string
|
||||
/** Disables all close actions (close button, ESC key, click outside). */
|
||||
disableClose?: boolean
|
||||
actionsDivider?: boolean
|
||||
}>(),
|
||||
{
|
||||
type: true,
|
||||
noblur: undefined,
|
||||
closable: true,
|
||||
danger: false,
|
||||
fade: undefined,
|
||||
closeOnClickOutside: true,
|
||||
closeOnEsc: true,
|
||||
warnOnClose: false,
|
||||
header: undefined,
|
||||
hideHeader: false,
|
||||
onHide: () => {},
|
||||
onAfterHide: () => {},
|
||||
onShow: () => {},
|
||||
beforeHide: undefined,
|
||||
mergeHeader: false,
|
||||
// TODO: migrate all modals to use scrollable and remove this prop
|
||||
scrollable: false,
|
||||
maxContentHeight: '70vh',
|
||||
noPadding: false,
|
||||
maxWidth: undefined,
|
||||
width: undefined,
|
||||
disableClose: false,
|
||||
actionsDivider: false,
|
||||
},
|
||||
)
|
||||
|
||||
const effectiveNoblur = computed(() => props.noblur ?? modalBehavior?.noblur.value ?? false)
|
||||
|
||||
const computedFade = computed(() => {
|
||||
if (props.fade) return props.fade
|
||||
if (props.danger) return 'danger'
|
||||
return 'standard'
|
||||
})
|
||||
|
||||
const shown = ref(false)
|
||||
const actuallyShown = ref(false)
|
||||
const modalId = `modal-${Math.random().toString(36).slice(2, 9)}`
|
||||
const headerId = `${modalId}-header`
|
||||
const closeLabel = computed(() => formatMessage(commonMessages.closeButton))
|
||||
|
||||
function show() {
|
||||
shown.value = true
|
||||
const open = ref(false)
|
||||
const visible = ref(false)
|
||||
const stackDepth = ref(0)
|
||||
const modalBodyRef = ref<HTMLElement | null>(null)
|
||||
let previousFocusEl: Element | null = null
|
||||
let hideTimeout: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const scrollContainer = ref<HTMLElement | null>(null)
|
||||
const { showTopFade, showBottomFade, checkScrollState } = useScrollIndicator(scrollContainer)
|
||||
|
||||
const FOCUSABLE_SELECTOR =
|
||||
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
||||
|
||||
function getFocusableElements(): HTMLElement[] {
|
||||
if (!modalBodyRef.value) return []
|
||||
return Array.from(modalBodyRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))
|
||||
}
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout)
|
||||
hideTimeout = null
|
||||
}
|
||||
props.onShow?.()
|
||||
const wasEmpty = modalStackSize() === 0
|
||||
stackDepth.value = modalStackSize()
|
||||
open.value = true
|
||||
previousFocusEl = document.activeElement
|
||||
pushModal()
|
||||
if (wasEmpty) modalBehavior?.onShow?.()
|
||||
|
||||
document.body.style.overflow = 'hidden'
|
||||
window.addEventListener('keydown', handleWindowKeyDown)
|
||||
window.addEventListener('mousedown', updateMousePosition)
|
||||
if (event) {
|
||||
updateMousePosition(event)
|
||||
} else {
|
||||
mouseX.value = Math.round(window.innerWidth / 2)
|
||||
mouseY.value = Math.round(window.innerHeight / 2)
|
||||
}
|
||||
setTimeout(() => {
|
||||
actuallyShown.value = true
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
const focusable = getFocusableElements()
|
||||
if (focusable.length > 0) {
|
||||
focusable[0].focus()
|
||||
} else {
|
||||
modalBodyRef.value?.focus()
|
||||
}
|
||||
})
|
||||
}, 50)
|
||||
}
|
||||
|
||||
function hide() {
|
||||
function hide(): boolean {
|
||||
if (props.disableClose) {
|
||||
return false
|
||||
}
|
||||
if (props.beforeHide?.() === false) {
|
||||
return false
|
||||
}
|
||||
props.onHide?.()
|
||||
actuallyShown.value = false
|
||||
setTimeout(() => {
|
||||
shown.value = false
|
||||
resetMousePosition()
|
||||
visible.value = false
|
||||
popModal()
|
||||
if (modalStackSize() === 0) {
|
||||
modalBehavior?.onHide?.()
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
window.removeEventListener('keydown', handleWindowKeyDown)
|
||||
window.removeEventListener('mousedown', updateMousePosition)
|
||||
if (previousFocusEl instanceof HTMLElement) {
|
||||
previousFocusEl.focus()
|
||||
}
|
||||
previousFocusEl = null
|
||||
hideTimeout = setTimeout(() => {
|
||||
open.value = false
|
||||
hideTimeout = null
|
||||
nextTick(() => props.onAfterHide?.())
|
||||
}, 300)
|
||||
return true
|
||||
}
|
||||
|
||||
async function scrollToBottom(behavior: ScrollBehavior = 'smooth') {
|
||||
await nextTick()
|
||||
if (!scrollContainer.value) return
|
||||
|
||||
scrollContainer.value.scrollTo({
|
||||
top: scrollContainer.value.scrollHeight,
|
||||
behavior,
|
||||
})
|
||||
requestAnimationFrame(checkScrollState)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
hide,
|
||||
checkScrollState,
|
||||
scrollToBottom,
|
||||
})
|
||||
|
||||
const mouseX = ref(0)
|
||||
const mouseY = ref(0)
|
||||
|
||||
const MODAL_STACK_BASE_Z = 100
|
||||
const stackZBase = computed(() => MODAL_STACK_BASE_Z + stackDepth.value * 10)
|
||||
const stackOverlayZ = computed(() => stackZBase.value + 19)
|
||||
const stackTauriZ = computed(() => stackZBase.value + 20)
|
||||
const stackContainerZ = computed(() => stackZBase.value + 21)
|
||||
const resolvedMaxWidth = computed(() => props.maxWidth ?? '60rem')
|
||||
const resolvedWidth = computed(() => props.width ?? 'fit-content')
|
||||
const mouseXOffset = computed(() => `calc((-50vw + ${mouseX.value}px) / 16)`)
|
||||
const mouseYOffset = computed(() => `calc((-50vh + ${mouseY.value}px) / 16)`)
|
||||
|
||||
function updateMousePosition(event: { clientX: number; clientY: number }) {
|
||||
mouseX.value = event.clientX
|
||||
mouseY.value = event.clientY
|
||||
}
|
||||
|
||||
function resetMousePosition() {
|
||||
mouseX.value = Math.round(window.innerWidth / 2)
|
||||
mouseY.value = Math.round(window.innerHeight / 2)
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout)
|
||||
hideTimeout = null
|
||||
}
|
||||
if (open.value) {
|
||||
popModal()
|
||||
window.removeEventListener('keydown', handleWindowKeyDown)
|
||||
window.removeEventListener('mousedown', updateMousePosition)
|
||||
if (modalStackSize() === 0) {
|
||||
document.body.style.overflow = ''
|
||||
modalBehavior?.onHide?.()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function handleWindowKeyDown(event: KeyboardEvent) {
|
||||
if (props.closeOnEsc && event.key === 'Escape' && props.closable) {
|
||||
if (!isTopmostModal()) return
|
||||
hide()
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
if (event.key === 'Tab') {
|
||||
const focusable = getFocusableElements()
|
||||
if (focusable.length === 0) return
|
||||
|
||||
const first = focusable[0]
|
||||
const last = focusable[focusable.length - 1]
|
||||
|
||||
if (event.shiftKey) {
|
||||
if (document.activeElement === first) {
|
||||
event.preventDefault()
|
||||
last.focus()
|
||||
}
|
||||
} else {
|
||||
if (document.activeElement === last) {
|
||||
event.preventDefault()
|
||||
first.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -88,7 +409,7 @@ defineExpose({
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
z-index: 20;
|
||||
z-index: v-bind(stackTauriZ);
|
||||
|
||||
&.shown {
|
||||
opacity: 1;
|
||||
@@ -97,14 +418,33 @@ defineExpose({
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
visibility: hidden;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 19;
|
||||
transition: all 0.3s ease-in-out;
|
||||
inset: -5rem;
|
||||
z-index: v-bind(stackOverlayZ);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: all 0.2s ease-out;
|
||||
//transform: translate(
|
||||
// calc((-50vw + var(--_mouse-x, 50vw) * 1px) / 2),
|
||||
// calc((-50vh + var(--_mouse-y, 50vh) * 1px) / 2)
|
||||
// )
|
||||
// scaleX(0.8) scaleY(0.5);
|
||||
border-radius: 180px;
|
||||
//filter: blur(5px);
|
||||
|
||||
// Fade variants
|
||||
&.standard {
|
||||
background: linear-gradient(to bottom, rgba(29, 48, 43, 0.52) 0%, rgba(14, 21, 26, 0.95) 100%);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: linear-gradient(to bottom, rgba(48, 38, 29, 0.52) 0%, rgba(26, 20, 14, 0.95) 100%);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: linear-gradient(to bottom, rgba(43, 18, 26, 0.52) 0%, rgba(49, 10, 15, 0.95) 100%);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none !important;
|
||||
@@ -113,12 +453,19 @@ defineExpose({
|
||||
&.shown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
background: hsla(0, 0%, 0%, 0.5);
|
||||
backdrop-filter: blur(3px);
|
||||
pointer-events: auto;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
&.noblur {
|
||||
backdrop-filter: none;
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modrinth-parent__no-modal-blurs {
|
||||
.modal-overlay {
|
||||
backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,52 +478,44 @@ defineExpose({
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 21;
|
||||
z-index: v-bind(stackContainerZ);
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transform: translate(v-bind(mouseXOffset), v-bind(mouseYOffset));
|
||||
transition: none;
|
||||
|
||||
&.shown {
|
||||
visibility: visible;
|
||||
.modal-body {
|
||||
transform: translate(0, 0);
|
||||
transition: all 0.2s ease-out;
|
||||
|
||||
> .modal-body {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transform: translateY(0);
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
> .modal-body {
|
||||
position: fixed;
|
||||
box-shadow: var(--shadow-raised), var(--shadow-inset);
|
||||
border-radius: var(--radius-lg);
|
||||
background-color: var(--color-raised-bg);
|
||||
box-shadow: 4px 4px 26px 10px rgba(0, 0, 0, 0.08);
|
||||
max-height: calc(100% - 2 * var(--gap-lg));
|
||||
overflow-y: visible;
|
||||
width: 600px;
|
||||
max-width: min(v-bind(resolvedMaxWidth), calc(100% - 2 * var(--gap-lg)));
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
width: v-bind(resolvedWidth);
|
||||
pointer-events: auto;
|
||||
scale: 0.97;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-color: var(--color-bg);
|
||||
padding: var(--gap-md) var(--gap-lg);
|
||||
|
||||
h1 {
|
||||
font-weight: bold;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
transform: translateY(50vh);
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.25s ease-in-out;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 650px) {
|
||||
@media screen and (max-width: 640px) {
|
||||
width: calc(100% - 2 * var(--gap-lg));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,523 +0,0 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="open" class="modal-root">
|
||||
<div
|
||||
:class="{ shown: visible }"
|
||||
class="tauri-overlay"
|
||||
data-tauri-drag-region
|
||||
@click="() => (closeOnClickOutside && closable ? hide() : {})"
|
||||
/>
|
||||
<div
|
||||
:class="[
|
||||
'modal-overlay',
|
||||
{
|
||||
shown: visible,
|
||||
noblur: effectiveNoblur,
|
||||
},
|
||||
computedFade,
|
||||
]"
|
||||
@click="() => (closeOnClickOutside && closable ? hide() : {})"
|
||||
/>
|
||||
<div class="modal-container" :class="{ shown: visible }">
|
||||
<div
|
||||
ref="modalBodyRef"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
:aria-labelledby="headerId"
|
||||
class="modal-body flex flex-col bg-bg-raised rounded-2xl border border-solid border-surface-5"
|
||||
v-bind="$attrs"
|
||||
@keydown="handleKeyDown"
|
||||
>
|
||||
<div
|
||||
v-if="!hideHeader"
|
||||
data-tauri-drag-region
|
||||
class="grid grid-cols-[1fr_auto] items-center gap-4 p-6 border-solid border-0 border-b-[1px] border-surface-5 max-w-full"
|
||||
>
|
||||
<div class="flex text-wrap break-words items-center gap-3 min-w-0">
|
||||
<slot name="title">
|
||||
<span v-if="header" :id="headerId" class="text-2xl font-semibold text-contrast">
|
||||
{{ header }}
|
||||
</span>
|
||||
</slot>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<slot name="header-actions" />
|
||||
<ButtonStyled v-if="closable" circular>
|
||||
<button
|
||||
v-tooltip="closeLabel"
|
||||
:aria-label="closeLabel"
|
||||
:disabled="disableClose"
|
||||
@click="hide"
|
||||
>
|
||||
<XIcon aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ButtonStyled
|
||||
v-if="props.mergeHeader && closable"
|
||||
class="absolute top-4 right-4 z-10"
|
||||
circular
|
||||
>
|
||||
<button
|
||||
v-tooltip="closeLabel"
|
||||
:aria-label="closeLabel"
|
||||
:disabled="disableClose"
|
||||
@click="hide"
|
||||
>
|
||||
<XIcon aria-hidden="true" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
|
||||
<div v-if="scrollable" class="relative flex-1 min-h-0 flex flex-col">
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-6"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-6"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTopFade"
|
||||
class="pointer-events-none absolute left-0 right-0 top-0 z-10 h-6 bg-gradient-to-b from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
|
||||
<div
|
||||
ref="scrollContainer"
|
||||
data-modal-content
|
||||
:class="[
|
||||
'flex-1 min-h-0 overflow-y-auto',
|
||||
props.noPadding ? '' : 'p-6 !pb-1 sm:pb-6',
|
||||
{ 'pt-12': props.mergeHeader && closable && !props.noPadding },
|
||||
]"
|
||||
:style="{ maxHeight: maxContentHeight }"
|
||||
@scroll="checkScrollState"
|
||||
>
|
||||
<slot> You just lost the game.</slot>
|
||||
</div>
|
||||
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-6"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-6"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showBottomFade"
|
||||
class="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-6 bg-gradient-to-t from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
data-modal-content
|
||||
:class="[
|
||||
'min-h-0',
|
||||
props.noPadding ? '' : 'overflow-y-auto p-6',
|
||||
{ 'pt-12': props.mergeHeader && closable && !props.noPadding },
|
||||
]"
|
||||
>
|
||||
<slot> You just lost the game.</slot>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="$slots.actions"
|
||||
:class="{ 'pt-4 border-0 border-t border-solid border-surface-5': actionsDivider }"
|
||||
class="p-4"
|
||||
>
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { XIcon } from '@modrinth/assets'
|
||||
import { computed, nextTick, onUnmounted, ref } from 'vue'
|
||||
|
||||
import { useVIntl } from '../../composables/i18n'
|
||||
import { useModalStack } from '../../composables/modal-stack'
|
||||
import { useScrollIndicator } from '../../composables/scroll-indicator'
|
||||
import { injectModalBehavior } from '../../providers'
|
||||
import { commonMessages } from '../../utils/common-messages'
|
||||
import ButtonStyled from '../base/ButtonStyled.vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const modalBehavior = injectModalBehavior(null)
|
||||
const {
|
||||
push: pushModal,
|
||||
pop: popModal,
|
||||
isTopmost: isTopmostModal,
|
||||
stackSize: modalStackSize,
|
||||
} = useModalStack()
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
noblur?: boolean
|
||||
closable?: boolean
|
||||
/** @deprecated Use `fade="danger"` instead */
|
||||
danger?: boolean
|
||||
fade?: 'standard' | 'warning' | 'danger'
|
||||
closeOnEsc?: boolean
|
||||
closeOnClickOutside?: boolean
|
||||
warnOnClose?: boolean
|
||||
header?: string
|
||||
hideHeader?: boolean
|
||||
onHide?: () => void
|
||||
onAfterHide?: () => void
|
||||
onShow?: () => void
|
||||
beforeHide?: () => boolean
|
||||
mergeHeader?: boolean
|
||||
scrollable?: boolean
|
||||
maxContentHeight?: string
|
||||
/** Removes padding from the content area. Useful for edge-to-edge layouts. */
|
||||
noPadding?: boolean
|
||||
/** Max width for the modal (e.g., '460px', '600px'). Defaults to '60rem'. */
|
||||
maxWidth?: string
|
||||
/** Width for the modal body (e.g., '460px', '600px'). */
|
||||
width?: string
|
||||
/** Disables all close actions (close button, ESC key, click outside). */
|
||||
disableClose?: boolean
|
||||
actionsDivider?: boolean
|
||||
}>(),
|
||||
{
|
||||
type: true,
|
||||
noblur: undefined,
|
||||
closable: true,
|
||||
danger: false,
|
||||
fade: undefined,
|
||||
closeOnClickOutside: true,
|
||||
closeOnEsc: true,
|
||||
warnOnClose: false,
|
||||
header: undefined,
|
||||
hideHeader: false,
|
||||
onHide: () => {},
|
||||
onAfterHide: () => {},
|
||||
onShow: () => {},
|
||||
beforeHide: undefined,
|
||||
mergeHeader: false,
|
||||
// TODO: migrate all modals to use scrollable and remove this prop
|
||||
scrollable: false,
|
||||
maxContentHeight: '70vh',
|
||||
noPadding: false,
|
||||
maxWidth: undefined,
|
||||
width: undefined,
|
||||
disableClose: false,
|
||||
actionsDivider: false,
|
||||
},
|
||||
)
|
||||
|
||||
const effectiveNoblur = computed(() => props.noblur ?? modalBehavior?.noblur.value ?? false)
|
||||
|
||||
const computedFade = computed(() => {
|
||||
if (props.fade) return props.fade
|
||||
if (props.danger) return 'danger'
|
||||
return 'standard'
|
||||
})
|
||||
|
||||
const modalId = `modal-${Math.random().toString(36).slice(2, 9)}`
|
||||
const headerId = `${modalId}-header`
|
||||
const closeLabel = computed(() => formatMessage(commonMessages.closeButton))
|
||||
|
||||
const open = ref(false)
|
||||
const visible = ref(false)
|
||||
const stackDepth = ref(0)
|
||||
const modalBodyRef = ref<HTMLElement | null>(null)
|
||||
let previousFocusEl: Element | null = null
|
||||
let hideTimeout: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const scrollContainer = ref<HTMLElement | null>(null)
|
||||
const { showTopFade, showBottomFade, checkScrollState } = useScrollIndicator(scrollContainer)
|
||||
|
||||
const FOCUSABLE_SELECTOR =
|
||||
'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'
|
||||
|
||||
function getFocusableElements(): HTMLElement[] {
|
||||
if (!modalBodyRef.value) return []
|
||||
return Array.from(modalBodyRef.value.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR))
|
||||
}
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout)
|
||||
hideTimeout = null
|
||||
}
|
||||
props.onShow?.()
|
||||
const wasEmpty = modalStackSize() === 0
|
||||
stackDepth.value = modalStackSize()
|
||||
open.value = true
|
||||
previousFocusEl = document.activeElement
|
||||
pushModal()
|
||||
if (wasEmpty) modalBehavior?.onShow?.()
|
||||
|
||||
document.body.style.overflow = 'hidden'
|
||||
window.addEventListener('keydown', handleWindowKeyDown)
|
||||
window.addEventListener('mousedown', updateMousePosition)
|
||||
if (event) {
|
||||
updateMousePosition(event)
|
||||
} else {
|
||||
mouseX.value = Math.round(window.innerWidth / 2)
|
||||
mouseY.value = Math.round(window.innerHeight / 2)
|
||||
}
|
||||
setTimeout(() => {
|
||||
visible.value = true
|
||||
nextTick(() => {
|
||||
const focusable = getFocusableElements()
|
||||
if (focusable.length > 0) {
|
||||
focusable[0].focus()
|
||||
} else {
|
||||
modalBodyRef.value?.focus()
|
||||
}
|
||||
})
|
||||
}, 50)
|
||||
}
|
||||
|
||||
function hide(): boolean {
|
||||
if (props.disableClose) {
|
||||
return false
|
||||
}
|
||||
if (props.beforeHide?.() === false) {
|
||||
return false
|
||||
}
|
||||
props.onHide?.()
|
||||
resetMousePosition()
|
||||
visible.value = false
|
||||
popModal()
|
||||
if (modalStackSize() === 0) {
|
||||
modalBehavior?.onHide?.()
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
window.removeEventListener('keydown', handleWindowKeyDown)
|
||||
window.removeEventListener('mousedown', updateMousePosition)
|
||||
if (previousFocusEl instanceof HTMLElement) {
|
||||
previousFocusEl.focus()
|
||||
}
|
||||
previousFocusEl = null
|
||||
hideTimeout = setTimeout(() => {
|
||||
open.value = false
|
||||
hideTimeout = null
|
||||
nextTick(() => props.onAfterHide?.())
|
||||
}, 300)
|
||||
return true
|
||||
}
|
||||
|
||||
async function scrollToBottom(behavior: ScrollBehavior = 'smooth') {
|
||||
await nextTick()
|
||||
if (!scrollContainer.value) return
|
||||
|
||||
scrollContainer.value.scrollTo({
|
||||
top: scrollContainer.value.scrollHeight,
|
||||
behavior,
|
||||
})
|
||||
requestAnimationFrame(checkScrollState)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
hide,
|
||||
checkScrollState,
|
||||
scrollToBottom,
|
||||
})
|
||||
|
||||
const mouseX = ref(0)
|
||||
const mouseY = ref(0)
|
||||
|
||||
const MODAL_STACK_BASE_Z = 100
|
||||
const stackZBase = computed(() => MODAL_STACK_BASE_Z + stackDepth.value * 10)
|
||||
const stackOverlayZ = computed(() => stackZBase.value + 19)
|
||||
const stackTauriZ = computed(() => stackZBase.value + 20)
|
||||
const stackContainerZ = computed(() => stackZBase.value + 21)
|
||||
const resolvedMaxWidth = computed(() => props.maxWidth ?? '60rem')
|
||||
const resolvedWidth = computed(() => props.width ?? 'fit-content')
|
||||
const mouseXOffset = computed(() => `calc((-50vw + ${mouseX.value}px) / 16)`)
|
||||
const mouseYOffset = computed(() => `calc((-50vh + ${mouseY.value}px) / 16)`)
|
||||
|
||||
function updateMousePosition(event: { clientX: number; clientY: number }) {
|
||||
mouseX.value = event.clientX
|
||||
mouseY.value = event.clientY
|
||||
}
|
||||
|
||||
function resetMousePosition() {
|
||||
mouseX.value = Math.round(window.innerWidth / 2)
|
||||
mouseY.value = Math.round(window.innerHeight / 2)
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
if (hideTimeout) {
|
||||
clearTimeout(hideTimeout)
|
||||
hideTimeout = null
|
||||
}
|
||||
if (open.value) {
|
||||
popModal()
|
||||
window.removeEventListener('keydown', handleWindowKeyDown)
|
||||
window.removeEventListener('mousedown', updateMousePosition)
|
||||
if (modalStackSize() === 0) {
|
||||
document.body.style.overflow = ''
|
||||
modalBehavior?.onHide?.()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function handleWindowKeyDown(event: KeyboardEvent) {
|
||||
if (props.closeOnEsc && event.key === 'Escape' && props.closable) {
|
||||
if (!isTopmostModal()) return
|
||||
hide()
|
||||
}
|
||||
}
|
||||
|
||||
function handleKeyDown(event: KeyboardEvent) {
|
||||
if (event.key === 'Tab') {
|
||||
const focusable = getFocusableElements()
|
||||
if (focusable.length === 0) return
|
||||
|
||||
const first = focusable[0]
|
||||
const last = focusable[focusable.length - 1]
|
||||
|
||||
if (event.shiftKey) {
|
||||
if (document.activeElement === first) {
|
||||
event.preventDefault()
|
||||
last.focus()
|
||||
}
|
||||
} else {
|
||||
if (document.activeElement === last) {
|
||||
event.preventDefault()
|
||||
first.focus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tauri-overlay {
|
||||
position: fixed;
|
||||
visibility: hidden;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
z-index: v-bind(stackTauriZ);
|
||||
|
||||
&.shown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
inset: -5rem;
|
||||
z-index: v-bind(stackOverlayZ);
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transition: all 0.2s ease-out;
|
||||
//transform: translate(
|
||||
// calc((-50vw + var(--_mouse-x, 50vw) * 1px) / 2),
|
||||
// calc((-50vh + var(--_mouse-y, 50vh) * 1px) / 2)
|
||||
// )
|
||||
// scaleX(0.8) scaleY(0.5);
|
||||
border-radius: 180px;
|
||||
//filter: blur(5px);
|
||||
|
||||
// Fade variants
|
||||
&.standard {
|
||||
background: linear-gradient(to bottom, rgba(29, 48, 43, 0.52) 0%, rgba(14, 21, 26, 0.95) 100%);
|
||||
}
|
||||
|
||||
&.warning {
|
||||
background: linear-gradient(to bottom, rgba(48, 38, 29, 0.52) 0%, rgba(26, 20, 14, 0.95) 100%);
|
||||
}
|
||||
|
||||
&.danger {
|
||||
background: linear-gradient(to bottom, rgba(43, 18, 26, 0.52) 0%, rgba(49, 10, 15, 0.95) 100%);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
&.shown {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
pointer-events: auto;
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
&.noblur {
|
||||
backdrop-filter: none;
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modrinth-parent__no-modal-blurs {
|
||||
.modal-overlay {
|
||||
backdrop-filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: v-bind(stackContainerZ);
|
||||
visibility: hidden;
|
||||
pointer-events: none;
|
||||
transform: translate(v-bind(mouseXOffset), v-bind(mouseYOffset));
|
||||
transition: none;
|
||||
|
||||
&.shown {
|
||||
visibility: visible;
|
||||
transform: translate(0, 0);
|
||||
transition: all 0.2s ease-out;
|
||||
|
||||
> .modal-body {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
scale: 1;
|
||||
}
|
||||
}
|
||||
|
||||
> .modal-body {
|
||||
position: fixed;
|
||||
box-shadow: 4px 4px 26px 10px rgba(0, 0, 0, 0.08);
|
||||
max-height: calc(100% - 2 * var(--gap-lg));
|
||||
max-width: min(v-bind(resolvedMaxWidth), calc(100% - 2 * var(--gap-lg)));
|
||||
overflow-y: hidden;
|
||||
overflow-x: hidden;
|
||||
width: v-bind(resolvedWidth);
|
||||
pointer-events: auto;
|
||||
scale: 0.97;
|
||||
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: all 0.2s ease-in-out;
|
||||
|
||||
@media (prefers-reduced-motion) {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
width: calc(100% - 2 * var(--gap-lg));
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user