Issue
I'm using an ion-icon
in my app and I'd like to be able to change some attributes within the svg dynamically. Specifically, I'm using the following battery icon and I want to change the percentage of its fill:
<ion-icon name="battery-full-outline"></ion-icon>
The attribute I'm interested in is the width
attribute in the second of the two <rect>
elements within the SVG. Using my browser tools, I've found the generated HTML to be the following:
<ion-icon _ngcontent-amc-c135="" name="battery-full-outline" ng-reflect-name="battery-full-outline" role="img" class="ios hydrated" aria-label="battery full outline">
#shadow-root (open)
<div class="icon-inner">
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon s-ion-icon" viewBox="0 0
512 512">
<title>Battery Full</title>
<rect x="32" y="144" width="400" height="224" rx="45.7" ry="45.7" stroke-linecap="square" stroke-miterlimit="10" class="ionicon-fill-none ionicon-stroke-width"></rect>
<rect x="85.69" y="198.93" width="292.63" height="114.14" rx="4" ry="4" stroke-linecap="square" stroke-miterlimit="10" class="ionicon-stroke-width"></rect>
<path stroke-linecap="round" stroke-miterlimit="10" d="M480 218.67v74.66" class="ionicon-fill-none ionicon-stroke-width"></path>
</svg>
</div>
</ion-icon>
The problem of course is that these elements are embedded within a shadow DOM, and Ionic icons don't expose any parts that the user can modify. Is there a way in Angular to get around this? I'm wondering if I can place a directive on the ion-icon
component that would use ElementRef
to access the underlying elements (but it seems like there are some things I haven't considered to make this work).
Solution
This certainly isn't a good practice (and goes against the fundamentals of Angular), but the simplest solution I could find was just to use plain JavaScript document methods to get the width
attribute I was looking for and to set a new value in the shadow DOM element:
const rect = document.querySelector('.my-icon-class').shadowRoot.querySelectorAll('icon-inner svg rect)[1];
const fullWidth = rect.getAttribute('width');
const newWidth = parseFloat(fullWidth) * BATTERY_PERCENTAGE * 0.01;
rect.setAttribute('width', `${newWidth}`);
Answered By - angus
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.