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

[labs/ssr-dom-shim] Add basic support for element internals #3677

Merged
merged 16 commits into from Mar 21, 2023

Conversation

calebdwilliams
Copy link
Contributor

@calebdwilliams calebdwilliams commented Feb 16, 2023

To do

  • Add tests
  • Add changeset

@changeset-bot
Copy link

changeset-bot bot commented Feb 16, 2023

🦋 Changeset detected

Latest commit: 056a39c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@lit-labs/ssr-dom-shim Minor
lit Minor
lit-element Minor
@lit-labs/ssr Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@calebdwilliams
Copy link
Contributor Author

Let me know if you'd like me to revert the package-lock as well.

@calebdwilliams
Copy link
Contributor Author

@justinfagnani it looks like I checked in some build files, is that normal for Lit or should I remove those?

@justinfagnani
Copy link
Collaborator

@calebdwilliams awesome!

looks like I checked in some build files, is that normal for Lit or should I remove those?

Those should be added to .gitignore. We typically put implementation modules in a folder named lib/ and ignore the whole folder.

@justinfagnani
Copy link
Collaborator

And yeah, let's revert the package-lock change, since there's no package.json change.

We've been trying to run on very recent versions of npm to keep the package-lock stable, btw.

@augustjk
Copy link
Member

Those should be added to .gitignore. We typically put implementation modules in a folder named lib/ and ignore the whole folder.

Also with regards to this, we need to add to wireit configs. @calebdwilliams I'm happy to handle any of our monorepo consistency related changes myself and push it up if you'd like.

@calebdwilliams
Copy link
Contributor Author

I updated the PR to remove changes to the package-lock and removed the compiled files.

@calebdwilliams calebdwilliams requested review from augustjk and removed request for aomarks, justinfagnani and augustjk February 21, 2023 21:56
@calebdwilliams
Copy link
Contributor Author

I apparently somehow removed @aomarks and @justinfagnani as reviewers. Not sure how that happened, sorry about that.

packages/labs/ssr-dom-shim/src/InternalsShim.ts Outdated Show resolved Hide resolved
packages/labs/ssr-dom-shim/src/InternalsShim.ts Outdated Show resolved Hide resolved
packages/labs/ssr-dom-shim/src/InternalsShim.ts Outdated Show resolved Hide resolved
packages/labs/ssr-dom-shim/src/InternalsShim.ts Outdated Show resolved Hide resolved

/**
* @TODO
* - This can be typed better with keyof ARIAMixin, but TypeScript's definition
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be great to have some reference links here. One to a Typescript DOM lib issue, another to the source of this list.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looks like all of the browsers currently support a different set of features. All of them do reflect the from AriaMixin, so would it just be better in the long run to keep this list to Record<keyof AriaMixin, string>?

Copy link
Collaborator

Choose a reason for hiding this comment

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

That sounds reasonable

role: 'role',
};

/** Force the attributes onto the reference element based on internals properties */
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure I understand the purpose of this method from this description. Is this something not part of AOM? When would we call it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does the new description help this?

packages/labs/ssr-dom-shim/src/InternalsShim.ts Outdated Show resolved Hide resolved
constructor(_host: InternalsHost) {
this._host = _host;

initAom(_host, this);
Copy link
Collaborator

Choose a reason for hiding this comment

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

native AOM doesn't automatically reflect to attributes, does it? I think we should probably leave behavior like this up to ElementRenderers like LitElementRenderer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It doesn't if you use internals. The purpose here is to hydrate that behavior. If we were following the semantics, we should check to see if the attributes are set, if they aren't, append it to the element for SEO/SSR purposes then remove the element upon hydration if it still matches.

I think having the AOM stuff reflected from internals to the pre-hydrated code would be a huge win for capturing the semantics of an element and for the DX of authoring components using internals/Lit SSR.

initAom(_host, this);
}
checkValidity() {
return true;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to implement this one? I'm not sure, but seems to me like we might want to throw rather than return a wrong answer. If we want to provide a correct answer, that would take some work, yeah?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it would take some work for sure. We could just throw an error on the methods or just noop them … 

I think the bigger question would be for things like setFormValue and setValidity, those should exist but only be side-effectful upon hydration.

packages/labs/ssr-dom-shim/src/index.ts Outdated Show resolved Hide resolved
@calebdwilliams calebdwilliams requested review from justinfagnani and augustjk and removed request for aomarks and justinfagnani February 21, 2023 23:05
* is created on an element to wire up the getters/setters
* for the AriaMixin properties
*
* TODO - Determine the proper way to hydrate any attributes set by the shim
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@justinfagnani Following up on your question from the other day. I'm happy to reference an issue, but I'm not sure where to put that. The version of TypeScript I'm running in VSCode matches the spec, but neither Chromium or Webkit (or Firefox with the ARIA reflection tag) have the same tags. The ones listed here are in line with Chromium's implementation.

To complicate that a bit more, the version of TypeScript building Lit's repo is different from the version running in VSCode (somehow) so that it recognizes different properties on ARIAMixin which appears to be somewhat volatile in TypeScript.

Any guidance you could provide on how to add more clarity here would be welcomed.

* Add a rough implementation for ElementShim.prototype.attachInternals
Fixes lit#3676
@augustjk augustjk force-pushed the feat/ssr-dom-shim-internals branch from 758469a to dcef2b4 Compare March 11, 2023 02:17
packages/labs/ssr-dom-shim/src/index.ts Show resolved Hide resolved
packages/labs/ssr-dom-shim/src/lib/element-internals.ts Outdated Show resolved Hide resolved
packages/labs/ssr-dom-shim/src/lib/element-internals.ts Outdated Show resolved Hide resolved
// created on an element to wire up the getters/setters for the ARIAMixin
// properties.
const internals = (
this.element as object as {__internals: ElementInternals}
Copy link
Collaborator

Choose a reason for hiding this comment

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

So this only work when we're using our shim. We need to think about what happens if someone loads jsdom. We may need adapters, like a getInternals() callback.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure if there's anything to be done right now. Neither jsdom nor happy-dom have attachInternals() implemented and a canonical way of getting the internals object from an element doesn't exist.

Do you mean a getInternals() on the element renderer? This would be more of a DOM shim dependent thing rather than an element renderer thing.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We should have an issue somewhere for using another DOM shim, and this can go on the list of things we'll need to consider there. What I mean by getInternals() is that since there's no standard DOM API for getting at that from outside a component, we'll need a callback per DOM emulation library to get at it. Future work, just noting it.

packages/labs/ssr/src/lib/lit-element-renderer.ts Outdated Show resolved Hide resolved
- Throw on repeat call to `attachInternals()`.
- Add warning for `checkValidity()` calls.
- Retype and rename `ariaMixinEnum` to `ariaMixinAttributes`.
- Loop through ariaAttrMap instead of internals instance.
@augustjk augustjk merged commit b95c86e into lit:main Mar 21, 2023
7 checks passed
@lit-robot lit-robot mentioned this pull request Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[ssr-dom-shim]: Add lightweight support for ElementInternals
3 participants