UNPKG

@sandlada/vue-mdc

Version:

![Vue MDC Logo](https://raw.githubusercontent.com/sandlada/vue-mdc/refs/heads/main/docs/vue-mdc-cover.png)

134 lines (133 loc) 3.68 kB
/** * @license * Copyright 2025 Sandlada & Kai Orion * SPDX-License-Identifier: MIT */ import { defineComponent, createVNode } from "vue"; import { componentNamePrefix } from "../../internals/component-name-prefix/component-name-prefix.js"; import { isServer } from "../../utils/is-server.js"; import { generateUuid } from "../../utils/uuid.js"; import { FocusRing } from "../focus-ring/focus-ring.js"; import "../../internals/navigation/render-navigation-destination.js"; import { Ripple } from "../ripple/ripple.js"; import { props } from "./radio.definition.js"; import css from "./styles/radio.module.scss.js"; const Radio = /* @__PURE__ */ defineComponent({ name: `${componentNamePrefix}-radio`, props, slots: {}, emits: ["update:modelValue", "change"], setup(props2) { }, created() { if (this.modelValue === null) { this.checked = this.defaultChecked; this.$emit("update:modelValue", this.defaultChecked); } else { this.checked = this.modelValue; } }, mounted() { if (isServer()) { return; } this.$el.addEventListener("click", this.handleClick); const maskElement = this.$el.querySelector("&>svg>.mask"); const needMaskElement = this.$el.querySelector("&>svg>.need-mask"); if (this.maskId === null) { this.maskId = generateUuid(); } maskElement?.setAttribute("id", this.maskId); needMaskElement?.setAttribute("mask", `url(#${this.maskId})`); }, beforeUpdate() { if (this.modelValue !== null) { this.setChecked(this.modelValue); } }, beforeUnmount() { this.$el.removeEventListener("click", this.handleClick); }, data: () => ({ checked: false, /** * Unique id for mask. */ maskId: null }), methods: { getRootElement() { return this.$el; }, getFocusRingElement() { return this.$el.querySelector('[data-component="focus-ring"]'); }, getInputElement() { return this.$el.querySelector(`input.${css.input}`); }, setChecked(checked) { const changeEvent = new Event("change", { cancelable: true }); this.$emit("change", changeEvent); const preventChange = !dispatchEvent(changeEvent); if (preventChange) { return; } if (this.checked === checked) { return; } this.checked = checked; this.$emit("update:modelValue", checked); }, handleClick() { if (this.disabled) { return; } this.setChecked(!this.checked); } }, render() { return createVNode("div", { "data-component": "radio", "role": "radio", "class": [css.radio, this.checked && css.checked, this.disabled && css.disabled], "tabindex": 0 }, [createVNode(Ripple, { "disabled": this.disabled }, null), createVNode(FocusRing, { "shapeInherit": false }, null), createVNode("svg", { "aria-hidden": "true", "class": css.icon, "viewBox": "0 0 20 20" }, [createVNode("mask", { "class": "mask" }, [createVNode("rect", { "width": "100%", "height": "100%", "fill": "white" }, null), createVNode("circle", { "cx": "10", "cy": "10", "r": "8", "fill": "black" }, null)]), createVNode("circle", { "class": ["need-mask", css.outer, css.circle], "cx": "10", "cy": "10", "r": "10" }, null), createVNode("circle", { "class": [css.inner, css.circle], "cx": "10", "cy": "10", "r": "5" }, null)]), createVNode("span", { "class": css["touch-target"] }, null)]); } }); export { Radio }; //# sourceMappingURL=radio.js.map