{"id":28110,"date":"2021-04-07T20:21:01","date_gmt":"2021-04-07T20:21:01","guid":{"rendered":"http:\/\/How-to-change-SVG-color-on-interaction-with-LitElement"},"modified":"2021-04-07T20:21:01","modified_gmt":"2021-04-07T20:21:01","slug":"how-to-change-svg-color-on-interaction-with-litelement","status":"publish","type":"post","link":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/","title":{"rendered":"How to change SVG color on interaction with LitElement"},"content":{"rendered":"<div class=\"wp-block-cloudinary-markdown \"><p>Web Components have been around for a couple of years now. According to the most recent <a href=\"https:\/\/developer.cdn.mozilla.net\/en-US\/docs\/Web\/Web_Components\">MDN<\/a> documentation:<\/p>\n<blockquote>\n<p>Web Components is a suite of technologies that allow you to create custom elements, whose functionality is encapsulated and separated from the rest of the source code, for use in web applications.<\/p>\n<\/blockquote>\n<p>On other hand, SVG content is the preferred way to add logos, icons, and other graphic resources on the web. Mainly because of their speed, accessibility, and resolution among other benefits.<\/p>\n<p>In this <em>Media Jam<\/em>, we\u2019l use <a href=\"\">LitElement<\/a> features and TypeScript to process interactions that allow changing the SVG colors in a practical way.<\/p>\n<h2>The Problem<\/h2>\n<p>Let\u2019s suppose you\u2019re working in a web application that needs to render some web components that are built using SVG content. However, it\u2019s needed to capture the user interaction to provide a change of the state of your widget using a different color. See the next image for a better understanding.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/res.cloudinary.com\/jesse-thisdot\/image\/upload\/c_limit,w_2000\/f_auto\/q_auto\/v1614993226\/e-60354e32ba3535006813ce00\/ijnquh051okxusfnbbjm.jpg\" alt=\"\" loading=\"lazy\" class=\"c-transformed-asset\"  width=\"1856\" height=\"1108\"\/><\/p>\n<p>As you may think, we can implement these widgets using the Web Components approach and provide an external component to trigger the state change. Let\u2019s get started.<\/p>\n<h2>The Solution<\/h2>\n<h3>The SVG Icons<\/h3>\n<p>Let\u2019s get started using a couple of SVG icons. Instead of creating <code>.svg<\/code> files, we can define this content as <a href=\"https:\/\/lit-html.polymer-project.org\/\">lit-html<\/a> templates.<\/p>\n<blockquote>\n<p>lit-html is an efficient, expressive, extensible HTML templating library for JavaScript.<\/p>\n<\/blockquote>\n<p>This is the template library to be used to render the custom components later.<\/p>\n<ul>\n<li>Start creating the <code>svg\/svg-heart.ts<\/code> file<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ svg-heart.ts<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { html } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit-html'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> corpIconHeart = html`<span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">svg<\/span>\n    <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"24\"<\/span>\n    <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"24\"<\/span>\n    <span class=\"hljs-attr\">viewBox<\/span>=<span class=\"hljs-string\">\"0 0 24 24\"<\/span>\n    <span class=\"hljs-attr\">fill<\/span>=<span class=\"hljs-string\">\"none\"<\/span>\n    <span class=\"hljs-attr\">xmlns<\/span>=<span class=\"hljs-string\">\"http:\/\/www.w3.org\/2000\/svg\"<\/span>\n  &gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">path<\/span>\n      <span class=\"hljs-attr\">d<\/span>=<span class=\"hljs-string\">\"M12 21.35L10.55 20.03C5.4 15.36 2 12.27 2 8.5C2 5.41 4.42 3 7.5 3C9.24 3 10.91 3.81 12 5.08C13.09 3.81 14.76 3 16.5 3C19.58 3 22 5.41 22 8.5C22 12.27 18.6 15.36 13.45 20.03L12 21.35Z\"<\/span>\n    \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">svg<\/span>&gt;<\/span>\n`<\/span>;\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<ul>\n<li>Now create an alternative icon in the <code>svg\/svg-user.ts<\/code> file.<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ svg-user.ts<\/span>\n\n<span class=\"hljs-keyword\">import<\/span> { html } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit-html'<\/span>;\n\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-keyword\">const<\/span> corpIconUser = html`<span class=\"xml\">\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">svg<\/span>\n    <span class=\"hljs-attr\">width<\/span>=<span class=\"hljs-string\">\"24\"<\/span>\n    <span class=\"hljs-attr\">height<\/span>=<span class=\"hljs-string\">\"24\"<\/span>\n    <span class=\"hljs-attr\">viewBox<\/span>=<span class=\"hljs-string\">\"0 0 24 24\"<\/span>\n    <span class=\"hljs-attr\">fill<\/span>=<span class=\"hljs-string\">\"none\"<\/span>\n    <span class=\"hljs-attr\">xmlns<\/span>=<span class=\"hljs-string\">\"http:\/\/www.w3.org\/2000\/svg\"<\/span>\n  &gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">path<\/span>\n      <span class=\"hljs-attr\">d<\/span>=<span class=\"hljs-string\">\"M7.5 6.5C7.5 8.981 9.519 11 12 11C14.481 11 16.5 8.981 16.5 6.5C16.5 4.019 14.481 2 12 2C9.519 2 7.5 4.019 7.5 6.5ZM20 21H21V20C21 16.141 17.859 13 14 13H10C6.14 13 3 16.141 3 20V21H20Z\"<\/span>\n    \/&gt;<\/span>\n  <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">svg<\/span>&gt;<\/span>\n`<\/span>;\n\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Creating the Icon Component<\/h3>\n<p>We can create a small component as an abstraction to load any icon defined in the application. Let\u2019s create it under the <code>corp-icon.ts<\/code> file with the following content.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-keyword\">import<\/span> {\n  LitElement,\n  html,\n  property,\n  customElement,\n  css,\n  TemplateResult,\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit-element'<\/span>;\n\n@customElement(<span class=\"hljs-string\">'corp-icon'<\/span>)\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CorpIcon<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">LitElement<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> styles = css`<span class=\"css\">\n    <span class=\"hljs-selector-pseudo\">:host<\/span> {\n      <span class=\"hljs-attribute\">display<\/span>: inline-block;\n    }\n    <span class=\"hljs-selector-class\">.corp-button<\/span> {\n      <span class=\"hljs-attribute\">padding<\/span>: <span class=\"hljs-number\">10px<\/span>;\n      <span class=\"hljs-attribute\">border-radius<\/span>: <span class=\"hljs-number\">5px<\/span>;\n      <span class=\"hljs-attribute\">cursor<\/span>: pointer;\n    }\n  `<\/span>;\n\n  @property({ <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-built_in\">String<\/span> }) icon?: TemplateResult;\n  @property({ <span class=\"hljs-attr\">type<\/span>: <span class=\"hljs-built_in\">String<\/span> }) color?: string;\n\n  <span class=\"hljs-keyword\">constructor<\/span>() {\n    <span class=\"hljs-keyword\">super<\/span>();\n  }\n\n  render() {\n    <span class=\"hljs-keyword\">return<\/span> html`<span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"corp-button\"<\/span>&gt;<\/span>\n        <\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.icon}<\/span><span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    `<\/span>;\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>Using the <code>@property<\/code> declaration from LitElement, we\u2019ll be rendering the template every time the given property changes.<\/p>\n<p>To have more control over the possible changes over any of these attributes, we can override the <code>updated<\/code> function as follows.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ corp-icon.ts<\/span>\n  updated(changedProperties: <span class=\"hljs-built_in\">Map<\/span>&lt;string, unknown&gt;) {\n    <span class=\"hljs-keyword\">if<\/span> (changedProperties.has(<span class=\"hljs-string\">'color'<\/span>)) {\n      <span class=\"hljs-keyword\">const<\/span> svg = <span class=\"hljs-keyword\">this<\/span>.shadowRoot.querySelector(<span class=\"hljs-string\">'svg'<\/span>);\n      <span class=\"hljs-keyword\">let<\/span> color: string;\n      <span class=\"hljs-keyword\">switch<\/span> (<span class=\"hljs-keyword\">this<\/span>.color) {\n        <span class=\"hljs-keyword\">case<\/span> <span class=\"hljs-string\">'primary'<\/span>:\n          color = <span class=\"hljs-string\">'#0066FF'<\/span>;\n          <span class=\"hljs-keyword\">break<\/span>;\n        <span class=\"hljs-keyword\">default<\/span>:\n          color = <span class=\"hljs-string\">'#555555'<\/span>;\n          <span class=\"hljs-keyword\">break<\/span>;\n      }\n      svg.style.fill = color;\n    }\n  }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>You can use the <code>updated<\/code> function(which is part of the <a href=\"https:\/\/lit-element.polymer-project.org\/guide\/lifecycle\">component\u2019s lifecycle<\/a>) to:<\/p>\n<ul>\n<li>Identify a property change<\/li>\n<li>Perform any post-updating task<\/li>\n<\/ul>\n<p>Also, let\u2019s understand what\u2019s happening in the above code snippet:<\/p>\n<ul>\n<li>\n<code>changedProperties.has('color')<\/code> verifies if the property <code>color<\/code> has been changed.<\/li>\n<li>Once the above property changes, we\u2019ll get access to the <code>&lt;svg&gt;<\/code> element in the DOM through the <code>this.shadowRoot.querySelector('svg')<\/code> call.<\/li>\n<li>According to the new state of the <code>color<\/code> attribute(<code>this.color<\/code>) we\u2019ll perform an update assigning the <em>primary<\/em> or a <em>default<\/em> value.<\/li>\n<li>Finally, the <code>svg.style.fill = color;<\/code> line will override any color value with the new one. It should be equivalent to have something like this in your CSS:<\/li>\n<\/ul>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css shcb-wrap-lines\"><span class=\"hljs-selector-tag\">svg<\/span> {\n  <span class=\"hljs-attribute\">fill<\/span>: color\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<h3>Creating the Container Component<\/h3>\n<p>The container component, again, will be an abstraction to wrap all the UI elements in the application. Let\u2019s create the <code>corp-container.ts<\/code> file.<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ corp-container.ts<\/span>\n<span class=\"hljs-keyword\">import<\/span> {\n  LitElement,\n  html,\n  customElement,\n  css,\n} <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'lit-element'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { corpIconUser } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/svg\/svg-user'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> { corpIconHeart } <span class=\"hljs-keyword\">from<\/span> <span class=\"hljs-string\">'.\/svg\/svg-heart'<\/span>;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-string\">'.\/corp-icon'<\/span>;\n\n@customElement(<span class=\"hljs-string\">'corp-container'<\/span>)\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CorpContainer<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">LitElement<\/span> <\/span>{\n  <span class=\"hljs-keyword\">static<\/span> styles = css`<span class=\"css\">\n    <span class=\"hljs-selector-pseudo\">:host<\/span> {\n      <span class=\"hljs-attribute\">display<\/span>: block;\n    }\n    <span class=\"hljs-selector-class\">.container<\/span> {\n      <span class=\"hljs-attribute\">display<\/span>: flex;\n      <span class=\"hljs-attribute\">flex-direction<\/span>: column;\n    }\n    <span class=\"hljs-selector-class\">.controls<\/span> {\n      <span class=\"hljs-attribute\">display<\/span>: flex;\n      <span class=\"hljs-attribute\">flex-direction<\/span>: row;\n    }    \n  `<\/span>;\n\n  color: string = <span class=\"hljs-string\">'basic'<\/span>;\n\n  <span class=\"hljs-keyword\">constructor<\/span>() {\n    <span class=\"hljs-keyword\">super<\/span>();\n  }\n\n  render() {\n    <span class=\"hljs-keyword\">return<\/span> html`<span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">corp-icon<\/span> <span class=\"hljs-attr\">.icon<\/span>=<\/span><\/span><span class=\"hljs-subst\">${corpIconUser}<\/span><span class=\"xml\"><span class=\"hljs-tag\"> <span class=\"hljs-attr\">.color<\/span>=<\/span><\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.color}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span> <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">corp-icon<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">corp-icon<\/span> <span class=\"hljs-attr\">.icon<\/span>=<\/span><\/span><span class=\"hljs-subst\">${corpIconHeart}<\/span><span class=\"xml\"><span class=\"hljs-tag\"> <span class=\"hljs-attr\">.color<\/span>=<\/span><\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.color}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span> <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">corp-icon<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    `<\/span>;\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>There are a couple of important notes to explain here:<\/p>\n<ul>\n<li>The <code>import '.\/corp-icon';<\/code> line will <em>import<\/em> the definition of the <em>CorpIcon<\/em> component.<\/li>\n<li>The <code>CorpContainer<\/code> class extends from <code>LitElement<\/code>, which is the base class provided by the library.<\/li>\n<li>The <code>static styles<\/code> line provides a context to define the styles needed by the local component.<\/li>\n<li>The <code>render()<\/code> function will return a template through <a href=\"https:\/\/lit-html.polymer-project.org\/\">lit-html<\/a>\n<ul>\n<li>Inside this function, you can define your template using the existing HTML elements and your custom ones.<\/li>\n<li>The <code>&lt;corp-icon&gt;<\/code> element is used here, and also pay attention to the JavaScript expressions to be evaluated for the <code>icon<\/code> and the <code>color<\/code> attributes.<\/li>\n<li>In LitElement, it\u2019s used the <em>dot notation<\/em> to <strong>bind<\/strong> an expression with a component property(ie. <code>.icon=${corpIconUser}<\/code>)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>Adding an Interaction<\/h3>\n<p>At this point, the app is able to render a couple of icons with a predefined style. However, it would be good to add a couple of controls to change their state.<\/p>\n<p>Let\u2019s update the <code>render<\/code> function in the <code>corp-container.ts<\/code> file to add two buttons:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\">  render() {\n    <span class=\"hljs-keyword\">return<\/span> html`<span class=\"xml\">\n      <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"container\"<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span> <span class=\"hljs-attr\">class<\/span>=<span class=\"hljs-string\">\"controls\"<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> @<span class=\"hljs-attr\">click<\/span>=<\/span><\/span><span class=\"hljs-subst\">${() =&gt; <span class=\"hljs-keyword\">this<\/span>.changeColor(<span class=\"hljs-string\">'primary'<\/span>)}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span>Primary<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">button<\/span> @<span class=\"hljs-attr\">click<\/span>=<\/span><\/span><span class=\"hljs-subst\">${() =&gt; <span class=\"hljs-keyword\">this<\/span>.changeColor(<span class=\"hljs-string\">'Basic'<\/span>)}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span>Basic<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">button<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">corp-icon<\/span> <span class=\"hljs-attr\">.icon<\/span>=<\/span><\/span><span class=\"hljs-subst\">${corpIconUser}<\/span><span class=\"xml\"><span class=\"hljs-tag\"> <span class=\"hljs-attr\">.color<\/span>=<\/span><\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.color}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span> <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">corp-icon<\/span>&gt;<\/span>\n          <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">corp-icon<\/span> <span class=\"hljs-attr\">.icon<\/span>=<\/span><\/span><span class=\"hljs-subst\">${corpIconHeart}<\/span><span class=\"xml\"><span class=\"hljs-tag\"> <span class=\"hljs-attr\">.color<\/span>=<\/span><\/span><span class=\"hljs-subst\">${<span class=\"hljs-keyword\">this<\/span>.color}<\/span><span class=\"xml\"><span class=\"hljs-tag\">&gt;<\/span> <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">corp-icon<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n      <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">div<\/span>&gt;<\/span>\n    `<\/span>;\n  }\n\n  private changeColor(color: string) {\n    <span class=\"hljs-keyword\">this<\/span>.color = color;\n  }\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>These new buttons are meant to provide the user a way to interact with the icons and change the style from <em>Primary<\/em> to <em>Basic<\/em> and vice versa.<\/p>\n<p>The LitElement-way to provide this behavior is with a custom function and the <strong>event handler binding<\/strong> using the <code>@<\/code> notation: <code>@click=${function()}<\/code>. This means the function will be called every time the user interacts with a <code>click<\/code> over both buttons.<\/p>\n<p>This code may not work at this time if you are interacting with the buttons already, since we have to find a way to say: \u201cWe changed a property\u2019s value. It\u2019s needed to perform and update\u201d.<\/p>\n<p>This can be done automatically with LitElement using the <code>@property<\/code> and <code>@internalProperty<\/code> decorators. And since this container doesn\u2019t need to define public properties, we can use the second one, and apply it to the <code>color<\/code> attribute as follows:<\/p>\n<pre class=\"js-syntax-highlighted\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript shcb-wrap-lines\"><span class=\"hljs-comment\">\/\/ corp-container.ts<\/span>\n\n@customElement(<span class=\"hljs-string\">'corp-container'<\/span>)\n<span class=\"hljs-keyword\">export<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CorpContainer<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">LitElement<\/span> <\/span>{\n  <span class=\"hljs-comment\">\/\/ styles<\/span>\n\n  @internalProperty() color: string = <span class=\"hljs-string\">'basic'<\/span>;\n\n  render() {\n    <span class=\"hljs-comment\">\/\/ returns the template<\/span>\n  }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n<p>The rendering issue will be fixed now since LitElement will make sure to trigger an \u201cupdate\u201d for the <code>CorpIcon<\/code> component.<\/p>\n<p>If you feel curious about the differences between <code>@property<\/code> and <code>@internalProperty<\/code> decorators, take a look into the <a href=\"https:\/\/labs.thisdot.co\/blog\/litelement-properties-property-vs-internalproperty\">LitElement properties: @proeprty vs @internalProperty<\/a> article.<\/p>\n<h2>Live Demo<\/h2>\n<p>This project is available on <a href=\"https:\/\/codesandbox.io\/s\/litelement-svg-color-typescript-zvnpi\">CodeSandbox<\/a>.<\/p>\n<p>If you prefer, you can play around with the project here too:<\/p>\n<\/div>\n  \n  <div class=\"wp-block-cloudinary-code-sandbox \">\n    <iframe\n      src=\"https:\/\/codesandbox.io\/embed\/litelement-svg-typescript-zvnpi?theme=dark&amp;codemirror=1&amp;highlights=&amp;editorsize=50&amp;fontsize=14&amp;expanddevtools=0&amp;hidedevtools=0&amp;eslint=0&amp;forcerefresh=0&amp;hidenavigation=0&amp;initialpath=%2F&amp;module=&amp;moduleview=0&amp;previewwindow=&amp;view=&amp;runonclick=1\"\n      height=\"500\"\n      style=\"width: 100%;\"\n      title=\"LiteElement SVG TypeScript\"\n      loading=\"lazy\"\n      allow=\"accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking\"\n      sandbox=\"allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts\"\n    ><\/iframe>\n  <\/div>\n\n  <div class=\"wp-block-cloudinary-markdown \"><p>Feel free to reach out on <a href=\"https:\/\/twitter.com\/luixaviles\">Twitter<\/a> if you have any questions. Follow me on <a href=\"https:\/\/github.com\/luixaviles\">GitHub<\/a> to see more about my work.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"","protected":false},"author":41,"featured_media":0,"comment_status":"","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_cloudinary_featured_overwrite":false,"footnotes":""},"categories":[1],"tags":[399,134,370,177,371],"class_list":["post-28110","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-ui-widget","tag-guest-post","tag-image","tag-javascript","tag-under-review"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.6 (Yoast SEO v26.9) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to change SVG color on interaction with LitElement<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to change SVG color on interaction with LitElement\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\" \/>\n<meta property=\"og:site_name\" content=\"Cloudinary Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-04-07T20:21:01+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"NewsArticle\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\"},\"author\":{\"name\":\"\",\"@id\":\"\"},\"headline\":\"How to change SVG color on interaction with LitElement\",\"datePublished\":\"2021-04-07T20:21:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\"},\"wordCount\":9,\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"keywords\":[\"(UI) Widget\",\"Guest Post\",\"Image\",\"Javascript\",\"Under Review\"],\"inLanguage\":\"en-US\",\"copyrightYear\":\"2021\",\"copyrightHolder\":{\"@id\":\"https:\/\/cloudinary.com\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\",\"url\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\",\"name\":\"How to change SVG color on interaction with LitElement\",\"isPartOf\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\"},\"datePublished\":\"2021-04-07T20:21:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cloudinary.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to change SVG color on interaction with LitElement\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#website\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"name\":\"Cloudinary Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cloudinary.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#organization\",\"name\":\"Cloudinary Blog\",\"url\":\"https:\/\/cloudinary.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"contentUrl\":\"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA\",\"width\":312,\"height\":60,\"caption\":\"Cloudinary Blog\"},\"image\":{\"@id\":\"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to change SVG color on interaction with LitElement","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/","og_locale":"en_US","og_type":"article","og_title":"How to change SVG color on interaction with LitElement","og_url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/","og_site_name":"Cloudinary Blog","article_published_time":"2021-04-07T20:21:01+00:00","twitter_card":"summary_large_image","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"NewsArticle","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#article","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/"},"author":{"name":"","@id":""},"headline":"How to change SVG color on interaction with LitElement","datePublished":"2021-04-07T20:21:01+00:00","mainEntityOfPage":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/"},"wordCount":9,"publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"keywords":["(UI) Widget","Guest Post","Image","Javascript","Under Review"],"inLanguage":"en-US","copyrightYear":"2021","copyrightHolder":{"@id":"https:\/\/cloudinary.com\/#organization"}},{"@type":"WebPage","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/","url":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/","name":"How to change SVG color on interaction with LitElement","isPartOf":{"@id":"https:\/\/cloudinary.com\/blog\/#website"},"datePublished":"2021-04-07T20:21:01+00:00","breadcrumb":{"@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/cloudinary.com\/blog\/guest_post\/how-to-change-svg-color-on-interaction-with-litelement\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cloudinary.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to change SVG color on interaction with LitElement"}]},{"@type":"WebSite","@id":"https:\/\/cloudinary.com\/blog\/#website","url":"https:\/\/cloudinary.com\/blog\/","name":"Cloudinary Blog","description":"","publisher":{"@id":"https:\/\/cloudinary.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cloudinary.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cloudinary.com\/blog\/#organization","name":"Cloudinary Blog","url":"https:\/\/cloudinary.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","contentUrl":"https:\/\/res.cloudinary.com\/cloudinary-marketing\/images\/f_auto,q_auto\/v1649718331\/Web_Assets\/blog\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877\/cloudinary_logo_for_white_bg_1937437aa7_19374666c7_193742f877.png?_i=AA","width":312,"height":60,"caption":"Cloudinary Blog"},"image":{"@id":"https:\/\/cloudinary.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":""}]}},"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/comments?post=28110"}],"version-history":[{"count":0,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/posts\/28110\/revisions"}],"wp:attachment":[{"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/media?parent=28110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/categories?post=28110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cloudinary.com\/blog\/wp-json\/wp\/v2\/tags?post=28110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}