UNPKG

@kobalte/core

Version:

Unstyled components and primitives for building accessible web apps and design systems with SolidJS.

162 lines (157 loc) 5.97 kB
import { RadioGroupItemControl, RadioGroupItemDescription, RadioGroupItemIndicator, RadioGroupItemLabel, RadioGroupLabel, useRadioGroupContext, RadioGroup, useRadioGroupItemContext } from '../chunk/JRXYFAAV.js'; export { RadioGroupItemControl as ItemControl, RadioGroupItemDescription as ItemDescription, RadioGroupItemIndicator as ItemIndicator, RadioGroupItemLabel as ItemLabel, RadioGroupLabel as Label } from '../chunk/JRXYFAAV.js'; import { createFormResetListener } from '../chunk/ANN3A2QM.js'; import { FormControlErrorMessage } from '../chunk/ICNSTULC.js'; export { FormControlErrorMessage as ErrorMessage } from '../chunk/ICNSTULC.js'; import { FormControlDescription } from '../chunk/YKGT7A57.js'; export { FormControlDescription as Description } from '../chunk/YKGT7A57.js'; import { Polymorphic } from '../chunk/6Y7B2NEO.js'; import { createComponent, mergeProps } from 'solid-js/web'; import { createContext, useContext, splitProps, createSignal, createEffect, on, batch, mergeProps as mergeProps$1 } from 'solid-js'; import { combineStyle } from '@solid-primitives/props'; import { createResizeObserver } from '@solid-primitives/resize-observer'; import { mergeRefs } from '@kobalte/utils'; var SegmentedControlContext = createContext(); function useSegmentedControlContext() { const context = useContext(SegmentedControlContext); if (context === void 0) { throw new Error("[kobalte]: `useSegmentedControlContext` must be used within a `SegmentedControl` component"); } return context; } // src/segmented-control/segmented-control-indicator.tsx function SegmentedControlIndicator(props) { const context = useSegmentedControlContext(); const [localProps, otherProps] = splitProps(props, ["style"]); const [style, setStyle] = createSignal(); const [resizing, setResizing] = createSignal(false); const computeStyle = () => { const element = context.selectedItem(); if (!element) { setStyle(void 0); return; } setStyle({ width: `${element.offsetWidth}px`, height: `${element.offsetHeight}px`, transform: computeTransform(element), "transition-duration": resizing() ? "0ms" : void 0 }); }; const computeTransform = (element) => { const style2 = getComputedStyle(element.parentElement); const x = element.offsetLeft - Number.parseFloat(style2.paddingLeft); const y = element.offsetTop - Number.parseFloat(style2.paddingTop); return `translate(${x}px, ${y}px)`; }; createEffect(on(context.selectedItem, () => { setResizing(!style()); computeStyle(); setResizing(false); })); createResizeObserver(context.root, () => { batch(() => { setResizing(true); computeStyle(); setResizing(false); }); }); return createComponent(Polymorphic, mergeProps({ as: "div", role: "presentation", get style() { return combineStyle(style(), localProps.style); }, get ["data-resizing"]() { return resizing(); }, get ["data-orientation"]() { return context.orientation(); } }, otherProps)); } var SegmentedControlItem = (props) => { const radioGroupContext = useRadioGroupContext(); const segmentedControlContext = useSegmentedControlContext(); const [localProps, otherProps] = splitProps(props, ["ref"]); const [ref, setRef] = createSignal(); createEffect(() => { const element = ref(); if (!element) return; if (radioGroupContext.isSelectedValue(props.value)) { segmentedControlContext.setSelectedItem(element); } }); return createComponent(RadioGroup.Item, mergeProps({ ref(r$) { const _ref$ = mergeRefs(setRef, localProps.ref); typeof _ref$ === "function" && _ref$(r$); } }, otherProps)); }; var SegmentedControlItemInput = (props) => { const radioGroupItemContext = useRadioGroupItemContext(); const [localProps, otherProps] = splitProps(props, ["ref"]); const [ref, setRef] = createSignal(); createFormResetListener(ref, () => { requestAnimationFrame(() => { if (radioGroupItemContext.isDefault()) { radioGroupItemContext.select(); } }); }); return createComponent(RadioGroup.ItemInput, mergeProps({ ref(r$) { const _ref$ = mergeRefs(setRef, localProps.ref); typeof _ref$ === "function" && _ref$(r$); } }, otherProps)); }; var SegmentedControlRoot = (props) => { const mergedProps = mergeProps$1({ defaultValue: props.value, orientation: "horizontal" }, props); const [localProps, otherProps] = splitProps(mergedProps, ["ref"]); const [ref, setRef] = createSignal(); const [selectedItem, setSelectedItem] = createSignal(); const context = { value: () => otherProps.value, defaultValue: () => otherProps.defaultValue, orientation: () => otherProps.orientation, root: ref, selectedItem, setSelectedItem }; createEffect(() => { if (context.value()) return; setSelectedItem(void 0); }); return createComponent(SegmentedControlContext.Provider, { value: context, get children() { return createComponent(RadioGroup, mergeProps({ ref(r$) { const _ref$ = mergeRefs(setRef, localProps.ref); typeof _ref$ === "function" && _ref$(r$); } }, otherProps)); } }); }; // src/segmented-control/index.tsx var SegmentedControl = Object.assign(SegmentedControlRoot, { Description: FormControlDescription, ErrorMessage: FormControlErrorMessage, Indicator: SegmentedControlIndicator, Item: SegmentedControlItem, ItemControl: RadioGroupItemControl, ItemDescription: RadioGroupItemDescription, ItemIndicator: RadioGroupItemIndicator, ItemInput: SegmentedControlItemInput, ItemLabel: RadioGroupItemLabel, Label: RadioGroupLabel }); export { SegmentedControlIndicator as Indicator, SegmentedControlItem as Item, SegmentedControlItemInput as ItemInput, SegmentedControlRoot as Root, SegmentedControl, useSegmentedControlContext };