Files
popa-launcher/src/renderer/components/Login/MemorySlider.tsx
2025-12-13 18:59:30 +05:00

189 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from 'react';
import { Box, Slider, Typography } from '@mui/material';
interface MemorySliderProps {
memory: number;
onChange: (e: Event, value: number | number[]) => void;
min?: number;
max?: number;
step?: number;
}
const gradientPrimary =
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)';
const formatMb = (v: number) => `${v} MB`;
const formatGb = (v: number) => `${(v / 1024).toFixed(v % 1024 === 0 ? 0 : 1)} GB`;
const MemorySlider = ({
memory,
onChange,
min = 1024,
max = 32768,
step = 1024,
}: MemorySliderProps) => {
// marks только на “красивых” значениях, чтобы не было каши
const marks = [
{ value: 1024, label: '1 GB' },
{ value: 4096, label: '4 GB' },
{ value: 8192, label: '8 GB' },
{ value: 16384, label: '16 GB' },
{ value: 32768, label: '32 GB' },
].filter((m) => m.value >= min && m.value <= max);
return (
<Box sx={{ width: '100%' }}>
{/* Header */}
<Box
sx={{
display: 'flex',
alignItems: 'baseline',
justifyContent: 'space-between',
mb: '1.2vh',
}}
>
<Typography
sx={{
fontFamily: 'Benzin-Bold, system-ui, -apple-system, Segoe UI, Roboto, Arial',
fontWeight: 800,
fontSize: '1.1vw',
color: '#fff',
textTransform: 'uppercase',
letterSpacing: 0.5,
}}
>
Память
</Typography>
<Typography
sx={{
fontFamily: 'Benzin-Bold, system-ui, -apple-system, Segoe UI, Roboto, Arial',
fontWeight: 800,
fontSize: '1.1vw',
backgroundImage: gradientPrimary,
WebkitBackgroundClip: 'text',
WebkitTextFillColor: 'transparent',
}}
>
{memory >= 1024 ? formatGb(memory) : formatMb(memory)}
</Typography>
</Box>
<Slider
name="memory"
aria-label="Memory"
valueLabelDisplay="auto"
valueLabelFormat={(v) => (v >= 1024 ? formatGb(v as number) : formatMb(v as number))}
shiftStep={step}
step={step}
marks={marks}
min={min}
max={max}
value={memory}
onChange={onChange}
sx={{
px: '0.2vw',
// rail (фон полосы)
'& .MuiSlider-rail': {
opacity: 1,
height: '0.9vh',
borderRadius: '999vw',
backgroundColor: 'rgba(255,255,255,0.10)',
boxShadow: 'inset 0 0.25vh 0.6vh rgba(0,0,0,0.45)',
},
// track (заполненная часть)
'& .MuiSlider-track': {
height: '0.9vh',
borderRadius: '999vw',
border: 'none',
background: gradientPrimary,
boxShadow: '0 0.6vh 1.6vh rgba(233,64,205,0.18)',
},
// thumb (ползунок)
'& .MuiSlider-thumb': {
width: '1.6vw',
height: '1.6vw',
minWidth: 14,
minHeight: 14,
borderRadius: '999vw',
background: 'rgba(10,10,20,0.92)',
border: '0.22vw solid rgba(255,255,255,0.18)',
boxShadow:
'0 0.9vh 2.4vh rgba(0,0,0,0.55), 0 0 1.2vw rgba(242,113,33,0.20)',
transition: 'transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease',
'&:hover': {
// transform: 'scale(1.06)',
borderColor: 'rgba(242,113,33,0.55)',
boxShadow:
'0 1.1vh 2.8vh rgba(0,0,0,0.62), 0 0 1.6vw rgba(233,64,205,0.28)',
},
// внутренний “свет”
'&:before': {
content: '""',
position: 'absolute',
inset: '18%',
borderRadius: '999vw',
background: gradientPrimary,
opacity: 0.85,
filter: 'blur(0.3vw)',
},
},
// value label (плашка значения)
'& .MuiSlider-valueLabel': {
fontFamily: 'Benzin-Bold, system-ui, -apple-system, Segoe UI, Roboto, Arial',
fontSize: '0.85vw',
borderRadius: '1.2vw',
padding: '0.4vh 0.8vw',
color: '#fff',
background: 'rgba(0,0,0,0.55)',
border: '1px solid rgba(255,255,255,0.10)',
backdropFilter: 'blur(10px)',
boxShadow: '0 1.2vh 3vh rgba(0,0,0,0.55)',
'&:before': { display: 'none' },
},
// marks (точки)
'& .MuiSlider-mark': {
width: '0.35vw',
height: '0.35vw',
minWidth: 4,
minHeight: 4,
borderRadius: '999vw',
backgroundColor: 'rgba(255,255,255,0.18)',
},
'& .MuiSlider-markActive': {
backgroundColor: 'rgba(255,255,255,0.55)',
},
// mark labels (подписи)
'& .MuiSlider-markLabel': {
color: 'rgba(255,255,255,0.55)',
fontSize: '0.75vw',
marginTop: '1vh',
userSelect: 'none',
},
// focus outline
'& .MuiSlider-thumb.Mui-focusVisible': {
outline: 'none',
boxShadow:
'0 0 0 0.25vw rgba(242,113,33,0.20), 0 1.1vh 2.8vh rgba(0,0,0,0.62)',
},
}}
/>
{/* Subtext */}
<Typography sx={{ mt: '1.2vh', color: 'rgba(255,255,255,0.55)', fontSize: '0.85vw' }}>
Шаг: {formatGb(step)} Рекомендуем: 48 GB для большинства сборок
</Typography>
</Box>
);
};
export default MemorySlider;