feat: Launcher reduced motion

This commit is contained in:
LynithDev 2024-05-17 21:20:15 +02:00
parent dfb4c09be7
commit 46a5606ade
11 changed files with 91 additions and 18 deletions

View file

@ -57,3 +57,8 @@ h4 { @apply text-lg font-medium; }
opacity: 1;
transform: translateX(0);
}
body.reduce-motion * {
transition-duration: 0.0001ms !important;
animation-duration: 0.0001ms !important;
}

View file

@ -0,0 +1,30 @@
import { type JSX, createSignal, splitProps } from 'solid-js';
type ToggleProps = JSX.HTMLAttributes<HTMLDivElement> & {
defaultChecked?: boolean;
onChecked?: (checked: boolean) => void;
showText?: 'left' | 'right';
};
function Toggle(props: ToggleProps) {
const [checked, setChecked] = createSignal(props.defaultChecked || false);
const [split, rest] = splitProps(props, ['class', 'defaultChecked', 'onChecked', 'text']);
function toggle() {
const newValue = !checked();
setChecked(newValue);
props.onChecked?.(newValue);
}
return (
<div
onClick={() => toggle()}
class={`w-[40px] h-[22px] p-3 flex flex-row relative rounded-full transition-colors overflow-hidden ${checked() ? 'bg-brand' : 'bg-gray-10'}${` ${split.class}` ?? ''}`}
{...rest}
>
<div class={`w-[16px] h-[16px] rounded-full mx-1 left-0 top-1/2 -translate-y-1/2 transition-transform bg-white absolute ${checked() ? 'translate-x-full' : 'translate-x-0'}`} />
</div>
);
}
export default Toggle;

View file

@ -36,7 +36,7 @@ function ContextMenu(props: ContextMenuProps) {
visible={props.visible}
setVisible={props.setVisible}
>
<div ref={setRef} class="bg-secondary rounded-xl border border-gray-10 p-1 shadow-lg shadow-black/50">
<div ref={setRef} class="bg-secondary rounded-xl border border-gray-05 p-1 shadow-md shadow-black/30">
<div class="flex flex-col gap-y-1 text-fg-primary">
{props.children}
</div>

View file

@ -4,10 +4,10 @@ import { EyeIcon, File06Icon, Globe04Icon, Image03Icon, PackagePlusIcon, Setting
import Sidebar from '../../components/Sidebar';
import AnimatedRoutes from '../../components/AnimatedRoutes';
import ErrorBoundary from '../../components/ErrorBoundary';
import ClusterOverview from './ClusterOverview';
import ClusterLogs from './ClusterLogs';
import ClusterMods from './ClusterMods';
import ClusterScreenshots from './ClusterScreenshots';
import ClusterOverview from './cluster/ClusterOverview';
import ClusterLogs from './cluster/ClusterLogs';
import ClusterMods from './cluster/ClusterMods';
import ClusterScreenshots from './cluster/ClusterScreenshots';
function ClusterRoutes() {
return (

View file

@ -1,7 +1,7 @@
import { useSearchParams } from '@solidjs/router';
import { For, Show, createEffect, createResource, createSignal } from 'solid-js';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-solid';
import { getClusterLog, getClusterLogs } from '../../../bridge/game';
import { getClusterLog, getClusterLogs } from '../../../../bridge/game';
function ClusterLogs() {
const [params] = useSearchParams();

View file

@ -50,8 +50,8 @@ function ModEntry(props: ModEntryProps) {
<div class="flex flex-row justify-between items-center">
<div class="flex flex-col items-start justify-center">
<div class="flex flex-row items-center">
<h3>{props.name}</h3>
<span class="flex flex-row items-center text-sm font-600 text-fg-secondary/50 ml-2">
<h4>{props.name}</h4>
<span class="flex flex-row items-center text-xs font-600 text-fg-secondary/50 ml-2">
{props.version}
{/* TODO: Add version checker */}
{/* <Show when={props.version.includes()}> */}

View file

@ -1,11 +1,11 @@
import { useSearchParams } from '@solidjs/router';
import { Show } from 'solid-js';
import { PlayIcon, Share07Icon } from '@untitled-theme/icons-solid';
import useCluster from '../../hooks/useCluster';
import ClusterCover from '../../components/game/ClusterCover';
import LoaderIcon from '../../components/game/LoaderIcon';
import Button from '../../components/base/Button';
import { launchCluster } from '../../../bridge/game';
import useCluster from '../../../hooks/useCluster';
import ClusterCover from '../../../components/game/ClusterCover';
import LoaderIcon from '../../../components/game/LoaderIcon';
import Button from '../../../components/base/Button';
import { launchCluster } from '../../../../bridge/game';
import ScrollableContainer from '~ui/components/ScrollableContainer';
function ClusterOverview() {

View file

@ -11,14 +11,14 @@ function SettingsRow(props: SettingsRowProps) {
const interactableClass = createEffect(() => props.clickable ? 'hover:bg-component-bg-hover active:bg-component-bg-pressed' : '');
return (
<div class={`flex flex-row bg-component-bg rounded-xl gap-4 px-5 p-4 ${interactableClass} items-center`}>
<div class={`flex flex-row bg-component-bg rounded-xl gap-3.5 p-4 ${interactableClass} items-center`}>
<div class="flex justify-center items-center h-8 w-8">
{props.icon}
</div>
<div class="flex flex-col gap-2 flex-1">
<h3>{props.title}</h3>
<p class="text-wrap">{props.description}</p>
<h3 class="text-lg">{props.title}</h3>
<p class="text-wrap text-sm">{props.description}</p>
</div>
<div class="">

View file

@ -1,21 +1,39 @@
import { ColorsIcon, PaintPourIcon } from '@untitled-theme/icons-solid';
import { ColorsIcon, PaintPourIcon, Speedometer04Icon } from '@untitled-theme/icons-solid';
import SettingsRow from '../components';
import ScrollableContainer from '~ui/components/ScrollableContainer';
import Button from '~ui/components/base/Button';
import Toggle from '~ui/components/base/Toggle';
import reducedMotionTracker from '~ui/state/reducedMotionTracker';
function SettingsAppearance() {
const { reducedMotion, setReducedMotion } = reducedMotionTracker;
return (
<ScrollableContainer title="Appearance">
<div class="flex flex-row items-center flex-1">
<p>theme placeholder</p>
</div>
<SettingsRow
title="Accent Color"
description="The main color used across the launcher. This doesn’t edit your theme."
description="The main color used across the launcher. This doesn't edit your theme."
icon={<PaintPourIcon />}
>
<Button iconLeft={<ColorsIcon />}>#ff0000</Button>
</SettingsRow>
<SettingsRow
title="Animations"
description="Toggle all animations in the launcher."
icon={<Speedometer04Icon />}
>
<Toggle
defaultChecked={reducedMotion()}
onChecked={(checked) => {
setReducedMotion(checked);
}}
/>
</SettingsRow>
</ScrollableContainer>
);
}

View file

@ -0,0 +1,20 @@
import { createEffect, createRoot, createSignal, onMount } from 'solid-js';
function createReducedMotionTracker() {
const [reducedMotion, setReducedMotion] = createSignal(false);
onMount(() => {
const enabled = window.localStorage.getItem('reduced-motion') === 'true';
setReducedMotion(enabled);
});
createEffect(() => {
const enabled = reducedMotion();
document.body.classList.toggle('reduce-motion', enabled);
window.localStorage.setItem('reduced-motion', enabled.toString());
});
return { reducedMotion, setReducedMotion };
}
export default createRoot(createReducedMotionTracker);