You've already forked AstralRinth
forked from didirus/AstralRinth
refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs * fix: prettier frontend * feat: config changes * fix: lint issues * fix: lint * fix: type imports * fix: cyclical import issue * fix: lockfile * fix: missing dep * fix: switch to tabs * fix: continue switch to tabs * fix: rustfmt parity * fix: moderation lint issue * fix: lint issues * fix: ui intl * fix: lint issues * Revert "fix: rustfmt parity" This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711. * feat: revert last rs
This commit is contained in:
@@ -1,222 +1,222 @@
|
||||
<template>
|
||||
<div class="mb-3 flex flex-wrap gap-2">
|
||||
<VersionFilterControl
|
||||
ref="versionFilters"
|
||||
:versions="versions"
|
||||
:game-versions="gameVersions"
|
||||
:base-id="`${baseId}-filter`"
|
||||
@update:query="updateQuery"
|
||||
/>
|
||||
<Pagination
|
||||
:page="currentPage"
|
||||
class="ml-auto mt-auto"
|
||||
:count="Math.ceil(filteredVersions.length / pageSize)"
|
||||
@switch-page="switchPage"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="versions.length > 0"
|
||||
class="flex flex-col gap-4 rounded-2xl bg-bg-raised px-6 pb-8 pt-4 supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[1fr_min-content] sm:px-8 supports-[grid-template-columns:subgrid]:sm:grid-cols-[min-content_auto_auto_auto_min-content] supports-[grid-template-columns:subgrid]:xl:grid-cols-[min-content_auto_auto_auto_auto_auto_min-content]"
|
||||
>
|
||||
<div class="versions-grid-row">
|
||||
<div class="w-9 max-sm:hidden"></div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden">Name</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Game version
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Platforms
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Published
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Downloads
|
||||
</div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden xl:collapse xl:hidden">
|
||||
Compatibility
|
||||
</div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden xl:collapse xl:hidden">Stats</div>
|
||||
<div class="w-9 max-sm:hidden"></div>
|
||||
</div>
|
||||
<template v-for="(version, index) in currentVersions" :key="index">
|
||||
<!-- Row divider -->
|
||||
<div
|
||||
class="versions-grid-row h-px w-full bg-button-bg"
|
||||
:class="{
|
||||
'max-sm:!hidden': index === 0,
|
||||
}"
|
||||
></div>
|
||||
<div class="versions-grid-row group relative">
|
||||
<AutoLink
|
||||
v-if="!!versionLink"
|
||||
class="absolute inset-[calc(-1rem-2px)_-2rem] before:absolute before:inset-0 before:transition-all before:content-[''] hover:before:backdrop-brightness-110"
|
||||
:to="versionLink?.(version)"
|
||||
/>
|
||||
<div class="flex flex-col justify-center gap-2 sm:contents">
|
||||
<div class="flex flex-row items-center gap-2 sm:contents">
|
||||
<div class="self-center">
|
||||
<div class="relative z-[1] cursor-pointer">
|
||||
<VersionChannelIndicator
|
||||
v-tooltip="`Toggle filter for ${version.version_type}`"
|
||||
:channel="version.version_type"
|
||||
@click="versionFilters?.toggleFilter('channel', version.version_type)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="pointer-events-none relative z-[1] flex flex-col justify-center"
|
||||
:class="{
|
||||
'group-hover:underline': !!versionLink,
|
||||
}"
|
||||
>
|
||||
<div class="font-bold text-contrast">{{ version.version_number }}</div>
|
||||
<div class="text-xs font-medium">{{ version.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center gap-2 sm:contents">
|
||||
<div class="flex flex-row flex-wrap items-center gap-1 xl:contents">
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<TagItem
|
||||
v-for="gameVersion in formatVersionsForDisplay(
|
||||
version.game_versions,
|
||||
gameVersions,
|
||||
)"
|
||||
:key="`version-tag-${gameVersion}`"
|
||||
v-tooltip="`Toggle filter for ${gameVersion}`"
|
||||
class="z-[1]"
|
||||
:action="
|
||||
() => versionFilters?.toggleFilters('gameVersion', version.game_versions)
|
||||
"
|
||||
>
|
||||
{{ gameVersion }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<TagItem
|
||||
v-for="platform in version.loaders"
|
||||
:key="`platform-tag-${platform}`"
|
||||
v-tooltip="`Toggle filter for ${platform}`"
|
||||
class="z-[1]"
|
||||
:style="`--_color: var(--color-platform-${platform})`"
|
||||
:action="() => versionFilters?.toggleFilter('platform', platform)"
|
||||
>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<svg v-html="loaders.find((x) => x.name === platform)?.icon"></svg>
|
||||
{{ formatCategory(platform) }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col justify-center gap-1 max-sm:flex-row max-sm:justify-start max-sm:gap-3 xl:contents"
|
||||
>
|
||||
<div
|
||||
v-tooltip="
|
||||
formatMessage(commonMessages.dateAtTimeTooltip, {
|
||||
date: new Date(version.date_published),
|
||||
time: new Date(version.date_published),
|
||||
})
|
||||
"
|
||||
class="z-[1] flex cursor-help items-center gap-1 text-nowrap font-medium xl:self-center"
|
||||
>
|
||||
<CalendarIcon class="xl:hidden" />
|
||||
{{ formatRelativeTime(version.date_published) }}
|
||||
</div>
|
||||
<div
|
||||
class="pointer-events-none z-[1] flex items-center gap-1 font-medium xl:self-center"
|
||||
>
|
||||
<DownloadIcon class="xl:hidden" />
|
||||
{{ formatNumber(version.downloads) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start justify-end gap-1 sm:items-center z-[1]">
|
||||
<slot name="actions" :version="version"></slot>
|
||||
</div>
|
||||
<div v-if="showFiles" class="tag-list pointer-events-none relative z-[1] col-span-full">
|
||||
<div
|
||||
v-for="(file, fileIdx) in version.files"
|
||||
:key="`platform-tag-${fileIdx}`"
|
||||
:class="`flex items-center gap-1 text-wrap rounded-full bg-button-bg px-2 py-0.5 text-xs font-medium ${file.primary || fileIdx === 0 ? 'bg-brand-highlight text-contrast' : 'text-primary'}`"
|
||||
>
|
||||
<StarIcon v-if="file.primary || fileIdx === 0" class="shrink-0" />
|
||||
{{ file.filename }} - {{ formatBytes(file.size) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex mt-3">
|
||||
<Pagination
|
||||
:page="currentPage"
|
||||
class="ml-auto"
|
||||
:count="Math.ceil(filteredVersions.length / pageSize)"
|
||||
@switch-page="switchPage"
|
||||
/>
|
||||
</div>
|
||||
<div class="mb-3 flex flex-wrap gap-2">
|
||||
<VersionFilterControl
|
||||
ref="versionFilters"
|
||||
:versions="versions"
|
||||
:game-versions="gameVersions"
|
||||
:base-id="`${baseId}-filter`"
|
||||
@update:query="updateQuery"
|
||||
/>
|
||||
<Pagination
|
||||
:page="currentPage"
|
||||
class="ml-auto mt-auto"
|
||||
:count="Math.ceil(filteredVersions.length / pageSize)"
|
||||
@switch-page="switchPage"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="versions.length > 0"
|
||||
class="flex flex-col gap-4 rounded-2xl bg-bg-raised px-6 pb-8 pt-4 supports-[grid-template-columns:subgrid]:grid supports-[grid-template-columns:subgrid]:grid-cols-[1fr_min-content] sm:px-8 supports-[grid-template-columns:subgrid]:sm:grid-cols-[min-content_auto_auto_auto_min-content] supports-[grid-template-columns:subgrid]:xl:grid-cols-[min-content_auto_auto_auto_auto_auto_min-content]"
|
||||
>
|
||||
<div class="versions-grid-row">
|
||||
<div class="w-9 max-sm:hidden"></div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden">Name</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Game version
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Platforms
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Published
|
||||
</div>
|
||||
<div
|
||||
class="text-sm font-bold text-contrast max-sm:hidden sm:max-xl:collapse sm:max-xl:hidden"
|
||||
>
|
||||
Downloads
|
||||
</div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden xl:collapse xl:hidden">
|
||||
Compatibility
|
||||
</div>
|
||||
<div class="text-sm font-bold text-contrast max-sm:hidden xl:collapse xl:hidden">Stats</div>
|
||||
<div class="w-9 max-sm:hidden"></div>
|
||||
</div>
|
||||
<template v-for="(version, index) in currentVersions" :key="index">
|
||||
<!-- Row divider -->
|
||||
<div
|
||||
class="versions-grid-row h-px w-full bg-button-bg"
|
||||
:class="{
|
||||
'max-sm:!hidden': index === 0,
|
||||
}"
|
||||
></div>
|
||||
<div class="versions-grid-row group relative">
|
||||
<AutoLink
|
||||
v-if="!!versionLink"
|
||||
class="absolute inset-[calc(-1rem-2px)_-2rem] before:absolute before:inset-0 before:transition-all before:content-[''] hover:before:backdrop-brightness-110"
|
||||
:to="versionLink?.(version)"
|
||||
/>
|
||||
<div class="flex flex-col justify-center gap-2 sm:contents">
|
||||
<div class="flex flex-row items-center gap-2 sm:contents">
|
||||
<div class="self-center">
|
||||
<div class="relative z-[1] cursor-pointer">
|
||||
<VersionChannelIndicator
|
||||
v-tooltip="`Toggle filter for ${version.version_type}`"
|
||||
:channel="version.version_type"
|
||||
@click="versionFilters?.toggleFilter('channel', version.version_type)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="pointer-events-none relative z-[1] flex flex-col justify-center"
|
||||
:class="{
|
||||
'group-hover:underline': !!versionLink,
|
||||
}"
|
||||
>
|
||||
<div class="font-bold text-contrast">{{ version.version_number }}</div>
|
||||
<div class="text-xs font-medium">{{ version.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center gap-2 sm:contents">
|
||||
<div class="flex flex-row flex-wrap items-center gap-1 xl:contents">
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<TagItem
|
||||
v-for="gameVersion in formatVersionsForDisplay(
|
||||
version.game_versions,
|
||||
gameVersions,
|
||||
)"
|
||||
:key="`version-tag-${gameVersion}`"
|
||||
v-tooltip="`Toggle filter for ${gameVersion}`"
|
||||
class="z-[1]"
|
||||
:action="
|
||||
() => versionFilters?.toggleFilters('gameVersion', version.game_versions)
|
||||
"
|
||||
>
|
||||
{{ gameVersion }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<TagItem
|
||||
v-for="platform in version.loaders"
|
||||
:key="`platform-tag-${platform}`"
|
||||
v-tooltip="`Toggle filter for ${platform}`"
|
||||
class="z-[1]"
|
||||
:style="`--_color: var(--color-platform-${platform})`"
|
||||
:action="() => versionFilters?.toggleFilter('platform', platform)"
|
||||
>
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<svg v-html="loaders.find((x) => x.name === platform)?.icon"></svg>
|
||||
{{ formatCategory(platform) }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="flex flex-col justify-center gap-1 max-sm:flex-row max-sm:justify-start max-sm:gap-3 xl:contents"
|
||||
>
|
||||
<div
|
||||
v-tooltip="
|
||||
formatMessage(commonMessages.dateAtTimeTooltip, {
|
||||
date: new Date(version.date_published),
|
||||
time: new Date(version.date_published),
|
||||
})
|
||||
"
|
||||
class="z-[1] flex cursor-help items-center gap-1 text-nowrap font-medium xl:self-center"
|
||||
>
|
||||
<CalendarIcon class="xl:hidden" />
|
||||
{{ formatRelativeTime(version.date_published) }}
|
||||
</div>
|
||||
<div
|
||||
class="pointer-events-none z-[1] flex items-center gap-1 font-medium xl:self-center"
|
||||
>
|
||||
<DownloadIcon class="xl:hidden" />
|
||||
{{ formatNumber(version.downloads) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start justify-end gap-1 sm:items-center z-[1]">
|
||||
<slot name="actions" :version="version"></slot>
|
||||
</div>
|
||||
<div v-if="showFiles" class="tag-list pointer-events-none relative z-[1] col-span-full">
|
||||
<div
|
||||
v-for="(file, fileIdx) in version.files"
|
||||
:key="`platform-tag-${fileIdx}`"
|
||||
:class="`flex items-center gap-1 text-wrap rounded-full bg-button-bg px-2 py-0.5 text-xs font-medium ${file.primary || fileIdx === 0 ? 'bg-brand-highlight text-contrast' : 'text-primary'}`"
|
||||
>
|
||||
<StarIcon v-if="file.primary || fileIdx === 0" class="shrink-0" />
|
||||
{{ file.filename }} - {{ formatBytes(file.size) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex mt-3">
|
||||
<Pagination
|
||||
:page="currentPage"
|
||||
class="ml-auto"
|
||||
:count="Math.ceil(filteredVersions.length / pageSize)"
|
||||
@switch-page="switchPage"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
formatBytes,
|
||||
formatCategory,
|
||||
formatNumber,
|
||||
formatVersionsForDisplay,
|
||||
type GameVersionTag,
|
||||
type PlatformTag,
|
||||
type Version,
|
||||
} from '@modrinth/utils'
|
||||
|
||||
import { commonMessages } from '../../utils/common-messages'
|
||||
import { CalendarIcon, DownloadIcon, StarIcon } from '@modrinth/assets'
|
||||
import { Pagination, VersionChannelIndicator, VersionFilterControl } from '../index'
|
||||
import {
|
||||
formatBytes,
|
||||
formatCategory,
|
||||
formatNumber,
|
||||
formatVersionsForDisplay,
|
||||
type GameVersionTag,
|
||||
type PlatformTag,
|
||||
type Version,
|
||||
} from '@modrinth/utils'
|
||||
import { useVIntl } from '@vintl/vintl'
|
||||
import { type Ref, ref, computed } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import { computed, type Ref, ref } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { useRelativeTime } from '../../composables'
|
||||
import { commonMessages } from '../../utils/common-messages'
|
||||
import AutoLink from '../base/AutoLink.vue'
|
||||
import TagItem from '../base/TagItem.vue'
|
||||
import { useRelativeTime } from '../../composables'
|
||||
import { Pagination, VersionChannelIndicator, VersionFilterControl } from '../index'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const formatRelativeTime = useRelativeTime()
|
||||
|
||||
type VersionWithDisplayUrlEnding = Version & {
|
||||
displayUrlEnding: string
|
||||
displayUrlEnding: string
|
||||
}
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
baseId?: string
|
||||
project: {
|
||||
project_type: string
|
||||
slug?: string
|
||||
id: string
|
||||
}
|
||||
versions: VersionWithDisplayUrlEnding[]
|
||||
showFiles?: boolean
|
||||
currentMember?: boolean
|
||||
loaders: PlatformTag[]
|
||||
gameVersions: GameVersionTag[]
|
||||
versionLink?: (version: Version) => string
|
||||
}>(),
|
||||
{
|
||||
baseId: undefined,
|
||||
showFiles: false,
|
||||
currentMember: false,
|
||||
versionLink: undefined,
|
||||
},
|
||||
defineProps<{
|
||||
baseId?: string
|
||||
project: {
|
||||
project_type: string
|
||||
slug?: string
|
||||
id: string
|
||||
}
|
||||
versions: VersionWithDisplayUrlEnding[]
|
||||
showFiles?: boolean
|
||||
currentMember?: boolean
|
||||
loaders: PlatformTag[]
|
||||
gameVersions: GameVersionTag[]
|
||||
versionLink?: (version: Version) => string
|
||||
}>(),
|
||||
{
|
||||
baseId: undefined,
|
||||
showFiles: false,
|
||||
currentMember: false,
|
||||
versionLink: undefined,
|
||||
},
|
||||
)
|
||||
|
||||
const currentPage: Ref<number> = ref(1)
|
||||
@@ -224,74 +224,74 @@ const pageSize: Ref<number> = ref(20)
|
||||
const versionFilters: Ref<InstanceType<typeof VersionFilterControl> | null> = ref(null)
|
||||
|
||||
const selectedGameVersions: Ref<string[]> = computed(
|
||||
() => versionFilters.value?.selectedGameVersions ?? [],
|
||||
() => versionFilters.value?.selectedGameVersions ?? [],
|
||||
)
|
||||
const selectedPlatforms: Ref<string[]> = computed(
|
||||
() => versionFilters.value?.selectedPlatforms ?? [],
|
||||
() => versionFilters.value?.selectedPlatforms ?? [],
|
||||
)
|
||||
const selectedChannels: Ref<string[]> = computed(() => versionFilters.value?.selectedChannels ?? [])
|
||||
|
||||
const filteredVersions = computed(() => {
|
||||
return props.versions.filter(
|
||||
(version) =>
|
||||
hasAnySelected(version.game_versions, selectedGameVersions.value) &&
|
||||
hasAnySelected(version.loaders, selectedPlatforms.value) &&
|
||||
isAnySelected(version.version_type, selectedChannels.value),
|
||||
)
|
||||
return props.versions.filter(
|
||||
(version) =>
|
||||
hasAnySelected(version.game_versions, selectedGameVersions.value) &&
|
||||
hasAnySelected(version.loaders, selectedPlatforms.value) &&
|
||||
isAnySelected(version.version_type, selectedChannels.value),
|
||||
)
|
||||
})
|
||||
|
||||
function hasAnySelected(values: string[], selected: string[]) {
|
||||
return selected.length === 0 || selected.some((value) => values.includes(value))
|
||||
return selected.length === 0 || selected.some((value) => values.includes(value))
|
||||
}
|
||||
|
||||
function isAnySelected(value: string, selected: string[]) {
|
||||
return selected.length === 0 || selected.includes(value)
|
||||
return selected.length === 0 || selected.includes(value)
|
||||
}
|
||||
|
||||
const currentVersions = computed(() =>
|
||||
filteredVersions.value.slice(
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
currentPage.value * pageSize.value,
|
||||
),
|
||||
filteredVersions.value.slice(
|
||||
(currentPage.value - 1) * pageSize.value,
|
||||
currentPage.value * pageSize.value,
|
||||
),
|
||||
)
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
if (route.query.page) {
|
||||
currentPage.value = Number(route.query.page) || 1
|
||||
currentPage.value = Number(route.query.page) || 1
|
||||
}
|
||||
|
||||
function switchPage(page: number) {
|
||||
currentPage.value = page
|
||||
currentPage.value = page
|
||||
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
page: currentPage.value !== 1 ? currentPage.value : undefined,
|
||||
},
|
||||
})
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
page: currentPage.value !== 1 ? currentPage.value : undefined,
|
||||
},
|
||||
})
|
||||
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
|
||||
function updateQuery(newQueries: Record<string, string | string[] | undefined | null>) {
|
||||
if (newQueries.page) {
|
||||
currentPage.value = Number(newQueries.page)
|
||||
} else if (newQueries.page === undefined) {
|
||||
currentPage.value = 1
|
||||
}
|
||||
if (newQueries.page) {
|
||||
currentPage.value = Number(newQueries.page)
|
||||
} else if (newQueries.page === undefined) {
|
||||
currentPage.value = 1
|
||||
}
|
||||
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
...newQueries,
|
||||
},
|
||||
})
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
...newQueries,
|
||||
},
|
||||
})
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.versions-grid-row {
|
||||
@apply grid grid-cols-[1fr_min-content] gap-4 supports-[grid-template-columns:subgrid]:col-span-full supports-[grid-template-columns:subgrid]:!grid-cols-subgrid sm:grid-cols-[min-content_1fr_1fr_1fr_min-content] xl:grid-cols-[min-content_1fr_1fr_1fr_1fr_1fr_min-content];
|
||||
@apply grid grid-cols-[1fr_min-content] gap-4 supports-[grid-template-columns:subgrid]:col-span-full supports-[grid-template-columns:subgrid]:!grid-cols-subgrid sm:grid-cols-[min-content_1fr_1fr_1fr_min-content] xl:grid-cols-[min-content_1fr_1fr_1fr_1fr_1fr_min-content];
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user