mirror of
https://github.com/zhigang1992/react.git
synced 2026-03-28 22:46:38 +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',
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
next-env.d.ts
vendored
1
next-env.d.ts
vendored
@@ -1,2 +1,3 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
34093
package-lock.json
generated
Normal file
34093
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
116
pages/en-us/components/rating.mdx
Normal file
116
pages/en-us/components/rating.mdx
Normal file
@@ -0,0 +1,116 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Rating, Grid, Spacer } from 'components'
|
||||
import { useState } from 'react'
|
||||
import { Award, Github } from '@geist-ui/react-icons'
|
||||
|
||||
export const meta = {
|
||||
title: 'Rating',
|
||||
group: 'Feedback',
|
||||
}
|
||||
|
||||
## Rating
|
||||
|
||||
Display an indicator of rankings with stars.
|
||||
|
||||
<Playground
|
||||
title="Default"
|
||||
desc="A default rating component with initializers and callbacks."
|
||||
scope={{ Rating, Grid, useState }}
|
||||
code={`
|
||||
() => {
|
||||
const [value, setValue] = useState(1)
|
||||
const [locked, setLocked] = useState(false)
|
||||
return(
|
||||
<Grid.Container gap={2}>
|
||||
<Grid xs={24} md={8} justify="center">
|
||||
<Rating onLockedChange={setLocked} value={value} onValueChange={setValue}/>
|
||||
</Grid>
|
||||
<Grid xs={12} md={8} justify="center">Selection: {value}</Grid>
|
||||
<Grid xs={12} md={8} justify="center">Locked: {locked ? "true" : "false"}</Grid>
|
||||
</Grid.Container>
|
||||
)
|
||||
}
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="Types"
|
||||
desc="Pass the property `type` to the Rating component."
|
||||
scope={{ Rating, Grid }}
|
||||
code={`
|
||||
<Grid.Container gap={2} justify="center">
|
||||
<Grid xs={24} sm={24} md={8} justify="center"><Rating type="success"/></Grid>
|
||||
<Grid xs={24} sm={12} md={8} justify="center"><Rating type="error"/></Grid>
|
||||
<Grid xs={24} sm={12} md={8} justify="center"><Rating type="warning"/></Grid>
|
||||
</Grid.Container>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="Custom Amount"
|
||||
desc="Customize the amount of stars."
|
||||
scope={{ Rating, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Rating count={2} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating value={3} count={6} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating value={4} count={8}/>
|
||||
</>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="Icon"
|
||||
desc="Customize the icons of a rating."
|
||||
scope={{ Rating, Award, Github, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Rating
|
||||
value={4}
|
||||
count={6}
|
||||
type="success"
|
||||
icon={<Github />} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating count={7} type="error" icon={<Award />} />
|
||||
</>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Attributes edit="/pages/en-us/components/rating.mdx">
|
||||
<Attributes.Title>Rating.Props</Attributes.Title>
|
||||
|
||||
| Attribute | Description | Type | Accepted values | Default |
|
||||
| ------------------ | ------------------- | ----------------------- | --------------------------- | --------- |
|
||||
| **type** | rating type | `RatingTypes` | [RatingTypes](#ratingtypes) | `default` |
|
||||
| **icon** | custom icon | `JSX.Element` | - | - |
|
||||
| **count** | rating star count | `number` | [RatingCount](#ratingcount) | `5` |
|
||||
| **value** | star values | `number` | [RatingValue](#ratingvalue) | - |
|
||||
| **initialValue** | initial star values | `number` | [RatingValue](#ratingvalue) | `1` |
|
||||
| **onValueChange** | value change event | `(value?: any) => void` | - | - |
|
||||
| **locked** | lock state | `boolean` | - | `false` |
|
||||
| **onLockedChange** | locked change event | `(value?: any) => void` | - | - |
|
||||
| ... | native props | `HTMLAttributes` | - | - |
|
||||
|
||||
<Attributes.Title>RatingTypes</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingTypes = 'default' | 'secondary' | 'success' | 'warning' | 'error'
|
||||
```
|
||||
|
||||
<Attributes.Title>RatingCount</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingCount = 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
```
|
||||
|
||||
<Attributes.Title>RatingValue</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingValue = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
```
|
||||
|
||||
</Attributes>
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>
|
||||
115
pages/zh-cn/components/rating.mdx
Normal file
115
pages/zh-cn/components/rating.mdx
Normal file
@@ -0,0 +1,115 @@
|
||||
import { Layout, Playground, Attributes } from 'lib/components'
|
||||
import { Rating, Grid, Spacer } from 'components'
|
||||
import { useState } from 'react'
|
||||
import { Award, Github } from '@geist-ui/react-icons'
|
||||
|
||||
export const meta = {
|
||||
title: '评分 Rating',
|
||||
group: '反馈',
|
||||
}
|
||||
|
||||
## Rating / 评分
|
||||
|
||||
以多个图标展示可互动的评分。
|
||||
|
||||
<Playground
|
||||
desc="设置初始值与回调事件。"
|
||||
scope={{ Rating, Grid, useState }}
|
||||
code={`
|
||||
() => {
|
||||
const [value, setValue] = useState(1)
|
||||
const [locked, setLocked] = useState(false)
|
||||
return(
|
||||
<Grid.Container gap={2}>
|
||||
<Grid xs={24} md={8} justify="center">
|
||||
<Rating onLockedChange={setLocked} value={value} onValueChange={setValue}/>
|
||||
</Grid>
|
||||
<Grid xs={12} md={8} justify="center">已选择: {value}</Grid>
|
||||
<Grid xs={12} md={8} justify="center">锁定: {locked ? "是" : "否"}</Grid>
|
||||
</Grid.Container>
|
||||
)
|
||||
}
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="类型"
|
||||
desc="通过 `type` 属性展示不同的评分组件。"
|
||||
scope={{ Rating, Grid }}
|
||||
code={`
|
||||
<Grid.Container gap={2} justify="center">
|
||||
<Grid xs={24} sm={24} md={8} justify="center"><Rating type="success"/></Grid>
|
||||
<Grid xs={24} sm={12} md={8} justify="center"><Rating type="error"/></Grid>
|
||||
<Grid xs={24} sm={12} md={8} justify="center"><Rating type="warning"/></Grid>
|
||||
</Grid.Container>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="最大数量"
|
||||
desc="定制图标的最大数量。"
|
||||
scope={{ Rating, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Rating count={2} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating value={3} count={6} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating value={4} count={8}/>
|
||||
</>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Playground
|
||||
title="图标"
|
||||
desc="以自定义 SVG 图标代替默认的星星图案。"
|
||||
scope={{ Rating, Award, Github, Spacer }}
|
||||
code={`
|
||||
<>
|
||||
<Rating
|
||||
value={4}
|
||||
count={6}
|
||||
type="success"
|
||||
icon={<Github />} />
|
||||
<Spacer h={0.5} />
|
||||
<Rating count={7} type="error" icon={<Award />} />
|
||||
</>
|
||||
`}
|
||||
/>
|
||||
|
||||
<Attributes edit="/pages/zh-cn/components/rating.mdx">
|
||||
<Attributes.Title>Rating.Props</Attributes.Title>
|
||||
|
||||
| 属性 | 描述 | 类型 | 推荐值 | 默认 |
|
||||
| ------------------ | ---------------- | ----------------------- | --------------------------- | --------- |
|
||||
| **type** | 评分组件类型 | `RatingTypes` | [RatingTypes](#ratingtypes) | `default` |
|
||||
| **icon** | 自定义图标 | `JSX.Element` | - | - |
|
||||
| **count** | 展示图标最大数量 | `number` | [RatingCount](#ratingcount) | `5` |
|
||||
| **value** | 选中值 | `number` | [RatingValue](#ratingvalue) | - |
|
||||
| **initialValue** | 初始值 | `number` | [RatingValue](#ratingvalue) | `1` |
|
||||
| **onValueChange** | 值变化的事件 | `(value?: any) => void` | - | - |
|
||||
| **locked** | 是否锁定 | `boolean` | - | `false` |
|
||||
| **onLockedChange** | 锁定变化事件 | `(value?: any) => void` | - | - |
|
||||
| ... | 原生属性 | `HTMLAttributes` | - | - |
|
||||
|
||||
<Attributes.Title>RatingTypes</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingTypes = 'default' | 'secondary' | 'success' | 'warning' | 'error'
|
||||
```
|
||||
|
||||
<Attributes.Title>RatingCount</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingCount = 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
```
|
||||
|
||||
<Attributes.Title>RatingValue</Attributes.Title>
|
||||
|
||||
```ts
|
||||
type RatingValue = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
|
||||
```
|
||||
|
||||
</Attributes>
|
||||
|
||||
export default ({ children }) => <Layout meta={meta}>{children}</Layout>
|
||||
Reference in New Issue
Block a user