Something went wrong. Try again.
experimental web port of the Union style engine + adapters
styling theming css solidjs react union kde
Something went wrong. Try again.
2.4 kB · 67 lines
TSX
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768import { createSignal, createMemo } from 'solid-js';import type { JSX } from 'solid-js';import { useUnion } from './useUnion.js';import { StyledRect } from './StyledRect.js';import { styleGroupToUnionStyleProps } from '@union-web/core';
type CheckboxProps = { children?: JSX.Element; checked?: boolean; disabled?: boolean; onChange?: (checked: boolean) => void;};
export function Checkbox(props: CheckboxProps) { const [hovered, setHovered] = createSignal(false); const [pressed, setPressed] = createSignal(false); const [internalChecked, setInternalChecked] = createSignal(false);
const checked = () => (props.checked !== undefined ? props.checked : internalChecked());
const state = () => { const parts: string[] = []; if (props.disabled) parts.push('disabled'); if (hovered()) parts.push('hovered'); if (pressed()) parts.push('pressed'); if (checked()) parts.push('checked'); return parts; };
const { current, UnionProvider, insidePositioner } = useUnion({ role: 'checkbox', state }); const { current: indicatorCurrent, insidePositioner: indicatorInsidePositioner } = useUnion({ role: 'indicator', hints: ['indicator'] });
const styleProps = createMemo(() => styleGroupToUnionStyleProps(current())); const indicatorStyleProps = createMemo(() => styleGroupToUnionStyleProps(indicatorCurrent()));
const handleClick = () => { if (props.disabled) return; const next = !checked(); if (props.checked === undefined) setInternalChecked(next); props.onChange?.(next); };
return ( <UnionProvider> <StyledRect insidePositioner={insidePositioner} style={styleProps()} style:cursor={props.disabled ? 'not-allowed' : 'pointer'} style:user-select="none" onClick={handleClick} onPointerEnter={() => !props.disabled && setHovered(true)} onPointerLeave={() => { setHovered(false); setPressed(false); }} onPointerDown={() => !props.disabled && setPressed(true)} onPointerUp={() => !props.disabled && setPressed(false)} > <StyledRect as="span" data-part="indicator" insidePositioner={indicatorInsidePositioner} style={indicatorStyleProps()} style:flex-shrink="0" /> <span>{props.children}</span> </StyledRect> </UnionProvider> );}