react-awesome-stars-rating 1.1.0 → 1.3.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/README.md +69 -18
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +27 -4
- package/dist/index.d.ts +27 -4
- package/dist/index.mjs +1 -1
- package/dist/index.umd.cjs +1 -1
- package/package.json +5 -4
- package/dist/gradient.d.ts +0 -12
- package/dist/star.d.ts +0 -20
- package/dist/styles.d.ts +0 -12
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[](https://github.com/fedoryakubovich/react-awesome-stars-rating/actions/workflows/ci.yml)
|
|
5
5
|
[](https://github.com/fedoryakubovich/react-awesome-stars-rating/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
An accessible star rating component for React. Half stars from pointer position, full keyboard control, any scale or palette — in
|
|
7
|
+
An accessible star rating component for React. Half stars from pointer position, full keyboard control, any scale or palette — in under 3 kB gzipped with no runtime dependencies.
|
|
8
8
|
|
|
9
9
|
**[Live demo](https://react-awesome-stars-rating.vercel.app)** · **[Storybook](https://react-awesome-stars-rating.vercel.app/storybook)**
|
|
10
10
|
|
|
@@ -12,7 +12,7 @@ An accessible star rating component for React. Half stars from pointer position,
|
|
|
12
12
|
|
|
13
13
|
## Highlights
|
|
14
14
|
|
|
15
|
-
-
|
|
15
|
+
- Under 3 kB gzipped, no runtime dependencies
|
|
16
16
|
- Half-star precision from pointer position, plus arrow-key stepping
|
|
17
17
|
- `role="slider"` with live `aria-valuenow` / `aria-valuetext`, verified with axe-core
|
|
18
18
|
- ESM + CJS with correct types for each, and a UMD bundle for CDN use
|
|
@@ -69,22 +69,27 @@ export default function Example() {
|
|
|
69
69
|
|
|
70
70
|
## Props
|
|
71
71
|
|
|
72
|
-
| Name | Description | Type
|
|
73
|
-
| :------------- | :---------------------------------------- |
|
|
74
|
-
| id | Identifier | `string`
|
|
75
|
-
| value |
|
|
76
|
-
|
|
|
77
|
-
|
|
|
78
|
-
|
|
|
79
|
-
|
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
72
|
+
| Name | Description | Type | Default |
|
|
73
|
+
| :------------- | :---------------------------------------- | :------------------------- | :-------------- |
|
|
74
|
+
| id | Identifier | `string` | auto-generated |
|
|
75
|
+
| value | Controlled current value | `number` | `undefined` |
|
|
76
|
+
| defaultValue | Initial uncontrolled value | `number` | `0` |
|
|
77
|
+
| onChange | Called when value changes | `(value: number) => void` | `() => {}` |
|
|
78
|
+
| name | Hidden native form input name | `string` | `undefined` |
|
|
79
|
+
| disabled | Disable interaction and form submission | `boolean` | `false` |
|
|
80
|
+
| isEdit | Editing mode | `boolean` | `true` |
|
|
81
|
+
| isHalf | Allow half stars | `boolean` | `true` |
|
|
82
|
+
| count | Number of stars | `number` | `5` |
|
|
83
|
+
| size | Star size (px) | `number` | `25` |
|
|
84
|
+
| starGap | Gap between stars | `number` | `0` |
|
|
85
|
+
| className | Container class | `string` | `''` |
|
|
86
|
+
| primaryColor | Active star color | `string` | `'orange'` |
|
|
87
|
+
| secondaryColor | Inactive star color | `string` | `'grey'` |
|
|
88
|
+
| hoverColor | Optional pointer-preview color | `string` | `undefined` |
|
|
89
|
+
| isArrowSubmit | Arrow keys trigger `onChange` immediately | `boolean` | `false` |
|
|
90
|
+
| ariaLabel | Accessible label (if no `ariaLabelledBy`) | `string` | `'Star rating'` |
|
|
91
|
+
| ariaLabelledBy | ID of element that labels the control | `string` | `undefined` |
|
|
92
|
+
| getValueText | Formats accessible value text | `(value, count) => string` | English text |
|
|
88
93
|
|
|
89
94
|
## Keyboard and accessibility
|
|
90
95
|
|
|
@@ -102,12 +107,58 @@ With `isArrowSubmit`, each arrow step reports through `onChange` immediately rat
|
|
|
102
107
|
|
|
103
108
|
When `isEdit` is `false` the control is inert regardless of `isArrowSubmit`: no hover preview, no keyboard, `tabIndex={-1}`, and `aria-readonly="true"`.
|
|
104
109
|
|
|
110
|
+
The slider explicitly reports `aria-orientation="horizontal"`. Use
|
|
111
|
+
`getValueText` to localize its spoken value:
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
<ReactStarsRating
|
|
115
|
+
value={2.5}
|
|
116
|
+
getValueText={(value, count) => `${value} von ${count} Sternen`}
|
|
117
|
+
/>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Hover preview color
|
|
121
|
+
|
|
122
|
+
Set `hoverColor` to distinguish the pointer preview from both the saved value
|
|
123
|
+
and inactive stars. It is opt-in, so omitting it preserves the original
|
|
124
|
+
two-color presentation.
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<ReactStarsRating
|
|
128
|
+
value={3}
|
|
129
|
+
primaryColor="#f59e0b"
|
|
130
|
+
hoverColor="#38bdf8"
|
|
131
|
+
secondaryColor="#374151"
|
|
132
|
+
/>
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When the pointer previews `1.5`, the first `1.5` stars use `hoverColor`, the
|
|
136
|
+
remainder of the saved value uses `primaryColor`, and inactive stars use
|
|
137
|
+
`secondaryColor`. When previewing above the saved value, only the additional
|
|
138
|
+
preview region uses `hoverColor`.
|
|
139
|
+
|
|
105
140
|
## Server components
|
|
106
141
|
|
|
107
142
|
The package carries the `'use client'` directive, so it can be imported directly from a server component in the Next.js App Router without a wrapper.
|
|
108
143
|
|
|
109
144
|
## Form Integrations
|
|
110
145
|
|
|
146
|
+
### Native HTML forms
|
|
147
|
+
|
|
148
|
+
Pass `name` to contribute a hidden value to `FormData`. `defaultValue` enables
|
|
149
|
+
uncontrolled usage and native form reset behavior.
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
<form action="/reviews" method="post">
|
|
153
|
+
<ReactStarsRating name="rating" defaultValue={3} />
|
|
154
|
+
<button type="submit">Submit</button>
|
|
155
|
+
<button type="reset">Reset</button>
|
|
156
|
+
</form>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Use `value` with `onChange` for controlled state. Supplying `value` always
|
|
160
|
+
takes precedence over `defaultValue`.
|
|
161
|
+
|
|
111
162
|
### React Hook Form
|
|
112
163
|
|
|
113
164
|
```tsx
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("react"),t=require("react/jsx-runtime");var n=({primaryColor:e,secondaryColor:
|
|
1
|
+
"use client";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});let e=require("react"),t=require("react/jsx-runtime");var n=(e,t)=>Math.min(100,Math.max(0,Math.round((e-(t-1))*1e4)/100)),r=({primaryColor:e,secondaryColor:r,offset:i=50,index:a,value:o,fullId:s,halfId:c,noneId:l,hoverColor:u,hoverValue:d=null,committedValue:f=o,hoverGradientId:p})=>{if(u&&d!==null&&p){let i=Math.min(f,d),o=Math.max(f,d),s=n(i,a),c=n(o,a),l=[{start:0,end:s,color:d<=f?u:e},{start:s,end:c,color:d<=f?e:u},{start:c,end:100,color:r}].filter(({start:e,end:t})=>t>e);return(0,t.jsx)(`defs`,{children:(0,t.jsx)(`linearGradient`,{id:p,children:l.flatMap(({start:e,end:n,color:r},i)=>[(0,t.jsx)(`stop`,{offset:`${e}%`,stopColor:r},`${i}-start`),(0,t.jsx)(`stop`,{offset:`${n}%`,stopColor:r},`${i}-end`)])})})}let m=i;return a===1&&(m=Math.round(o%1*1e4)/100),a===1?(0,t.jsxs)(`defs`,{children:[(0,t.jsx)(`linearGradient`,{id:s,children:(0,t.jsx)(`stop`,{offset:`100%`,stopColor:e})}),(0,t.jsx)(`linearGradient`,{id:l,children:(0,t.jsx)(`stop`,{offset:`100%`,stopColor:r})}),(0,t.jsxs)(`linearGradient`,{id:c,children:[(0,t.jsx)(`stop`,{offset:`${m}%`,stopColor:e}),(0,t.jsx)(`stop`,{offset:`${m}%`,stopColor:r})]})]}):null},i=({viewBox:e=`0 0 306 306`,size:n,onPointerMove:i,onPointerLeave:a,onPointerDown:o,onPointerUp:s,onPointerCancel:c,index:l,value:u,isHalf:d,primaryColor:f,secondaryColor:p,hoverColor:m,hoverValue:h=null,committedValue:g=u,fill:_,offset:v=50,fullId:y,halfId:b,noneId:x})=>{let S=_,C=`${y}-hover-${l}`;return S=m&&h!==null?`url(#${C})`:l<=u?`url(#${y})`:d&&Math.ceil(u)===l?`url(#${b})`:`url(#${x})`,(0,t.jsxs)(`svg`,{width:n,viewBox:e,xmlns:`http://www.w3.org/2000/svg`,xmlnsXlink:`http://www.w3.org/1999/xlink`,onPointerLeave:a,onPointerMove:i,onPointerDown:o,onPointerUp:s,onPointerCancel:c,children:[(0,t.jsx)(r,{primaryColor:f,secondaryColor:p,offset:v,index:l,value:u,fullId:y,halfId:b,noneId:x,hoverColor:m,hoverValue:h,committedValue:g,hoverGradientId:C}),(0,t.jsx)(`polygon`,{fill:S,points:`153,230.775 247.35,299.625 211.65,187.425 306,121.125 191.25,121.125 153,6.375 114.75,121.125 0,121.125 94.35,187.425 58.65,299.625`,pointerEvents:`none`})]})},a={activeContainer:{border:`none`,display:`inline-flex`},inActiveContainer:{border:`none`,outline:0,display:`inline-flex`}},o=e=>Number.isFinite(e)&&e>=1?Math.floor(e):5,s=(e,t,n=0)=>Number.isFinite(e)&&e>=n?e:t,c=(e,t,n)=>{let r=Math.min(Math.max(Number.isFinite(e)?e:0,0),t);return n?r:Math.round(r)},l=({id:n,value:r,defaultValue:l=0,onChange:u=()=>{},name:d,disabled:f=!1,isEdit:p=!0,isHalf:m=!0,count:h=5,size:g=25,starGap:_=0,className:v=``,primaryColor:y=`orange`,secondaryColor:b=`grey`,hoverColor:x,isArrowSubmit:S=!1,ariaLabel:C=`Star rating`,ariaLabelledBy:w,getValueText:ee=(e,t)=>`${e} of ${t}`})=>{let T=o(h),te=s(g,25,2**-52),E=s(_,0),D=r!==void 0,[ne,O]=(0,e.useState)(()=>c(l,T,m)),k=c(r??ne,T,m),A=(0,e.useId)().replace(/:/g,``),j=n??`react-stars-rating-${A}`,[M,N]=(0,e.useState)(()=>({sourceValue:k,displayValue:k})),P=(0,e.useRef)(null),[F,I]=(0,e.useState)(null),L=(0,e.useRef)(null),R=M.sourceValue===k?M.displayValue:k,z=e=>{N({sourceValue:k,displayValue:c(e,T,m)})},re=(0,e.useMemo)(()=>`fullId-${j}`,[j]),B=(0,e.useMemo)(()=>`halfId-${j}`,[j]),V=(0,e.useMemo)(()=>`noneId-${j}`,[j]);(0,e.useEffect)(()=>{P.current=null},[k]),(0,e.useEffect)(()=>{if(D)return;let e=L.current?.closest(`form`),t=()=>{let e=c(l,T,m);P.current=null,I(null),O(e),N({sourceValue:e,displayValue:e})};return e?.addEventListener(`reset`,t),()=>e?.removeEventListener(`reset`,t)},[l,D,m,T]);let H=(e,t)=>{let n=Array.from(L.current?.querySelectorAll(`svg`)??[]),r=n.find(t=>{let n=t.getBoundingClientRect();return n.width>0&&e.clientX<=n.right})??n[n.length-1]??e.currentTarget,i=n.indexOf(r)+1||t;if(!m)return i;let a=r.getBoundingClientRect();return e.clientX-a.left>a.width/2?i:i-.5},U=(e,t)=>{if(!p||f)return;let n=typeof e.currentTarget.hasPointerCapture==`function`&&e.currentTarget.hasPointerCapture(e.pointerId);if(e.pointerType===`touch`&&!n)return;let r=H(e,t);P.current=null,I(r),z(r)},W=e=>{!p||f||e.buttons!==0||(I(null),z(k))},G=()=>{let e=P.current;e!==null&&(P.current=null,K(e))},K=e=>{let t=c(e,T,m);z(t),D||O(t),u(t)},q=(e,t)=>{if(!p||f)return;L.current?.focus(),e.currentTarget.setPointerCapture?.(e.pointerId),P.current=null;let n=H(e,t);I(n),z(n)},J=(e,t)=>{!p||f||(K(H(e,t)),e.currentTarget.releasePointerCapture?.(e.pointerId),e.pointerType===`touch`&&I(null))},Y=e=>{e.currentTarget.releasePointerCapture?.(e.pointerId),P.current=null,I(null),z(k)},X=e=>{let t=c(e,T,m);t!==R&&(z(t),S?(P.current=null,K(t)):P.current=t)},Z=e=>{let t=R%1==.5?R:Math.round(R);X(t+e)},ie=e=>{switch(e.key){case`ArrowLeft`:case`ArrowDown`:e.preventDefault(),Z(m?-.5:-1);break;case`ArrowRight`:case`ArrowUp`:e.preventDefault(),Z(m?.5:1);break;case`Home`:e.preventDefault(),X(0);break;case`End`:e.preventDefault(),X(T);break;case`Enter`:e.preventDefault(),P.current=null,K(R)}},ae=()=>Array.from({length:T},(e,n)=>{let r=n+1,a=r===T?void 0:{paddingRight:E};return(0,t.jsx)(`span`,{className:`star star-${r}`,style:a,children:(0,t.jsx)(i,{index:r,value:R,size:te,isHalf:m,fullId:re,halfId:B,noneId:V,primaryColor:y,secondaryColor:b,hoverColor:x,hoverValue:F,committedValue:k,onPointerMove:e=>U(e,r),onPointerLeave:W,onPointerDown:e=>q(e,r),onPointerUp:e=>J(e,r),onPointerCancel:Y})},`react-stars-rating-char${r}`)}),Q=p&&!f,$=c(R,T,m);return(0,t.jsxs)(`span`,{ref:L,id:j,role:`slider`,"aria-label":w?void 0:C,"aria-labelledby":w,"aria-valuemin":0,"aria-valuemax":T,"aria-valuenow":$,"aria-valuetext":ee($,T),"aria-orientation":`horizontal`,"aria-readonly":!p,"aria-disabled":f||void 0,tabIndex:Q?0:-1,onKeyDown:Q?ie:void 0,onBlur:Q?G:void 0,style:p?a.activeContainer:a.inActiveContainer,className:v,children:[ae(),d?(0,t.jsx)(`input`,{type:`hidden`,name:d,value:k,disabled:f}):null]})};exports.ReactStarsRating=l,exports.default=l;
|
package/dist/index.d.cts
CHANGED
|
@@ -5,18 +5,28 @@ export type ReactStarsRatingProps = {
|
|
|
5
5
|
*/
|
|
6
6
|
id?: string;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Controlled current rating. Values outside `0` to
|
|
9
|
+
* {@link ReactStarsRatingProps.count} are clamped. When omitted, the
|
|
10
|
+
* component manages its own value.
|
|
11
|
+
*/
|
|
12
|
+
value?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Initial value when the component is uncontrolled. Ignored when
|
|
15
|
+
* {@link ReactStarsRatingProps.value} is provided.
|
|
10
16
|
*
|
|
11
17
|
* @defaultValue 0
|
|
12
18
|
*/
|
|
13
|
-
|
|
19
|
+
defaultValue?: number;
|
|
14
20
|
/**
|
|
15
21
|
* Called with the new rating on click, on `Enter`, and on blur — and on
|
|
16
22
|
* every arrow key when {@link ReactStarsRatingProps.isArrowSubmit} is set.
|
|
17
23
|
* Hovering never calls it.
|
|
18
24
|
*/
|
|
19
25
|
onChange?: (value: number) => void;
|
|
26
|
+
/** Name of the hidden input contributed to the nearest HTML form. */
|
|
27
|
+
name?: string;
|
|
28
|
+
/** Disable interaction and native form submission. */
|
|
29
|
+
disabled?: boolean;
|
|
20
30
|
/**
|
|
21
31
|
* Whether the rating can be changed. When `false` the control has no hover
|
|
22
32
|
* preview, no keyboard handling, and is removed from the tab order.
|
|
@@ -70,6 +80,13 @@ export type ReactStarsRatingProps = {
|
|
|
70
80
|
* @defaultValue 'grey'
|
|
71
81
|
*/
|
|
72
82
|
secondaryColor?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Optional color for the portion being previewed by the pointer. The saved
|
|
85
|
+
* value keeps {@link ReactStarsRatingProps.primaryColor}, so moving below an
|
|
86
|
+
* existing rating can display preview, saved, and inactive regions at once.
|
|
87
|
+
* When omitted, hover previews retain the original two-color behavior.
|
|
88
|
+
*/
|
|
89
|
+
hoverColor?: string;
|
|
73
90
|
/**
|
|
74
91
|
* Report every arrow-key step through
|
|
75
92
|
* {@link ReactStarsRatingProps.onChange} immediately, instead of waiting for
|
|
@@ -91,6 +108,12 @@ export type ReactStarsRatingProps = {
|
|
|
91
108
|
* {@link ReactStarsRatingProps.ariaLabel}.
|
|
92
109
|
*/
|
|
93
110
|
ariaLabelledBy?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Formats the accessible value description.
|
|
113
|
+
*
|
|
114
|
+
* @defaultValue `(value, count) => `${value} of ${count}``
|
|
115
|
+
*/
|
|
116
|
+
getValueText?: (value: number, count: number) => string;
|
|
94
117
|
};
|
|
95
118
|
/**
|
|
96
119
|
* A star rating control. Renders as a single `role="slider"` element that
|
|
@@ -103,6 +126,6 @@ export type ReactStarsRatingProps = {
|
|
|
103
126
|
* <ReactStarsRating value={value} onChange={setValue} isHalf size={32} />
|
|
104
127
|
* ```
|
|
105
128
|
*/
|
|
106
|
-
declare const ReactStarsRating: ({ id, value, onChange, isEdit, isHalf, count, size, starGap, className, primaryColor, secondaryColor, isArrowSubmit, ariaLabel, ariaLabelledBy, }: ReactStarsRatingProps) => import("react").JSX.Element;
|
|
129
|
+
declare const ReactStarsRating: ({ id, value, defaultValue, onChange, name, disabled, isEdit, isHalf, count, size, starGap, className, primaryColor, secondaryColor, hoverColor, isArrowSubmit, ariaLabel, ariaLabelledBy, getValueText, }: ReactStarsRatingProps) => import("react").JSX.Element;
|
|
107
130
|
export { ReactStarsRating };
|
|
108
131
|
export default ReactStarsRating;
|
package/dist/index.d.ts
CHANGED
|
@@ -5,18 +5,28 @@ export type ReactStarsRatingProps = {
|
|
|
5
5
|
*/
|
|
6
6
|
id?: string;
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
8
|
+
* Controlled current rating. Values outside `0` to
|
|
9
|
+
* {@link ReactStarsRatingProps.count} are clamped. When omitted, the
|
|
10
|
+
* component manages its own value.
|
|
11
|
+
*/
|
|
12
|
+
value?: number;
|
|
13
|
+
/**
|
|
14
|
+
* Initial value when the component is uncontrolled. Ignored when
|
|
15
|
+
* {@link ReactStarsRatingProps.value} is provided.
|
|
10
16
|
*
|
|
11
17
|
* @defaultValue 0
|
|
12
18
|
*/
|
|
13
|
-
|
|
19
|
+
defaultValue?: number;
|
|
14
20
|
/**
|
|
15
21
|
* Called with the new rating on click, on `Enter`, and on blur — and on
|
|
16
22
|
* every arrow key when {@link ReactStarsRatingProps.isArrowSubmit} is set.
|
|
17
23
|
* Hovering never calls it.
|
|
18
24
|
*/
|
|
19
25
|
onChange?: (value: number) => void;
|
|
26
|
+
/** Name of the hidden input contributed to the nearest HTML form. */
|
|
27
|
+
name?: string;
|
|
28
|
+
/** Disable interaction and native form submission. */
|
|
29
|
+
disabled?: boolean;
|
|
20
30
|
/**
|
|
21
31
|
* Whether the rating can be changed. When `false` the control has no hover
|
|
22
32
|
* preview, no keyboard handling, and is removed from the tab order.
|
|
@@ -70,6 +80,13 @@ export type ReactStarsRatingProps = {
|
|
|
70
80
|
* @defaultValue 'grey'
|
|
71
81
|
*/
|
|
72
82
|
secondaryColor?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Optional color for the portion being previewed by the pointer. The saved
|
|
85
|
+
* value keeps {@link ReactStarsRatingProps.primaryColor}, so moving below an
|
|
86
|
+
* existing rating can display preview, saved, and inactive regions at once.
|
|
87
|
+
* When omitted, hover previews retain the original two-color behavior.
|
|
88
|
+
*/
|
|
89
|
+
hoverColor?: string;
|
|
73
90
|
/**
|
|
74
91
|
* Report every arrow-key step through
|
|
75
92
|
* {@link ReactStarsRatingProps.onChange} immediately, instead of waiting for
|
|
@@ -91,6 +108,12 @@ export type ReactStarsRatingProps = {
|
|
|
91
108
|
* {@link ReactStarsRatingProps.ariaLabel}.
|
|
92
109
|
*/
|
|
93
110
|
ariaLabelledBy?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Formats the accessible value description.
|
|
113
|
+
*
|
|
114
|
+
* @defaultValue `(value, count) => `${value} of ${count}``
|
|
115
|
+
*/
|
|
116
|
+
getValueText?: (value: number, count: number) => string;
|
|
94
117
|
};
|
|
95
118
|
/**
|
|
96
119
|
* A star rating control. Renders as a single `role="slider"` element that
|
|
@@ -103,6 +126,6 @@ export type ReactStarsRatingProps = {
|
|
|
103
126
|
* <ReactStarsRating value={value} onChange={setValue} isHalf size={32} />
|
|
104
127
|
* ```
|
|
105
128
|
*/
|
|
106
|
-
declare const ReactStarsRating: ({ id, value, onChange, isEdit, isHalf, count, size, starGap, className, primaryColor, secondaryColor, isArrowSubmit, ariaLabel, ariaLabelledBy, }: ReactStarsRatingProps) => import("react").JSX.Element;
|
|
129
|
+
declare const ReactStarsRating: ({ id, value, defaultValue, onChange, name, disabled, isEdit, isHalf, count, size, starGap, className, primaryColor, secondaryColor, hoverColor, isArrowSubmit, ariaLabel, ariaLabelledBy, getValueText, }: ReactStarsRatingProps) => import("react").JSX.Element;
|
|
107
130
|
export { ReactStarsRating };
|
|
108
131
|
export default ReactStarsRating;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";import{useEffect as e,useId as t,useMemo as n,useRef as r,useState as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";var s=({primaryColor:e,secondaryColor:t,offset:n=50,index:r,value:i,fullId:
|
|
1
|
+
"use client";import{useEffect as e,useId as t,useMemo as n,useRef as r,useState as i}from"react";import{jsx as a,jsxs as o}from"react/jsx-runtime";var s=(e,t)=>Math.min(100,Math.max(0,Math.round((e-(t-1))*1e4)/100)),c=({primaryColor:e,secondaryColor:t,offset:n=50,index:r,value:i,fullId:c,halfId:l,noneId:u,hoverColor:d,hoverValue:f=null,committedValue:p=i,hoverGradientId:m})=>{if(d&&f!==null&&m){let n=Math.min(p,f),i=Math.max(p,f),o=s(n,r),c=s(i,r),l=[{start:0,end:o,color:f<=p?d:e},{start:o,end:c,color:f<=p?e:d},{start:c,end:100,color:t}].filter(({start:e,end:t})=>t>e);return a(`defs`,{children:a(`linearGradient`,{id:m,children:l.flatMap(({start:e,end:t,color:n},r)=>[a(`stop`,{offset:`${e}%`,stopColor:n},`${r}-start`),a(`stop`,{offset:`${t}%`,stopColor:n},`${r}-end`)])})})}let h=n;return r===1&&(h=Math.round(i%1*1e4)/100),r===1?o(`defs`,{children:[a(`linearGradient`,{id:c,children:a(`stop`,{offset:`100%`,stopColor:e})}),a(`linearGradient`,{id:u,children:a(`stop`,{offset:`100%`,stopColor:t})}),o(`linearGradient`,{id:l,children:[a(`stop`,{offset:`${h}%`,stopColor:e}),a(`stop`,{offset:`${h}%`,stopColor:t})]})]}):null},l=({viewBox:e=`0 0 306 306`,size:t,onPointerMove:n,onPointerLeave:r,onPointerDown:i,onPointerUp:s,onPointerCancel:l,index:u,value:d,isHalf:f,primaryColor:p,secondaryColor:m,hoverColor:h,hoverValue:g=null,committedValue:_=d,fill:v,offset:y=50,fullId:b,halfId:x,noneId:S})=>{let C=v,w=`${b}-hover-${u}`;return C=h&&g!==null?`url(#${w})`:u<=d?`url(#${b})`:f&&Math.ceil(d)===u?`url(#${x})`:`url(#${S})`,o(`svg`,{width:t,viewBox:e,xmlns:`http://www.w3.org/2000/svg`,xmlnsXlink:`http://www.w3.org/1999/xlink`,onPointerLeave:r,onPointerMove:n,onPointerDown:i,onPointerUp:s,onPointerCancel:l,children:[a(c,{primaryColor:p,secondaryColor:m,offset:y,index:u,value:d,fullId:b,halfId:x,noneId:S,hoverColor:h,hoverValue:g,committedValue:_,hoverGradientId:w}),a(`polygon`,{fill:C,points:`153,230.775 247.35,299.625 211.65,187.425 306,121.125 191.25,121.125 153,6.375 114.75,121.125 0,121.125 94.35,187.425 58.65,299.625`,pointerEvents:`none`})]})},u={activeContainer:{border:`none`,display:`inline-flex`},inActiveContainer:{border:`none`,outline:0,display:`inline-flex`}},d=e=>Number.isFinite(e)&&e>=1?Math.floor(e):5,f=(e,t,n=0)=>Number.isFinite(e)&&e>=n?e:t,p=(e,t,n)=>{let r=Math.min(Math.max(Number.isFinite(e)?e:0,0),t);return n?r:Math.round(r)},m=({id:s,value:c,defaultValue:m=0,onChange:h=()=>{},name:g,disabled:_=!1,isEdit:v=!0,isHalf:y=!0,count:b=5,size:x=25,starGap:S=0,className:C=``,primaryColor:w=`orange`,secondaryColor:T=`grey`,hoverColor:E,isArrowSubmit:ee=!1,ariaLabel:D=`Star rating`,ariaLabelledBy:O,getValueText:k=(e,t)=>`${e} of ${t}`})=>{let A=d(b),j=f(x,25,2**-52),M=f(S,0),N=c!==void 0,[te,P]=i(()=>p(m,A,y)),F=p(c??te,A,y),ne=t().replace(/:/g,``),I=s??`react-stars-rating-${ne}`,[L,R]=i(()=>({sourceValue:F,displayValue:F})),z=r(null),[B,V]=i(null),H=r(null),U=L.sourceValue===F?L.displayValue:F,W=e=>{R({sourceValue:F,displayValue:p(e,A,y)})},G=n(()=>`fullId-${I}`,[I]),K=n(()=>`halfId-${I}`,[I]),q=n(()=>`noneId-${I}`,[I]);e(()=>{z.current=null},[F]),e(()=>{if(N)return;let e=H.current?.closest(`form`),t=()=>{let e=p(m,A,y);z.current=null,V(null),P(e),R({sourceValue:e,displayValue:e})};return e?.addEventListener(`reset`,t),()=>e?.removeEventListener(`reset`,t)},[m,N,y,A]);let J=(e,t)=>{let n=Array.from(H.current?.querySelectorAll(`svg`)??[]),r=n.find(t=>{let n=t.getBoundingClientRect();return n.width>0&&e.clientX<=n.right})??n[n.length-1]??e.currentTarget,i=n.indexOf(r)+1||t;if(!y)return i;let a=r.getBoundingClientRect();return e.clientX-a.left>a.width/2?i:i-.5},re=(e,t)=>{if(!v||_)return;let n=typeof e.currentTarget.hasPointerCapture==`function`&&e.currentTarget.hasPointerCapture(e.pointerId);if(e.pointerType===`touch`&&!n)return;let r=J(e,t);z.current=null,V(r),W(r)},ie=e=>{!v||_||e.buttons!==0||(V(null),W(F))},ae=()=>{let e=z.current;e!==null&&(z.current=null,Y(e))},Y=e=>{let t=p(e,A,y);W(t),N||P(t),h(t)},oe=(e,t)=>{if(!v||_)return;H.current?.focus(),e.currentTarget.setPointerCapture?.(e.pointerId),z.current=null;let n=J(e,t);V(n),W(n)},se=(e,t)=>{!v||_||(Y(J(e,t)),e.currentTarget.releasePointerCapture?.(e.pointerId),e.pointerType===`touch`&&V(null))},ce=e=>{e.currentTarget.releasePointerCapture?.(e.pointerId),z.current=null,V(null),W(F)},X=e=>{let t=p(e,A,y);t!==U&&(W(t),ee?(z.current=null,Y(t)):z.current=t)},Z=e=>{let t=U%1==.5?U:Math.round(U);X(t+e)},le=e=>{switch(e.key){case`ArrowLeft`:case`ArrowDown`:e.preventDefault(),Z(y?-.5:-1);break;case`ArrowRight`:case`ArrowUp`:e.preventDefault(),Z(y?.5:1);break;case`Home`:e.preventDefault(),X(0);break;case`End`:e.preventDefault(),X(A);break;case`Enter`:e.preventDefault(),z.current=null,Y(U)}},ue=()=>Array.from({length:A},(e,t)=>{let n=t+1,r=n===A?void 0:{paddingRight:M};return a(`span`,{className:`star star-${n}`,style:r,children:a(l,{index:n,value:U,size:j,isHalf:y,fullId:G,halfId:K,noneId:q,primaryColor:w,secondaryColor:T,hoverColor:E,hoverValue:B,committedValue:F,onPointerMove:e=>re(e,n),onPointerLeave:ie,onPointerDown:e=>oe(e,n),onPointerUp:e=>se(e,n),onPointerCancel:ce})},`react-stars-rating-char${n}`)}),Q=v&&!_,$=p(U,A,y);return o(`span`,{ref:H,id:I,role:`slider`,"aria-label":O?void 0:D,"aria-labelledby":O,"aria-valuemin":0,"aria-valuemax":A,"aria-valuenow":$,"aria-valuetext":k($,A),"aria-orientation":`horizontal`,"aria-readonly":!v,"aria-disabled":_||void 0,tabIndex:Q?0:-1,onKeyDown:Q?le:void 0,onBlur:Q?ae:void 0,style:v?u.activeContainer:u.inActiveContainer,className:C,children:[ue(),g?a(`input`,{type:`hidden`,name:g,value:F,disabled:_}):null]})};export{m as ReactStarsRating,m as default};
|
package/dist/index.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use client";(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react")):typeof define==`function`&&define.amd?define([`exports`,`react`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ReactAwesomeStarsRating={},e.React))})(this,function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var n=({primaryColor:e,secondaryColor:t,offset:
|
|
1
|
+
"use client";(function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports,require("react")):typeof define==`function`&&define.amd?define([`exports`,`react`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.ReactAwesomeStarsRating={},e.React))})(this,function(e,t){Object.defineProperties(e,{__esModule:{value:!0},[Symbol.toStringTag]:{value:`Module`}});var n=(e,t)=>Math.min(100,Math.max(0,Math.round((e-(t-1))*1e4)/100)),r=({primaryColor:e,secondaryColor:t,offset:r=50,index:i,value:a,fullId:o,halfId:s,noneId:c,hoverColor:l,hoverValue:u=null,committedValue:d=a,hoverGradientId:f})=>{if(l&&u!==null&&f){let r=Math.min(d,u),a=Math.max(d,u),o=n(r,i),s=n(a,i),c=[{start:0,end:o,color:u<=d?l:e},{start:o,end:s,color:u<=d?e:l},{start:s,end:100,color:t}].filter(({start:e,end:t})=>t>e);return React.createElement(`defs`,null,React.createElement(`linearGradient`,{id:f},c.flatMap(({start:e,end:t,color:n},r)=>[React.createElement(`stop`,{key:`${r}-start`,offset:`${e}%`,stopColor:n}),React.createElement(`stop`,{key:`${r}-end`,offset:`${t}%`,stopColor:n})])))}let p=r;return i===1&&(p=Math.round(a%1*1e4)/100),i===1?React.createElement(`defs`,null,React.createElement(`linearGradient`,{id:o},React.createElement(`stop`,{offset:`100%`,stopColor:e})),React.createElement(`linearGradient`,{id:c},React.createElement(`stop`,{offset:`100%`,stopColor:t})),React.createElement(`linearGradient`,{id:s},React.createElement(`stop`,{offset:`${p}%`,stopColor:e}),React.createElement(`stop`,{offset:`${p}%`,stopColor:t}))):null},i=({viewBox:e=`0 0 306 306`,size:t,onPointerMove:n,onPointerLeave:i,onPointerDown:a,onPointerUp:o,onPointerCancel:s,index:c,value:l,isHalf:u,primaryColor:d,secondaryColor:f,hoverColor:p,hoverValue:m=null,committedValue:h=l,fill:g,offset:_=50,fullId:v,halfId:y,noneId:b})=>{let x=g,S=`${v}-hover-${c}`;return x=p&&m!==null?`url(#${S})`:c<=l?`url(#${v})`:u&&Math.ceil(l)===c?`url(#${y})`:`url(#${b})`,React.createElement(`svg`,{width:t,viewBox:e,xmlns:`http://www.w3.org/2000/svg`,xmlnsXlink:`http://www.w3.org/1999/xlink`,onPointerLeave:i,onPointerMove:n,onPointerDown:a,onPointerUp:o,onPointerCancel:s},React.createElement(r,{primaryColor:d,secondaryColor:f,offset:_,index:c,value:l,fullId:v,halfId:y,noneId:b,hoverColor:p,hoverValue:m,committedValue:h,hoverGradientId:S}),React.createElement(`polygon`,{fill:x,points:`153,230.775 247.35,299.625 211.65,187.425 306,121.125 191.25,121.125 153,6.375 114.75,121.125 0,121.125 94.35,187.425 58.65,299.625`,pointerEvents:`none`}))},a={activeContainer:{border:`none`,display:`inline-flex`},inActiveContainer:{border:`none`,outline:0,display:`inline-flex`}},o=e=>Number.isFinite(e)&&e>=1?Math.floor(e):5,s=(e,t,n=0)=>Number.isFinite(e)&&e>=n?e:t,c=(e,t,n)=>{let r=Math.min(Math.max(Number.isFinite(e)?e:0,0),t);return n?r:Math.round(r)},l=({id:e,value:n,defaultValue:r=0,onChange:l=()=>{},name:u,disabled:d=!1,isEdit:f=!0,isHalf:p=!0,count:m=5,size:h=25,starGap:g=0,className:_=``,primaryColor:v=`orange`,secondaryColor:y=`grey`,hoverColor:b,isArrowSubmit:x=!1,ariaLabel:S=`Star rating`,ariaLabelledBy:C,getValueText:w=(e,t)=>`${e} of ${t}`})=>{let T=o(m),E=s(h,25,2**-52),D=s(g,0),O=n!==void 0,[k,A]=(0,t.useState)(()=>c(r,T,p)),j=c(n??k,T,p),ee=(0,t.useId)().replace(/:/g,``),M=e??`react-stars-rating-${ee}`,[N,P]=(0,t.useState)(()=>({sourceValue:j,displayValue:j})),F=(0,t.useRef)(null),[I,L]=(0,t.useState)(null),R=(0,t.useRef)(null),z=N.sourceValue===j?N.displayValue:j,B=e=>{P({sourceValue:j,displayValue:c(e,T,p)})},V=(0,t.useMemo)(()=>`fullId-${M}`,[M]),H=(0,t.useMemo)(()=>`halfId-${M}`,[M]),U=(0,t.useMemo)(()=>`noneId-${M}`,[M]);(0,t.useEffect)(()=>{F.current=null},[j]),(0,t.useEffect)(()=>{if(O)return;let e=R.current?.closest(`form`),t=()=>{let e=c(r,T,p);F.current=null,L(null),A(e),P({sourceValue:e,displayValue:e})};return e?.addEventListener(`reset`,t),()=>e?.removeEventListener(`reset`,t)},[r,O,p,T]);let W=(e,t)=>{let n=Array.from(R.current?.querySelectorAll(`svg`)??[]),r=n.find(t=>{let n=t.getBoundingClientRect();return n.width>0&&e.clientX<=n.right})??n[n.length-1]??e.currentTarget,i=n.indexOf(r)+1||t;if(!p)return i;let a=r.getBoundingClientRect();return e.clientX-a.left>a.width/2?i:i-.5},G=(e,t)=>{if(!f||d)return;let n=typeof e.currentTarget.hasPointerCapture==`function`&&e.currentTarget.hasPointerCapture(e.pointerId);if(e.pointerType===`touch`&&!n)return;let r=W(e,t);F.current=null,L(r),B(r)},K=e=>{!f||d||e.buttons!==0||(L(null),B(j))},q=()=>{let e=F.current;e!==null&&(F.current=null,J(e))},J=e=>{let t=c(e,T,p);B(t),O||A(t),l(t)},Y=(e,t)=>{if(!f||d)return;R.current?.focus(),e.currentTarget.setPointerCapture?.(e.pointerId),F.current=null;let n=W(e,t);L(n),B(n)},te=(e,t)=>{!f||d||(J(W(e,t)),e.currentTarget.releasePointerCapture?.(e.pointerId),e.pointerType===`touch`&&L(null))},ne=e=>{e.currentTarget.releasePointerCapture?.(e.pointerId),F.current=null,L(null),B(j)},X=e=>{let t=c(e,T,p);t!==z&&(B(t),x?(F.current=null,J(t)):F.current=t)},Z=e=>{let t=z%1==.5?z:Math.round(z);X(t+e)},re=e=>{switch(e.key){case`ArrowLeft`:case`ArrowDown`:e.preventDefault(),Z(p?-.5:-1);break;case`ArrowRight`:case`ArrowUp`:e.preventDefault(),Z(p?.5:1);break;case`Home`:e.preventDefault(),X(0);break;case`End`:e.preventDefault(),X(T);break;case`Enter`:e.preventDefault(),F.current=null,J(z)}},ie=()=>Array.from({length:T},(e,t)=>{let n=t+1,r=n===T?void 0:{paddingRight:D};return React.createElement(`span`,{key:`react-stars-rating-char${n}`,className:`star star-${n}`,style:r},React.createElement(i,{index:n,value:z,size:E,isHalf:p,fullId:V,halfId:H,noneId:U,primaryColor:v,secondaryColor:y,hoverColor:b,hoverValue:I,committedValue:j,onPointerMove:e=>G(e,n),onPointerLeave:K,onPointerDown:e=>Y(e,n),onPointerUp:e=>te(e,n),onPointerCancel:ne}))}),Q=f&&!d,$=c(z,T,p);return React.createElement(`span`,{ref:R,id:M,role:`slider`,"aria-label":C?void 0:S,"aria-labelledby":C,"aria-valuemin":0,"aria-valuemax":T,"aria-valuenow":$,"aria-valuetext":w($,T),"aria-orientation":`horizontal`,"aria-readonly":!f,"aria-disabled":d||void 0,tabIndex:Q?0:-1,onKeyDown:Q?re:void 0,onBlur:Q?q:void 0,style:f?a.activeContainer:a.inActiveContainer,className:_},ie(),u?React.createElement(`input`,{type:`hidden`,name:u,value:j,disabled:d}):null)};e.ReactStarsRating=l,e.default=l});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-awesome-stars-rating",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "Accessible star rating component for React, with half stars, keyboard control and any scale or palette.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"coverage": "vitest run --coverage",
|
|
70
70
|
"verify:package": "node scripts/verify-package.mjs",
|
|
71
71
|
"verify:release": "node scripts/verify-release-notes.mjs",
|
|
72
|
+
"verify:published": "node scripts/verify-published.mjs",
|
|
72
73
|
"lint:package": "publint && attw --pack",
|
|
73
74
|
"size": "size-limit",
|
|
74
75
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
@@ -139,19 +140,19 @@
|
|
|
139
140
|
{
|
|
140
141
|
"name": "ESM entry",
|
|
141
142
|
"path": "dist/index.mjs",
|
|
142
|
-
"limit": "
|
|
143
|
+
"limit": "2.55 kB",
|
|
143
144
|
"gzip": true
|
|
144
145
|
},
|
|
145
146
|
{
|
|
146
147
|
"name": "CJS entry",
|
|
147
148
|
"path": "dist/index.cjs",
|
|
148
|
-
"limit": "
|
|
149
|
+
"limit": "2.6 kB",
|
|
149
150
|
"gzip": true
|
|
150
151
|
},
|
|
151
152
|
{
|
|
152
153
|
"name": "UMD bundle",
|
|
153
154
|
"path": "dist/index.umd.cjs",
|
|
154
|
-
"limit": "
|
|
155
|
+
"limit": "2.7 kB",
|
|
155
156
|
"gzip": true
|
|
156
157
|
}
|
|
157
158
|
],
|
package/dist/gradient.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
type GradientProps = {
|
|
2
|
-
primaryColor: string;
|
|
3
|
-
secondaryColor: string;
|
|
4
|
-
offset?: number;
|
|
5
|
-
index: number;
|
|
6
|
-
value: number;
|
|
7
|
-
fullId: string;
|
|
8
|
-
halfId: string;
|
|
9
|
-
noneId: string;
|
|
10
|
-
};
|
|
11
|
-
declare const Gradient: ({ primaryColor, secondaryColor, offset, index, value, fullId, halfId, noneId, }: GradientProps) => import("react").JSX.Element | null;
|
|
12
|
-
export default Gradient;
|
package/dist/star.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { MouseEvent } from 'react';
|
|
2
|
-
type StarProps = {
|
|
3
|
-
viewBox?: string;
|
|
4
|
-
size: number;
|
|
5
|
-
primaryColor: string;
|
|
6
|
-
secondaryColor: string;
|
|
7
|
-
onMouseLeave?: (event: MouseEvent<SVGSVGElement>) => void;
|
|
8
|
-
onMouseMove?: (event: MouseEvent<SVGSVGElement>) => void;
|
|
9
|
-
onChange?: (event: MouseEvent<SVGSVGElement>) => void;
|
|
10
|
-
isHalf: boolean;
|
|
11
|
-
fill?: string;
|
|
12
|
-
index: number;
|
|
13
|
-
value: number;
|
|
14
|
-
offset?: number;
|
|
15
|
-
fullId: string;
|
|
16
|
-
halfId: string;
|
|
17
|
-
noneId: string;
|
|
18
|
-
};
|
|
19
|
-
declare const StarSVG: ({ viewBox, size, onMouseMove, onMouseLeave, onChange, index, value, isHalf, primaryColor, secondaryColor, fill, offset, fullId, halfId, noneId, }: StarProps) => import("react").JSX.Element;
|
|
20
|
-
export default StarSVG;
|