@smastrom/react-rating
Advanced tools
Comparing version 1.2.2 to 1.3.0
@@ -1,300 +0,1 @@ | ||
import r, { useEffect as e, useLayoutEffect as t, useRef as n, useState as o, isValidElement as a, forwardRef as i, useMemo as s, useCallback as c, Fragment as l } from "react"; | ||
const u = (r2) => { | ||
}, f = "undefined" == typeof window ? e : t, d = (r2) => "number" == typeof r2 && r2 > 0, m = (r2) => d(r2) ? r2 : 0, h = (r2) => Math.round(100 * r2) / 100, p = (r2) => Math.round(2 * r2) / 2, g = (r2) => 0 === r2 ? 0 : -1 * h(r2); | ||
const b = {}; | ||
const y = "rr--group", v = "rr--box", x = "rr--svg", S = "rr--reset", $ = "rr--focus-reset", C = "rr--svg-stop-1", w = "rr--svg-stop-2", B = "rr--on", k = "rr--off", A = "rr--fx-zoom", E = "rr--fx-position", N = "rr--fx-opacity", M = "rr--fx-colors", W = "rr--rx-sm", I = "rr--rx-md", L = "rr--rx-lg", R = "rr--rx-full", D = "rr--gap-sm", F = "rr--gap-md", O = "rr--gap-lg", H = "rr--space-sm", V = "rr--space-md", Z = "rr--space-lg", j = "rr--pointer", P = "rr--disabled", z = "rr--dir-y", T = "rr--dir-x", q = "rr--has-stroke", _ = "rr--has-border", G = "rr--hf-box-on", J = "rr--hf-box-int", K = "rr--hf-box-off", U = "rr--hf-svg-on", X = "rr--hf-svg-off", Y = "--rr--fill-on-color", Q = "--rr--box-on-color", rr = "--rr--border-on-color", er = "--rr--stroke-on-color", tr = "--rr--fill-off-color", nr = "--rr--box-off-color", or = "--rr--border-off-color", ar = "--rr--stroke-off-color", ir = "--rr--border-width", sr = "horizontal", cr = "vertical", lr = "svg", ur = "box", fr = "none", dr = "small", mr = "medium", hr = "large", pr = "full", gr = "none", br = "zoom", yr = "position", vr = "opacity", xr = "colors", Sr = "activeFillColor", $r = "activeBoxColor", Cr = "activeBoxBorderColor", wr = "activeStrokeColor", Br = "inactiveFillColor", kr = "inactiveBoxColor", Ar = "inactiveBoxBorderColor", Er = "inactiveStrokeColor"; | ||
function Nr({ itemShapes: e2, testId: t2, itemStrokeWidth: a2 = 0, orientation: i2 = sr, hasHF: s2 = false }) { | ||
const c2 = a2 > 0 ? -a2 / 2 : 0, l2 = a2 > 0 ? `${c2} ${c2}` : "0 0", u2 = n(null), d2 = n(null), [m2, p2] = o(null); | ||
return f(() => { | ||
if (s2 && !d2.current && (d2.current = `rr_hf_${(Math.random() + 1).toString(36).substring(7)}`), u2.current) { | ||
const { width: r2, height: e3, x: t3, y: n2 } = u2.current.getBBox(); | ||
if (((...r3) => r3.every((r4) => "number" == typeof r4))(r2, e3, t3, n2)) { | ||
const o2 = `${l2} ${h(r2 + a2)} ${h(e3 + a2)}`, i3 = `${g(t3)} ${g(n2)}`; | ||
p2({ viewBox: o2, translateData: i3 }); | ||
} | ||
} | ||
}, [e2, a2, s2]), r.createElement("svg", { "aria-hidden": "true", className: x, xmlns: "http://www.w3.org/2000/svg", viewBox: m2 ? m2.viewBox : "0 0 0 0", preserveAspectRatio: "xMidYMid meet", ...a2 > 0 ? { strokeWidth: a2 } : {}, ...t2 }, s2 && d2.current && r.createElement("defs", {}, r.createElement("linearGradient", { id: d2.current, ...i2 === cr ? { gradientTransform: "rotate(90)" } : {} }, r.createElement("stop", { className: C, offset: "50%" }), r.createElement("stop", { className: w, offset: "50%" }))), r.createElement("g", { ref: u2, shapeRendering: "geometricPrecision", ...function() { | ||
if (m2) { | ||
const r2 = `translate(${m2 == null ? void 0 : m2.translateData})`; | ||
return "translate(0 0)" === r2 ? {} : { transform: r2 }; | ||
} | ||
return { transform: void 0 }; | ||
}(), ...s2 ? { fill: `url('#${d2.current}')` } : {} }, e2)); | ||
} | ||
function Mr(r2, e2, t2) { | ||
switch (e2) { | ||
case Sr: | ||
return r2[Y] = t2, true; | ||
case $r: | ||
return r2[Q] = t2, true; | ||
case Cr: | ||
return r2[rr] = t2, true; | ||
case wr: | ||
return r2[er] = t2, true; | ||
} | ||
return false; | ||
} | ||
function Wr(r2, e2, t2) { | ||
if (!Mr(r2, e2, t2)) | ||
switch (e2) { | ||
case Br: | ||
r2[tr] = t2; | ||
break; | ||
case kr: | ||
r2[nr] = t2; | ||
break; | ||
case Ar: | ||
r2[or] = t2; | ||
break; | ||
case Er: | ||
r2[ar] = t2; | ||
} | ||
} | ||
function Ir(r2, e2, t2) { | ||
const n2 = {}; | ||
let o2; | ||
for (const [t3, o3] of Object.entries(r2)) | ||
Mr(n2, t3, o3[e2]); | ||
return t2 ? (o2 = Array(e2).fill({}), o2.push(n2)) : o2 = Array(e2 + 1).fill(n2), o2; | ||
} | ||
const Lr = (r2) => `${r2} ${M}`; | ||
function Rr({ className: r2, radius: e2, readOnly: t2, isDisabled: n2, isDynamic: o2, transition: a2, orientation: i2, absoluteBoxBorderWidth: s2, absoluteStrokeWidth: c2, spaceBetween: l2, spaceInside: u2 }) { | ||
const f2 = o2 ? j : "", d2 = function(r3) { | ||
switch (r3) { | ||
case dr: | ||
return D; | ||
case mr: | ||
return F; | ||
case hr: | ||
return O; | ||
default: | ||
return ""; | ||
} | ||
}(l2), m2 = function(r3) { | ||
switch (r3) { | ||
case dr: | ||
return H; | ||
case mr: | ||
return V; | ||
case hr: | ||
return Z; | ||
default: | ||
return ""; | ||
} | ||
}(u2), h2 = !t2 && n2 ? P : "", p2 = o2 && a2 !== gr ? function(r3) { | ||
switch (r3) { | ||
case br: | ||
return Lr(A); | ||
case yr: | ||
return Lr(E); | ||
case vr: | ||
return Lr(N); | ||
case xr: | ||
return M; | ||
default: | ||
return ""; | ||
} | ||
}(a2) : "", g2 = i2 === cr ? z : T, b2 = function(r3) { | ||
switch (r3) { | ||
case dr: | ||
return W; | ||
case mr: | ||
return I; | ||
case hr: | ||
return L; | ||
case pr: | ||
return R; | ||
default: | ||
return ""; | ||
} | ||
}(e2); | ||
return `${y} ${g2} ${c2 > 0 ? q : ""} ${s2 > 0 ? _ : ""} | ||
${p2} ${b2} ${f2} ${h2} ${d2} | ||
${m2} ${r2}`.replace(/ +/g, " ").trimEnd(); | ||
} | ||
function Dr(r2, e2, t2) { | ||
return Array.from({ length: e2 }, (e3, n2) => r2 ? n2 === t2 ? B : k : n2 <= t2 ? B : k); | ||
} | ||
function Fr(r2, e2, t2) { | ||
const n2 = Math.floor(p(r2)); | ||
return Array.from({ length: e2 }, (r3, e3) => "box" === t2 ? e3 > n2 ? K : e3 === n2 ? J : G : e3 > n2 ? X : U); | ||
} | ||
function Or(r2, e2) { | ||
const t2 = {}; | ||
d(e2) && (t2[ir] = `${e2}px`); | ||
const n2 = Object.entries(r2); | ||
if (n2.length > 0) | ||
for (const [r3, e3] of n2) | ||
Wr(t2, r3, e3); | ||
return t2; | ||
} | ||
const Hr = [Sr, $r, wr, Cr]; | ||
function Vr(r2, e2, t2 = false) { | ||
return Array.from({ length: r2 }, (n2, o2) => t2 && e2 < 0 ? o2 === r2 - 1 ? 0 : -1 : e2 <= 0 ? 0 === o2 ? 0 : -1 : e2 > 0 ? o2 === e2 ? 0 : -1 : void 0); | ||
} | ||
const Zr = "@smastrom/react-rating"; | ||
function jr(r2, e2) { | ||
return r2.shouldRender = false, r2.reason = ((r3) => `[${Zr}] - Nothing's returned from rendering. Reason: ${r3}.`)(e2), r2; | ||
} | ||
const Pr = "itemShapes is not a valid JSX element"; | ||
const zr = r.createElement("polygon", { points: "25 9.02 16.4 7.75 12.46 0 8.59 7.79 0 9.14 6.21 15.23 4.85 23.81 12.55 19.79 20.3 23.74 18.85 15.17 25 9.02" }), Tr = r.createElement("path", { d: "M12.5,18.16l-7.73,5.61,2.95-9.08L0,9.07H9.55S12.5,0,12.5,0l2.95,9.07h9.55l-7.73,5.62,2.95,9.08-7.73-5.61Z" }), qr = r.createElement("path", { d: "M112.46,57.88c-.23-.72-.88-1.22-1.63-1.27l-6.63-.46-2.45-6.19c-.27-.7-.95-1.16-1.7-1.16h0c-.75,0-1.42,.46-1.7,1.16l-2.5,6.23-6.58,.42c-.75,.05-1.4,.55-1.63,1.27-.24,.73,0,1.53,.58,2.02l5.07,4.28-1.51,5.92c-.21,.82,.1,1.69,.78,2.19,.66,.48,1.55,.5,2.24,.07l5.23-3.31h.02l5.63,3.56c.29,.19,.63,.29,.97,.29,1.02,0,1.83-.84,1.83-1.86,0-.16-.02-.31-.06-.47l-1.6-6.48,5.04-4.2c.59-.49,.82-1.29,.58-2.02Z" }), _r = r.createElement("path", { d: "M22.72,8.24h-6.68L13.97,1.88c-.81-2.51-2.13-2.51-2.95,0l-2.07,6.36H2.28c-2.63,0-3.04,1.25-.91,2.8l5.41,3.93-2.06,6.36c-.81,2.51,.25,3.28,2.39,1.73l5.41-3.93,5.41,3.93c2.13,1.55,3.2,.77,2.39-1.73l-2.07-6.36,5.41-3.93c2.13-1.55,1.72-2.8-.91-2.8Z" }), Gr = r.createElement("path", { d: "M11.58,.77c.51-1.02,1.33-1.02,1.84,0l2.34,4.73c.5,1.02,1.84,2,2.98,2.16l5.22,.76c1.13,.17,1.39,.95,.57,1.75l-3.78,3.68c-.82,.8-1.33,2.37-1.14,3.5l.89,5.2c.19,1.13-.48,1.61-1.49,1.08l-4.67-2.45c-1.01-.53-2.67-.53-3.68,0l-4.67,2.46c-1.01,.53-1.68,.05-1.49-1.08l.89-5.2c.19-1.13-.32-2.7-1.14-3.5L.48,10.17c-.82-.8-.56-1.58,.57-1.75l5.22-.76c1.13-.16,2.47-1.14,2.98-2.16L11.58,.77h0Z" }), Jr = r.createElement("path", { d: "M19.29,1.61c-2.15-2.15-5.63-2.15-7.78,0,0,0,0,0,0,0l-1.06,1.06-1.06-1.06C7.24-.54,3.76-.54,1.61,1.61-.54,3.76-.54,7.24,1.61,9.39l1.06,1.06,7.78,7.78,7.78-7.78,1.06-1.06c2.15-2.15,2.15-5.63,0-7.78,0,0,0,0,0,0Z" }), Kr = { itemShapes: zr, itemStrokeWidth: 2, activeFillColor: "#ffb23f", inactiveFillColor: "#fff7ed", activeStrokeColor: "#e17b21", inactiveStrokeColor: "#eda76a" }, Ur = i(({ value: t2, items: i2 = 5, readOnly: d2 = false, onChange: h2 = u, onHoverChange: g2 = u, onFocus: y2 = u, onBlur: x2 = u, isDisabled: C2 = false, highlightOnlySelected: w2 = false, orientation: B2 = sr, spaceBetween: k2 = fr, spaceInside: A2 = dr, radius: E2 = fr, transition: N2 = xr, itemStyles: M2 = Kr, isRequired: W2 = false, halfFillMode: I2 = lr, visibleLabelId: L2, visibleItemLabelIds: R2, invisibleLabel: D2 = d2 ? `Rated ${t2} on ${i2}` : "Rating", invisibleItemLabels: F2, resetLabel: O2 = "No rating", id: H2, className: V2, style: Z2 }, j2) => { | ||
const P2 = Array.from({ length: i2 }, (r2, e2) => e2 + 1), z2 = d2 && !Number.isInteger(t2), T2 = z2 && !w2, q2 = z2 && w2 ? Math.round(t2) : t2, _2 = !d2 && !C2, G2 = q2 >= 0.25, J2 = "string" == typeof V2 ? V2 : "", K2 = I2 === ur ? ur : lr, U2 = T2 && !((r2) => Number.isInteger(p(r2)))(q2), X2 = !W2 && !d2, Y2 = W2 ? i2 : i2 + 1, Q2 = T2 ? function(r2, e2) { | ||
const t3 = p(e2); | ||
return Number.isInteger(t3) ? r2.indexOf(t3) : Math.floor(t3); | ||
}(P2, q2) : P2.indexOf(q2), { staticColors: rr2, arrayColors: er2, itemShapes: tr2, absoluteStrokeWidth: nr2, absoluteBoxBorderWidth: or2 } = s(() => { | ||
const { itemShapes: r2, itemStrokeWidth: e2, boxBorderWidth: t3, ...n2 } = M2, o2 = function(r3) { | ||
const e3 = { ...r3 }, t4 = {}, n3 = Object.entries(e3); | ||
if (n3.length > 0) | ||
for (const [r4, o3] of n3) | ||
if (Array.isArray(o3) || "string" == typeof o3) { | ||
if (Array.isArray(o3)) | ||
for (const n4 of Hr) | ||
if (n4 === r4) { | ||
const n5 = o3.filter((r5) => "string" == typeof r5); | ||
n5.length > 0 && (t4[r4] = n5, delete e3[r4]); | ||
} else | ||
delete e3[r4]; | ||
} else | ||
delete e3[r4]; | ||
return { arrayColors: t4, staticColors: e3 }; | ||
}(n2); | ||
return { itemShapes: r2, absoluteStrokeWidth: m(e2), absoluteBoxBorderWidth: m(t3), ...o2 }; | ||
}, [M2]), ar2 = Object.keys(er2).length > 0, ir2 = c((r2, e2) => ({ dynamicClassNames: U2 ? Fr(q2, i2, K2) : Dr(w2, i2, r2), dynamicCssVars: e2 && ar2 ? Ir(er2, r2, w2) : [] }), [er2, ar2, w2, K2, U2, i2, q2]), cr2 = c(() => $r2(Vr(Y2, Q2, !W2)), [Q2, Y2, W2]), mr2 = n(true), hr2 = n(true), pr2 = n(null), gr2 = n([]), br2 = n(false), [yr2, vr2] = o({ staticCssVars: Or(rr2, or2), ...ir2(Q2, G2) }), [Sr2, $r2] = o(() => _2 ? Vr(Y2, Q2, !W2) : []); | ||
f(() => { | ||
_2 && gr2.current && (br2.current = function(r2) { | ||
if (r2) | ||
return "rtl" === getComputedStyle(r2).getPropertyValue("direction"); | ||
return false; | ||
}(gr2.current[0])); | ||
}, [_2]), e(() => { | ||
if (!mr2.current) | ||
return vr2({ staticCssVars: Or(rr2, or2), ...ir2(Q2, G2) }); | ||
mr2.current = false; | ||
}, [rr2, ir2, or2, Q2, G2]), e(() => { | ||
if (!hr2.current && _2) | ||
return cr2(); | ||
hr2.current = false; | ||
}, [_2, cr2]); | ||
const { shouldRender: Cr2, reason: wr2 } = function({ items: r2, itemShapes: e2 }) { | ||
const t3 = { shouldRender: true, reason: "" }; | ||
if ("number" != typeof r2 || r2 < 1 || r2 > 10) | ||
return jr(t3, "items is invalid"); | ||
if (!e2) | ||
return jr(t3, "itemStyles needs at least the property itemShapes set"); | ||
if (!Array.isArray(e2) && !a(e2)) | ||
return jr(t3, Pr); | ||
if (Array.isArray(e2)) { | ||
if (e2.length !== r2) | ||
return jr(t3, "itemShapes length mismatch"); | ||
if (!e2.every((r3) => a(r3))) | ||
return jr(t3, Pr); | ||
} | ||
return t3; | ||
}({ items: i2, itemShapes: tr2 }); | ||
if (!Cr2) | ||
return console.error(wr2), null; | ||
function Br2(r2, e2, t3 = () => { | ||
}) { | ||
gr2.current.some((e3) => e3 === r2.relatedTarget) ? t3() : e2(); | ||
} | ||
function kr2() { | ||
g2(0), cr2(); | ||
} | ||
function Ar2(r2) { | ||
Br2(r2, () => { | ||
kr2(); | ||
}), vr2({ ...yr2, ...ir2(Q2, G2) }); | ||
} | ||
function Er2(r2) { | ||
Br2(r2, () => { | ||
kr2(), x2(); | ||
}); | ||
} | ||
function Mr2(r2, e2) { | ||
const t3 = !W2 && e2 === P2.length ? 0 : e2 + 1; | ||
Br2(r2, () => { | ||
y2(), g2(t3); | ||
}, () => { | ||
g2(t3); | ||
}); | ||
} | ||
function Wr2(r2) { | ||
$r2(Vr(Y2, r2, !W2)), gr2.current[r2].focus(); | ||
} | ||
const Lr2 = Rr({ className: J2, radius: E2, readOnly: d2, isDisabled: C2, isDynamic: _2, transition: N2, orientation: B2, absoluteBoxBorderWidth: or2, absoluteStrokeWidth: nr2, spaceBetween: k2, spaceInside: A2 }); | ||
function Zr2(r2) { | ||
return { ref: (e2) => gr2.current[r2] = e2 }; | ||
} | ||
function zr2(r2) { | ||
return { tabIndex: Sr2[r2], onKeyDown: (e2) => function(r3, e3) { | ||
let t3 = 0; | ||
const n2 = W2 ? P2.length - 1 : P2.length, o2 = e3 - 1, a2 = e3 + 1, i3 = !W2 && e3 === P2.length, s2 = 0 === e3 ? n2 : o2, c2 = n2 === e3 ? 0 : a2; | ||
switch (r3.code) { | ||
case "Shift": | ||
case "Tab": | ||
return true; | ||
case "ArrowDown": | ||
case "ArrowRight": | ||
return t3 = br2.current ? s2 : c2, Wr2(t3); | ||
case "ArrowUp": | ||
case "ArrowLeft": | ||
return t3 = br2.current ? c2 : s2, Wr2(t3); | ||
case "Enter": | ||
case "Space": | ||
return r3.preventDefault(), h2(i3 ? 0 : e3 + 1); | ||
} | ||
r3.preventDefault(), r3.stopPropagation(); | ||
}(e2, r2) }; | ||
} | ||
function Tr2(r2) { | ||
return { onClick: (e2) => function(r3, e3) { | ||
r3.stopPropagation(), h2(W2 || Q2 !== e3 ? e3 + 1 : 0); | ||
}(e2, r2), onMouseEnter: () => function(r3) { | ||
g2(r3 + 1), vr2({ ...yr2, ...ir2(r3, true) }); | ||
}(r2), onMouseLeave: Ar2 }; | ||
} | ||
function qr2(r2) { | ||
if (d2) | ||
return {}; | ||
const e2 = {}; | ||
if (Array.isArray(R2)) | ||
e2["aria-labelledby"] = R2[r2]; | ||
else { | ||
const t3 = Array.isArray(F2) ? F2 : P2.map((r3, e3) => `Rate ${e3 + 1}`); | ||
e2["aria-label"] = t3[r2]; | ||
} | ||
return C2 && (e2["aria-disabled"] = "true"), { role: "radio", "aria-checked": r2 + 1 === q2, ...e2 }; | ||
} | ||
function _r2(r2) { | ||
const e2 = { itemShapes: Array.isArray(tr2) ? tr2[r2] : tr2, itemStrokeWidth: nr2, orientation: B2, hasHF: false, testId: {} }; | ||
return U2 && K2 === lr && (e2.hasHF = r2 === Q2), e2; | ||
} | ||
return r.createElement("div", { id: H2, className: Lr2, style: { ...Z2, ...yr2.staticCssVars }, ref: function(r2) { | ||
_2 && !W2 && (pr2.current = r2), j2 && (j2.current = r2); | ||
}, ...function() { | ||
if (!d2) { | ||
const r2 = W2 && !C2, e2 = { role: "radiogroup", "aria-required": r2 }; | ||
return r2 && (e2["aria-invalid"] = q2 <= 0), "string" == typeof L2 && L2.length > 0 ? e2["aria-labelledby"] = L2 : e2["aria-label"] = D2, e2; | ||
} | ||
return { role: "img", "aria-label": D2 }; | ||
}(), ...b }, P2.map((e2, t3) => { | ||
return r.createElement(l, { key: e2 }, r.createElement("div", { className: `${v} ${yr2.dynamicClassNames[t3]}`, style: yr2.dynamicCssVars[t3], ...qr2(t3), ...(o2 = t3, _2 ? { ...Zr2(o2), ...zr2(o2), ...Tr2(o2), onFocus: (r2) => Mr2(r2, o2), onBlur: (r2) => Er2(r2) } : {}) }, r.createElement(Nr, { ..._r2(t3) })), X2 && t3 === P2.length - 1 && r.createElement("div", { ...(n2 = t3 + 1, { className: S, role: "radio", "aria-label": O2, "aria-checked": 0 === q2, onClick: () => h2(0), onFocus: (r2) => { | ||
var _a; | ||
Mr2(r2, n2), (_a = pr2.current) == null ? void 0 : _a.classList.add($); | ||
}, onBlur: (r2) => { | ||
var _a; | ||
Er2(r2), (_a = pr2.current) == null ? void 0 : _a.classList.remove($); | ||
}, ...zr2(n2), ...Zr2(n2), ...C2 ? { "aria-disabled": "true" } : {} }) })); | ||
var n2, o2; | ||
})); | ||
}); | ||
Ur.displayName = "Rating"; | ||
export { | ||
Jr as Heart, | ||
Ur as Rating, | ||
qr as RoundedStar, | ||
zr as Star, | ||
Gr as StickerStar, | ||
_r as ThinRoundedStar, | ||
Tr as ThinStar | ||
}; | ||
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("react/jsx-runtime"),e=require("react"),t=r=>{},n="undefined"==typeof window?e.useEffect:e.useLayoutEffect,o=r=>"number"==typeof r&&r>0,s=r=>o(r)?r:0,a=r=>Math.round(100*r)/100,i=r=>Math.round(2*r)/2,c=r=>0===r?0:-1*a(r),l={},u={GROUP:"rr--group",BOX:"rr--box",SVG:"rr--svg",RESET:"rr--reset",GROUP_RESET:"rr--focus-reset",DEF_50:"rr--svg-stop-1",DEF_100:"rr--svg-stop-2"},f="rr--on",d="rr--off",h="rr--fx-zoom",m="rr--fx-position",p="rr--fx-opacity",g="rr--fx-colors",b="rr--rx-sm",x="rr--rx-md",y="rr--rx-lg",R="rr--rx-full",S="rr--gap-sm",v="rr--gap-md",B="rr--gap-lg",O="rr--space-sm",E="rr--space-md",L="rr--space-lg",C={FILL:"--rr--fill-on-color",BOX:"--rr--box-on-color",BORDER:"--rr--border-on-color",STROKE:"--rr--stroke-on-color"},$={FILL:"--rr--fill-off-color",BOX:"--rr--box-off-color",BORDER:"--rr--border-off-color",STROKE:"--rr--stroke-off-color"},w="horizontal",k="vertical",A="svg",F="none",D="small",j="medium",I="large",T="full",M="none",N="zoom",W="position",X="opacity",K="colors",P={FILL:"activeFillColor",BOX:"activeBoxColor",BORDER:"activeBoxBorderColor",STROKE:"activeStrokeColor"},V={FILL:"inactiveFillColor",BOX:"inactiveBoxColor",BORDER:"inactiveBoxBorderColor",STROKE:"inactiveStrokeColor"};function _({itemShapes:t,testId:o,itemStrokeWidth:s=0,orientation:i=w,hasHF:l=!1}){const f=s>0?-s/2:0,d=s>0?`${f} ${f}`:"0 0",h=e.useRef(null),m=e.useRef(null),[p,g]=e.useState(null);return n((()=>{if(l&&!m.current&&(m.current=`rr_hf_${(Math.random()+1).toString(36).substring(7)}`),h.current){const{width:r,height:e,x:t,y:n}=h.current.getBBox();if(((...r)=>r.every((r=>"number"==typeof r)))(r,e,t,n)){const o=`${d} ${a(r+s)} ${a(e+s)}`,i=`${c(t)} ${c(n)}`;g({viewBox:o,translateData:i})}}}),[t,s,l]),r.jsxs("svg",{"aria-hidden":"true",className:u.SVG,xmlns:"http://www.w3.org/2000/svg",viewBox:p?p.viewBox:"0 0 0 0",preserveAspectRatio:"xMidYMid meet",...s>0?{strokeWidth:s}:{},...o,children:[l&&m.current&&r.jsx("defs",{children:r.jsxs("linearGradient",{id:m.current,...i===k?{gradientTransform:"rotate(90)"}:{},children:[r.jsx("stop",{className:u.DEF_50,offset:"50%"}),r.jsx("stop",{className:u.DEF_100,offset:"50%"})]})}),r.jsx("g",{ref:h,shapeRendering:"geometricPrecision",...function(){if(p){const r=`translate(${null==p?void 0:p.translateData})`;return"translate(0 0)"===r?{}:{transform:r}}return{transform:void 0}}(),...l?{fill:`url('#${m.current}')`}:{},children:t})]})}function G(r,e,t){switch(e){case P.FILL:return r[C.FILL]=t,!0;case P.BOX:return r[C.BOX]=t,!0;case P.BORDER:return r[C.BORDER]=t,!0;case P.STROKE:return r[C.STROKE]=t,!0}return!1}function H(r,e,t){if(!G(r,e,t))switch(e){case V.FILL:r[$.FILL]=t;break;case V.BOX:r[$.BOX]=t;break;case V.BORDER:r[$.BORDER]=t;break;case V.STROKE:r[$.STROKE]=t}}function U(r,e,t){const n={};let o;for(const[s,a]of Object.entries(r))G(n,s,a[e]);return t?(o=Array(e).fill({}),o.push(n)):o=Array(e+1).fill(n),o}const Z=r=>`${r} ${g}`;function q(r,e,t){return Array.from({length:e},((e,n)=>r?n===t?f:d:n<=t?f:d))}function z(r,e,t){const n=Math.floor(i(r));return Array.from({length:e},((r,e)=>"box"===t?e>n?"rr--hf-box-off":e===n?"rr--hf-box-int":"rr--hf-box-on":e>n?"rr--hf-svg-off":"rr--hf-svg-on"))}function J(r,e){const t={};o(e)&&(t["--rr--border-width"]=`${e}px`);const n=Object.entries(r);if(n.length>0)for(const[o,s]of n)H(t,o,s);return t}const Y=[P.FILL,P.BOX,P.STROKE,P.BORDER];function Q(r,e,t=!1){return Array.from({length:r},((n,o)=>t&&e<0?o===r-1?0:-1:e<=0?0===o?0:-1:e>0?o===e?0:-1:void 0))}function rr(r,e){return r.shouldRender=!1,r.reason=(r=>`[@smastrom/react-rating] - Nothing's returned from rendering. Reason: ${r}.`)(e),r}const er="itemShapes is not a valid JSX element",tr=r.jsx("polygon",{points:"25 9.02 16.4 7.75 12.46 0 8.59 7.79 0 9.14 6.21 15.23 4.85 23.81 12.55 19.79 20.3 23.74 18.85 15.17 25 9.02"}),nr=r.jsx("path",{d:"M12.5,18.16l-7.73,5.61,2.95-9.08L0,9.07H9.55S12.5,0,12.5,0l2.95,9.07h9.55l-7.73,5.62,2.95,9.08-7.73-5.61Z"}),or=r.jsx("path",{d:"M112.46,57.88c-.23-.72-.88-1.22-1.63-1.27l-6.63-.46-2.45-6.19c-.27-.7-.95-1.16-1.7-1.16h0c-.75,0-1.42,.46-1.7,1.16l-2.5,6.23-6.58,.42c-.75,.05-1.4,.55-1.63,1.27-.24,.73,0,1.53,.58,2.02l5.07,4.28-1.51,5.92c-.21,.82,.1,1.69,.78,2.19,.66,.48,1.55,.5,2.24,.07l5.23-3.31h.02l5.63,3.56c.29,.19,.63,.29,.97,.29,1.02,0,1.83-.84,1.83-1.86,0-.16-.02-.31-.06-.47l-1.6-6.48,5.04-4.2c.59-.49,.82-1.29,.58-2.02Z"}),sr=r.jsx("path",{d:"M22.72,8.24h-6.68L13.97,1.88c-.81-2.51-2.13-2.51-2.95,0l-2.07,6.36H2.28c-2.63,0-3.04,1.25-.91,2.8l5.41,3.93-2.06,6.36c-.81,2.51,.25,3.28,2.39,1.73l5.41-3.93,5.41,3.93c2.13,1.55,3.2,.77,2.39-1.73l-2.07-6.36,5.41-3.93c2.13-1.55,1.72-2.8-.91-2.8Z"}),ar=r.jsx("path",{d:"M11.58,.77c.51-1.02,1.33-1.02,1.84,0l2.34,4.73c.5,1.02,1.84,2,2.98,2.16l5.22,.76c1.13,.17,1.39,.95,.57,1.75l-3.78,3.68c-.82,.8-1.33,2.37-1.14,3.5l.89,5.2c.19,1.13-.48,1.61-1.49,1.08l-4.67-2.45c-1.01-.53-2.67-.53-3.68,0l-4.67,2.46c-1.01,.53-1.68,.05-1.49-1.08l.89-5.2c.19-1.13-.32-2.7-1.14-3.5L.48,10.17c-.82-.8-.56-1.58,.57-1.75l5.22-.76c1.13-.16,2.47-1.14,2.98-2.16L11.58,.77h0Z"}),ir=r.jsx("path",{d:"M19.29,1.61c-2.15-2.15-5.63-2.15-7.78,0,0,0,0,0,0,0l-1.06,1.06-1.06-1.06C7.24-.54,3.76-.54,1.61,1.61-.54,3.76-.54,7.24,1.61,9.39l1.06,1.06,7.78,7.78,7.78-7.78,1.06-1.06c2.15-2.15,2.15-5.63,0-7.78,0,0,0,0,0,0Z"}),cr={itemShapes:tr,itemStrokeWidth:2,activeFillColor:"#ffb23f",inactiveFillColor:"#fff7ed",activeStrokeColor:"#e17b21",inactiveStrokeColor:"#eda76a"},lr=e.forwardRef((({value:o,items:a=5,readOnly:c=!1,onChange:f=t,onHoverChange:d=t,onFocus:C=t,onBlur:$=t,isDisabled:P=!1,highlightOnlySelected:V=!1,orientation:G=w,spaceBetween:H=F,spaceInside:tr=D,radius:nr=F,transition:or=K,itemStyles:sr=cr,isRequired:ar=!1,halfFillMode:ir=A,visibleLabelId:lr,visibleItemLabelIds:ur,invisibleItemLabels:fr,invisibleLabel:dr=(c?o>0?`Rated ${o} on ${a}`:"Not rated":"Rating Selection"),resetLabel:hr="Reset rating",id:mr,className:pr,style:gr},br)=>{const xr=Array.from({length:a},((r,e)=>e+1)),yr=c&&!Number.isInteger(o),Rr=yr&&!V,Sr=yr&&V?Math.round(o):o,vr=!c&&!P,Br=Sr>=.25,Or="string"==typeof pr?pr:"",Er="box"===ir?"box":A,Lr=Rr&&(Ur=Sr,!Number.isInteger(i(Ur))),Cr=!ar&&!c,$r=ar?a:a+1,wr=Rr?function(r,e){const t=i(e);return Number.isInteger(t)?r.indexOf(t):Math.floor(t)}(xr,Sr):xr.indexOf(Sr),{staticColors:kr,arrayColors:Ar,itemShapes:Fr,absoluteStrokeWidth:Dr,absoluteBoxBorderWidth:jr}=e.useMemo((()=>{const{itemShapes:r,itemStrokeWidth:e,boxBorderWidth:t,...n}=sr,o=function(r){const e={...r},t={},n=Object.entries(e);if(n.length>0)for(const[o,s]of n)if(Array.isArray(s)||"string"==typeof s){if(Array.isArray(s))for(const r of Y)if(r===o){const r=s.filter((r=>"string"==typeof r));r.length>0&&(t[o]=r,delete e[o])}else delete e[o]}else delete e[o];return{arrayColors:t,staticColors:e}}(n);return{itemShapes:r,absoluteStrokeWidth:s(e),absoluteBoxBorderWidth:s(t),...o}}),[sr]),Ir=Object.keys(Ar).length>0,Tr=e.useCallback(((r,e)=>({dynamicClassNames:Lr?z(Sr,a,Er):q(V,a,r),dynamicCssVars:e&&Ir?U(Ar,r,V):[]})),[Ar,Ir,V,Er,Lr,a,Sr]),Mr=e.useCallback((()=>Hr(Q($r,wr,!ar))),[wr,$r,ar]),Nr=e.useRef(!0),Wr=e.useRef(!0),Xr=e.useRef(null),Kr=e.useRef([]),Pr=e.useRef(!1),[Vr,_r]=e.useState({staticCssVars:J(kr,jr),...Tr(wr,Br)}),[Gr,Hr]=e.useState((()=>vr?Q($r,wr,!ar):[]));var Ur;n((()=>{vr&&Kr.current&&(Pr.current=function(r){return!!r&&"rtl"===getComputedStyle(r).getPropertyValue("direction")}(Kr.current[0]))}),[vr]),e.useEffect((()=>{if(!Nr.current)return _r({staticCssVars:J(kr,jr),...Tr(wr,Br)});Nr.current=!1}),[kr,Tr,jr,wr,Br]),e.useEffect((()=>{if(!Wr.current&&vr)return Mr();Wr.current=!1}),[vr,Mr]);const{shouldRender:Zr,reason:qr}=function({items:r,itemShapes:t}){const n={shouldRender:!0,reason:""};if("number"!=typeof r||r<1||r>10)return rr(n,"items is invalid");if(!t)return rr(n,"itemStyles needs at least the property itemShapes set");if(!Array.isArray(t)&&!e.isValidElement(t))return rr(n,er);if(Array.isArray(t)){if(t.length!==r)return rr(n,"itemShapes length mismatch");if(!t.every((r=>e.isValidElement(r))))return rr(n,er)}return n}({items:a,itemShapes:Fr});if(!Zr)return console.error(qr),null;function zr(r,e,t=(()=>{})){Kr.current.some((e=>e===r.relatedTarget))?t():e()}function Jr(){d(0),Mr()}function Yr(r){zr(r,(()=>{Jr()})),_r({...Vr,...Tr(wr,Br)})}function Qr(r){zr(r,(()=>{Jr(),$()}))}function re(r,e){const t=ar||e!==xr.length?e+1:0;zr(r,(()=>{C(),d(t)}),(()=>{d(t)}))}function ee(r){Hr(Q($r,r,!ar)),Kr.current[r].focus()}const te=function({className:r,radius:e,readOnly:t,isDisabled:n,isDynamic:o,transition:s,orientation:a,absoluteBoxBorderWidth:i,absoluteStrokeWidth:c,spaceBetween:l,spaceInside:f}){const d=o?"rr--pointer":"",C=function(r){switch(r){case D:return S;case j:return v;case I:return B;default:return""}}(l),$=function(r){switch(r){case D:return O;case j:return E;case I:return L;default:return""}}(f),w=!t&&n?"rr--disabled":"",A=o&&s!==M?function(r){switch(r){case N:return Z(h);case W:return Z(m);case X:return Z(p);case K:return g;default:return""}}(s):"",F=a===k?"rr--dir-y":"rr--dir-x",P=function(r){switch(r){case D:return b;case j:return x;case I:return y;case T:return R;default:return""}}(e),V=i>0?"rr--has-border":"",_=c>0?"rr--has-stroke":"";return`${u.GROUP} ${F} ${_} ${V}\n${A} ${P} ${d} ${w} ${C}\n${$} ${r}`.replace(/ +/g," ").trimEnd()}({className:Or,radius:nr,readOnly:c,isDisabled:P,isDynamic:vr,transition:or,orientation:G,absoluteBoxBorderWidth:jr,absoluteStrokeWidth:Dr,spaceBetween:H,spaceInside:tr});function ne(r){return{ref:e=>Kr.current[r]=e}}function oe(r){return{tabIndex:Gr[r],onKeyDown:e=>function(r,e){let t=0;const n=ar?xr.length-1:xr.length,o=e-1,s=e+1,a=!ar&&e===xr.length,i=0===e?n:o,c=n===e?0:s;switch(r.code){case"Shift":case"Tab":return!0;case"ArrowDown":case"ArrowRight":return t=Pr.current?i:c,ee(t);case"ArrowUp":case"ArrowLeft":return t=Pr.current?c:i,ee(t);case"Enter":case"Space":return r.preventDefault(),f(a?0:e+1)}r.preventDefault(),r.stopPropagation()}(e,r)}}function se(r){return{onClick:e=>{return t=r,e.stopPropagation(),void f(ar||wr!==t?t+1:0);var t},onMouseEnter:()=>{return d((e=r)+1),void _r({...Vr,...Tr(e,!0)});var e},onMouseLeave:Yr}}function ae(r){if(c)return{};const e={};if(Array.isArray(ur))e["aria-labelledby"]=ur[r];else{const t=Array.isArray(fr)?fr:xr.map(((r,e)=>`Rate ${e+1}`));e["aria-label"]=t[r]}return P&&(e["aria-disabled"]="true"),{role:"radio","aria-checked":r+1===Sr,...e}}function ie(r){const e={itemShapes:Array.isArray(Fr)?Fr[r]:Fr,itemStrokeWidth:Dr,orientation:G,hasHF:!1,testId:{}};return Lr&&Er===A&&(e.hasHF=r===wr),e}return r.jsx("div",{id:mr,className:te,style:{...gr,...Vr.staticCssVars},ref:function(r){vr&&!ar&&(Xr.current=r),br&&(br.current=r)},...function(){if(!c){const r=ar&&!P,e={role:"radiogroup","aria-required":r};return r&&(e["aria-invalid"]=Sr<=0),"string"==typeof lr&&lr.length>0?e["aria-labelledby"]=lr:e["aria-label"]=dr,e}return{role:"img","aria-label":dr}}(),...l,children:xr.map(((t,n)=>{return r.jsxs(e.Fragment,{children:[r.jsx("div",{className:`${u.BOX} ${Vr.dynamicClassNames[n]}`,style:Vr.dynamicCssVars[n],...ae(n),...(s=n,vr?{...ne(s),...oe(s),...se(s),onFocus:r=>re(r,s),onBlur:r=>Qr(r)}:{}),children:r.jsx(_,{...ie(n)})}),Cr&&n===xr.length-1&&r.jsx("div",{...(o=n+1,{className:u.RESET,role:"radio","aria-label":hr,"aria-checked":0===Sr,onClick:()=>f(0),onFocus:r=>{var e;re(r,o),null==(e=Xr.current)||e.classList.add(u.GROUP_RESET)},onBlur:r=>{var e;Qr(r),null==(e=Xr.current)||e.classList.remove(u.GROUP_RESET)},...oe(o),...ne(o),...P?{"aria-disabled":"true"}:{}})})]},t);var o,s}))})}));lr.displayName="Rating",exports.Heart=ir,exports.Rating=lr,exports.RoundedStar=or,exports.Star=tr,exports.StickerStar=ar,exports.ThinRoundedStar=sr,exports.ThinStar=nr; |
207
package.json
{ | ||
"name": "@smastrom/react-rating", | ||
"version": "1.2.2", | ||
"private": false, | ||
"keywords": [ | ||
"react", | ||
"rating", | ||
"react rating", | ||
"react-rating", | ||
"rating star", | ||
"rating-star", | ||
"rating-component", | ||
"rating component", | ||
"stars", | ||
"star", | ||
"star-component", | ||
"star component", | ||
"reviews", | ||
"review", | ||
"reviews-component", | ||
"reviews component", | ||
"react reviews", | ||
"react-reviews" | ||
], | ||
"homepage": "https://react-rating.onrender.com/", | ||
"bugs": { | ||
"url": "https://github.com/smastrom/react-rating/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/smastrom/react-rating" | ||
}, | ||
"license": "MIT", | ||
"author": "Simone Mastromattei <smastrom@proton.me>", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.js", | ||
"require": "./dist/index.umd.min.js" | ||
}, | ||
"./style.css": { | ||
"import": "./style.css", | ||
"require": "./style.css" | ||
}, | ||
"./style": { | ||
"import": "./style.css", | ||
"require": "./style.css" | ||
} | ||
}, | ||
"main": "dist/index.umd.min.js", | ||
"module": "dist/index.js", | ||
"browser": "dist/index.umd.min.js", | ||
"types": "dist/index.d.ts", | ||
"style": "style.css", | ||
"files": [ | ||
"dist", | ||
"style.css" | ||
], | ||
"scripts": { | ||
"prebuild": "rimraf dist style.css src/exportedTypes.d.ts", | ||
"build": "tsc && vite build && yarn declare", | ||
"postbuild": "cpy dist/style.css ./ --flat && cpy src/exportedTypes.d.ts dist --rename index.d.ts --flat && rimraf src/exportedTypes.d.ts dist/style.css", | ||
"coverage": "vitest run --coverage", | ||
"declare": "tsc src/exportedTypes --declaration --emitDeclarationOnly", | ||
"dev": "vite", | ||
"e2e": "playwright test -c playwright-ct.config.ts", | ||
"e2e:rtl": "IS_RTL=true yarn e2e", | ||
"lint": "yarn eslint . --ext .ts,.tsx && prettier --write \"**/*.{ts,tsx,css,md}\"", | ||
"prepare": "husky install", | ||
"test": "vitest" | ||
}, | ||
"lint-staged": { | ||
"*.{ts,tsx}": "eslint --cache --fix", | ||
"*.{ts,tsx,css,md}": "prettier --write" | ||
}, | ||
"devDependencies": { | ||
"@playwright/experimental-ct-react": "^1.29.0", | ||
"@playwright/test": "^1.29.0", | ||
"@testing-library/jest-dom": "^5.16.5", | ||
"@testing-library/react": "^13.4.0", | ||
"@testing-library/user-event": "^14.4.3", | ||
"@typescript-eslint/eslint-plugin": "^5.47.0", | ||
"@typescript-eslint/parser": "^5.47.0", | ||
"@vitejs/plugin-react": "^3.0.0", | ||
"@vitest/coverage-c8": "^0.26.0", | ||
"cpy-cli": "^4.2.0", | ||
"eslint": "^8.30.0", | ||
"eslint-plugin-react": "^7.31.11", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"husky": "^8.0.2", | ||
"jsdom": "^20.0.3", | ||
"lint-staged": "^13.1.0", | ||
"prettier": "^2.8.1", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"typescript": "^4.9.4", | ||
"vite": "^4.0.2", | ||
"vitest": "^0.26.1" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=16.8.0", | ||
"react-dom": ">=16.8.0" | ||
} | ||
} | ||
"name": "@smastrom/react-rating", | ||
"version": "1.3.0", | ||
"private": false, | ||
"keywords": [ | ||
"react", | ||
"rating", | ||
"react rating", | ||
"react-rating", | ||
"rating star", | ||
"rating-star", | ||
"rating-component", | ||
"rating component", | ||
"stars", | ||
"star", | ||
"star-component", | ||
"star component", | ||
"reviews", | ||
"review", | ||
"reviews-component", | ||
"reviews component", | ||
"react reviews", | ||
"react-reviews" | ||
], | ||
"homepage": "https://react-rating.onrender.com/", | ||
"bugs": { | ||
"url": "https://github.com/smastrom/react-rating/issues" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/smastrom/react-rating" | ||
}, | ||
"license": "MIT", | ||
"author": "Simone Mastromattei <smastrom@proton.me>", | ||
"exports": { | ||
".": { | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.js" | ||
}, | ||
"./style.css": "./style.css", | ||
"./style": "./style.css", | ||
"./styles.css": "./style.css", | ||
"./styles": "./style.css" | ||
}, | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"browser": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"style": "style.css", | ||
"files": [ | ||
"dist", | ||
"style.css" | ||
], | ||
"lint-staged": { | ||
"*.{ts,tsx}": "eslint --cache --fix", | ||
"*.{ts,tsx,css,md}": "prettier --write" | ||
}, | ||
"devDependencies": { | ||
"@playwright/experimental-ct-react": "1.29.0", | ||
"@playwright/test": "1.29.0", | ||
"@rollup/plugin-terser": "^0.4.0", | ||
"@testing-library/dom": "^9.2.0", | ||
"@testing-library/jest-dom": "^5.16.5", | ||
"@testing-library/react": "^14.0.0", | ||
"@testing-library/user-event": "^14.4.3", | ||
"@types/node": "^18.15.9", | ||
"@types/react": "^18.0.29", | ||
"@types/react-dom": "^18.0.11", | ||
"@types/testing-library__jest-dom": "^5.14.5", | ||
"@typescript-eslint/eslint-plugin": "^5.56.0", | ||
"@typescript-eslint/parser": "^5.56.0", | ||
"@vitejs/plugin-react": "^3.1.0", | ||
"@vitest/coverage-c8": "^0.29.7", | ||
"cpy-cli": "^4.2.0", | ||
"eslint": "^8.36.0", | ||
"eslint-plugin-react": "^7.32.2", | ||
"eslint-plugin-react-hooks": "^4.6.0", | ||
"husky": "^8.0.3", | ||
"jsdom": "^21.1.1", | ||
"lint-staged": "^13.2.0", | ||
"prettier": "^2.8.7", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"rimraf": "^4.4.1", | ||
"typescript": "^5.0.2", | ||
"vite": "^4.2.1", | ||
"vitest": "^0.29.7" | ||
}, | ||
"peerDependencies": { | ||
"react": ">=17", | ||
"react-dom": ">=17" | ||
}, | ||
"scripts": { | ||
"prebuild": "rimraf dist style.css src/exportedTypes.d.ts", | ||
"build": "tsc && vite build && pnpm declare", | ||
"postbuild": "cpy dist/style.css ./ --flat && cpy src/exportedTypes.d.ts dist --rename index.d.ts --flat && rimraf src/exportedTypes.d.ts dist/style.css", | ||
"coverage": "vitest run --coverage", | ||
"declare": "tsc src/exportedTypes --declaration --emitDeclarationOnly", | ||
"dev": "vite", | ||
"test": "vitest", | ||
"test:ct": "playwright test -c playwright-ct.config.ts", | ||
"test:ct:rtl": "IS_RTL=true pnpm test:ct", | ||
"lint": "eslint . --ext .ts,.tsx && prettier --write \"**/*.{ts,tsx,css,md}\"" | ||
} | ||
} |
364
README.md
@@ -18,13 +18,13 @@ ![react-rating-version](https://img.shields.io/npm/v/@smastrom/react-rating?color=22C55E) ![react-rating-build-workflow](https://img.shields.io/github/actions/workflow/status/smastrom/react-rating/build.yml?branch=main&color=22C55E) | ||
- **Use any SVG**: No headaches, icon fonts or packages to install in order to use your favorite shapes. | ||
- Endless possibilities of customization | ||
- Most common rating shapes included | ||
- Zero-config smart half-fill | ||
- Dead simple per-active-item styling | ||
- Built with accessibility in mind | ||
- Truly responsive and mobile-first | ||
- Controllable with React Hook Form | ||
- Simple DOM structure | ||
- Zero-config RTL support | ||
- Works with SSR | ||
- **Use any SVG**: No headaches, icon fonts or packages to install in order to use your favorite shapes. | ||
- Endless possibilities of customization | ||
- Most common rating shapes included | ||
- Zero-config smart half-fill | ||
- Dead simple per-active-item styling | ||
- Built with accessibility in mind | ||
- Truly responsive and mobile-first | ||
- Controllable with React Hook Form | ||
- Simple DOM structure | ||
- Zero-config RTL support | ||
- Works with SSR | ||
@@ -35,6 +35,14 @@ <br/> | ||
```console | ||
```zsh | ||
pnpm add @smastrom/react-rating | ||
``` | ||
```zsh | ||
yarn add @smastrom/react-rating | ||
``` | ||
```zsh | ||
npm i @smastrom/react-rating | ||
``` | ||
<br /> | ||
@@ -52,3 +60,3 @@ | ||
> Importing the CSS **only once** (usually _main.js_ or _App.jsx_) is enough to use Rating in any component of your App. | ||
> Importing the CSS **only once** (most likely _main.js_ or _App.jsx_) is enough to use Rating in any other component of your App. | ||
@@ -177,5 +185,5 @@ <details><summary><strong>Remix</strong></summary> | ||
function App() { | ||
const [rating, setRating] = useState(0) // Initial value | ||
const [rating, setRating] = useState(0) // Initial value | ||
return <Rating style={{ maxWidth: 250 }} value={rating} onChange={setRating} /> | ||
return <Rating style={{ maxWidth: 250 }} value={rating} onChange={setRating} /> | ||
} | ||
@@ -191,3 +199,3 @@ ``` | ||
.my-rating-class { | ||
max-width: 600px; | ||
max-width: 600px; | ||
} | ||
@@ -202,5 +210,5 @@ ``` | ||
function App() { | ||
const [rating, setRating] = useState(0) | ||
const [rating, setRating] = useState(0) | ||
return <Rating className="my-rating-class" value={rating} onChange={setRating} /> | ||
return <Rating className="my-rating-class" value={rating} onChange={setRating} /> | ||
} | ||
@@ -230,4 +238,4 @@ ``` | ||
| :green_circle: | `value` | An integer from 0 to `items`. It can be a float if `readOnly` is **true**. | number | undefined | :white_check_mark: | | ||
| :large_blue_circle: | `onChange` | Setter or custom function to update the rating. | RatingChange | undefined | Only if `readOnly` is **false** | | ||
| :large_blue_circle: | `onHoverChange` | Callback to execute while navigating the rating items. | (hoveredValue: number) => void | noop | :x: | | ||
| :large_blue_circle: | `onChange` | Setter or custom function to update the rating. | RatingChange | () => {} | Only if `readOnly` is **false** | | ||
| :large_blue_circle: | `onHoverChange` | Callback to execute while navigating the rating items. | (hoveredValue: number) => void | () => {} | :x: | | ||
| :green_circle: | `items` | Rating items to display. | 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 \| 10 | 5 | :x: | | ||
@@ -259,9 +267,9 @@ | :green_circle: | `readOnly` | Whether to render an accessible image element or not. | boolean | false | :x: | | ||
| :thinking: | Prop | Description | Type | Default | Required | | ||
| ------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------- | -------- | | ||
| :green_circle: | `invisibleLabel` | Accessible label of the rating group / image. | string | `Rating` or `Rated <value> on <items>` if `readOnly` is **true** | :x: | | ||
| :large_blue_circle: | `invisibleItemLabels` | Accessible labels of each each rating item. | string[] | `Rate 1`, `Rate 2`... | :x: | | ||
| :large_blue_circle: | `visibleLabelId` | DOM ID of the element used as rating group label. If set, takes precedence over `invisibleLabel`. | string | undefined | :x: | | ||
| :large_blue_circle: | `visibleItemLabelIds` | DOM IDs of the elements used as labels for each rating item. If set, takes precedence over `invisibleItemLabels`. | string[] | undefined | :x: | | ||
| :large_blue_circle: | `resetLabel` | Accessible label of the reset radio button. | string | `No Rating` | :x: | | ||
| :thinking: | Prop | Description | Type | Default | Required | | ||
| ------------------- | --------------------- | ----------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------- | -------- | | ||
| :green_circle: | `invisibleLabel` | Accessible label of the rating group / image. | string | • `Rating Selection` (radioGroup) <br /> • `Rated {value} on {items}` (readOnly) | :x: | | ||
| :large_blue_circle: | `invisibleItemLabels` | Accessible labels of each rating item. | string[] | `Rate 1`, `Rate 2`... | :x: | | ||
| :large_blue_circle: | `visibleLabelId` | DOM ID of the element used as rating group label. If set, takes precedence over `invisibleLabel`. | string | undefined | :x: | | ||
| :large_blue_circle: | `visibleItemLabelIds` | DOM IDs of the elements used as labels for each rating item. If set, takes precedence over `invisibleItemLabels`. | string[] | undefined | :x: | | ||
| :large_blue_circle: | `resetLabel` | Accessible label of the reset radio button. | string | `Reset Rating` | :x: | | ||
@@ -277,4 +285,4 @@ <br /> | ||
type RatingChange = | ||
| React.Dispatch<React.SetStateAction<number>> | ||
| ((selectedValue: number) => void | Promise<void>) | ||
| React.Dispatch<React.SetStateAction<number>> | ||
| ((selectedValue: number) => void | Promise<void>) | ||
``` | ||
@@ -290,5 +298,5 @@ | ||
function App() { | ||
const [rating, setRating] = useState(0) | ||
const [rating, setRating] = useState(0) | ||
return <Rating value={rating} onChange={setRating} /> | ||
return <Rating value={rating} onChange={setRating} /> | ||
} | ||
@@ -303,21 +311,21 @@ ``` | ||
function App() { | ||
const [state, setState] = useState({ | ||
review: '', | ||
rating: 0 // Initial value | ||
}) | ||
const [state, setState] = useState({ | ||
review: '', | ||
rating: 0 // Initial value | ||
}) | ||
function handleChange(selectedValue) { | ||
// 1. Logs the selected rating (1, 2, 3...) | ||
console.log(selectedValue) | ||
function handleChange(selectedValue) { | ||
// 1. Logs the selected rating (1, 2, 3...) | ||
console.log(selectedValue) | ||
// 2. Do something with or without the value... | ||
// 2. Do something with or without the value... | ||
// 3. Update Rating UI | ||
setState((prevState) => ({ | ||
...prevState, | ||
rating: selectedValue | ||
})) | ||
} | ||
// 3. Update Rating UI | ||
setState((prevState) => ({ | ||
...prevState, | ||
rating: selectedValue | ||
})) | ||
} | ||
return <Rating onChange={handleChange} value={state.rating} /> | ||
return <Rating onChange={handleChange} value={state.rating} /> | ||
} | ||
@@ -339,2 +347,4 @@ ``` | ||
> :bulb: Don't like the default focus style? Check [here](#troubleshooting) how to customize it. | ||
### 2. Rating without reset | ||
@@ -352,8 +362,10 @@ | ||
- It is not possible to reset by clicking again on the selected rating or by using the invisible radio. | ||
- It is not possible to reset by clicking again on the selected rating or by using the invisible radio. | ||
- It is announced by screen readers that rating **is required**. | ||
- It is announced by screen readers that rating **is required**. | ||
- If value equals to 0, it is announced by screen readers that rating **is invalid** . | ||
- If value equals to 0, it is announced by screen readers that rating **is invalid** . | ||
> :bulb: Don't like the default focus style? Check [here](#troubleshooting) how to customize it. | ||
<br/> | ||
@@ -381,18 +393,13 @@ | ||
const myStyles = { | ||
itemShapes: ThinStar, | ||
activeFillColor: '#ffb700', | ||
inactiveFillColor: '#fbf1a9' | ||
itemShapes: ThinStar, | ||
activeFillColor: '#ffb700', | ||
inactiveFillColor: '#fbf1a9' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(0) | ||
const [rating, setRating] = useState(0) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 300 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
/> | ||
) | ||
return ( | ||
<Rating style={{ maxWidth: 300 }} value={rating} onChange={setRating} itemStyles={myStyles} /> | ||
) | ||
} | ||
@@ -409,16 +416,16 @@ ``` | ||
type ItemStyles = { | ||
itemShapes: JSX.Element | JSX.Element[] | ||
itemShapes: JSX.Element | JSX.Element[] | ||
itemStrokeWidth?: number | ||
boxBorderWidth?: number | ||
itemStrokeWidth?: number | ||
boxBorderWidth?: number | ||
activeFillColor?: string | string[] | ||
activeStrokeColor?: string | string[] | ||
activeBoxColor?: string | string[] | ||
activeBoxBorderColor?: string | string[] | ||
activeFillColor?: string | string[] | ||
activeStrokeColor?: string | string[] | ||
activeBoxColor?: string | string[] | ||
activeBoxBorderColor?: string | string[] | ||
inactiveFillColor?: string | ||
inactiveStrokeColor?: string | ||
inactiveBoxColor?: string | ||
inactiveBoxBorderColor?: string | ||
inactiveFillColor?: string | ||
inactiveStrokeColor?: string | ||
inactiveBoxColor?: string | ||
inactiveBoxBorderColor?: string | ||
} | ||
@@ -433,22 +440,17 @@ ``` | ||
const CustomStar = ( | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
) | ||
const myStyles = { | ||
itemShapes: CustomStar, | ||
activeFillColor: '#22C55E', | ||
inactiveFillColor: '#BBF7D0' | ||
itemShapes: CustomStar, | ||
activeFillColor: '#22C55E', | ||
inactiveFillColor: '#BBF7D0' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(4) | ||
const [rating, setRating] = useState(4) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 300 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
/> | ||
) | ||
return ( | ||
<Rating style={{ maxWidth: 300 }} value={rating} onChange={setRating} itemStyles={myStyles} /> | ||
) | ||
} | ||
@@ -469,9 +471,9 @@ ``` | ||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> | ||
<path | ||
fill="currentColor" | ||
stroke="2" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" | ||
/> | ||
<path | ||
fill="currentColor" | ||
stroke="2" | ||
stroke-linecap="round" | ||
stroke-linejoin="round" | ||
d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" | ||
/> | ||
</svg> | ||
@@ -484,25 +486,20 @@ ``` | ||
const CustomStar = ( | ||
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" /> | ||
<path d="M3.612 15.443c-.386.198-.824-.149-.746-.592l.83-4.73L.173 6.765c-.329-.314-.158-.888.283-.95l4.898-.696L7.538.792c.197-.39.73-.39.927 0l2.184 4.327 4.898.696c.441.062.612.636.282.95l-3.522 3.356.83 4.73c.078.443-.36.79-.746.592L8 13.187l-4.389 2.256z" /> | ||
) | ||
const myStyles = { | ||
itemShapes: CustomStar, | ||
itemStrokeWidth: 2, | ||
activeFillColor: 'LightSeaGreen', | ||
activeStrokeColor: '#99F6E4', | ||
inactiveFillColor: '#99F6E4', | ||
inactiveStrokeColor: 'LightSeaGreen' | ||
itemShapes: CustomStar, | ||
itemStrokeWidth: 2, | ||
activeFillColor: 'LightSeaGreen', | ||
activeStrokeColor: '#99F6E4', | ||
inactiveFillColor: '#99F6E4', | ||
inactiveStrokeColor: 'LightSeaGreen' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(4) | ||
const [rating, setRating] = useState(4) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 300 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
/> | ||
) | ||
return ( | ||
<Rating style={{ maxWidth: 300 }} value={rating} onChange={setRating} itemStyles={myStyles} /> | ||
) | ||
} | ||
@@ -521,16 +518,16 @@ ``` | ||
type ItemStyles = { | ||
itemShapes: JSX.Element | JSX.Element[] | ||
itemShapes: JSX.Element | JSX.Element[] | ||
itemStrokeWidth?: number | ||
boxBorderWidth?: number | ||
itemStrokeWidth?: number | ||
boxBorderWidth?: number | ||
activeFillColor?: string | string[] | ||
activeStrokeColor?: string | string[] | ||
activeBoxColor?: string | string[] | ||
activeBoxBorderColor?: string | string[] | ||
activeFillColor?: string | string[] | ||
activeStrokeColor?: string | string[] | ||
activeBoxColor?: string | string[] | ||
activeBoxBorderColor?: string | string[] | ||
inactiveFillColor?: string | ||
inactiveStrokeColor?: string | ||
inactiveBoxColor?: string | ||
inactiveBoxBorderColor?: string | ||
inactiveFillColor?: string | ||
inactiveStrokeColor?: string | ||
inactiveBoxColor?: string | ||
inactiveBoxBorderColor?: string | ||
} | ||
@@ -545,22 +542,17 @@ ``` | ||
const CustomStar = ( | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
) | ||
const myStyles = { | ||
itemShapes: CustomStar, | ||
activeFillColor: '#22C55E', | ||
inactiveFillColor: '#BBF7D0' | ||
itemShapes: CustomStar, | ||
activeFillColor: '#22C55E', | ||
inactiveFillColor: '#BBF7D0' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(4) | ||
const [rating, setRating] = useState(4) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 300 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
/> | ||
) | ||
return ( | ||
<Rating style={{ maxWidth: 300 }} value={rating} onChange={setRating} itemStyles={myStyles} /> | ||
) | ||
} | ||
@@ -578,8 +570,8 @@ ``` | ||
const defaultItemStyles = { | ||
itemShapes: Star, | ||
itemStrokeWidth: 2, | ||
activeFillColor: '#ffb23f', | ||
activeStrokeColor: '#e17b21', | ||
inactiveFillColor: '#fff7ed', | ||
inactiveStrokeColor: '#e17b21' | ||
itemShapes: Star, | ||
itemStrokeWidth: 2, | ||
activeFillColor: '#ffb23f', | ||
activeStrokeColor: '#e17b21', | ||
inactiveFillColor: '#fff7ed', | ||
inactiveStrokeColor: '#e17b21' | ||
} | ||
@@ -615,9 +607,9 @@ ``` | ||
const Star = ( | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
<polygon points="478.53 189 318.53 152.69 239.26 0 160 152.69 0 189 111.02 303.45 84 478.53 239.26 396.63 394.53 478.53 367.51 303.45 478.53 189" /> | ||
) | ||
const myStyles: ItemStyles = { | ||
itemShapes: Star, | ||
activeFillColor: 'green', | ||
inactiveFillColor: 'gray' | ||
itemShapes: Star, | ||
activeFillColor: 'green', | ||
inactiveFillColor: 'gray' | ||
} | ||
@@ -652,28 +644,28 @@ ``` | ||
const SadFace = ( | ||
<path d="M12.0000002,1.99896738 C17.523704,1.99896738 22.0015507,6.47681407 22.0015507,12.0005179 C22.0015507,17.5242217 17.523704,22.0020684 12.0000002,22.0020684 C6.47629639,22.0020684 1.99844971,17.5242217 1.99844971,12.0005179 C1.99844971,6.47681407 6.47629639,1.99896738 12.0000002,1.99896738 Z M12.0000002,3.49896738 C7.30472352,3.49896738 3.49844971,7.30524119 3.49844971,12.0005179 C3.49844971,16.6957946 7.30472352,20.5020684 12.0000002,20.5020684 C16.6952769,20.5020684 20.5015507,16.6957946 20.5015507,12.0005179 C20.5015507,7.30524119 16.6952769,3.49896738 12.0000002,3.49896738 Z M12.0000001,13.4979816 C13.6312483,13.4979816 15.1603686,14.1528953 16.2810488,15.2934358 C16.5713583,15.5888901 16.5671876,16.0637455 16.2717333,16.354055 C15.976279,16.6443646 15.5014236,16.6401939 15.211114,16.3447396 C14.3696444,15.4883577 13.2246935,14.9979816 12.0000001,14.9979816 C10.7726114,14.9979816 9.62535029,15.4905359 8.78347552,16.3502555 C8.49366985,16.6462041 8.01882223,16.6511839 7.72287367,16.3613782 C7.4269251,16.0715726 7.4219453,15.5967249 7.71175097,15.3007764 C8.83296242,14.155799 10.3651558,13.4979816 12.0000001,13.4979816 Z M9.00044779,8.75115873 C9.69041108,8.75115873 10.2497368,9.3104845 10.2497368,10.0004478 C10.2497368,10.6904111 9.69041108,11.2497368 9.00044779,11.2497368 C8.3104845,11.2497368 7.75115873,10.6904111 7.75115873,10.0004478 C7.75115873,9.3104845 8.3104845,8.75115873 9.00044779,8.75115873 Z M15.0004478,8.75115873 C15.6904111,8.75115873 16.2497368,9.3104845 16.2497368,10.0004478 C16.2497368,10.6904111 15.6904111,11.2497368 15.0004478,11.2497368 C14.3104845,11.2497368 13.7511587,10.6904111 13.7511587,10.0004478 C13.7511587,9.3104845 14.3104845,8.75115873 15.0004478,8.75115873 Z" /> | ||
<path d="M12.0000002,1.99896738 C17.523704,1.99896738 22.0015507,6.47681407 22.0015507,12.0005179 C22.0015507,17.5242217 17.523704,22.0020684 12.0000002,22.0020684 C6.47629639,22.0020684 1.99844971,17.5242217 1.99844971,12.0005179 C1.99844971,6.47681407 6.47629639,1.99896738 12.0000002,1.99896738 Z M12.0000002,3.49896738 C7.30472352,3.49896738 3.49844971,7.30524119 3.49844971,12.0005179 C3.49844971,16.6957946 7.30472352,20.5020684 12.0000002,20.5020684 C16.6952769,20.5020684 20.5015507,16.6957946 20.5015507,12.0005179 C20.5015507,7.30524119 16.6952769,3.49896738 12.0000002,3.49896738 Z M12.0000001,13.4979816 C13.6312483,13.4979816 15.1603686,14.1528953 16.2810488,15.2934358 C16.5713583,15.5888901 16.5671876,16.0637455 16.2717333,16.354055 C15.976279,16.6443646 15.5014236,16.6401939 15.211114,16.3447396 C14.3696444,15.4883577 13.2246935,14.9979816 12.0000001,14.9979816 C10.7726114,14.9979816 9.62535029,15.4905359 8.78347552,16.3502555 C8.49366985,16.6462041 8.01882223,16.6511839 7.72287367,16.3613782 C7.4269251,16.0715726 7.4219453,15.5967249 7.71175097,15.3007764 C8.83296242,14.155799 10.3651558,13.4979816 12.0000001,13.4979816 Z M9.00044779,8.75115873 C9.69041108,8.75115873 10.2497368,9.3104845 10.2497368,10.0004478 C10.2497368,10.6904111 9.69041108,11.2497368 9.00044779,11.2497368 C8.3104845,11.2497368 7.75115873,10.6904111 7.75115873,10.0004478 C7.75115873,9.3104845 8.3104845,8.75115873 9.00044779,8.75115873 Z M15.0004478,8.75115873 C15.6904111,8.75115873 16.2497368,9.3104845 16.2497368,10.0004478 C16.2497368,10.6904111 15.6904111,11.2497368 15.0004478,11.2497368 C14.3104845,11.2497368 13.7511587,10.6904111 13.7511587,10.0004478 C13.7511587,9.3104845 14.3104845,8.75115873 15.0004478,8.75115873 Z" /> | ||
) | ||
const SmilingFace = ( | ||
<path d="M12.0000002,1.99896738 C17.523704,1.99896738 22.0015507,6.47681407 22.0015507,12.0005179 C22.0015507,17.5242217 17.523704,22.0020684 12.0000002,22.0020684 C6.47629639,22.0020684 1.99844971,17.5242217 1.99844971,12.0005179 C1.99844971,6.47681407 6.47629639,1.99896738 12.0000002,1.99896738 Z M12.0000002,3.49896738 C7.30472352,3.49896738 3.49844971,7.30524119 3.49844971,12.0005179 C3.49844971,16.6957946 7.30472352,20.5020684 12.0000002,20.5020684 C16.6952769,20.5020684 20.5015507,16.6957946 20.5015507,12.0005179 C20.5015507,7.30524119 16.6952769,3.49896738 12.0000002,3.49896738 Z M8.46174078,14.7838355 C9.31087697,15.8615555 10.6018926,16.5020843 11.9999849,16.5020843 C13.396209,16.5020843 14.6856803,15.8632816 15.5349376,14.7880078 C15.7916692,14.4629512 16.2633016,14.4075628 16.5883582,14.6642944 C16.9134148,14.9210259 16.9688032,15.3926584 16.7120717,15.717715 C15.5813083,17.1494133 13.8601276,18.0020843 11.9999849,18.0020843 C10.1373487,18.0020843 8.41411759,17.1471146 7.28351576,15.7121597 C7.02716611,15.3868018 7.08310832,14.9152347 7.40846617,14.6588851 C7.73382403,14.4025354 8.20539113,14.4584777 8.46174078,14.7838355 Z M9.00044779,8.75115873 C9.69041108,8.75115873 10.2497368,9.3104845 10.2497368,10.0004478 C10.2497368,10.6904111 9.69041108,11.2497368 9.00044779,11.2497368 C8.3104845,11.2497368 7.75115873,10.6904111 7.75115873,10.0004478 C7.75115873,9.3104845 8.3104845,8.75115873 9.00044779,8.75115873 Z M15.0004478,8.75115873 C15.6904111,8.75115873 16.2497368,9.3104845 16.2497368,10.0004478 C16.2497368,10.6904111 15.6904111,11.2497368 15.0004478,11.2497368 C14.3104845,11.2497368 13.7511587,10.6904111 13.7511587,10.0004478 C13.7511587,9.3104845 14.3104845,8.75115873 15.0004478,8.75115873 Z" /> | ||
<path d="M12.0000002,1.99896738 C17.523704,1.99896738 22.0015507,6.47681407 22.0015507,12.0005179 C22.0015507,17.5242217 17.523704,22.0020684 12.0000002,22.0020684 C6.47629639,22.0020684 1.99844971,17.5242217 1.99844971,12.0005179 C1.99844971,6.47681407 6.47629639,1.99896738 12.0000002,1.99896738 Z M12.0000002,3.49896738 C7.30472352,3.49896738 3.49844971,7.30524119 3.49844971,12.0005179 C3.49844971,16.6957946 7.30472352,20.5020684 12.0000002,20.5020684 C16.6952769,20.5020684 20.5015507,16.6957946 20.5015507,12.0005179 C20.5015507,7.30524119 16.6952769,3.49896738 12.0000002,3.49896738 Z M8.46174078,14.7838355 C9.31087697,15.8615555 10.6018926,16.5020843 11.9999849,16.5020843 C13.396209,16.5020843 14.6856803,15.8632816 15.5349376,14.7880078 C15.7916692,14.4629512 16.2633016,14.4075628 16.5883582,14.6642944 C16.9134148,14.9210259 16.9688032,15.3926584 16.7120717,15.717715 C15.5813083,17.1494133 13.8601276,18.0020843 11.9999849,18.0020843 C10.1373487,18.0020843 8.41411759,17.1471146 7.28351576,15.7121597 C7.02716611,15.3868018 7.08310832,14.9152347 7.40846617,14.6588851 C7.73382403,14.4025354 8.20539113,14.4584777 8.46174078,14.7838355 Z M9.00044779,8.75115873 C9.69041108,8.75115873 10.2497368,9.3104845 10.2497368,10.0004478 C10.2497368,10.6904111 9.69041108,11.2497368 9.00044779,11.2497368 C8.3104845,11.2497368 7.75115873,10.6904111 7.75115873,10.0004478 C7.75115873,9.3104845 8.3104845,8.75115873 9.00044779,8.75115873 Z M15.0004478,8.75115873 C15.6904111,8.75115873 16.2497368,9.3104845 16.2497368,10.0004478 C16.2497368,10.6904111 15.6904111,11.2497368 15.0004478,11.2497368 C14.3104845,11.2497368 13.7511587,10.6904111 13.7511587,10.0004478 C13.7511587,9.3104845 14.3104845,8.75115873 15.0004478,8.75115873 Z" /> | ||
) | ||
const myStyles = { | ||
itemShapes: [SadFace, SmilingFace], | ||
activeFillColor: ['#da1600', '#61bb00'], | ||
inactiveFillColor: '#a8a8a8' | ||
itemShapes: [SadFace, SmilingFace], | ||
activeFillColor: ['#da1600', '#61bb00'], | ||
inactiveFillColor: '#a8a8a8' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(0) | ||
const [rating, setRating] = useState(0) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 200 }} | ||
value={rating} | ||
onChange={setRating} | ||
items={2} | ||
itemStyles={myStyles} | ||
highlightOnlySelected | ||
/> | ||
) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 200 }} | ||
value={rating} | ||
onChange={setRating} | ||
items={2} | ||
itemStyles={myStyles} | ||
highlightOnlySelected | ||
/> | ||
) | ||
} | ||
@@ -686,31 +678,31 @@ ``` | ||
const Star = ( | ||
<path d="M62 25.154H39.082L32 3l-7.082 22.154H2l18.541 13.693L13.459 61L32 47.309L50.541 61l-7.082-22.152L62 25.154z" /> | ||
<path d="M62 25.154H39.082L32 3l-7.082 22.154H2l18.541 13.693L13.459 61L32 47.309L50.541 61l-7.082-22.152L62 25.154z" /> | ||
) | ||
const myStyles = { | ||
itemShapes: Star, | ||
boxBorderWidth: 3, | ||
itemShapes: Star, | ||
boxBorderWidth: 3, | ||
activeFillColor: ['#FEE2E2', '#FFEDD5', '#FEF9C3', '#ECFCCB', '#D1FAE5'], | ||
activeBoxColor: ['#da1600', '#db711a', '#dcb000', '#61bb00', '#009664'], | ||
activeBoxBorderColor: ['#c41400', '#d05e00', '#cca300', '#498d00', '#00724c'], | ||
activeFillColor: ['#FEE2E2', '#FFEDD5', '#FEF9C3', '#ECFCCB', '#D1FAE5'], | ||
activeBoxColor: ['#da1600', '#db711a', '#dcb000', '#61bb00', '#009664'], | ||
activeBoxBorderColor: ['#c41400', '#d05e00', '#cca300', '#498d00', '#00724c'], | ||
inactiveFillColor: 'white', | ||
inactiveBoxColor: '#dddddd', | ||
inactiveBoxBorderColor: '#a8a8a8' | ||
inactiveFillColor: 'white', | ||
inactiveBoxColor: '#dddddd', | ||
inactiveBoxBorderColor: '#a8a8a8' | ||
} | ||
function App() { | ||
const [rating, setRating] = useState(0) | ||
const [rating, setRating] = useState(0) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 500 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
radius="large" | ||
spaceInside="large" | ||
/> | ||
) | ||
return ( | ||
<Rating | ||
style={{ maxWidth: 500 }} | ||
value={rating} | ||
onChange={setRating} | ||
itemStyles={myStyles} | ||
radius="large" | ||
spaceInside="large" | ||
/> | ||
) | ||
} | ||
@@ -770,7 +762,7 @@ ``` | ||
- Rating must be confirmed with `Enter/Space` keys and cannot be set directly with arrows like native radios. | ||
- Rating must be confirmed with `Enter/Space` keys and cannot be set directly with arrows like native radios. | ||
- `onChange` is called on both `Enter/Space` keys and click. | ||
- `onChange` is called on both `Enter/Space` keys and click. | ||
- `onHoverChange` is called on `← → ↑ ↓` navigation, mouse hovering, focus-from / blur-to a _non-react-rating_ element. | ||
- `onHoverChange` is called on `← → ↑ ↓` navigation, mouse hovering, focus-from / blur-to a _non-react-rating_ element. | ||
@@ -823,3 +815,3 @@ ### Disabled state | ||
.rr--box:focus-visible .rr--svg { | ||
/* Your styles */ | ||
/* Your styles */ | ||
} | ||
@@ -832,3 +824,3 @@ ``` | ||
.rr--focus-reset { | ||
/* Your styles */ | ||
/* Your styles */ | ||
} | ||
@@ -841,7 +833,7 @@ ``` | ||
.rr--focus-reset { | ||
outline: 6px double #0079ff; | ||
outline: 6px double #0079ff; | ||
} | ||
.rr--box:focus-visible .rr--svg { | ||
outline: 6px double #0079ff; | ||
outline: 6px double #0079ff; | ||
} | ||
@@ -856,2 +848,2 @@ ``` | ||
MIT Licensed. Copyright (c) Simone Mastromattei 2022. | ||
MIT — Copyright (c) 2022 - Present, Simone Mastromattei |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Copyleft License
License(Experimental) Copyleft license information was found
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No License Found
License(Experimental) License information could not be found
Found 1 instance in 1 package
Non-permissive License
License(Experimental) A license not known to be considered permissive was found
Found 1 instance in 1 package
72357
0
488
29
821
1