Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent duplicate icons rendered #102

Merged
merged 1 commit into from
Oct 16, 2023
Merged

Prevent duplicate icons rendered #102

merged 1 commit into from
Oct 16, 2023

Conversation

maxatdetroit
Copy link
Member

@maxatdetroit maxatdetroit commented Oct 5, 2023

The Bug

The current implementation of Icon.js was not guarding against connectedCallback being called multiple times.

See details for when this may happen.

Details

The most common scenario in our UXDS would be when we're adding the <cod-icon/> element to another slotted custom element. This causes the <cod-icon/> component to be connected twice: once when attached to the slot, then again when onslotchange event handler attaches it to the shadowDOM of the parent component. E.g.

NOTE: In the below example, the component is actually connected three times because both cod-card and cod-card-icon-container are slotted elements.

  <cod-card data-width="18em" data-extra-classes="text-center">
    <cod-card-icon-container>
      <cod-icon data-icon="house" data-size="x-large"></cod-icon>
    </cod-card-icon-container>
    <cod-card-body>
      <h5 class="card-title">Card title</h5>
      <p class="card-text">
        Some compelling text.
      </p>
    </cod-card-body>
  </cod-card>

This results in the following:
Screenshot 2023-10-05 at 10 48 53 AM

Proposed Fix (This PR)

Add a guard in connectedCallback to check if the icon span is already attached to the shadowDom and return early if so.

Alternatives Considered

  1. We could attach the shadow root as part of the connectedCallback method which would recreate a shadowDOM each time the component is attached to the DOM. This is a reasonable alternative but the performance implications are unclear and connectedCallback can be called many times.

  2. We could remove the icon element from the shadowDOM on disconnectedCallback lifecycle event. This type of lifecycle management might be appropriate if we were managing some state that needed to be reset, but since the icon elememnt does not change between lifecycle events, it's probably best to just let it live between events.

Testing

  • Build a story that uses the icon element nested in a couple slotted elements.
  • Before this PR: observe that the icon is rendered multiple times.
Screenshot 2023-10-05 at 10 48 53 AM
  • After this PR: observe that the icon is rendered once.
Screenshot 2023-10-05 at 10 49 07 AM

@maxatdetroit maxatdetroit added the bug Something isn't working label Oct 5, 2023
@maxatdetroit maxatdetroit requested a review from jedgar1mx October 5, 2023 15:46
@maxatdetroit maxatdetroit self-assigned this Oct 5, 2023
@jedgar1mx jedgar1mx merged commit ad2d552 into dev Oct 16, 2023
@jedgar1mx jedgar1mx deleted the fix.icon-shadowdom branch October 16, 2023 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants