@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
162 lines (157 loc) • 5.97 kB
JavaScript
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 };