vue-rating-input
Version:
[](https://www.npmjs.com/package/vue-rating-input)
191 lines (190 loc) • 7.15 kB
JavaScript
import { defineComponent as w, ref as m, useId as B, computed as h, createElementBlock as i, openBlock as r, Fragment as y, createBlock as M, createCommentVNode as _, createElementVNode as n, unref as k, Teleport as x, onMounted as R, withDirectives as z, renderSlot as S, renderList as E, normalizeClass as N, createVNode as H, vModelText as I } from "vue";
import './index.css';const T = ["fill", "height", "width"], A = ["id"], D = ["width"], G = ["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(l) {
const a = m(null), e = l, t = B(), c = h(() => e.value * 100), p = h(() => (document.querySelectorAll(".v-rating-star-svg__defs").length || 0) > 0);
return (s, b) => (r(), i(y, null, [
(r(), i("svg", {
class: "v-rating-star-svg",
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: `${c.value}%`,
height: "100%"
}, null, 8, D)
], 8, A)
]),
e.backgroundColor ? (r(), i("use", {
key: 0,
"xlink:href": "#filled",
fill: e.backgroundColor
}, null, 8, G)) : _("", !0),
e.enableOutline ? (r(), i("use", Z)) : _("", !0),
n("use", {
"xlink:href": "#filled",
"clip-path": `url(#clip-star-${k(t)})`
}, null, 8, q)
], 8, T)),
p.value ? _("", !0) : (r(), M(x, {
key: 0,
to: "body"
}, [
n("div", {
class: "v-rating-star-svg__defs",
ref_key: "iconsDefs",
ref: a
}, [...b[0] || (b[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 = (l, a) => {
const e = l.__vccOpts || l;
for (const [t, c] of a)
e[t] = c;
return e;
}, U = /* @__PURE__ */ O(F, [["__scopeId", "data-v-88790c4c"]]);
function P() {
const l = 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 && (l.value = s, a.value = s.getBoundingClientRect(), s.addEventListener("mousemove", t));
}, endObserve: () => {
l.value && (l.value.removeEventListener("mousemove", t), l.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(l, { emit: a }) {
const e = { min: 2, max: 10 }, t = l, c = a, { startObserve: p, endObserve: s, mouseInLeftHalf: b } = P(), d = m(t.modelValue), v = m(0);
R(() => {
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 $ = (o) => {
if (v.value !== 0)
return t.allowHalfSelect ? v.value >= o ? v.value == o && b.value ? 0.5 : 1 : 0 : v.value >= o ? 1 : 0;
const u = d.value - (o - 1);
return Math.max(0, Math.min(u, 1));
}, V = (o, u) => {
t.readonly || (p(u.currentTarget), v.value = o);
}, L = () => {
v.value = 0, s();
}, C = (o) => {
if (t.readonly) return;
const u = t.allowHalfSelect ? o - (b.value ? 0.5 : 0) : o;
d.value !== u && (d.value = u, c("update:modelValue", d.value));
};
return (o, u) => (r(), i("div", W, [
n("div", X, [
o.$slots.before ? (r(), i("div", j, [
S(o.$slots, "before", {}, void 0, !0)
])) : _("", !0),
(r(!0), i(y, null, E(t.numberOfStars, (f) => (r(), i("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)),
o.$slots.after ? (r(), i("div", K, [
S(o.$slots, "after", {}, void 0, !0)
])) : _("", !0)
]),
z(n("input", {
type: "hidden",
"onUpdate:modelValue": u[0] || (u[0] = (f) => d.value = f)
}, null, 512), [
[I, d.value]
])
]));
}
}), Y = /* @__PURE__ */ O(Q, [["__scopeId", "data-v-d44dd498"]]), te = {
install(l) {
l.component("RatingInput", Y);
}
};
export {
te as VueRatingInput,
Y as default
};