You've already forked AstralRinth
forked from didirus/AstralRinth
Fix a number of light mode issues and get rid of scrollbar jumping on menus (#4760)
* Fix DEV-466, Fixes #4692 as well as a bunch of other poor contrast and inconsistency issues in light mode. Adds shadows to buttons and makes scrollbar gutter stable. * lintttt & only do scrollbar gutter on website * try to fix following hydration issue * try another clientonly approach * fix home page link animation * lint * remove dropdown style from checkbox & improve shadow consistency * liiiint
This commit is contained in:
@@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="checkbox-outer button-within"
|
||||
:class="{ disabled, checked: modelValue }"
|
||||
role="presentation"
|
||||
@click="toggle"
|
||||
>
|
||||
<button
|
||||
class="checkbox"
|
||||
role="checkbox"
|
||||
:disabled="disabled"
|
||||
:class="{ checked: modelValue, collapsing: collapsingToggleStyle }"
|
||||
:aria-label="description ?? label"
|
||||
:aria-checked="modelValue"
|
||||
>
|
||||
<CheckIcon v-if="modelValue && !collapsingToggleStyle" aria-hidden="true" />
|
||||
<DropdownIcon v-else-if="collapsingToggleStyle" aria-hidden="true" />
|
||||
</button>
|
||||
<!-- aria-hidden is set so screenreaders only use the <button>'s aria-label -->
|
||||
<p v-if="label" aria-hidden="true">
|
||||
{{ label }}
|
||||
</p>
|
||||
<slot v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { CheckIcon, DropdownIcon } from '@modrinth/assets'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CheckIcon,
|
||||
DropdownIcon,
|
||||
},
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: '',
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
modelValue: Boolean,
|
||||
clickEvent: {
|
||||
type: Function,
|
||||
required: false,
|
||||
default: () => {},
|
||||
},
|
||||
collapsingToggleStyle: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
emits: ['update:modelValue'],
|
||||
methods: {
|
||||
toggle() {
|
||||
if (!this.disabled) {
|
||||
this.$emit('update:modelValue', !this.modelValue)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.checkbox-outer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
p {
|
||||
user-select: none;
|
||||
padding: 0.2rem 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.checked {
|
||||
outline: 2px solid transparent;
|
||||
outline-offset: 4px;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
min-width: 1rem;
|
||||
min-height: 1rem;
|
||||
|
||||
padding: 0;
|
||||
margin: 0 0.5rem 0 0;
|
||||
|
||||
color: var(--color-button-text);
|
||||
background-color: var(--color-button-bg);
|
||||
border-radius: var(--size-rounded-control);
|
||||
box-shadow:
|
||||
var(--shadow-inset-sm),
|
||||
0 0 0 0 transparent;
|
||||
|
||||
&.checked {
|
||||
background-color: var(--color-brand);
|
||||
}
|
||||
|
||||
svg {
|
||||
color: var(--color-accent-contrast, var(--color-brand-inverted));
|
||||
stroke-width: 0.2rem;
|
||||
height: 0.8rem;
|
||||
width: 0.8rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&.collapsing {
|
||||
background-color: transparent !important;
|
||||
box-shadow: none;
|
||||
|
||||
svg {
|
||||
color: inherit;
|
||||
height: 1rem;
|
||||
width: 1rem;
|
||||
transition: transform 0.25s ease-in-out;
|
||||
}
|
||||
|
||||
&.checked {
|
||||
svg {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
box-shadow: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,6 +1,8 @@
|
||||
<template>
|
||||
<nav :aria-label="ariaLabel" class="w-full">
|
||||
<ul class="m-0 flex list-none flex-col items-start gap-1.5 rounded-2xl bg-bg-raised p-4">
|
||||
<ul
|
||||
class="card-shadow m-0 flex list-none flex-col items-start gap-1.5 rounded-2xl bg-bg-raised p-4"
|
||||
>
|
||||
<slot v-if="hasSlotContent" />
|
||||
|
||||
<template v-else>
|
||||
|
||||
@@ -152,7 +152,7 @@ const onSubmitHandler = () => {
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
margin-top: var(--gap-md);
|
||||
border: 1px solid var(--color-button-bg);
|
||||
border: 1px solid var(--color-divider);
|
||||
background-color: var(--color-raised-bg);
|
||||
|
||||
.table-row {
|
||||
|
||||
@@ -356,7 +356,7 @@ svg {
|
||||
:deep(.apexcharts-yaxistooltip) {
|
||||
background: var(--color-raised-bg) !important;
|
||||
border-radius: var(--radius-sm) !important;
|
||||
border: 1px solid var(--color-button-bg) !important;
|
||||
border: 1px solid var(--color-divider) !important;
|
||||
box-shadow: var(--shadow-floating) !important;
|
||||
font-size: var(--font-size-nm) !important;
|
||||
}
|
||||
@@ -371,7 +371,7 @@ svg {
|
||||
:deep(.apexcharts-xaxistooltip) {
|
||||
background: var(--color-raised-bg) !important;
|
||||
border-radius: var(--radius-sm) !important;
|
||||
border: 1px solid var(--color-button-bg) !important;
|
||||
border: 1px solid var(--color-divider) !important;
|
||||
font-size: var(--font-size-nm) !important;
|
||||
color: var(--color-base) !important;
|
||||
|
||||
|
||||
@@ -891,7 +891,7 @@ const defaultRanges: RangeObject[] = [
|
||||
flex-direction: column;
|
||||
background-color: var(--color-bg);
|
||||
border-radius: var(--radius-sm);
|
||||
border: 1px solid var(--color-button-bg);
|
||||
border: 1px solid var(--color-divider);
|
||||
gap: var(--gap-md);
|
||||
padding: var(--gap-md);
|
||||
margin-top: var(--gap-md);
|
||||
@@ -920,7 +920,7 @@ const defaultRanges: RangeObject[] = [
|
||||
width: 100%;
|
||||
height: 1rem;
|
||||
background-color: var(--color-raised-bg);
|
||||
border: 1px solid var(--color-button-bg);
|
||||
border: 1px solid var(--color-divider);
|
||||
border-radius: var(--radius-sm);
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
@@ -159,10 +159,10 @@ defineExpose({
|
||||
flex-direction: column;
|
||||
|
||||
gap: var(--gap-xs);
|
||||
border: 1px solid var(--color-button-bg);
|
||||
border: 1px solid var(--color-divider);
|
||||
border-radius: var(--radius-md);
|
||||
background-color: var(--color-raised-bg);
|
||||
box-shadow: var(--shadow-floating);
|
||||
box-shadow: var(--shadow-card);
|
||||
|
||||
color: var(--color-base);
|
||||
font-size: var(--font-size-nm);
|
||||
@@ -192,7 +192,7 @@ svg {
|
||||
:deep(.apexcharts-yaxistooltip) {
|
||||
background: var(--color-raised-bg) !important;
|
||||
border-radius: var(--radius-sm) !important;
|
||||
border: 1px solid var(--color-button-bg) !important;
|
||||
border: 1px solid var(--color-divider) !important;
|
||||
box-shadow: var(--shadow-floating) !important;
|
||||
font-size: var(--font-size-nm) !important;
|
||||
}
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
<template>
|
||||
<Checkbox
|
||||
class="filter"
|
||||
:model-value="activeFilters.includes(facetName)"
|
||||
:description="displayName"
|
||||
@update:model-value="toggle()"
|
||||
>
|
||||
<div class="filter-text">
|
||||
<div v-if="icon" aria-hidden="true" class="icon" v-html="icon" />
|
||||
<div v-else class="icon">
|
||||
<slot />
|
||||
</div>
|
||||
<span aria-hidden="true"> {{ displayName }}</span>
|
||||
</div>
|
||||
</Checkbox>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Checkbox from '~/components/ui/Checkbox.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Checkbox,
|
||||
},
|
||||
props: {
|
||||
facetName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
displayName: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
activeFilters: {
|
||||
type: Array,
|
||||
default() {
|
||||
return []
|
||||
},
|
||||
},
|
||||
},
|
||||
emits: ['toggle'],
|
||||
methods: {
|
||||
toggle() {
|
||||
this.$emit('toggle', this.facetName)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.filter {
|
||||
margin-bottom: 0.5rem;
|
||||
|
||||
:deep(.filter-text) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.icon {
|
||||
height: 1rem;
|
||||
|
||||
svg {
|
||||
margin-right: 0.25rem;
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -245,13 +245,20 @@ import {
|
||||
LockOpenIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { Admonition, Avatar, ButtonStyled, Combobox, CopyCode, NewModal } from '@modrinth/ui'
|
||||
import {
|
||||
Admonition,
|
||||
Avatar,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
Combobox,
|
||||
CopyCode,
|
||||
NewModal,
|
||||
} from '@modrinth/ui'
|
||||
import TagItem from '@modrinth/ui/src/components/base/TagItem.vue'
|
||||
import { formatCategory, formatVersionsForDisplay, type Mod, type Version } from '@modrinth/utils'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import Accordion from '~/components/ui/Accordion.vue'
|
||||
import Checkbox from '~/components/ui/Checkbox.vue'
|
||||
import ContentVersionFilter, {
|
||||
type ListedGameVersion,
|
||||
type ListedPlatform,
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
v-for="(option, index) in filteredOptions"
|
||||
:key="isDivider(option) ? `divider-${index}` : option.id"
|
||||
>
|
||||
<div v-if="isDivider(option)" class="h-px w-full bg-button-bg"></div>
|
||||
<div v-if="isDivider(option)" class="h-px w-full bg-surface-5"></div>
|
||||
<ButtonStyled v-else type="transparent" role="menuitem" :color="option.color">
|
||||
<button
|
||||
v-if="typeof option.action === 'function'"
|
||||
@@ -288,19 +288,10 @@ const handleMouseOver = (index: number) => {
|
||||
|
||||
// Scrolling is disabled for keyboard navigation
|
||||
const disableBodyScroll = () => {
|
||||
// Make opening not shift page when there's a vertical scrollbar
|
||||
const scrollBarWidth = window.innerWidth - document.documentElement.clientWidth
|
||||
if (scrollBarWidth > 0) {
|
||||
document.body.style.paddingRight = `${scrollBarWidth}px`
|
||||
} else {
|
||||
document.body.style.paddingRight = ''
|
||||
}
|
||||
|
||||
document.body.style.overflow = 'hidden'
|
||||
}
|
||||
|
||||
const enableBodyScroll = () => {
|
||||
document.body.style.paddingRight = ''
|
||||
document.body.style.overflow = ''
|
||||
}
|
||||
|
||||
|
||||
@@ -261,9 +261,14 @@ import {
|
||||
SendIcon,
|
||||
XIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { CopyCode, injectNotificationManager, MarkdownEditor, OverflowMenu } from '@modrinth/ui'
|
||||
import {
|
||||
Checkbox,
|
||||
CopyCode,
|
||||
injectNotificationManager,
|
||||
MarkdownEditor,
|
||||
OverflowMenu,
|
||||
} from '@modrinth/ui'
|
||||
|
||||
import Checkbox from '~/components/ui/Checkbox.vue'
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
import ThreadMessage from '~/components/ui/thread/ThreadMessage.vue'
|
||||
import { useImageUpload } from '~/composables/image-upload.ts'
|
||||
|
||||
Reference in New Issue
Block a user