vue-rating-input
Version:
[](https://www.npmjs.com/package/vue-rating-input)
196 lines (195 loc) • 7.21 kB
JavaScript
import { defineComponent as w, ref as m, useId as B, computed as h, openBlock as r, createElementBlock as u, Fragment as y, createElementVNode as n, unref as k, createCommentVNode as _, createBlock as M, Teleport as R, onMounted as z, renderSlot as S, renderList as E, normalizeClass as N, createVNode as H, withDirectives as T, vModelText as x } from "vue";
import './index.css';const A = ["fill", "height", "width"], D = ["id"], G = ["width"], I = ["fill"], Z = {
key: 1,
"xlink:href": "#outline"
}, q = ["clip-path"], F = /* @__PURE__ */ w({
__name: "StarSVG",
props: {
value: { default: 0 },
color: { default: "#ffb74b" },
size: { default: "2rem" },
enableOutline: { type: Boolean, default: !0 },
backgroundColor: {}
},
setup(o) {
const a = m(null), e = o, t = B(), d = h(() => e.value * 100), b = h(() => (document.querySelectorAll(".rating-svg-icons__defs").length || 0) > 0);
return (s, p) => (r(), u(y, null, [
(r(), u("svg", {
class: "rating-svg-icon",
fill: e.color,
height: e.size,
width: e.size
}, [
n("defs", null, [
n("clipPath", {
id: `clip-star-${k(t)}`
}, [
n("rect", {
x: "0",
y: "0",
width: `${d.value}%`,
height: "100%"
}, null, 8, G)
], 8, D)
]),
e.backgroundColor ? (r(), u("use", {
key: 0,
"xlink:href": "#filled",
fill: e.backgroundColor
}, null, 8, I)) : _("", !0),
e.enableOutline ? (r(), u("use", Z)) : _("", !0),
n("use", {
"xlink:href": "#filled",
"clip-path": `url(#clip-star-${k(t)})`
}, null, 8, q)
], 8, A)),
b.value ? _("", !0) : (r(), M(R, {
key: 0,
to: "body"
}, [
n("div", {
class: "rating-svg-icons__defs",
ref_key: "iconsDefs",
ref: a
}, p[0] || (p[0] = [
n("svg", {
xmlns: "http://www.w3.org/2000/svg",
"xmlns:xlink": "http://www.w3.org/1999/xlink"
}, [
n("defs", null, [
n("symbol", {
viewBox: "0 0 14 13",
id: "outline"
}, [
n("path", {
"fill-rule": "evenodd",
d: "M13.85 4.96a.38.38 0 0 0-.34-.27l-4.18-.3L7.75.32A.38.38 0 0 0 7.4.08a.38.38 0 0 0-.35.25L5.5 4.38l-4.2.3a.38.38 0 0 0-.32.27.4.4 0 0 0 .11.43l3.22 2.8-1.02 4.25a.4.4 0 0 0 .14.41.36.36 0 0 0 .42.02l3.56-2.32 3.56 2.32c.06.04.13.06.2.06a.38.38 0 0 0 .22-.08.4.4 0 0 0 .15-.41L10.5 8.19l3.22-2.81a.4.4 0 0 0 .12-.42Zm-7.82.14-3.8.28 2.92 2.54-.9 3.77L7.4 9.63l3.16 2.06-.9-3.77 2.9-2.54L8.8 5.1 7.4 1.53 6.03 5.1Z",
"clip-rule": "evenodd"
})
]),
n("symbol", {
viewBox: "0 0 14 13",
id: "filled"
}, [
n("path", {
"fill-rule": "evenodd",
d: "M13.48 4.96a.38.38 0 0 0-.33-.27l-4.19-.3L7.4.32a.38.38 0 0 0-.35-.25.38.38 0 0 0-.34.25L5.12 4.38l-4.18.3a.38.38 0 0 0-.33.28.4.4 0 0 0 .11.42l3.22 2.8-1.02 4.25a.4.4 0 0 0 .14.41.37.37 0 0 0 .43.02l3.56-2.32 3.55 2.32a.36.36 0 0 0 .42-.02.4.4 0 0 0 .15-.41l-1.02-4.24 3.22-2.81a.4.4 0 0 0 .11-.42Z",
"clip-rule": "evenodd"
})
])
])
], -1)
]), 512)
]))
], 64));
}
}), O = (o, a) => {
const e = o.__vccOpts || o;
for (const [t, d] of a)
e[t] = d;
return e;
}, U = /* @__PURE__ */ O(F, [["__scopeId", "data-v-81a86319"]]);
function P() {
const o = m(null), a = m(null), e = m(!1), t = (s) => {
a.value ? e.value = s.clientX < a.value.left + a.value.width / 2 : e.value = !1;
};
return { startObserve: (s) => {
s && (o.value = s, a.value = s.getBoundingClientRect(), s.addEventListener("mousemove", t));
}, endObserve: () => {
o.value && (o.value.removeEventListener("mousemove", t), o.value = null, a.value = null);
}, mouseInLeftHalf: e };
}
const W = { class: "v-rating" }, X = { class: "v-rating__stars" }, j = {
key: 0,
class: "v-rating__star"
}, J = ["onMouseover", "onClick"], K = {
key: 1,
class: "v-rating__star"
}, Q = /* @__PURE__ */ w({
__name: "rating-input",
props: {
numberOfStars: { default: 5 },
size: { default: "2rem" },
color: { default: "#ffb74b" },
backgroundColor: {},
enableOutline: { type: Boolean, default: !0 },
readonly: { type: Boolean, default: !1 },
allowHalfSelect: { type: Boolean, default: !1 },
modelValue: { default: 0 }
},
emits: ["update:modelValue"],
setup(o, { emit: a }) {
const e = { min: 2, max: 10 }, t = o, d = a, { startObserve: b, endObserve: s, mouseInLeftHalf: p } = P(), c = m(t.modelValue), v = m(0);
z(() => {
if (t.numberOfStars) {
if (Number.isNaN(t.numberOfStars))
throw new Error("numberOfStars must be a number between 0 10");
if (t.numberOfStars < e.min || t.numberOfStars > e.max)
throw new RangeError(`The prop \`numberOfStars\` is out of range [${e.min}, ${e.max}].`);
}
});
const $ = (l) => {
if (v.value !== 0)
return t.allowHalfSelect ? v.value >= l ? v.value == l && p.value ? 0.5 : 1 : 0 : v.value >= l ? 1 : 0;
const i = c.value - (l - 1);
return Math.max(0, Math.min(i, 1));
}, V = (l, i) => {
t.readonly || (b(i.currentTarget), v.value = l);
}, L = () => {
v.value = 0, s();
}, C = (l) => {
if (!(t.readonly || c.value === l)) {
if (t.allowHalfSelect) {
const i = l - (p.value ? 0.5 : 0);
c.value = i;
} else
c.value = l;
d("update:modelValue", c.value);
}
};
return (l, i) => (r(), u("div", W, [
n("div", X, [
l.$slots.before ? (r(), u("div", j, [
S(l.$slots, "before", {}, void 0, !0)
])) : _("", !0),
(r(!0), u(y, null, E(t.numberOfStars, (f) => (r(), u("div", {
key: `v-rating-${f}`,
class: N([
"v-rating__star",
t.readonly && "v-rating__star--is-readonly"
]),
type: "button",
tabindex: "0",
onMouseover: (g) => V(f, g),
onMouseleave: L,
onClick: (g) => C(f)
}, [
H(U, {
value: $(f),
color: l.color,
size: l.size,
"enable-outline": l.enableOutline,
"background-color": l.backgroundColor
}, null, 8, ["value", "color", "size", "enable-outline", "background-color"])
], 42, J))), 128)),
l.$slots.after ? (r(), u("div", K, [
S(l.$slots, "after", {}, void 0, !0)
])) : _("", !0)
]),
T(n("input", {
type: "hidden",
"onUpdate:modelValue": i[0] || (i[0] = (f) => c.value = f)
}, null, 512), [
[x, c.value]
])
]));
}
}), Y = /* @__PURE__ */ O(Q, [["__scopeId", "data-v-96aa76e2"]]), te = {
install(o) {
o.component("RatingInput", Y);
}
};
export {
te as VueRatingInput,
Y as default
};