@spark-ui/components 15.0.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dialog/Dialog.d.ts +1 -0
- package/dist/dialog/index.js +1 -1
- package/dist/dialog/index.js.map +1 -1
- package/dist/dialog/index.mjs +19 -18
- package/dist/dialog/index.mjs.map +1 -1
- package/dist/rating/Rating.d.ts +17 -12
- package/dist/rating/RatingStar.d.ts +12 -3
- package/dist/rating/index.js +1 -1
- package/dist/rating/index.js.map +1 -1
- package/dist/rating/index.mjs +210 -163
- package/dist/rating/index.mjs.map +1 -1
- package/dist/rating/types.d.ts +2 -1
- package/dist/rating/utils.d.ts +1 -2
- package/dist/rating-display/RatingDisplay.d.ts +26 -0
- package/dist/rating-display/RatingDisplayContext.d.ts +12 -0
- package/dist/rating-display/RatingDisplayCount.d.ts +12 -0
- package/dist/rating-display/RatingDisplayStar.d.ts +16 -0
- package/dist/rating-display/RatingDisplayStars.d.ts +22 -0
- package/dist/rating-display/RatingDisplayValue.d.ts +13 -0
- package/dist/rating-display/index.d.mts +14 -0
- package/dist/rating-display/index.d.ts +14 -0
- package/dist/rating-display/index.js +2 -0
- package/dist/rating-display/index.js.map +1 -0
- package/dist/rating-display/index.mjs +150 -0
- package/dist/rating-display/index.mjs.map +1 -0
- package/dist/rating-display/types.d.ts +1 -0
- package/dist/rating-display/utils.d.ts +10 -0
- package/dist/switch/index.js +1 -1
- package/dist/switch/index.js.map +1 -1
- package/dist/switch/index.mjs +1 -1
- package/dist/switch/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/rating/index.mjs
CHANGED
|
@@ -1,41 +1,46 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useCombinedState as
|
|
3
|
-
import { cx as
|
|
4
|
-
import { useRef as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
{
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
false: ""
|
|
15
|
-
},
|
|
16
|
-
readOnly: {
|
|
17
|
-
true: "",
|
|
18
|
-
false: ""
|
|
19
|
-
},
|
|
20
|
-
gap: {
|
|
21
|
-
sm: ["after:w-[calc(100%+(var(--spacing-sm)))]", "last-of-type:after:content-none"],
|
|
22
|
-
md: ["after:w-[calc(100%+(var(--spacing-md)))]", "last-of-type:after:content-none"]
|
|
23
|
-
}
|
|
1
|
+
import { jsxs as K, jsx as n } from "react/jsx-runtime";
|
|
2
|
+
import { useCombinedState as X } from "@spark-ui/hooks/use-combined-state";
|
|
3
|
+
import { cx as S, cva as L } from "class-variance-authority";
|
|
4
|
+
import { useState as _, useRef as Y, useId as Z, useCallback as j } from "react";
|
|
5
|
+
import { useFormFieldControl as ee } from "../form-field/index.mjs";
|
|
6
|
+
import { StarFill as ae } from "@spark-ui/icons/StarFill";
|
|
7
|
+
import { StarOutline as te } from "@spark-ui/icons/StarOutline";
|
|
8
|
+
import { I as q } from "../Icon-Ck-dhfLd.mjs";
|
|
9
|
+
const re = S("[&_>_div]:peer-hover:w-0!"), se = L(["peer after:inset-0 group relative after:block after:absolute"], {
|
|
10
|
+
variants: {
|
|
11
|
+
disabled: {
|
|
12
|
+
true: "opacity-dim-3",
|
|
13
|
+
false: ""
|
|
24
14
|
},
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
15
|
+
readOnly: {
|
|
16
|
+
true: "",
|
|
17
|
+
false: ""
|
|
18
|
+
},
|
|
19
|
+
gap: {
|
|
20
|
+
sm: ["after:w-[calc(100%+(var(--spacing-sm)))]", "last-of-type:after:content-none"],
|
|
21
|
+
md: ["after:w-[calc(100%+(var(--spacing-md)))]", "last-of-type:after:content-none"]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
compoundVariants: [
|
|
25
|
+
{
|
|
34
26
|
readOnly: !1,
|
|
35
|
-
|
|
27
|
+
disabled: !1,
|
|
28
|
+
className: S(
|
|
29
|
+
re,
|
|
30
|
+
"cursor-pointer transition-all duration-200 scale-100",
|
|
31
|
+
/* mouseOver / focusIn => scale 150 */
|
|
32
|
+
"hover:scale-150 focus-visible:scale-150",
|
|
33
|
+
/* mouseOut / focusOut / selection (click) => no scale; mouseMove clears selection => scale again */
|
|
34
|
+
"[&[data-suppress-scale]]:hover:scale-100 [&[data-suppress-scale]]:focus-visible:scale-100"
|
|
35
|
+
)
|
|
36
36
|
}
|
|
37
|
+
],
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
disabled: !1,
|
|
40
|
+
readOnly: !1,
|
|
41
|
+
gap: "sm"
|
|
37
42
|
}
|
|
38
|
-
),
|
|
43
|
+
}), H = L("", {
|
|
39
44
|
variants: {
|
|
40
45
|
size: {
|
|
41
46
|
sm: "text-caption-link",
|
|
@@ -50,154 +55,196 @@ const F = f("[&_>_div]:peer-hover:w-0!"), q = k(
|
|
|
50
55
|
outlined: ["text-on-surface/dim-3"]
|
|
51
56
|
}
|
|
52
57
|
}
|
|
53
|
-
}),
|
|
58
|
+
}), ne = ({
|
|
54
59
|
value: e,
|
|
55
|
-
size:
|
|
56
|
-
disabled:
|
|
57
|
-
readOnly:
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
60
|
+
size: t,
|
|
61
|
+
disabled: r,
|
|
62
|
+
readOnly: o,
|
|
63
|
+
checked: i = !1,
|
|
64
|
+
ariaLabel: l,
|
|
65
|
+
ariaLabelledBy: c,
|
|
66
|
+
tabIndex: I,
|
|
67
|
+
onClick: u,
|
|
68
|
+
onKeyDown: v,
|
|
69
|
+
onMouseEnter: k,
|
|
70
|
+
children: w,
|
|
71
|
+
ref: f
|
|
72
|
+
}) => {
|
|
73
|
+
const h = !r && !o, [C, b] = _(!1), N = (x) => {
|
|
74
|
+
u?.(x), h && b(!0);
|
|
75
|
+
}, g = () => b(!1);
|
|
76
|
+
return /* @__PURE__ */ K(
|
|
77
|
+
"div",
|
|
78
|
+
{
|
|
79
|
+
ref: f,
|
|
80
|
+
role: "radio",
|
|
81
|
+
"aria-checked": i,
|
|
82
|
+
"aria-label": l,
|
|
83
|
+
"aria-labelledby": c,
|
|
84
|
+
tabIndex: I,
|
|
85
|
+
"data-spark-component": "rating-star",
|
|
86
|
+
"data-part": "star",
|
|
87
|
+
...h && C && { "data-suppress-scale": "" },
|
|
88
|
+
className: se({
|
|
89
|
+
gap: t === "lg" ? "md" : "sm",
|
|
90
|
+
disabled: r,
|
|
91
|
+
readOnly: o
|
|
92
|
+
}),
|
|
93
|
+
onClick: N,
|
|
94
|
+
onKeyDown: v,
|
|
95
|
+
onMouseEnter: k,
|
|
96
|
+
onMouseLeave: g,
|
|
97
|
+
onMouseMove: g,
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ n(
|
|
100
|
+
"div",
|
|
101
|
+
{
|
|
102
|
+
className: S(
|
|
103
|
+
"z-raised absolute overflow-hidden",
|
|
104
|
+
"group-[[data-part=star][data-hovered]]:overflow-visible"
|
|
105
|
+
),
|
|
106
|
+
style: { width: e * 100 + "%" },
|
|
107
|
+
children: /* @__PURE__ */ n(
|
|
108
|
+
q,
|
|
109
|
+
{
|
|
110
|
+
className: H({
|
|
111
|
+
size: t,
|
|
112
|
+
design: "filled"
|
|
113
|
+
}),
|
|
114
|
+
children: /* @__PURE__ */ n(ae, {})
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
),
|
|
119
|
+
/* @__PURE__ */ n(q, { className: H({ size: t, design: "outlined" }), children: /* @__PURE__ */ n(te, {}) }),
|
|
120
|
+
w
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
function oe({ value: e, index: t }) {
|
|
103
126
|
if (e === void 0) return 0;
|
|
104
|
-
const
|
|
105
|
-
return
|
|
127
|
+
const r = t + 1;
|
|
128
|
+
return e >= r ? 1 : 0;
|
|
129
|
+
}
|
|
130
|
+
function ie(e, t) {
|
|
131
|
+
const r = e.slice(0, t), o = e.slice(t);
|
|
132
|
+
return [r, o];
|
|
106
133
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return
|
|
134
|
+
const le = (e) => e === void 0 || !Number.isInteger(e) || e < 1 ? 0 : Math.min(5, Math.max(1, e));
|
|
135
|
+
function ce(e, t, r, o) {
|
|
136
|
+
return (i) => {
|
|
137
|
+
if (o)
|
|
138
|
+
switch (i.key) {
|
|
139
|
+
case "ArrowRight":
|
|
140
|
+
case "ArrowDown":
|
|
141
|
+
i.preventDefault();
|
|
142
|
+
const l = Math.min(4, e + 1);
|
|
143
|
+
r(l + 1), t.current[l]?.focus();
|
|
144
|
+
break;
|
|
145
|
+
case "ArrowLeft":
|
|
146
|
+
case "ArrowUp":
|
|
147
|
+
i.preventDefault();
|
|
148
|
+
const c = Math.max(0, e - 1);
|
|
149
|
+
r(c + 1), t.current[c]?.focus();
|
|
150
|
+
break;
|
|
151
|
+
case " ":
|
|
152
|
+
i.preventDefault(), r(e + 1);
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
function de(e, t) {
|
|
158
|
+
return t >= 1 ? t - 1 === e ? 0 : -1 : e === 0 ? 0 : -1;
|
|
110
159
|
}
|
|
111
|
-
const
|
|
160
|
+
const ye = ({
|
|
112
161
|
defaultValue: e,
|
|
113
|
-
value:
|
|
114
|
-
onValueChange:
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
name:
|
|
119
|
-
id:
|
|
120
|
-
"aria-label":
|
|
121
|
-
|
|
122
|
-
|
|
162
|
+
value: t,
|
|
163
|
+
onValueChange: r,
|
|
164
|
+
disabled: o,
|
|
165
|
+
readOnly: i,
|
|
166
|
+
required: l,
|
|
167
|
+
name: c,
|
|
168
|
+
id: I,
|
|
169
|
+
"aria-label": u,
|
|
170
|
+
getStarLabel: v,
|
|
171
|
+
ref: k,
|
|
172
|
+
...w
|
|
123
173
|
}) => {
|
|
124
|
-
const
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
174
|
+
const {
|
|
175
|
+
labelId: f,
|
|
176
|
+
isInvalid: h,
|
|
177
|
+
isRequired: C,
|
|
178
|
+
description: b,
|
|
179
|
+
name: N,
|
|
180
|
+
disabled: g,
|
|
181
|
+
readOnly: x
|
|
182
|
+
} = ee(), d = Y([]), R = Z(), [O, $] = _(null), [J, A] = X(t, e, r), y = le(J ?? 0), E = o ?? g, F = i ?? x, z = l !== void 0 ? l : C, V = c ?? N, m = !(E || F), D = v !== void 0 || u !== void 0, B = O !== null ? O + 1 : y;
|
|
183
|
+
function P(s) {
|
|
184
|
+
if (!m) return;
|
|
185
|
+
const a = s + 1;
|
|
186
|
+
A(a), d.current[s]?.focus();
|
|
130
187
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
188
|
+
const T = j(
|
|
189
|
+
(s) => ce(s, d, A, m),
|
|
190
|
+
[m, A]
|
|
191
|
+
);
|
|
192
|
+
function U({ currentTarget: s }) {
|
|
193
|
+
const a = d.current.findIndex((p) => p === s);
|
|
194
|
+
$(a >= 0 ? a : null);
|
|
195
|
+
const [M, W] = ie(d.current, a + 1);
|
|
196
|
+
M.forEach((p) => p?.setAttribute("data-hovered", "")), W.forEach((p) => p?.removeAttribute("data-hovered"));
|
|
140
197
|
}
|
|
141
|
-
|
|
142
|
-
|
|
198
|
+
const G = j(
|
|
199
|
+
(s) => (a) => {
|
|
200
|
+
d.current[s] = a;
|
|
201
|
+
},
|
|
202
|
+
[]
|
|
203
|
+
);
|
|
204
|
+
function Q() {
|
|
205
|
+
$(null), d.current.forEach((s) => s?.removeAttribute("data-hovered"));
|
|
143
206
|
}
|
|
144
|
-
return /* @__PURE__ */
|
|
207
|
+
return /* @__PURE__ */ K(
|
|
145
208
|
"div",
|
|
146
209
|
{
|
|
210
|
+
ref: k,
|
|
211
|
+
id: I,
|
|
212
|
+
role: "radiogroup",
|
|
213
|
+
"aria-label": u,
|
|
214
|
+
"aria-labelledby": f,
|
|
215
|
+
"aria-invalid": h,
|
|
216
|
+
"aria-required": z,
|
|
217
|
+
"aria-describedby": b,
|
|
147
218
|
className: "relative inline-flex",
|
|
148
|
-
ref: I,
|
|
149
219
|
"data-spark-component": "rating",
|
|
150
|
-
...
|
|
151
|
-
onMouseLeave:
|
|
220
|
+
...w,
|
|
221
|
+
onMouseLeave: Q,
|
|
152
222
|
children: [
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
|
|
223
|
+
V !== void 0 && /* @__PURE__ */ n("input", { type: "hidden", name: V, value: y, "aria-hidden": !0, "data-part": "input" }),
|
|
224
|
+
/* @__PURE__ */ n("div", { className: S("gap-x-md", "flex"), children: Array.from({ length: 5 }).map((s, a) => /* @__PURE__ */ n(
|
|
225
|
+
ne,
|
|
155
226
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
),
|
|
173
|
-
/* @__PURE__ */ o(
|
|
174
|
-
"div",
|
|
175
|
-
{
|
|
176
|
-
className: f(
|
|
177
|
-
r === "lg" ? "gap-x-md" : "gap-x-sm",
|
|
178
|
-
"flex",
|
|
179
|
-
"peer-focus-visible:u-outline peer-[[data-part=input][data-clicked]]:shadow-none"
|
|
180
|
-
),
|
|
181
|
-
children: Array.from({ length: 5 }).map((t, c) => /* @__PURE__ */ o(
|
|
182
|
-
G,
|
|
183
|
-
{
|
|
184
|
-
disabled: i,
|
|
185
|
-
readOnly: s,
|
|
186
|
-
size: r,
|
|
187
|
-
onClick: () => g && E(c),
|
|
188
|
-
onMouseEnter: (h) => g && V(h),
|
|
189
|
-
ref: D,
|
|
190
|
-
value: J({ index: c, value: p })
|
|
191
|
-
},
|
|
192
|
-
c
|
|
193
|
-
))
|
|
194
|
-
}
|
|
195
|
-
)
|
|
227
|
+
ref: G(a),
|
|
228
|
+
disabled: E,
|
|
229
|
+
readOnly: F,
|
|
230
|
+
size: "lg",
|
|
231
|
+
value: oe({ index: a, value: B }),
|
|
232
|
+
checked: y === a + 1,
|
|
233
|
+
ariaLabel: D ? v?.(a) ?? `${u} ${a + 1}` : void 0,
|
|
234
|
+
ariaLabelledBy: !D && f ? `${f} ${R}-star-${a + 1}` : void 0,
|
|
235
|
+
tabIndex: m ? de(a, y) : -1,
|
|
236
|
+
onClick: () => P(a),
|
|
237
|
+
onKeyDown: T(a),
|
|
238
|
+
onMouseEnter: (M) => m && U(M),
|
|
239
|
+
children: !D && /* @__PURE__ */ n("span", { id: `${R}-star-${a + 1}`, className: "sr-only", children: a + 1 })
|
|
240
|
+
},
|
|
241
|
+
a
|
|
242
|
+
)) })
|
|
196
243
|
]
|
|
197
244
|
}
|
|
198
245
|
);
|
|
199
246
|
};
|
|
200
247
|
export {
|
|
201
|
-
|
|
248
|
+
ye as Rating
|
|
202
249
|
};
|
|
203
250
|
//# sourceMappingURL=index.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../src/rating/RatingStar.styles.ts","../../src/rating/RatingStar.tsx","../../src/rating/utils.ts","../../src/rating/Rating.tsx"],"sourcesContent":["import { cva, cx, VariantProps } from 'class-variance-authority'\n\nconst emptyRemainingStarsOnHoverClass = cx('[&_>_div]:peer-hover:w-0!')\n\nconst ratingStarStyles = cva(\n ['peer', 'after:inset-0', 'group', 'relative', 'after:block after:absolute'],\n {\n variants: {\n disabled: {\n true: 'opacity-dim-3',\n false: '',\n },\n readOnly: {\n true: '',\n false: '',\n },\n gap: {\n sm: ['after:w-[calc(100%+(var(--spacing-sm)))]', 'last-of-type:after:content-none'],\n md: ['after:w-[calc(100%+(var(--spacing-md)))]', 'last-of-type:after:content-none'],\n },\n },\n compoundVariants: [\n {\n readOnly: false,\n disabled: false,\n className: cx(emptyRemainingStarsOnHoverClass, 'cursor-pointer'),\n },\n ],\n defaultVariants: {\n disabled: false,\n readOnly: false,\n gap: 'sm',\n },\n }\n)\n\nconst ratingStarIconStyles = cva('', {\n variants: {\n size: {\n sm: 'text-caption-link',\n md: 'text-body-1',\n lg: 'text-display-1',\n },\n design: {\n filled: [\n 'text-main-variant',\n 'group-[[data-part=star][data-hovered]]:text-main-variant-hovered',\n ],\n outlined: ['text-on-surface/dim-3'],\n },\n },\n})\n\ntype RatingStarstylesProps = Omit<VariantProps<typeof ratingStarStyles>, 'gap'>\ntype RatingStarIconStylesProps = Omit<VariantProps<typeof ratingStarIconStyles>, 'design'>\n\nexport { ratingStarStyles, ratingStarIconStyles }\nexport type { RatingStarstylesProps, RatingStarIconStylesProps }\n","import { StarFill } from '@spark-ui/icons/StarFill'\nimport { StarOutline } from '@spark-ui/icons/StarOutline'\nimport { cx } from 'class-variance-authority'\nimport { type MouseEvent, Ref } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n ratingStarIconStyles,\n type RatingStarIconStylesProps,\n ratingStarStyles,\n type RatingStarstylesProps,\n} from './RatingStar.styles'\nimport type { StarValue } from './types'\n\nexport interface RatingStarProps extends RatingStarstylesProps, RatingStarIconStylesProps {\n value: StarValue\n onClick?: (event: MouseEvent<HTMLDivElement>) => void\n onMouseEnter?: (event: MouseEvent<HTMLDivElement>) => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const RatingStar = ({\n value,\n size,\n disabled,\n readOnly,\n onClick,\n onMouseEnter,\n ref: forwardedRef,\n}: RatingStarProps) => {\n return (\n <div\n data-spark-component=\"rating-star\"\n ref={forwardedRef}\n onMouseEnter={onMouseEnter}\n className={ratingStarStyles({\n gap: size === 'lg' ? 'md' : 'sm',\n disabled,\n readOnly,\n })}\n data-part=\"star\"\n onClick={onClick}\n >\n <div\n className={cx(\n 'z-raised absolute overflow-hidden',\n 'group-[[data-part=star][data-hovered]]:overflow-visible'\n )}\n style={{ width: value * 100 + '%' }}\n >\n <Icon\n className={ratingStarIconStyles({\n size,\n design: 'filled',\n })}\n >\n <StarFill />\n </Icon>\n </div>\n\n <Icon className={ratingStarIconStyles({ size, design: 'outlined' })}>\n <StarOutline />\n </Icon>\n </div>\n )\n}\n","import { type StarValue } from './types'\n\nfunction getNearestHalfDecimal(num: number): number {\n return Math.round(num / 0.5) * 0.5\n}\n\nfunction getStarValue({ value, index }: { value?: number; index: number }): StarValue {\n if (value === undefined) return 0\n\n const starPosition = index + 1\n const formattedValue = getNearestHalfDecimal(value)\n\n if (Math.ceil(formattedValue) < starPosition) return 0\n\n return formattedValue >= starPosition ? 1 : 0.5\n}\n\nfunction splitAt<T>(arr: T[], index: number): [T[], T[]] {\n const prev = arr.slice(0, index)\n const next = arr.slice(index)\n\n return [prev, next]\n}\n\nexport { getNearestHalfDecimal, getStarValue, splitAt }\n","import { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { cx } from 'class-variance-authority'\nimport {\n type ChangeEvent,\n type ComponentPropsWithRef,\n type MouseEvent,\n type PropsWithChildren,\n useCallback,\n useRef,\n} from 'react'\n\nimport { RatingStar, type RatingStarProps } from './RatingStar'\nimport { getNearestHalfDecimal, getStarValue, splitAt } from './utils'\n\nexport interface RatingProps extends PropsWithChildren<ComponentPropsWithRef<'div'>> {\n /**\n * Use the `defaultValue` prop to set the default value of the input, on a from 0 to 5.\n *\n * Use this when you want to use it in an uncontrolled manner\n */\n defaultValue?: number\n /**\n * The value is the number of the rating selected, on a scale from 0 to 5.\n *\n * Use this when you want to use it in a controlled manner,\n * in conjunction with the `onValueChange` prop\n */\n value?: number\n /**\n * Event handler called when the value changes.\n */\n onValueChange?: (value: number) => void\n /**\n * Sets the component as interactive or not.\n * @default undefined\n */\n readOnly?: boolean\n /**\n * When `true`, prevents the user from interacting.\n * @default false\n */\n disabled?: boolean\n /**\n * Sets the size of the stars.\n * @default 'md'\n */\n size?: RatingStarProps['size']\n /**\n * Name of the underlying input.\n * @default undefined\n */\n name?: string\n /**\n * id of the underlying input.\n * @default undefined\n */\n id?: string\n /**\n * aria-label of the underlying input.\n * @default undefined\n */\n 'aria-label': string\n}\n\nexport const Rating = ({\n defaultValue,\n value: propValue,\n onValueChange,\n size = 'md',\n disabled,\n readOnly,\n name,\n id,\n 'aria-label': ariaLabel,\n ref,\n ...rest\n}: RatingProps) => {\n const inputRef = useRef<HTMLInputElement>(null)\n const starRefList = useRef<HTMLDivElement[]>([])\n\n const [value, setRatingValue] = useCombinedState(propValue, defaultValue, onValueChange)\n\n const valueRef = useRef(value)\n const isInteractive = !(disabled || readOnly)\n\n function onStarClick(index: number) {\n if (!inputRef.current) return\n\n setRatingValue(index + 1)\n valueRef.current = index + 1\n\n inputRef.current.focus()\n inputRef.current.setAttribute('data-clicked', '')\n }\n\n function onInputChange(event: ChangeEvent<HTMLInputElement>) {\n // 1. Avoiding unnecessary calls to onValueChange prop if value doesn't change\n // 2. Preventing value to be resetted to 0\n if (valueRef.current === Number(event.target.value) || Number(event.target.value) === 0) {\n return\n }\n valueRef.current = Number(event.target.value)\n\n setRatingValue(Number(event.target.value))\n }\n\n function onStarMouseEnter({ currentTarget }: MouseEvent<HTMLDivElement>) {\n const currentStarIndex = starRefList.current.findIndex(star => star === currentTarget)\n\n const [previousStars, followingStars] = splitAt(starRefList.current, currentStarIndex + 1)\n\n previousStars.forEach(star => star.setAttribute('data-hovered', ''))\n followingStars.forEach(star => star.removeAttribute('data-hovered'))\n }\n\n const handleStarRef = useCallback((elm: HTMLDivElement | null) => {\n if (!elm) return\n starRefList.current.push(elm)\n }, [])\n\n function resetDataPartInputAttr() {\n inputRef.current?.removeAttribute('data-clicked')\n }\n\n function resetDataPartStarAttr() {\n starRefList.current.forEach(star => star.removeAttribute('data-hovered'))\n }\n\n return (\n <div\n className=\"relative inline-flex\"\n ref={ref}\n data-spark-component=\"rating\"\n {...rest}\n onMouseLeave={resetDataPartStarAttr}\n >\n <input\n name={name}\n id={id}\n aria-label={ariaLabel}\n ref={inputRef}\n data-part=\"input\"\n className=\"peer absolute inset-0 opacity-0\"\n type=\"range\"\n min=\"0\"\n max=\"5\"\n step={readOnly ? 0.5 : 1}\n disabled={disabled}\n readOnly={readOnly}\n value={getNearestHalfDecimal(value ?? 0)}\n onChange={event => isInteractive && onInputChange(event)}\n onBlur={resetDataPartInputAttr}\n />\n <div\n className={cx(\n size === 'lg' ? 'gap-x-md' : 'gap-x-sm',\n 'flex',\n 'peer-focus-visible:u-outline peer-[[data-part=input][data-clicked]]:shadow-none'\n )}\n >\n {Array.from({ length: 5 }).map((_, index) => (\n <RatingStar\n disabled={disabled}\n readOnly={readOnly}\n size={size}\n onClick={() => isInteractive && onStarClick(index)}\n onMouseEnter={event => isInteractive && onStarMouseEnter(event)}\n ref={handleStarRef}\n key={index}\n value={getStarValue({ index, value })}\n />\n ))}\n </div>\n </div>\n )\n}\n"],"names":["emptyRemainingStarsOnHoverClass","cx","ratingStarStyles","cva","ratingStarIconStyles","RatingStar","value","size","disabled","readOnly","onClick","onMouseEnter","forwardedRef","jsxs","jsx","Icon","StarFill","StarOutline","getNearestHalfDecimal","num","getStarValue","index","starPosition","formattedValue","splitAt","arr","prev","next","Rating","defaultValue","propValue","onValueChange","name","id","ariaLabel","ref","rest","inputRef","useRef","starRefList","setRatingValue","useCombinedState","valueRef","isInteractive","onStarClick","onInputChange","event","onStarMouseEnter","currentTarget","currentStarIndex","star","previousStars","followingStars","handleStarRef","useCallback","elm","resetDataPartInputAttr","resetDataPartStarAttr","_"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/rating/RatingStar.styles.ts","../../src/rating/RatingStar.tsx","../../src/rating/utils.ts","../../src/rating/Rating.tsx"],"sourcesContent":["import { cva, cx, VariantProps } from 'class-variance-authority'\n\nconst emptyRemainingStarsOnHoverClass = cx('[&_>_div]:peer-hover:w-0!')\n\nconst ratingStarStyles = cva(['peer after:inset-0 group relative after:block after:absolute'], {\n variants: {\n disabled: {\n true: 'opacity-dim-3',\n false: '',\n },\n readOnly: {\n true: '',\n false: '',\n },\n gap: {\n sm: ['after:w-[calc(100%+(var(--spacing-sm)))]', 'last-of-type:after:content-none'],\n md: ['after:w-[calc(100%+(var(--spacing-md)))]', 'last-of-type:after:content-none'],\n },\n },\n compoundVariants: [\n {\n readOnly: false,\n disabled: false,\n className: cx(\n emptyRemainingStarsOnHoverClass,\n 'cursor-pointer transition-all duration-200 scale-100',\n /* mouseOver / focusIn => scale 150 */\n 'hover:scale-150 focus-visible:scale-150',\n /* mouseOut / focusOut / selection (click) => no scale; mouseMove clears selection => scale again */\n '[&[data-suppress-scale]]:hover:scale-100 [&[data-suppress-scale]]:focus-visible:scale-100'\n ),\n },\n ],\n defaultVariants: {\n disabled: false,\n readOnly: false,\n gap: 'sm',\n },\n})\n\nconst ratingStarIconStyles = cva('', {\n variants: {\n size: {\n sm: 'text-caption-link',\n md: 'text-body-1',\n lg: 'text-display-1',\n },\n design: {\n filled: [\n 'text-main-variant',\n 'group-[[data-part=star][data-hovered]]:text-main-variant-hovered',\n ],\n outlined: ['text-on-surface/dim-3'],\n },\n },\n})\n\ntype RatingStarstylesProps = Omit<VariantProps<typeof ratingStarStyles>, 'gap'>\ntype RatingStarIconStylesProps = Omit<VariantProps<typeof ratingStarIconStyles>, 'design'>\n\nexport { ratingStarStyles, ratingStarIconStyles }\nexport type { RatingStarstylesProps, RatingStarIconStylesProps }\n","import { StarFill } from '@spark-ui/icons/StarFill'\nimport { StarOutline } from '@spark-ui/icons/StarOutline'\nimport { cx } from 'class-variance-authority'\nimport { type KeyboardEvent, type MouseEvent, type PropsWithChildren, Ref, useState } from 'react'\n\nimport { Icon } from '../icon'\nimport {\n ratingStarIconStyles,\n type RatingStarIconStylesProps,\n ratingStarStyles,\n type RatingStarstylesProps,\n} from './RatingStar.styles'\nimport type { StarValue } from './types'\n\nexport interface RatingStarProps\n extends PropsWithChildren<RatingStarstylesProps>,\n RatingStarIconStylesProps {\n value: StarValue\n /** Whether this radio option is selected (for radiogroup pattern). */\n checked?: boolean\n /** Accessible name for the radio (e.g. \"one star\", \"two stars\"). */\n ariaLabel?: string\n /** Accessible ids used to compose the radio name. */\n ariaLabelledBy?: string\n /** Tab index for roving tabindex (0 or -1). */\n tabIndex?: number\n onClick?: (event: MouseEvent<HTMLDivElement>) => void\n onKeyDown?: (event: KeyboardEvent<HTMLDivElement>) => void\n onMouseEnter?: (event: MouseEvent<HTMLDivElement>) => void\n ref?: Ref<HTMLDivElement>\n}\n\nexport const RatingStar = ({\n value,\n size,\n disabled,\n readOnly,\n checked = false,\n ariaLabel,\n ariaLabelledBy,\n tabIndex,\n onClick,\n onKeyDown,\n onMouseEnter,\n children,\n ref: forwardedRef,\n}: RatingStarProps) => {\n const isInteractive = !disabled && !readOnly\n const [justClicked, setJustClicked] = useState(false)\n\n const handleClick = (event: MouseEvent<HTMLDivElement>) => {\n onClick?.(event)\n if (isInteractive) setJustClicked(true)\n }\n\n const clearJustClicked = () => setJustClicked(false)\n\n return (\n <div\n ref={forwardedRef}\n role=\"radio\"\n aria-checked={checked}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n tabIndex={tabIndex}\n data-spark-component=\"rating-star\"\n data-part=\"star\"\n {...(isInteractive && justClicked && { 'data-suppress-scale': '' })}\n className={ratingStarStyles({\n gap: size === 'lg' ? 'md' : 'sm',\n disabled,\n readOnly,\n })}\n onClick={handleClick}\n onKeyDown={onKeyDown}\n onMouseEnter={onMouseEnter}\n onMouseLeave={clearJustClicked}\n onMouseMove={clearJustClicked}\n >\n <div\n className={cx(\n 'z-raised absolute overflow-hidden',\n 'group-[[data-part=star][data-hovered]]:overflow-visible'\n )}\n style={{ width: value * 100 + '%' }}\n >\n <Icon\n className={ratingStarIconStyles({\n size,\n design: 'filled',\n })}\n >\n <StarFill />\n </Icon>\n </div>\n\n <Icon className={ratingStarIconStyles({ size, design: 'outlined' })}>\n <StarOutline />\n </Icon>\n {children}\n </div>\n )\n}\n","import { type StarValue } from './types'\n\nfunction getStarValue({ value, index }: { value?: number; index: number }): StarValue {\n if (value === undefined) return 0\n\n const starPosition = index + 1\n\n return value >= starPosition ? 1 : 0\n}\n\nfunction splitAt<T>(arr: T[], index: number): [T[], T[]] {\n const prev = arr.slice(0, index)\n const next = arr.slice(index)\n\n return [prev, next]\n}\n\nexport { getStarValue, splitAt }\n","/* eslint-disable max-lines-per-function */\nimport { useCombinedState } from '@spark-ui/hooks/use-combined-state'\nimport { cx } from 'class-variance-authority'\nimport {\n type ComponentPropsWithRef,\n type KeyboardEvent,\n type MouseEvent,\n type PropsWithChildren,\n type RefObject,\n useCallback,\n useId,\n useRef,\n useState,\n} from 'react'\n\nimport { useFormFieldControl } from '../form-field'\nimport { RatingStar } from './RatingStar'\nimport type { RatingValue } from './types'\nimport { getStarValue, splitAt } from './utils'\n\nconst getRatingInteger = (value: number | undefined): RatingValue => {\n if (value === undefined || !Number.isInteger(value) || value < 1) {\n return 0\n }\n\n return Math.min(5, Math.max(1, value)) as RatingValue\n}\n\nfunction createStarKeyDownHandler(\n index: number,\n starRefList: RefObject<(HTMLDivElement | null)[]>,\n setRatingValue: (value: RatingValue) => void,\n isInteractive: boolean\n) {\n return (event: KeyboardEvent<HTMLDivElement>) => {\n if (!isInteractive) return\n\n switch (event.key) {\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n const nextIndex = Math.min(4, index + 1)\n setRatingValue((nextIndex + 1) as RatingValue)\n starRefList.current[nextIndex]?.focus()\n break\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n const prevIndex = Math.max(0, index - 1)\n setRatingValue((prevIndex + 1) as RatingValue)\n starRefList.current[prevIndex]?.focus()\n break\n case ' ':\n event.preventDefault()\n setRatingValue((index + 1) as RatingValue)\n break\n default:\n break\n }\n }\n}\n\nfunction getStarTabIndex(index: number, ratingValue: RatingValue): number {\n if (ratingValue >= 1) {\n return ratingValue - 1 === index ? 0 : -1\n }\n\n return index === 0 ? 0 : -1\n}\n\nexport interface RatingProps extends PropsWithChildren<ComponentPropsWithRef<'div'>> {\n /**\n * Use the `defaultValue` prop to set the default value of the input, on a from 0 to 5.\n *\n * Use this when you want to use it in an uncontrolled manner\n */\n defaultValue?: RatingValue\n /**\n * The value is the number of the rating selected, on a scale from 0 to 5.\n *\n * Use this when you want to use it in a controlled manner,\n * in conjunction with the `onValueChange` prop\n */\n value?: RatingValue\n /**\n * Event handler called when the value changes.\n */\n onValueChange?: (value: RatingValue) => void\n /**\n * Sets the component as interactive or not.\n * @default undefined\n */\n readOnly?: boolean\n /**\n * When `true`, prevents the user from interacting.\n * @default false\n */\n disabled?: boolean\n /**\n * When true, indicates that the user must select a rating before form submission.\n * @default false\n */\n required?: boolean\n /**\n * Name of the underlying hidden input (for form submission).\n * @default undefined\n */\n name?: string\n /**\n * id of the underlying hidden input.\n * @default undefined\n */\n id?: string\n /**\n * aria-label of the radiogroup.\n * @default undefined\n */\n 'aria-label'?: string\n /**\n * Returns the aria-label applied to each radio star.\n * Defaults to `${aria-label} ${index + 1}`.\n */\n getStarLabel?: (index: number) => string\n}\n\nexport const Rating = ({\n defaultValue,\n value: propValue,\n onValueChange,\n disabled,\n readOnly,\n required: requiredProp,\n name,\n id,\n 'aria-label': ariaLabel,\n getStarLabel,\n ref,\n ...rest\n}: RatingProps) => {\n const {\n labelId,\n isInvalid,\n isRequired,\n description,\n name: formFieldName,\n disabled: formFieldDisabled,\n readOnly: formFieldReadOnly,\n } = useFormFieldControl()\n const starRefList = useRef<(HTMLDivElement | null)[]>([])\n const ratingId = useId()\n const [hoveredStarIndex, setHoveredStarIndex] = useState<number | null>(null)\n const [value, setRatingValue] = useCombinedState(propValue, defaultValue, onValueChange)\n const ratingValue = getRatingInteger(value ?? 0)\n const resolvedDisabled = disabled ?? formFieldDisabled\n const resolvedReadOnly = readOnly ?? formFieldReadOnly\n const required = requiredProp !== undefined ? requiredProp : isRequired\n const groupName = name ?? formFieldName\n const isInteractive = !(resolvedDisabled || resolvedReadOnly)\n const hasExplicitStarLabel = getStarLabel !== undefined || ariaLabel !== undefined\n const displayValue = hoveredStarIndex !== null ? hoveredStarIndex + 1 : ratingValue\n\n function onStarClick(index: number) {\n if (!isInteractive) return\n\n const newValue = (index + 1) as RatingValue\n setRatingValue(newValue)\n starRefList.current[index]?.focus()\n }\n\n const onStarKeyDown = useCallback(\n (index: number) => createStarKeyDownHandler(index, starRefList, setRatingValue, isInteractive),\n [isInteractive, setRatingValue]\n )\n\n function onStarMouseEnter({ currentTarget }: MouseEvent<HTMLDivElement>) {\n const currentStarIndex = starRefList.current.findIndex(star => star === currentTarget)\n setHoveredStarIndex(currentStarIndex >= 0 ? currentStarIndex : null)\n const [previousStars, followingStars] = splitAt(starRefList.current, currentStarIndex + 1)\n previousStars.forEach(star => star?.setAttribute('data-hovered', ''))\n followingStars.forEach(star => star?.removeAttribute('data-hovered'))\n }\n\n const handleStarRef = useCallback(\n (index: number) => (elm: HTMLDivElement | null) => {\n starRefList.current[index] = elm\n },\n []\n )\n\n function resetDataPartStarAttr() {\n setHoveredStarIndex(null)\n starRefList.current.forEach(star => star?.removeAttribute('data-hovered'))\n }\n\n return (\n <div\n ref={ref}\n id={id}\n role=\"radiogroup\"\n aria-label={ariaLabel}\n aria-labelledby={labelId}\n aria-invalid={isInvalid}\n aria-required={required}\n aria-describedby={description}\n className=\"relative inline-flex\"\n data-spark-component=\"rating\"\n {...rest}\n onMouseLeave={resetDataPartStarAttr}\n >\n {groupName !== undefined && (\n <input type=\"hidden\" name={groupName} value={ratingValue} aria-hidden data-part=\"input\" />\n )}\n <div className={cx('gap-x-md', 'flex')}>\n {Array.from({ length: 5 }).map((_, index) => (\n <RatingStar\n ref={handleStarRef(index)}\n key={index}\n disabled={resolvedDisabled}\n readOnly={resolvedReadOnly}\n size=\"lg\"\n value={getStarValue({ index, value: displayValue })}\n checked={ratingValue === index + 1}\n ariaLabel={\n hasExplicitStarLabel\n ? (getStarLabel?.(index) ?? `${ariaLabel} ${index + 1}`)\n : undefined\n }\n ariaLabelledBy={\n !hasExplicitStarLabel && labelId\n ? `${labelId} ${ratingId}-star-${index + 1}`\n : undefined\n }\n tabIndex={isInteractive ? getStarTabIndex(index, ratingValue) : -1}\n onClick={() => onStarClick(index)}\n onKeyDown={onStarKeyDown(index)}\n onMouseEnter={event => isInteractive && onStarMouseEnter(event)}\n >\n {!hasExplicitStarLabel && (\n <span id={`${ratingId}-star-${index + 1}`} className=\"sr-only\">\n {index + 1}\n </span>\n )}\n </RatingStar>\n ))}\n </div>\n </div>\n )\n}\n"],"names":["emptyRemainingStarsOnHoverClass","cx","ratingStarStyles","cva","ratingStarIconStyles","RatingStar","value","size","disabled","readOnly","checked","ariaLabel","ariaLabelledBy","tabIndex","onClick","onKeyDown","onMouseEnter","children","forwardedRef","isInteractive","justClicked","setJustClicked","useState","handleClick","event","clearJustClicked","jsxs","jsx","Icon","StarFill","StarOutline","getStarValue","index","starPosition","splitAt","arr","prev","next","getRatingInteger","createStarKeyDownHandler","starRefList","setRatingValue","nextIndex","prevIndex","getStarTabIndex","ratingValue","Rating","defaultValue","propValue","onValueChange","requiredProp","name","id","getStarLabel","ref","rest","labelId","isInvalid","isRequired","description","formFieldName","formFieldDisabled","formFieldReadOnly","useFormFieldControl","useRef","ratingId","useId","hoveredStarIndex","setHoveredStarIndex","useCombinedState","resolvedDisabled","resolvedReadOnly","required","groupName","hasExplicitStarLabel","displayValue","onStarClick","newValue","onStarKeyDown","useCallback","onStarMouseEnter","currentTarget","currentStarIndex","star","previousStars","followingStars","handleStarRef","elm","resetDataPartStarAttr","_"],"mappings":"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"}
|
package/dist/rating/types.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type RatingValue = 0 | 1 | 2 | 3 | 4 | 5;
|
|
2
|
+
export type StarValue = 0 | 1;
|
package/dist/rating/utils.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { StarValue } from './types';
|
|
2
|
-
declare function getNearestHalfDecimal(num: number): number;
|
|
3
2
|
declare function getStarValue({ value, index }: {
|
|
4
3
|
value?: number;
|
|
5
4
|
index: number;
|
|
6
5
|
}): StarValue;
|
|
7
6
|
declare function splitAt<T>(arr: T[], index: number): [T[], T[]];
|
|
8
|
-
export {
|
|
7
|
+
export { getStarValue, splitAt };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, PropsWithChildren } from 'react';
|
|
2
|
+
import { RatingDisplayStarProps } from './RatingDisplayStar';
|
|
3
|
+
export interface RatingDisplayProps extends PropsWithChildren<ComponentPropsWithRef<'div'>> {
|
|
4
|
+
/**
|
|
5
|
+
* The rating value to display, on a scale from 0 to 5.
|
|
6
|
+
*/
|
|
7
|
+
value?: number;
|
|
8
|
+
/**
|
|
9
|
+
* Sets the size of the stars.
|
|
10
|
+
* @default 'md'
|
|
11
|
+
*/
|
|
12
|
+
size?: RatingDisplayStarProps['size'];
|
|
13
|
+
/**
|
|
14
|
+
* Optional count value available to `RatingDisplay.Count`.
|
|
15
|
+
*/
|
|
16
|
+
count?: number;
|
|
17
|
+
/**
|
|
18
|
+
* Accessible description of the rating content.
|
|
19
|
+
*/
|
|
20
|
+
'aria-label': string;
|
|
21
|
+
}
|
|
22
|
+
export type RatingDisplayRootProps = RatingDisplayProps;
|
|
23
|
+
export declare const RatingDisplay: {
|
|
24
|
+
({ value, size, count, ref, children, ...rest }: RatingDisplayProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
displayName: string;
|
|
26
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { RatingDisplayStarProps } from './RatingDisplayStar';
|
|
3
|
+
interface RatingDisplayContextValue {
|
|
4
|
+
value: number;
|
|
5
|
+
size: RatingDisplayStarProps['size'];
|
|
6
|
+
count?: number;
|
|
7
|
+
}
|
|
8
|
+
interface RatingDisplayProviderProps extends PropsWithChildren<RatingDisplayContextValue> {
|
|
9
|
+
}
|
|
10
|
+
export declare const RatingDisplayProvider: ({ value, size, count, children, }: RatingDisplayProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const useRatingDisplay: () => RatingDisplayContextValue;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
export interface RatingDisplayCountProps extends Omit<ComponentPropsWithRef<'span'>, 'children'> {
|
|
3
|
+
/**
|
|
4
|
+
* Custom count content.
|
|
5
|
+
* Pass a render function to receive the count value and return the content to render.
|
|
6
|
+
*/
|
|
7
|
+
children?: ReactNode | ((count: number) => ReactNode);
|
|
8
|
+
}
|
|
9
|
+
export declare const RatingDisplayCount: {
|
|
10
|
+
({ className, children, ...rest }: RatingDisplayCountProps): import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
displayName: string;
|
|
12
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { VariantProps } from 'class-variance-authority';
|
|
2
|
+
import { StarValue } from './types';
|
|
3
|
+
declare const ratingDisplayStarStyles: (props?: ({
|
|
4
|
+
gap?: "sm" | "md" | null | undefined;
|
|
5
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
6
|
+
declare const ratingDisplayStarIconStyles: (props?: ({
|
|
7
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
8
|
+
design?: "filled" | "outlined" | null | undefined;
|
|
9
|
+
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
10
|
+
type RatingDisplayStarstylesProps = Omit<VariantProps<typeof ratingDisplayStarStyles>, never>;
|
|
11
|
+
type RatingDisplayStarIconStylesProps = Omit<VariantProps<typeof ratingDisplayStarIconStyles>, 'design'>;
|
|
12
|
+
export interface RatingDisplayStarProps extends RatingDisplayStarstylesProps, RatingDisplayStarIconStylesProps {
|
|
13
|
+
value: StarValue;
|
|
14
|
+
}
|
|
15
|
+
export declare const RatingDisplayStar: ({ value, size }: RatingDisplayStarProps) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { RatingDisplayStarProps } from './RatingDisplayStar';
|
|
2
|
+
import { StarValue } from './types';
|
|
3
|
+
export interface RatingDisplayStarsProps {
|
|
4
|
+
size?: RatingDisplayStarProps['size'];
|
|
5
|
+
/**
|
|
6
|
+
* Sets the rendering mode for stars.
|
|
7
|
+
* @default 'default'
|
|
8
|
+
*/
|
|
9
|
+
variant?: 'default' | 'single-star';
|
|
10
|
+
/**
|
|
11
|
+
* Custom fill algorithm for each star.
|
|
12
|
+
* By default, stars are rounded to the nearest 0.5.
|
|
13
|
+
*/
|
|
14
|
+
getFillMode?: ({ value, index }: {
|
|
15
|
+
value?: number;
|
|
16
|
+
index: number;
|
|
17
|
+
}) => StarValue;
|
|
18
|
+
}
|
|
19
|
+
export declare const RatingDisplayStars: {
|
|
20
|
+
({ size, variant, getFillMode, }: RatingDisplayStarsProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
displayName: string;
|
|
22
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ComponentPropsWithRef, ReactNode } from 'react';
|
|
2
|
+
export interface RatingDisplayValueProps extends Omit<ComponentPropsWithRef<'span'>, 'children'> {
|
|
3
|
+
/**
|
|
4
|
+
* Custom value content.
|
|
5
|
+
* Pass a render function to receive the formatted value (first arg) and raw value (second arg),
|
|
6
|
+
* then return the content to render.
|
|
7
|
+
*/
|
|
8
|
+
children?: ReactNode | ((formattedValue: string, value: number) => ReactNode);
|
|
9
|
+
}
|
|
10
|
+
export declare const RatingDisplayValue: {
|
|
11
|
+
({ className, children, ...rest }: RatingDisplayValueProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
displayName: string;
|
|
13
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RatingDisplay as Root } from './RatingDisplay';
|
|
2
|
+
import { RatingDisplayCount as Count } from './RatingDisplayCount';
|
|
3
|
+
import { RatingDisplayStars as Stars } from './RatingDisplayStars';
|
|
4
|
+
import { RatingDisplayValue as Value } from './RatingDisplayValue';
|
|
5
|
+
export declare const RatingDisplay: typeof Root & {
|
|
6
|
+
Stars: typeof Stars;
|
|
7
|
+
Value: typeof Value;
|
|
8
|
+
Count: typeof Count;
|
|
9
|
+
};
|
|
10
|
+
export { type RatingDisplayProps, type RatingDisplayRootProps } from './RatingDisplay';
|
|
11
|
+
export { type RatingDisplayStarsProps } from './RatingDisplayStars';
|
|
12
|
+
export { type RatingDisplayValueProps } from './RatingDisplayValue';
|
|
13
|
+
export { type RatingDisplayCountProps } from './RatingDisplayCount';
|
|
14
|
+
export type { StarValue } from './types';
|