fixes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { type ComponentPropsWithoutRef } from 'react';
|
||||
import { type ComponentPropsWithoutRef, useEffect, useRef } from 'react';
|
||||
import { ToggleGroup as RToggleGroup } from 'radix-ui';
|
||||
import { cx } from '../utils';
|
||||
|
||||
@@ -18,22 +18,49 @@ export const SegmentedControl = ({
|
||||
items,
|
||||
className,
|
||||
...props
|
||||
}: SegProps) => (
|
||||
<RToggleGroup.Root
|
||||
type="single"
|
||||
className={cx('modern-sk-seg', className)}
|
||||
value={value}
|
||||
onValueChange={(v) => v && onValueChange(v)}
|
||||
{...props}
|
||||
>
|
||||
{items.map((it) => (
|
||||
<RToggleGroup.Item
|
||||
key={it.value}
|
||||
value={it.value}
|
||||
className="modern-sk-seg__item"
|
||||
>
|
||||
{it.label}
|
||||
</RToggleGroup.Item>
|
||||
))}
|
||||
</RToggleGroup.Root>
|
||||
);
|
||||
}: SegProps) => {
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
const thumbRef = useRef<HTMLSpanElement>(null);
|
||||
const initialized = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
const root = rootRef.current;
|
||||
const thumb = thumbRef.current;
|
||||
if (!root || !thumb) return;
|
||||
const selected = root.querySelector<HTMLElement>('[data-state="on"]');
|
||||
if (!selected) return;
|
||||
|
||||
if (!initialized.current) {
|
||||
thumb.style.transition = 'none';
|
||||
}
|
||||
thumb.style.transform = `translateX(${selected.offsetLeft}px)`;
|
||||
thumb.style.width = `${selected.offsetWidth}px`;
|
||||
if (!initialized.current) {
|
||||
thumb.getBoundingClientRect();
|
||||
thumb.style.transition = '';
|
||||
initialized.current = true;
|
||||
}
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<RToggleGroup.Root
|
||||
ref={rootRef}
|
||||
type="single"
|
||||
className={cx('modern-sk-seg', className)}
|
||||
value={value}
|
||||
onValueChange={(v) => v && onValueChange(v)}
|
||||
{...props}
|
||||
>
|
||||
<span ref={thumbRef} className="modern-sk-seg__thumb" aria-hidden />
|
||||
{items.map((it) => (
|
||||
<RToggleGroup.Item
|
||||
key={it.value}
|
||||
value={it.value}
|
||||
className="modern-sk-seg__item"
|
||||
>
|
||||
{it.label}
|
||||
</RToggleGroup.Item>
|
||||
))}
|
||||
</RToggleGroup.Root>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,14 +1,62 @@
|
||||
import { type ComponentPropsWithoutRef } from 'react';
|
||||
import { Slider as RSlider } from 'radix-ui';
|
||||
|
||||
export const Slider = (props: ComponentPropsWithoutRef<typeof RSlider.Root>) => (
|
||||
<RSlider.Root className="modern-sk-slider" {...props}>
|
||||
<RSlider.Track className="modern-sk-slider__track">
|
||||
<RSlider.Range className="modern-sk-slider__range" />
|
||||
</RSlider.Track>
|
||||
<RSlider.Thumb className="modern-sk-slider__thumb" aria-label="Value" />
|
||||
</RSlider.Root>
|
||||
);
|
||||
type Step = { value: number; label?: string };
|
||||
|
||||
type SliderProps = ComponentPropsWithoutRef<typeof RSlider.Root> & {
|
||||
steps?: number | Step[];
|
||||
};
|
||||
|
||||
function resolveSteps(steps: number | Step[], min: number, max: number): Step[] {
|
||||
if (Array.isArray(steps)) return steps;
|
||||
if (steps < 2) return [];
|
||||
return Array.from({ length: steps }, (_, i) => ({
|
||||
value: min + (i / (steps - 1)) * (max - min),
|
||||
}));
|
||||
}
|
||||
|
||||
export const Slider = ({ steps, min = 0, max = 100, ...props }: SliderProps) => {
|
||||
const resolved = steps != null ? resolveSteps(steps, min, max) : [];
|
||||
const hasSteps = resolved.length > 0;
|
||||
|
||||
return (
|
||||
<RSlider.Root
|
||||
className={`modern-sk-slider${hasSteps ? ' modern-sk-slider--has-steps' : ''}`}
|
||||
min={min}
|
||||
max={max}
|
||||
{...props}
|
||||
>
|
||||
<RSlider.Track className="modern-sk-slider__track">
|
||||
<RSlider.Range className="modern-sk-slider__range" />
|
||||
{hasSteps && resolved.map((step) => (
|
||||
<div
|
||||
key={step.value}
|
||||
className="modern-sk-slider__step-dot"
|
||||
aria-hidden
|
||||
style={{ left: `${((step.value - min) / (max - min)) * 100}%` }}
|
||||
/>
|
||||
))}
|
||||
</RSlider.Track>
|
||||
<RSlider.Thumb className="modern-sk-slider__thumb" aria-label="Value" />
|
||||
{hasSteps && (
|
||||
<div className="modern-sk-slider__steps" aria-hidden>
|
||||
{resolved.map((step) => (
|
||||
<div
|
||||
key={step.value}
|
||||
className="modern-sk-slider__step"
|
||||
style={{ left: `${((step.value - min) / (max - min)) * 100}%` }}
|
||||
>
|
||||
<div className="modern-sk-slider__step-tick" />
|
||||
{step.label != null && (
|
||||
<span className="modern-sk-slider__step-label">{step.label}</span>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</RSlider.Root>
|
||||
);
|
||||
};
|
||||
|
||||
export const Stepper = ({
|
||||
onDecrement,
|
||||
|
||||
@@ -9,7 +9,7 @@ type TooltipProps = {
|
||||
open?: boolean;
|
||||
defaultOpen?: boolean;
|
||||
onOpenChange?: (o: boolean) => void;
|
||||
} & Omit<ComponentPropsWithoutRef<typeof RTooltip.Content>, 'children'>;
|
||||
} & Omit<ComponentPropsWithoutRef<typeof RTooltip.Content>, 'children' | 'content'>;
|
||||
|
||||
export const Tooltip = ({
|
||||
content,
|
||||
|
||||
Reference in New Issue
Block a user