mirror of
https://github.com/zhigang1992/react.git
synced 2026-04-28 20:25:29 +08:00
feat(rating): a new component rating indicator (#543)
* chore(deps): bump lodash from 4.17.20 to 4.17.21 (#537) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * (feature) rating state working and islocked working * (feature) custom emojis for the ratings added * refactor(rating): migrate component to scaleable * feat(rating): use inline icon component test(rating): update testcase * docs(rating): add document for zh-cn Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: unix <unix.bio@gmail.com>
This commit is contained in:
@@ -118,6 +118,9 @@ export type { ProgressProps } from './progress'
|
||||
export { default as Radio } from './radio'
|
||||
export type { RadioProps, RadioGroupProps, RadioDescriptionProps } from './radio'
|
||||
|
||||
export { default as Rating } from './rating'
|
||||
export type { RatingProps } from './rating'
|
||||
|
||||
export { default as Select } from './select'
|
||||
export type { SelectProps, SelectOptionProps } from './select'
|
||||
|
||||
|
||||
362
components/rating/__tests__/__snapshots__/index.test.tsx.snap
Normal file
362
components/rating/__tests__/__snapshots__/index.test.tsx.snap
Normal file
@@ -0,0 +1,362 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Rating should render correctly 1`] = `
|
||||
"<div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div>"
|
||||
`;
|
||||
|
||||
exports[`Rating should show different initialization values 1`] = `
|
||||
"<div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div></div>"
|
||||
`;
|
||||
|
||||
exports[`Rating should update snapshot on mouse enter 1`] = `
|
||||
"<div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #0070f3;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #0070f3;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div id=\\"valueDiv\\">5</div><div id=\\"lockDiv\\">false</div></div>"
|
||||
`;
|
||||
|
||||
exports[`Rating should update snapshot on mouse enter 2`] = `
|
||||
"<div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #0070f3;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: default;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #0070f3;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div id=\\"valueDiv\\">5</div><div id=\\"lockDiv\\">true</div></div>"
|
||||
`;
|
||||
|
||||
exports[`Rating should work with different types 1`] = `
|
||||
"<div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #000;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #000;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #0070f3;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #0070f3;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #f5a623;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #f5a623;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div><div class=\\"rating \\"><div class=\\"icon-box hovered\\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><div class=\\"icon-box \\"><svg viewBox=\\"0 0 24 24\\" width=\\"24\\" height=\\"24\\" stroke=\\"currentColor\\" stroke-width=\\"1.5\\" stroke-linecap=\\"round\\" stroke-linejoin=\\"round\\" fill=\\"none\\" shape-rendering=\\"geometricPrecision\\"><path d=\\"M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z\\"></path></svg></div><style>
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: calc(1 * 16px);
|
||||
font-size: var(--rating-font-size);
|
||||
width: auto;
|
||||
height: auto;
|
||||
padding: 0 0 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: #e00;
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: pointer;
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: #e00;
|
||||
transform: scale(0.9);
|
||||
}
|
||||
</style></div></div>"
|
||||
`;
|
||||
108
components/rating/__tests__/index.test.tsx
Normal file
108
components/rating/__tests__/index.test.tsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Rating } from 'components'
|
||||
import { mount } from 'enzyme'
|
||||
import { nativeEvent } from 'tests/utils'
|
||||
|
||||
describe('Rating', () => {
|
||||
it('should render correctly', () => {
|
||||
const wrapper = mount(<Rating />)
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should work with different types', () => {
|
||||
const wrapper = mount(
|
||||
<div>
|
||||
<Rating type="secondary" />
|
||||
<Rating type="success" />
|
||||
<Rating type="warning" />
|
||||
<Rating type="error" />
|
||||
</div>,
|
||||
)
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should show different initialization values', () => {
|
||||
const wrapper = mount(
|
||||
<div>
|
||||
<Rating count={10} value={5} />
|
||||
<Rating count={2} value={1} />
|
||||
<Rating count={10} value={10} />
|
||||
<Rating count={2} value={2} />
|
||||
</div>,
|
||||
)
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
expect(() => wrapper.unmount()).not.toThrow()
|
||||
})
|
||||
|
||||
it('should initialize state and lock value', () => {
|
||||
const WrapperRating = () => {
|
||||
const [value, setValue] = useState<number>(1)
|
||||
const [lock, setLock] = useState<boolean>(false)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Rating
|
||||
type="success"
|
||||
value={value}
|
||||
onLockedChange={setLock}
|
||||
onValueChange={setValue}
|
||||
/>
|
||||
<div id="valueDiv">{value}</div>
|
||||
<div id="lockDiv">{lock ? 'true' : 'false'}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperRating />)
|
||||
expect(wrapper.find('svg').children())
|
||||
expect(wrapper.find('#valueDiv').text()).toContain('1')
|
||||
expect(wrapper.find('#lockDiv').text()).toContain('false')
|
||||
})
|
||||
|
||||
it('should update state and lock value on click', () => {
|
||||
const WrapperRating = () => {
|
||||
const [value, setValue] = useState<number>(1)
|
||||
const [lock, setLock] = useState<boolean>(false)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Rating type="success" onLockedChange={setLock} onValueChange={setValue} />
|
||||
<div id="valueDiv">{value}</div>
|
||||
<div id="lockDiv">{lock ? 'true' : 'false'}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperRating />)
|
||||
expect(wrapper.find('.icon-box').last().simulate('click', nativeEvent))
|
||||
expect(wrapper.find('#valueDiv').text()).toContain('5')
|
||||
expect(wrapper.find('#lockDiv').text()).toContain('true')
|
||||
// unlock again
|
||||
expect(wrapper.find('.icon-box').last().simulate('click', nativeEvent))
|
||||
expect(wrapper.find('#valueDiv').text()).toContain('5')
|
||||
expect(wrapper.find('#lockDiv').text()).toContain('false')
|
||||
})
|
||||
|
||||
it('should update snapshot on mouse enter', () => {
|
||||
const WrapperRating = () => {
|
||||
const [value, setValue] = useState<number>(0)
|
||||
const [lock, setLock] = useState<boolean>(false)
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Rating type="success" onLockedChange={setLock} onValueChange={setValue} />
|
||||
<div id="valueDiv">{value}</div>
|
||||
<div id="lockDiv">{lock ? 'true' : 'false'}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
const wrapper = mount(<WrapperRating />)
|
||||
const lastStar = wrapper.find('.icon-box').last()
|
||||
const firstStar = wrapper.find('.icon-box').first()
|
||||
expect(lastStar.simulate('mouseenter'))
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
expect(lastStar.simulate('click', nativeEvent))
|
||||
expect(firstStar.simulate('mouseenter'))
|
||||
expect(wrapper.html()).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
4
components/rating/index.ts
Normal file
4
components/rating/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import Rating from './rating'
|
||||
|
||||
export type { RatingProps, RatingTypes, RatingCount, RatingValue } from './rating'
|
||||
export default Rating
|
||||
21
components/rating/rating-icon.tsx
Normal file
21
components/rating/rating-icon.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react'
|
||||
|
||||
const RatingIcon: React.FC<unknown> = () => {
|
||||
return (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
width="24"
|
||||
height="24"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
fill="none"
|
||||
shapeRendering="geometricPrecision">
|
||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
RatingIcon.displayName = 'GeistRatingIcon'
|
||||
export default RatingIcon
|
||||
141
components/rating/rating.tsx
Normal file
141
components/rating/rating.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { GeistUIThemesPalette } from '../themes'
|
||||
import { NormalTypes, tupleNumber } from '../utils/prop-types'
|
||||
import RatingIcon from './rating-icon'
|
||||
import useTheme from '../use-theme'
|
||||
import useScaleable, { withScaleable } from '../use-scaleable'
|
||||
|
||||
export type RatingTypes = NormalTypes
|
||||
const ratingCountTuple = tupleNumber(2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
const ratingValueTuple = tupleNumber(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
||||
export type RatingValue = typeof ratingValueTuple[number]
|
||||
export type RatingCount = typeof ratingCountTuple[number]
|
||||
|
||||
interface Props {
|
||||
type?: RatingTypes
|
||||
className?: string
|
||||
icon?: JSX.Element
|
||||
count?: RatingCount | number
|
||||
value?: RatingValue | number
|
||||
initialValue?: RatingValue
|
||||
onValueChange?: (value: number) => void
|
||||
locked?: boolean
|
||||
onLockedChange?: (locked: boolean) => void
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
type: 'default' as RatingTypes,
|
||||
className: '',
|
||||
icon: (<RatingIcon />) as JSX.Element,
|
||||
count: 5 as RatingCount,
|
||||
initialValue: 1 as RatingValue,
|
||||
locked: false,
|
||||
}
|
||||
|
||||
type NativeAttrs = Omit<React.HTMLAttributes<any>, keyof Props>
|
||||
export type RatingProps = Props & NativeAttrs
|
||||
|
||||
const getColor = (type: RatingTypes, palette: GeistUIThemesPalette): string => {
|
||||
const colors: { [key in RatingTypes]?: string } = {
|
||||
default: palette.foreground,
|
||||
success: palette.success,
|
||||
warning: palette.warning,
|
||||
error: palette.error,
|
||||
}
|
||||
return colors[type] || (colors.default as string)
|
||||
}
|
||||
|
||||
const RatingComponent: React.FC<RatingProps> = ({
|
||||
type,
|
||||
children,
|
||||
className,
|
||||
icon,
|
||||
count,
|
||||
value: customValue,
|
||||
initialValue,
|
||||
onValueChange,
|
||||
locked,
|
||||
onLockedChange,
|
||||
...props
|
||||
}: React.PropsWithChildren<RatingProps> & typeof defaultProps) => {
|
||||
const theme = useTheme()
|
||||
const { SCALES } = useScaleable()
|
||||
const color = useMemo(() => getColor(type, theme.palette), [type, theme.palette])
|
||||
const [value, setValue] = useState<number>(initialValue)
|
||||
const [isLocked, setIsLocked] = useState<boolean>(locked)
|
||||
|
||||
const lockedChangeHandler = (next: boolean) => {
|
||||
setIsLocked(next)
|
||||
onLockedChange && onLockedChange(next)
|
||||
}
|
||||
const valueChangeHandler = (next: number) => {
|
||||
setValue(next)
|
||||
const emitValue = next > count ? count : next
|
||||
onValueChange && onValueChange(emitValue)
|
||||
}
|
||||
const clickHandler = (index: number) => {
|
||||
if (isLocked) return lockedChangeHandler(false)
|
||||
valueChangeHandler(index)
|
||||
lockedChangeHandler(true)
|
||||
}
|
||||
const mouseEnterHandler = (index: number) => {
|
||||
if (isLocked) return
|
||||
valueChangeHandler(index)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof customValue === 'undefined') return
|
||||
setValue(customValue < 0 ? 0 : customValue)
|
||||
}, [customValue])
|
||||
|
||||
return (
|
||||
<div className={`rating ${className}`} {...props}>
|
||||
{[...Array(count)].map((_, index) => (
|
||||
<div
|
||||
className={`icon-box ${index + 1 <= value ? 'hovered' : ''}`}
|
||||
key={index}
|
||||
onMouseEnter={() => mouseEnterHandler(index + 1)}
|
||||
onClick={() => clickHandler(index + 1)}>
|
||||
{icon}
|
||||
</div>
|
||||
))}
|
||||
<style jsx>{`
|
||||
.rating {
|
||||
box-sizing: border-box;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
--rating-font-size: ${SCALES.font(1)};
|
||||
font-size: var(--rating-font-size);
|
||||
width: ${SCALES.width(1, 'auto')};
|
||||
height: ${SCALES.height(1, 'auto')};
|
||||
padding: ${SCALES.pt(0)} ${SCALES.pr(0)} ${SCALES.pb(0)} ${SCALES.pl(0)};
|
||||
margin: ${SCALES.mt(0)} ${SCALES.mr(0)} ${SCALES.mb(0)} ${SCALES.ml(0)};
|
||||
}
|
||||
.icon-box {
|
||||
box-sizing: border-box;
|
||||
color: ${color};
|
||||
width: calc(var(--rating-font-size) * 1.5);
|
||||
height: calc(var(--rating-font-size) * 1.5);
|
||||
margin-right: calc(var(--rating-font-size) * 1 / 5);
|
||||
cursor: ${isLocked ? 'default' : 'pointer'};
|
||||
}
|
||||
.icon-box :global(svg) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
fill: transparent;
|
||||
transform: scale(1);
|
||||
transition: transform, color, fill 30ms linear;
|
||||
}
|
||||
.hovered :global(svg) {
|
||||
fill: ${color};
|
||||
transform: scale(0.9);
|
||||
}
|
||||
`}</style>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
RatingComponent.defaultProps = defaultProps
|
||||
RatingComponent.displayName = 'GeistRating'
|
||||
const Rating = withScaleable(RatingComponent)
|
||||
export default Rating
|
||||
@@ -1,5 +1,7 @@
|
||||
export const tuple = <T extends string[]>(...args: T) => args
|
||||
|
||||
export const tupleNumber = <T extends number[]>(...args: T) => args
|
||||
|
||||
const buttonTypes = tuple(
|
||||
'default',
|
||||
'secondary',
|
||||
|
||||
Reference in New Issue
Block a user