Лендинг
This commit is contained in:
37
src/components/Switch/Switch.module.css
Normal file
37
src/components/Switch/Switch.module.css
Normal file
@@ -0,0 +1,37 @@
|
||||
.root {
|
||||
position: relative;
|
||||
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-8));
|
||||
width: fit-content;
|
||||
border-radius: var(--mantine-radius-md);
|
||||
padding: 5px;
|
||||
border: 1px solid light-dark(var(--mantine-color-gray-2), var(--mantine-color-dark-4));
|
||||
}
|
||||
|
||||
.control {
|
||||
padding: 7px 12px;
|
||||
line-height: 1;
|
||||
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-2));
|
||||
border-radius: var(--mantine-radius-md);
|
||||
font-size: var(--mantine-font-size-sm);
|
||||
transition: color 100ms ease;
|
||||
font-weight: 500;
|
||||
|
||||
@mixin hover {
|
||||
color: light-dark(var(--mantine-color-black), var(--mantine-color-white));
|
||||
background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-7));
|
||||
}
|
||||
|
||||
&[data-active] {
|
||||
color: var(--mantine-color-white);
|
||||
}
|
||||
}
|
||||
|
||||
.controlLabel {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.indicator {
|
||||
background-color: var(--mantine-primary-color-filled);
|
||||
border-radius: var(--mantine-radius-md);
|
||||
}
|
||||
51
src/components/Switch/Switch.tsx
Normal file
51
src/components/Switch/Switch.tsx
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useState } from 'react';
|
||||
import { FloatingIndicator, UnstyledButton } from '@mantine/core';
|
||||
import classes from './Switch.module.css';
|
||||
|
||||
interface SwitchProps {
|
||||
data: string[];
|
||||
onChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
export function Switch(props: SwitchProps) {
|
||||
const [rootRef, setRootRef] = useState<HTMLDivElement | null>(null);
|
||||
const [controlsRefs, setControlsRefs] = useState<Record<string, HTMLButtonElement | null>>({});
|
||||
const [active, setActive] = useState(0);
|
||||
|
||||
const setControlRef = (index: number) => (node: HTMLButtonElement) => {
|
||||
controlsRefs[index] = node;
|
||||
setControlsRefs(controlsRefs);
|
||||
};
|
||||
|
||||
const changeActive = (index: number) => {
|
||||
setActive(index);
|
||||
if(!props.onChange){
|
||||
return;
|
||||
}
|
||||
props.onChange(props.data[index]);
|
||||
}
|
||||
|
||||
const controls = props.data.map((item, index) => (
|
||||
<UnstyledButton
|
||||
key={item}
|
||||
className={classes.control}
|
||||
ref={setControlRef(index)}
|
||||
onClick={() => changeActive(index)}
|
||||
mod={{ active: active === index }}
|
||||
>
|
||||
<span className={classes.controlLabel}>{item}</span>
|
||||
</UnstyledButton>
|
||||
));
|
||||
|
||||
return (
|
||||
<div className={classes.root} ref={setRootRef}>
|
||||
{controls}
|
||||
|
||||
<FloatingIndicator
|
||||
target={controlsRefs[active]}
|
||||
parent={rootRef}
|
||||
className={classes.indicator}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user