forked from riccardoperra/codeimage
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSegmentedField.tsx
More file actions
60 lines (53 loc) · 1.71 KB
/
SegmentedField.tsx
File metadata and controls
60 lines (53 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import * as styles from './SegmentedField.css';
import {createMemo, For, JSX, JSXElement} from 'solid-js';
import clsx from 'clsx';
import {assignInlineVars} from '@vanilla-extract/dynamic';
import {useText, UseTextProps} from '../Text';
import {Box} from '../Box';
export interface SegmentedFieldItem<T> {
label: string | JSXElement;
value: T;
}
interface SegmentedFieldProps<T> {
items: readonly SegmentedFieldItem<T>[];
value: T;
onChange?: (value: T) => void;
size?: UseTextProps['size'];
id?: string;
}
export function SegmentedField<T>(props: SegmentedFieldProps<T>): JSX.Element {
const segmentWidth = createMemo(() => `calc(100% / ${props.items.length})`);
const activeIndex = createMemo(() =>
props.items.findIndex(item => item.value === props.value),
);
const activeSegmentOffset = createMemo(
() => `calc(${segmentWidth()} * ${activeIndex()})`,
);
const segmentedTextStyle = useText(props);
return (
<Box class={clsx(styles.wrapper)} id={props.id}>
<div class={styles.box}>
<div
style={assignInlineVars({
[styles.segmentedFieldVars.activeSegmentedWidth]: segmentWidth(),
[styles.segmentedFieldVars.activeSegmentedOffset]:
activeSegmentOffset(),
})}
class={clsx(styles.segmentActive)}
/>
<For each={props.items}>
{(item, index) => (
// TODO: div broke build
<Box
class={clsx(styles.segment, segmentedTextStyle())}
data-active={index() === activeIndex()}
onClick={() => props.onChange?.(item.value)}
>
{item.label}
</Box>
)}
</For>
</div>
</Box>
);
}