@varlet/ui
Version:
A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.
168 lines (167 loc) • 5.79 kB
JavaScript
import { computed, defineComponent, nextTick, ref, watch } from "vue";
import { call, isFunction, preventDefault } from "@varlet/shared";
import { useEventListener } from "@varlet/use";
import VarFormDetails from "../form-details/index.mjs";
import { useForm } from "../form/provide.mjs";
import VarRadio from "../radio/index.mjs";
import { createNamespace, MaybeVNode, useValidation } from "../utils/components.mjs";
import { props } from "./props.mjs";
import { useRadios } from "./provide.mjs";
const { name, n, classes } = createNamespace("radio-group");
import { renderList as _renderList, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock, resolveComponent as _resolveComponent, createVNode as _createVNode, withCtx as _withCtx, createBlock as _createBlock, createCommentVNode as _createCommentVNode, renderSlot as _renderSlot, normalizeClass as _normalizeClass, createElementVNode as _createElementVNode } from "vue";
const _hoisted_1 = ["aria-label"];
function __render__(_ctx, _cache) {
const _component_maybe_v_node = _resolveComponent("maybe-v-node");
const _component_var_radio = _resolveComponent("var-radio");
const _component_var_form_details = _resolveComponent("var-form-details");
return _openBlock(), _createElementBlock(
"div",
{
class: _normalizeClass(_ctx.n("wrap"))
},
[
_createElementVNode("div", {
"aria-label": _ctx.ariaLabel,
role: "radiogroup",
class: _normalizeClass(_ctx.classes(_ctx.n(), _ctx.n(`--${_ctx.direction}`)))
}, [
_ctx.options.length ? (_openBlock(true), _createElementBlock(
_Fragment,
{ key: 0 },
_renderList(_ctx.options, (option) => {
return _openBlock(), _createBlock(_component_var_radio, {
key: option[_ctx.valueKey],
"checked-value": option[_ctx.valueKey],
disabled: option.disabled
}, {
default: _withCtx(({ checked }) => [
_createVNode(_component_maybe_v_node, {
is: _ctx.isFunction(option[_ctx.labelKey]) ? option[_ctx.labelKey](option, checked) : option[_ctx.labelKey]
}, null, 8, ["is"])
]),
_: 2
/* DYNAMIC */
}, 1032, ["checked-value", "disabled"]);
}),
128
/* KEYED_FRAGMENT */
)) : _createCommentVNode("v-if", true),
_renderSlot(_ctx.$slots, "default")
], 10, _hoisted_1),
_createVNode(_component_var_form_details, { "error-message": _ctx.errorMessage }, null, 8, ["error-message"])
],
2
/* CLASS */
);
}
const __sfc__ = defineComponent({
name,
components: { VarFormDetails, VarRadio, MaybeVNode },
props,
setup(props2) {
const { length, radios, bindRadios } = useRadios();
const { bindForm } = useForm();
const {
errorMessage,
validateWithTrigger: vt,
validate: v,
// expose
resetValidation
} = useValidation();
const radioGroupErrorMessage = computed(() => errorMessage.value);
const hasChecked = ref(false);
const radioGroupProvider = {
onToggle,
validate,
reset,
resetValidation,
hasChecked: computed(() => hasChecked.value),
errorMessage: radioGroupErrorMessage
};
watch(() => props2.modelValue, syncRadios);
watch(() => length.value, syncRadios);
call(bindForm, radioGroupProvider);
bindRadios(radioGroupProvider);
useEventListener(() => window, "keydown", handleKeydown);
function handleKeydown(event) {
const focusingRadioIndex = radios.findIndex(({ isFocusing }) => isFocusing.value);
if (focusingRadioIndex === -1) {
return;
}
const hasMoveableRadio = radios.some(({ moveable }, index) => index === focusingRadioIndex ? false : moveable());
if (!hasMoveableRadio) {
return;
}
if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(event.key)) {
preventDefault(event);
}
if (event.key === "ArrowUp" || event.key === "ArrowLeft") {
moveRadio(focusingRadioIndex, "prev");
return;
}
if (event.key === "ArrowDown" || event.key === "ArrowRight") {
moveRadio(focusingRadioIndex, "next");
}
}
function moveRadio(fromIndex, method) {
const looping = true;
while (looping) {
if (method === "prev") {
fromIndex--;
} else {
fromIndex++;
}
if (fromIndex < 0) {
fromIndex = radios.length - 1;
}
if (fromIndex > radios.length - 1) {
fromIndex = 0;
}
const radio = radios[fromIndex];
if (radio.moveable()) {
radio.move();
break;
}
}
}
function validateWithTrigger(trigger) {
nextTick(() => {
const { validateTrigger, rules, modelValue } = props2;
vt(validateTrigger, trigger, rules, modelValue);
});
}
function syncRadios() {
radios.forEach(({ sync }) => {
if (sync(props2.modelValue)) {
hasChecked.value = true;
}
});
}
function onToggle(changedValue) {
call(props2["onUpdate:modelValue"], changedValue);
call(props2.onChange, changedValue);
validateWithTrigger("onChange");
}
function validate() {
return v(props2.rules, props2.modelValue);
}
function reset() {
call(props2["onUpdate:modelValue"], void 0);
resetValidation();
}
return {
errorMessage,
n,
classes,
reset,
validate,
resetValidation,
isFunction
};
}
});
__sfc__.render = __render__;
var stdin_default = __sfc__;
export {
stdin_default as default
};