@sandlada/vue-mdc
Version:

134 lines (133 loc) • 3.68 kB
JavaScript
/**
* @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