{"id":56,"date":"2017-09-29T04:09:00","date_gmt":"2017-09-29T04:09:00","guid":{"rendered":"https:\/\/blog.raoulwegat.com\/?p=56"},"modified":"2023-09-05T07:42:55","modified_gmt":"2023-09-05T07:42:55","slug":"intermediate-svg-icons-in-react","status":"publish","type":"post","link":"https:\/\/blog.raoulwegat.com\/?p=56","title":{"rendered":"Intermediate SVG Icons in\u00a0React"},"content":{"rendered":"\n<p id=\"70ae\">One of the things Product Designers at Automattic get to do plenty of is to tinker with code. Whether it\u2019s prototyping, writing CSS, or even playing with&nbsp;<a href=\"http:\/\/processing.org\/\" rel=\"noreferrer noopener\" target=\"_blank\">new tools<\/a>. And that\u2019s what I normally get up to on Hack\/Trash Day \u2014 our internal day to work on something that\u2019s not you\u2019re regular job \u2014 fixing something that needs fixing.<\/p>\n\n\n\n<p id=\"8716\">During last August\u2019s Hack\/Trash Day, I picked \u201creplace Noticons with Gridicons in&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\" rel=\"noreferrer noopener\" target=\"_blank\">Calypso<\/a>\u201d. Noticons are our old icon font based icons, and&nbsp;<a href=\"https:\/\/github.com\/Automattic\/gridicons\/\" rel=\"noreferrer noopener\" target=\"_blank\">Gridicons<\/a>&nbsp;are our new SVG-based icons.<\/p>\n\n\n\n<p id=\"bea7\">One of my icon font to SVG replacements involved creating a&nbsp;<a href=\"https:\/\/github.com\/Automattic\/gridicons\/pull\/249\" rel=\"noreferrer noopener\" target=\"_blank\">half-star Gridicon<\/a>&nbsp;so our&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\/tree\/master\/client\/components\/rating\" rel=\"noreferrer noopener\" target=\"_blank\">Rating component<\/a>&nbsp;in Calypso could be updated to use all SVG-based Gridicons.<\/p>\n\n\n\n<p id=\"fde8\">In my Github PR to present the new icon, my colleague&nbsp;<a href=\"https:\/\/design.blog\/2016\/08\/08\/davide-casali\/\" rel=\"noreferrer noopener\" target=\"_blank\">Davide Casali<\/a>mentioned how there\u2019d been previous discussion to create intermediate icons by overlaying a solid icon over an outline icon and masking out what you don\u2019t need. This was a brilliant solution to help keep our SVG icon library compact and performant, so I got straight to work.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"6639\">HTML\/CSS Prototype<\/h2>\n\n\n\n<p id=\"3116\">First up, I prototyped the rating component using just HTML and CSS at&nbsp;<a href=\"https:\/\/codepen.io\/raoulwegat\/pen\/yzBqEm\" rel=\"noreferrer noopener\" target=\"_blank\">Codepen<\/a>. At it\u2019s core, the rating component has two rows of icons, one positioned absolutely over the other. Masking is handled by both the new&nbsp;<code>clip-path<\/code>&nbsp;property, and the deprecated&nbsp;<code>clip<\/code>&nbsp;properties. Why use a deprecated property? Unfortunately,&nbsp;<code>\u2019clip-path<\/code>&nbsp;is not supported by any Microsoft browsers, but&nbsp;<code>clip<\/code>&nbsp;is still supported by every browser. And I figure that Microsoft won\u2019t be pulling support for&nbsp;<code>clip<\/code>&nbsp;until they introduce&nbsp;<code>clip-path<\/code>.<\/p>\n\n\n\n<p id=\"6cdf\">It\u2019s important to note that there\u2019s two differences in how&nbsp;<code>clip<\/code>&nbsp;and&nbsp;<code>clip-path<\/code>calculate the masking rectangles:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"clip: rect(0, $mask-position, $height, 0);\nclip-path: inset(0 $clip-path-mask-position 0 0);\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">clip: rect(0, $mask-position, $height, 0)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">clip-path: inset(0 $clip-path-mask-position 0 0)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"has-d-8-dee-9-ff-color has-text-color has-875-rem-font-size\"><code>rect<\/code>&nbsp;values are positional: top, left, bottom and right; whereas&nbsp;<code>inset<\/code>&nbsp;values are: from-top, from-right, from-bottom and from-left.<\/p>\n\n\n\n<p id=\"785c\">Once I was happy with the result and tested it on our supported browsers, I got started on integrating it into its home, the&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\/tree\/master\/client\/components\/rating\" rel=\"noreferrer noopener\" target=\"_blank\">React component<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"107c\">Reactify<\/h2>\n\n\n\n<p id=\"324f\">My JavaScript skills are very far removed from what Automattic\u2019s JavaScript Wranglers are capable of, but I\u2019ve had some exposure to React, so I was determined to give it a good go.<\/p>\n\n\n\n<p id=\"d8e6\">One of my first realizations was that most of what I had written in SASS, would need to be rewritten into JavaScript\/React.<\/p>\n\n\n\n<p id=\"ae51\">For example the SASS mixin to change the outline-only stars:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"@mixin outline-grey( $rating ) {\n  $inverse-rating: 100 - $rating;\n  @if $inverse-rating \/ 20 &gt;= 1 {\n\t\/\/ need an integer to make this work\n\t$count: floor($inverse-rating \/ 20);\n\t\/\/ add a color class to only those stars outside the rating\n\t@for $i from 1 through $count {\n\t  .gridicon.outline-#{$i} {\n\t\tfill: lighten( $gray, 20% );\n\t  }\n\t}\n  }\n}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">@mixin<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">outline-grey<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> $rating <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  $inverse-rating<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #88C0D0\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #88C0D0\"> $rating<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #81A1C1\">@if<\/span><span style=\"color: #D8DEE9FF\"> $inverse-rating <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">&gt;=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t<\/span><span style=\"color: #616E88\">\/\/ need an integer to make this work<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t$count<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">floor<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\">$inverse-rating <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #88C0D0\"> <\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t<\/span><span style=\"color: #616E88\">\/\/ add a color class to only those stars outside the rating<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t<\/span><span style=\"color: #81A1C1\">@for<\/span><span style=\"color: #D8DEE9FF\"> $i <\/span><span style=\"color: #81A1C1\">from<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">1<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">through<\/span><span style=\"color: #D8DEE9FF\"> $count <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t  <\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">gridicon<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">outline-<\/span><span style=\"color: #81A1C1; font-style: italic\">#{<\/span><span style=\"color: #D8DEE9; font-style: italic\">$i<\/span><span style=\"color: #81A1C1; font-style: italic\">}<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t\t<\/span><span style=\"color: #D8DEE9\">fill<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">lighten<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #88C0D0\"> $gray<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #88C0D0\"> <\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #81A1C1\">%<\/span><span style=\"color: #88C0D0\"> <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t  <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t<\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">  <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p id=\"8b65\">became a JavaScript loop:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"let outlineStyles = { fill: '#00aadc' };\nif ( inverseRating \/ 20 &gt;= 1 ) {\n\tif ( i &gt; ( 5 - outlineCount ) ) {\n\t\toutlineStyles = {\n\t\t\tfill: '#c8d7e1',\n\t\t};\n\t}\n}\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">let outlineStyles = <\/span><span style=\"color: #ECEFF4\">{<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fill<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">#00aadc<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">if ( inverseRating \/ 20 &gt;= 1 ) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\tif ( <\/span><span style=\"color: #81A1C1\">i<\/span><span style=\"color: #D8DEE9FF\"> &gt; ( 5 - outlineCount ) ) <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t\toutlineStyles = <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t\t\t<\/span><span style=\"color: #D8DEE9\">fill<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">#c8d7e1<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #88C0D0\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t\t<\/span><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">\t<\/span><span style=\"color: #ECEFF4\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p id=\"06ab\">But the SASS math to calculate the values:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"$rating: round($rating \/ 10) * 10;\n$width: $height * 5;\n$mask-position: ( ( $rating \/ 100 ) * $width );\n$clip-path-mask-position: ( $width - ( ( $rating \/ 100 ) * $width ) );\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">$rating<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">round<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\">$rating <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">10<\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">10<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">$width<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> $height <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">5<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">$mask-position<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> $rating <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> $width <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">$clip-path-mask-position<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> $width <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> $rating <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> $width <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p id=\"f6df\">remained math:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"const roundRating = Math.round( this.props.rating \/ 10 ) * 10;\nconst ratingWidth = ( this.props.size * 5 );\nconst maskPosition = ( ( roundRating \/ 100 ) * ratingWidth ) + 'px';\nconst clipPathMaskPosition = ( ratingWidth - ( ( roundRating \/ 100 ) * ratingWidth ) ) + 'px';\nconst overlayHeightPx = ( this.props.size ) + 'px';\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">const roundRating = <\/span><span style=\"color: #81A1C1\">Math<\/span><span style=\"color: #D8DEE9FF\">.round( this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">props<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">rating<\/span><span style=\"color: #D8DEE9FF\"> \/ 10 ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> 10<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">const ratingWidth = ( this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">props<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">size<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> 5 )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">const maskPosition = ( ( roundRating \/ 100 ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> ratingWidth ) + &#39;px&#39;<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">const clipPathMaskPosition = ( ratingWidth - ( ( roundRating \/ 100 ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> ratingWidth ) ) + &#39;px&#39;<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">const overlayHeightPx = ( this<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">props<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #8FBCBB\">size<\/span><span style=\"color: #D8DEE9FF\"> ) + &#39;px&#39;<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p id=\"ecd3\">And to add an additional CSS class to a DOM object, you firstly create an object to hold the CSS property:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"const style = { fill: '#ffffff' }\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9FF\">const <\/span><span style=\"color: #81A1C1\">style<\/span><span style=\"color: #D8DEE9FF\"> = <\/span><span style=\"color: #ECEFF4\">{<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">fill<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">#ffffff<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p id=\"bc4c\">And then add your additional CSS properties using Object.assign like this:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"allStyles = Object.assign( {}, style, { color: '#c8d7e1' } );\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D8DEE9\">allStyles<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Object<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">assign<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #ECEFF4\">{},<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">style<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">color<\/span><span style=\"color: #ECEFF4\">:<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">#c8d7e1<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"b4d8\">Testing<\/h1>\n\n\n\n<p id=\"69fe\">We use&nbsp;<a href=\"https:\/\/wpcalypso.wordpress.com\/devdocs\/docs\/testing\/component-tests.md\" rel=\"noreferrer noopener\" target=\"_blank\">component testing<\/a>&nbsp;on&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\" rel=\"noreferrer noopener\" target=\"_blank\">Calypso<\/a>&nbsp;to ensure code and UI components work as they should. As the final part of this update, I needed to rewrite the&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\/blob\/master\/client\/components\/rating\/test\/index.js\" rel=\"noreferrer noopener\" target=\"_blank\">test for this component<\/a>&nbsp;which had been written to count the number of font icons being rendered.<\/p>\n\n\n\n<p id=\"2f33\">Because all SVG icons were being rendered all of the time, I needed to take a different approach, and that was to check that the mask being created was of the correct dimension. Basically I was running the component code in reverse and in one test, inside a loop over each value the component would display (0\u2013100).<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"const ratingList = [ 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 ];\n    it.each( ratingList, 'should render rating %s as %s', [ 'element', 'element' ], function( element ) {\n        const rating = element,\n            size = 24, \/\/ use default size\n            wrapper = shallow(\n                &lt;Rating\n                    rating={ rating }\n                    size={ size }\n                \/&gt;\n            );\n \n        const roundRating = Math.round( rating \/ 10 ) * 10;\n        const ratingWidth = ( size * 5 );\n        const maskPosition = ( ( roundRating \/ 100 ) * ratingWidth );\n        const clipPathMaskPosition = ( ratingWidth - ( ( roundRating \/ 100 ) * ratingWidth ) );\n        const component = wrapper.find( 'div.rating__overlay' );\n        expect( component.props().style.clipPath ).to.equal( 'inset(0 ' + clipPathMaskPosition + 'px 0 0 )' );\n        expect( component.props().style.clip ).to.equal( 'rect(0, ' + maskPosition + 'px, ' + size + 'px, 0)' );\n    } );\" style=\"color:#d8dee9ff;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki nord\" style=\"background-color: #2e3440ff\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ratingList<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> [ <\/span><span style=\"color: #B48EAD\">10<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">20<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">30<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">40<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">50<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">60<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">70<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">80<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">90<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #D8DEE9FF\"> ]<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #D8DEE9\">it<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">each<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #D8DEE9\">ratingList<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">should render rating %s as %s<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> [ <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">element<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">element<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> ]<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">function<\/span><span style=\"color: #ECEFF4\">(<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">element<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">)<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">rating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">element<\/span><span style=\"color: #ECEFF4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">size<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">24<\/span><span style=\"color: #ECEFF4\">,<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #616E88\">\/\/ use default size<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            <\/span><span style=\"color: #D8DEE9\">wrapper<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #88C0D0\">shallow<\/span><span style=\"color: #D8DEE9FF\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #81A1C1\">&lt;<\/span><span style=\"color: #8FBCBB\">Rating<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                    <\/span><span style=\"color: #8FBCBB\">rating<\/span><span style=\"color: #81A1C1\">={<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">rating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                    <\/span><span style=\"color: #8FBCBB\">size<\/span><span style=\"color: #81A1C1\">={<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">size<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">                <\/span><span style=\"color: #81A1C1\">\/&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">            )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">roundRating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">Math<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">round<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #D8DEE9\">rating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">10<\/span><span style=\"color: #D8DEE9FF\"> ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">10<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ratingWidth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> ( <\/span><span style=\"color: #D8DEE9\">size<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">5<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">maskPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> ( ( <\/span><span style=\"color: #D8DEE9\">roundRating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #D8DEE9FF\"> ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ratingWidth<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">clipPathMaskPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> ( <\/span><span style=\"color: #D8DEE9\">ratingWidth<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">-<\/span><span style=\"color: #D8DEE9FF\"> ( ( <\/span><span style=\"color: #D8DEE9\">roundRating<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">\/<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #B48EAD\">100<\/span><span style=\"color: #D8DEE9FF\"> ) <\/span><span style=\"color: #81A1C1\">*<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">ratingWidth<\/span><span style=\"color: #D8DEE9FF\"> ) )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #81A1C1\">const<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">component<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">=<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">wrapper<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">find<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">div.rating__overlay<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #88C0D0\">expect<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #D8DEE9\">component<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">props<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">style<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">clipPath<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">to<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">equal<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">inset(0 <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">clipPathMaskPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">px 0 0 )<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">        <\/span><span style=\"color: #88C0D0\">expect<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #D8DEE9\">component<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">props<\/span><span style=\"color: #D8DEE9FF\">()<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">style<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">clip<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #D8DEE9\">to<\/span><span style=\"color: #ECEFF4\">.<\/span><span style=\"color: #88C0D0\">equal<\/span><span style=\"color: #D8DEE9FF\">( <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">rect(0, <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">maskPosition<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">px, <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #D8DEE9\">size<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #81A1C1\">+<\/span><span style=\"color: #D8DEE9FF\"> <\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #A3BE8C\">px, 0)<\/span><span style=\"color: #ECEFF4\">&#39;<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D8DEE9FF\">    <\/span><span style=\"color: #ECEFF4\">}<\/span><span style=\"color: #D8DEE9FF\"> )<\/span><span style=\"color: #81A1C1\">;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"a859\">Challenges<\/h1>\n\n\n\n<p id=\"9266\">The biggest challenge I faced was that the component was written almost two years ago, and the current preferred JavaScript style is ES6. I don\u2019t know enough about the differences to make changes, so I largely left the linter recommendations alone.<\/p>\n\n\n\n<p id=\"2184\">I knew that come the code review, a JavaScript Wrangler would come to the code\u2019s rescue and bring it into 2017. As it happened, that colleague would be&nbsp;<a href=\"https:\/\/github.com\/aidvu\" rel=\"noreferrer noopener\" target=\"_blank\">Andrija Vucinic<\/a>, who also gave my code a nice cleanup&nbsp;<a href=\"https:\/\/github.com\/Automattic\/wp-calypso\/pull\/18103\/commits\/503a6df12c8a28a25db0d5535fe68309650a0d2d\" rel=\"noreferrer noopener\" target=\"_blank\">refactor<\/a>.<\/p>\n\n\n\n<p id=\"0b40\">If you have a self-hosted WordPress site and use the Jetpack plugin, you can see the component in action on&nbsp;<a href=\"http:\/\/wordpress.com\/\" rel=\"noreferrer noopener\" target=\"_blank\">WordPress.com<\/a>&nbsp;in the Manage Plugins page.<\/p>\n\n\n\n<p id=\"31f5\">So there you have it, a new and performant way to do rating stars and also how to bring it nicely into React.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p><em>Originally published at&nbsp;<\/em><a rel=\"noreferrer noopener\" href=\"https:\/\/a8cdesignflow.wordpress.com\/2017\/09\/29\/intermediate-svg-icons-in-react\/\" target=\"_blank\"><em>a8cdesignflow.wordpress.com<\/em><\/a><em>&nbsp;on September 29, 2017.<\/em><\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the things Product Designers at Automattic get to do plenty of is to tinker with code. Whether it\u2019s prototyping, writing CSS, or even playing with&nbsp;new tools. And that\u2019s what I normally get up to on Hack\/Trash Day \u2014 our internal day to work on something that\u2019s not you\u2019re regular job \u2014 fixing something [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":815,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-56","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/posts\/56","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=56"}],"version-history":[{"count":1,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/posts\/56\/revisions"}],"predecessor-version":[{"id":791,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/posts\/56\/revisions\/791"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=\/wp\/v2\/media\/815"}],"wp:attachment":[{"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=56"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=56"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.raoulwegat.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=56"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}