UNPKG

@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
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 };