@kobalte/core
Version:
Unstyled components and primitives for building accessible web apps and design systems with SolidJS.
489 lines (474 loc) • 14 kB
JSX
import {
FormControlLabel
} from "./FOXVCQFV.jsx";
import {
createFormResetListener
} from "./QJIB6BDF.jsx";
import {
FormControlErrorMessage
} from "./ZZYKR3VO.jsx";
import {
FORM_CONTROL_PROP_NAMES,
FormControlContext,
FormControlDescription,
createFormControl,
useFormControlContext
} from "./XUUROM4M.jsx";
import {
createRegisterId
} from "./JNCCF6MP.jsx";
import {
createControllableSignal
} from "./FN6EICGO.jsx";
import {
Polymorphic
} from "./FLVHQV4A.jsx";
import {
__export
} from "./5WXHJDCZ.jsx";
// src/radio-group/index.tsx
var radio_group_exports = {};
__export(radio_group_exports, {
Description: () => FormControlDescription,
ErrorMessage: () => FormControlErrorMessage,
Item: () => RadioGroupItem,
ItemControl: () => RadioGroupItemControl,
ItemDescription: () => RadioGroupItemDescription,
ItemIndicator: () => RadioGroupItemIndicator,
ItemInput: () => RadioGroupItemInput,
ItemLabel: () => RadioGroupItemLabel,
Label: () => RadioGroupLabel,
RadioGroup: () => RadioGroup,
Root: () => RadioGroupRoot,
useRadioGroupContext: () => useRadioGroupContext
});
// src/radio-group/radio-group-item.tsx
import {
callHandler,
createGenerateId,
mergeDefaultProps
} from "@kobalte/utils";
import {
createMemo,
createSignal,
createUniqueId,
splitProps
} from "solid-js";
// src/radio-group/radio-group-context.tsx
import { createContext, useContext } from "solid-js";
var RadioGroupContext = createContext();
function useRadioGroupContext() {
const context = useContext(RadioGroupContext);
if (context === void 0) {
throw new Error(
"[kobalte]: `useRadioGroupContext` must be used within a `RadioGroup` component"
);
}
return context;
}
// src/radio-group/radio-group-item-context.tsx
import { createContext as createContext2, useContext as useContext2 } from "solid-js";
var RadioGroupItemContext = createContext2();
function useRadioGroupItemContext() {
const context = useContext2(RadioGroupItemContext);
if (context === void 0) {
throw new Error(
"[kobalte]: `useRadioGroupItemContext` must be used within a `RadioGroup.Item` component"
);
}
return context;
}
// src/radio-group/radio-group-item.tsx
function RadioGroupItem(props) {
const formControlContext = useFormControlContext();
const radioGroupContext = useRadioGroupContext();
const defaultId = `${formControlContext.generateId(
"item"
)}-${createUniqueId()}`;
const mergedProps = mergeDefaultProps(
{
id: defaultId
},
props
);
const [local, others] = splitProps(mergedProps, [
"value",
"disabled",
"onPointerDown"
]);
const [inputId, setInputId] = createSignal();
const [labelId, setLabelId] = createSignal();
const [descriptionId, setDescriptionId] = createSignal();
const [inputRef, setInputRef] = createSignal();
const [isFocused, setIsFocused] = createSignal(false);
const isDefault = createMemo(() => {
return radioGroupContext.isDefaultValue(local.value);
});
const isSelected = createMemo(() => {
return radioGroupContext.isSelectedValue(local.value);
});
const isDisabled = createMemo(() => {
return local.disabled || formControlContext.isDisabled() || false;
});
const onPointerDown = (e) => {
callHandler(e, local.onPointerDown);
if (isFocused()) {
e.preventDefault();
}
};
const dataset = createMemo(() => ({
...formControlContext.dataset(),
"data-disabled": isDisabled() ? "" : void 0,
"data-checked": isSelected() ? "" : void 0
}));
const context = {
value: () => local.value,
dataset,
isDefault,
isSelected,
isDisabled,
inputId,
labelId,
descriptionId,
inputRef,
select: () => radioGroupContext.setSelectedValue(local.value),
generateId: createGenerateId(() => others.id),
registerInput: createRegisterId(setInputId),
registerLabel: createRegisterId(setLabelId),
registerDescription: createRegisterId(setDescriptionId),
setIsFocused,
setInputRef
};
return <RadioGroupItemContext.Provider value={context}><Polymorphic
as="div"
role="group"
onPointerDown={onPointerDown}
{...dataset()}
{...others}
/></RadioGroupItemContext.Provider>;
}
// src/radio-group/radio-group-item-control.tsx
import { EventKey, callHandler as callHandler2, mergeDefaultProps as mergeDefaultProps2 } from "@kobalte/utils";
import { splitProps as splitProps2 } from "solid-js";
function RadioGroupItemControl(props) {
const context = useRadioGroupItemContext();
const mergedProps = mergeDefaultProps2(
{
id: context.generateId("control")
},
props
);
const [local, others] = splitProps2(mergedProps, ["onClick", "onKeyDown"]);
const onClick = (e) => {
callHandler2(e, local.onClick);
context.select();
context.inputRef()?.focus();
};
const onKeyDown = (e) => {
callHandler2(e, local.onKeyDown);
if (e.key === EventKey.Space) {
context.select();
context.inputRef()?.focus();
}
};
return <Polymorphic
as="div"
onClick={onClick}
onKeyDown={onKeyDown}
{...context.dataset()}
{...others}
/>;
}
// src/radio-group/radio-group-item-description.tsx
import { mergeDefaultProps as mergeDefaultProps3 } from "@kobalte/utils";
import { createEffect, onCleanup } from "solid-js";
function RadioGroupItemDescription(props) {
const context = useRadioGroupItemContext();
const mergedProps = mergeDefaultProps3(
{
id: context.generateId("description")
},
props
);
createEffect(() => onCleanup(context.registerDescription(mergedProps.id)));
return <Polymorphic
as="div"
{...context.dataset()}
{...mergedProps}
/>;
}
// src/radio-group/radio-group-item-indicator.tsx
import { mergeDefaultProps as mergeDefaultProps4, mergeRefs } from "@kobalte/utils";
import { Show, createSignal as createSignal2, splitProps as splitProps3 } from "solid-js";
import createPresence from "solid-presence";
function RadioGroupItemIndicator(props) {
const context = useRadioGroupItemContext();
const mergedProps = mergeDefaultProps4(
{
id: context.generateId("indicator")
},
props
);
const [local, others] = splitProps3(mergedProps, ["ref", "forceMount"]);
const [ref, setRef] = createSignal2();
const { present } = createPresence({
show: () => local.forceMount || context.isSelected(),
element: () => ref() ?? null
});
return <Show when={present()}><Polymorphic
as="div"
ref={mergeRefs(setRef, local.ref)}
{...context.dataset()}
{...others}
/></Show>;
}
// src/radio-group/radio-group-item-input.tsx
import {
callHandler as callHandler3,
mergeDefaultProps as mergeDefaultProps5,
mergeRefs as mergeRefs2,
visuallyHiddenStyles
} from "@kobalte/utils";
import {
createEffect as createEffect2,
createSignal as createSignal3,
on,
onCleanup as onCleanup2,
splitProps as splitProps4
} from "solid-js";
import { combineStyle } from "@solid-primitives/props";
function RadioGroupItemInput(props) {
const formControlContext = useFormControlContext();
const radioGroupContext = useRadioGroupContext();
const radioContext = useRadioGroupItemContext();
const mergedProps = mergeDefaultProps5(
{
id: radioContext.generateId("input")
},
props
);
const [local, others] = splitProps4(mergedProps, [
"ref",
"style",
"aria-labelledby",
"aria-describedby",
"onChange",
"onFocus",
"onBlur"
]);
const ariaLabelledBy = () => {
return [
local["aria-labelledby"],
radioContext.labelId(),
// If there is both an aria-label and aria-labelledby, add the input itself has an aria-labelledby
local["aria-labelledby"] != null && others["aria-label"] != null ? others.id : void 0
].filter(Boolean).join(" ") || void 0;
};
const ariaDescribedBy = () => {
return [
local["aria-describedby"],
radioContext.descriptionId(),
radioGroupContext.ariaDescribedBy()
].filter(Boolean).join(" ") || void 0;
};
const [isInternalChangeEvent, setIsInternalChangeEvent] = createSignal3(false);
const onChange = (e) => {
callHandler3(e, local.onChange);
e.stopPropagation();
if (!isInternalChangeEvent()) {
radioGroupContext.setSelectedValue(radioContext.value());
const target = e.target;
target.checked = radioContext.isSelected();
}
setIsInternalChangeEvent(false);
};
const onFocus = (e) => {
callHandler3(e, local.onFocus);
radioContext.setIsFocused(true);
};
const onBlur = (e) => {
callHandler3(e, local.onBlur);
radioContext.setIsFocused(false);
};
createEffect2(
on(
[() => radioContext.isSelected(), () => radioContext.value()],
(c) => {
if (!c[0] && c[1] === radioContext.value())
return;
setIsInternalChangeEvent(true);
const ref = radioContext.inputRef();
ref?.dispatchEvent(
new Event("input", { bubbles: true, cancelable: true })
);
ref?.dispatchEvent(
new Event("change", { bubbles: true, cancelable: true })
);
},
{
defer: true
}
)
);
createEffect2(() => onCleanup2(radioContext.registerInput(others.id)));
return <Polymorphic
as="input"
ref={mergeRefs2(radioContext.setInputRef, local.ref)}
type="radio"
name={formControlContext.name()}
value={radioContext.value()}
checked={radioContext.isSelected()}
required={formControlContext.isRequired()}
disabled={radioContext.isDisabled()}
readonly={formControlContext.isReadOnly()}
style={combineStyle({ ...visuallyHiddenStyles }, local.style)}
aria-labelledby={ariaLabelledBy()}
aria-describedby={ariaDescribedBy()}
onChange={onChange}
onFocus={onFocus}
onBlur={onBlur}
{...radioContext.dataset()}
{...others}
/>;
}
// src/radio-group/radio-group-item-label.tsx
import { mergeDefaultProps as mergeDefaultProps6 } from "@kobalte/utils";
import { createEffect as createEffect3, onCleanup as onCleanup3 } from "solid-js";
function RadioGroupItemLabel(props) {
const context = useRadioGroupItemContext();
const mergedProps = mergeDefaultProps6(
{
id: context.generateId("label")
},
props
);
createEffect3(() => onCleanup3(context.registerLabel(mergedProps.id)));
return <Polymorphic
as="label"
for={context.inputId()}
{...context.dataset()}
{...mergedProps}
/>;
}
// src/radio-group/radio-group-label.tsx
function RadioGroupLabel(props) {
return <FormControlLabel
as="span"
{...props}
/>;
}
// src/radio-group/radio-group-root.tsx
import {
access,
mergeDefaultProps as mergeDefaultProps7,
mergeRefs as mergeRefs3
} from "@kobalte/utils";
import { createUniqueId as createUniqueId2, splitProps as splitProps5 } from "solid-js";
function RadioGroupRoot(props) {
let ref;
const defaultId = `radiogroup-${createUniqueId2()}`;
const mergedProps = mergeDefaultProps7(
{
id: defaultId,
orientation: "vertical"
},
props
);
const [local, formControlProps, others] = splitProps5(
mergedProps,
[
"ref",
"value",
"defaultValue",
"onChange",
"orientation",
"aria-labelledby",
"aria-describedby"
],
FORM_CONTROL_PROP_NAMES
);
const [selected, setSelected] = createControllableSignal({
value: () => local.value,
defaultValue: () => local.defaultValue,
onChange: (value) => local.onChange?.(value)
});
const { formControlContext } = createFormControl(formControlProps);
createFormResetListener(
() => ref,
() => setSelected(local.defaultValue ?? "")
);
const ariaLabelledBy = () => {
return formControlContext.getAriaLabelledBy(
access(formControlProps.id),
others["aria-label"],
local["aria-labelledby"]
);
};
const ariaDescribedBy = () => {
return formControlContext.getAriaDescribedBy(local["aria-describedby"]);
};
const isDefaultValue = (value) => {
return value === props.defaultValue;
};
const isSelectedValue = (value) => {
return value === selected();
};
const setSelectedValue = (value) => {
if (formControlContext.isReadOnly() || formControlContext.isDisabled()) {
return;
}
setSelected(value);
if (ref)
for (const el of ref.querySelectorAll("[type='radio']")) {
const radio = el;
radio.checked = isSelectedValue(radio.value);
}
};
const context = {
ariaDescribedBy,
isDefaultValue,
isSelectedValue,
setSelectedValue
};
return <FormControlContext.Provider value={formControlContext}><RadioGroupContext.Provider value={context}><Polymorphic
as="div"
ref={mergeRefs3((el) => ref = el, local.ref)}
role="radiogroup"
id={access(formControlProps.id)}
aria-invalid={formControlContext.validationState() === "invalid" || void 0}
aria-required={formControlContext.isRequired() || void 0}
aria-disabled={formControlContext.isDisabled() || void 0}
aria-readonly={formControlContext.isReadOnly() || void 0}
aria-orientation={local.orientation}
aria-labelledby={ariaLabelledBy()}
aria-describedby={ariaDescribedBy()}
{...formControlContext.dataset()}
{...others}
/></RadioGroupContext.Provider></FormControlContext.Provider>;
}
// src/radio-group/index.tsx
var RadioGroup = Object.assign(RadioGroupRoot, {
Description: FormControlDescription,
ErrorMessage: FormControlErrorMessage,
Item: RadioGroupItem,
ItemControl: RadioGroupItemControl,
ItemDescription: RadioGroupItemDescription,
ItemIndicator: RadioGroupItemIndicator,
ItemInput: RadioGroupItemInput,
ItemLabel: RadioGroupItemLabel,
Label: RadioGroupLabel
});
export {
useRadioGroupContext,
useRadioGroupItemContext,
RadioGroupItem,
RadioGroupItemControl,
RadioGroupItemDescription,
RadioGroupItemIndicator,
RadioGroupItemInput,
RadioGroupItemLabel,
RadioGroupLabel,
RadioGroupRoot,
RadioGroup,
radio_group_exports
};