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

refactor(dom): Update getSlotted utility to handle querying for item(s) in default slot #3788

Merged
merged 18 commits into from
Jan 7, 2022

Conversation

driskull
Copy link
Member

@driskull driskull commented Dec 28, 2021

Related Issue: None

Summary

refactor(dom): Update getSlotted utility to handle querying for item(s) in default slot

  • Update dom utility getSlotted to query for an element in the default slot.
  • make slotName param optional

This will allow us to replace this.hasDefaultSlot = this.el.querySelector(":not([slot])") !== null; taken from combobox-item.

@github-actions github-actions bot added this to the Sprint 12/20 - 12/31 milestone Dec 28, 2021
@github-actions github-actions bot added the refactor Issues tied to code that needs to be significantly reworked. label Dec 28, 2021
@driskull driskull marked this pull request as ready for review December 28, 2021 18:40
@driskull driskull requested a review from a team as a code owner December 28, 2021 18:40
@driskull driskull requested a review from jcfranco December 28, 2021 18:40
Copy link
Member

@jcfranco jcfranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking great! This will be a nice update to getSlotted. 🎉

@@ -185,7 +187,7 @@ function querySingle<T extends Element = Element>(
match = options && options.direct === false ? match : match?.parentElement === element ? match : null;

const selector = options?.selector;
return selector ? match.querySelector<T>(selector) : match;
return selector ? match?.querySelector<T>(selector) : match;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the default slot selector will also return children in a custom element without a <slot>, this should also make sure that assignedSlot from the default slot selector result is not null.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the assignedSlot will work on the spec test. I think we would have to setup an e2e test?

src/utils/dom.spec.ts Show resolved Hide resolved
src/utils/dom.ts Outdated
options?: GetSlottedOptions
): T | null;
export function getSlotted<T extends Element = Element>(
element: Element,
slotName: string,
slotName?: string,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update the signature to support both

getSlotted(el, slotName, options);
getSlotted(el, options);

?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, or we can just update the slotName to be apart of options? What do you think?

Do you have an example of making the second param be identified as the third?

src/utils/dom.spec.ts Outdated Show resolved Hide resolved
@driskull driskull requested a review from jcfranco December 29, 2021 23:25
@driskull
Copy link
Member Author

@jcfranco can you review again?

@@ -196,6 +205,10 @@ function queryMultiple<T extends Element = Element>(
let matches = Array.from(element.querySelectorAll<T>(slotSelector));
matches = options && options.direct === false ? matches : matches.filter((el) => el.parentElement === element);

if (slotSelector === defaultSlotSelector) {
matches = matches.filter((match) => match?.assignedSlot);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jcfranco It seems like this would work but we would need to move the spec tests to e2e for assignedSlot to work I think.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 7, 2022

This PR has been automatically marked as stale because it has not had recent activity. Please close your PR if it is no longer relevant. Thank you for your contributions.

@github-actions github-actions bot added the Stale Issues or pull requests that have not had recent activity. label Jan 7, 2022
<calcite-dropdown>
<calcite-action slot="dropdown-trigger">Open dropdown</calcite-button>
<calcite-action slot="dropdown-trigger">Open dropdown</calcite-action>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed this in review :( cc @Elijbet

Copy link
Member

@jcfranco jcfranco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes LGTM!

For the remaining items I brought up (1. getSlotted signature, 2. assignedSlot check), can you create follow up issues?

</slot-test>
`;

const assignedSlot = document.querySelector("slot-test").shadowRoot.querySelector(`slot:not([name])`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a workaround for Node.assignedSlot missing? If so, just wanted to check if it's working or not based on your comments to move to an e2e test.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is a workaround.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without this, the assignedNode won't be there. So we would have to run the getSlotted() method in the browser. Which means placing the whole utility in the browser so that all methods can be accessed.

@@ -162,24 +162,33 @@ interface GetSlottedOptions {
selector?: string;
}

const defaultSlotSelector = "> :not([slot])";

export function getSlotted<T extends Element = Element>(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be typed like so:

export function getSlotted<T extends Element = Element>(element: Element, options: GetSlottedOptions & { all: true }): T[];
export function getSlotted<T extends Element = Element>(element: Element, options?: GetSlottedOptions): T[];
export function getSlotted<T extends Element = Element>(element: Element, slotName: string | string[], options: GetSlottedOptions & { all: true }): T[];
export function getSlotted<T extends Element = Element>(element: Element, slotName: string | string[], options?: GetSlottedOptions): T[];
export function getSlotted<T extends Element = Element>(
  element: Element,
  slotNameOrOptions: string | string[] | GetSlottedOptions,
  optionsOrUndefined?: GetSlottedOptions): (T | null) | T[] { /* ... */ }

Can you create a separate refactor issue this one and assign it to me?

@driskull driskull merged commit 26c926b into master Jan 7, 2022
@driskull driskull deleted the dris0000/default-slot-query branch January 7, 2022 23:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
refactor Issues tied to code that needs to be significantly reworked. Stale Issues or pull requests that have not had recent activity.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants