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

Lit cheat sheet #1355

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Lit cheat sheet #1355

wants to merge 1 commit into from

Conversation

e111077
Copy link
Collaborator

@e111077 e111077 commented Jul 19, 2024

See it here:

https://pr1355-f7f7b43---lit-dev-5ftespv5na-uc.a.run.app/articles/lit-cheat-sheet/

This PR also adds lazy loading to lit-example via intersection observer so that we do not load the 300kb TS worker a million times per page and so that it can cache.

@justinfagnani
Copy link
Contributor

Whoa, awesome!!!

I'm reading through now and my first/only comment is that some of the example are really long compared to their main topic. I think the Templating section has the most of this. eg, the event listener expression example could just be a single button and an output element (similar to the common counter example) without validation, etc.

It would be great to get in small Task and Context example too, and may an ElementInternals thing (custom state?).

@e111077
Copy link
Collaborator Author

e111077 commented Jul 19, 2024

I was uploading this in hopes of getting something up and running in the live preview. Also I'm not sure how much I can contribute to this because coming up with and subsequently plowing through the boilerplate for example takes up a lot more time than expected and my calendar is getting filled up with other work. My plan forward was either of the following:

  1. get this reviewed and in and make it a living document with other contributors adding to it
  2. keep this up and have someone else fork it and pick it up from there

@justinfagnani
Copy link
Contributor

I can definitely contribute to refining this branch! This is such a good start.

@e111077
Copy link
Collaborator Author

e111077 commented Jul 19, 2024

let me debug get this working in the preview first!

@e111077
Copy link
Collaborator Author

e111077 commented Jul 20, 2024

lol it was a real bug and not a flake. good job, tests!

@e111077 e111077 marked this pull request as ready for review July 20, 2024 00:49
@filimon-danopoulos
Copy link

I've read through it and it will be a gold mine. I have the same thought as Justin about section length.

One thing that stod out was the mention of running on the server in the lifecycle section. Seems a little premature given that the SSR package is still in labs. I think that the lifecycle section could be compacted into a table instead.

Would it be reasonable to include a short glossary section?

I have a couple of smaller suggestions with the text but I get the impression that we don't want to put these here but in a separate PR.

@e111077
Copy link
Collaborator Author

e111077 commented Jul 23, 2024

Thanks for the look-over Filimon! The nice thing about articles is that they have more of a chance to live as a living document, so lifecycle reference can change over time. Though I do think that this information is very useful for people trying to actually use our SSR package and we should strive to make it easier to use. I also agree with you and think that there needs to be some sort of "labs" warning near that

@JosefJezek
Copy link

Could you write a page about Lit vs React? With comparisons all Lit + Signal solutions instead of React hooks.

resources:

@e111077 e111077 force-pushed the cheat-sheet branch 3 times, most recently from b82f44e to 6ceb3fb Compare November 26, 2024 07:33
@e111077
Copy link
Collaborator Author

e111077 commented Nov 26, 2024

Can I get another review? I'd like to get this out before thanksgiving or by cyber monday

@e111077
Copy link
Collaborator Author

e111077 commented Nov 26, 2024

I've added a bunch of sections and a signals section

@filimon-danopoulos
Copy link

I have looked it over but not at every detail as it is a lot to go through but this looks really good.

A common misconception is around converters is that they are run when the property is set. Your example does not make it worse as it is clear enough but maybe add a warning/note making that extra clear?

I think that a pattern around derived state is probably nice to have to. Maybe with get/set and with lifecycle? By no means a requirement though and easy enough to add eventually.

I have not worked enough with signals to have meaningful feedback.

Really well done!

@e111077
Copy link
Collaborator Author

e111077 commented Nov 26, 2024

Thanks for the suggestion @filimon-danopoulos, I added that note in custom attribute converters and I also added 4 examples for:

  • Derived Read-Only State
    • getters (nothing on setters for now)
  • Reconcile Values Between Reactive Properties
    • willUpdate()
  • Sync Reactive Property with Browser Features
    • update() RP + localstorage
  • Reconcile Values Between Reactive Properties and DOM
    • updated()

@sorvell
Copy link
Member

sorvell commented Nov 26, 2024

Sync Reactive Property with Browser Features
update() RP + localstorage

Why update and not updated?

@e111077 e111077 changed the title [WIP] lit cheat sheet Lit cheat sheet Nov 26, 2024
@e111077
Copy link
Collaborator Author

e111077 commented Nov 26, 2024

@sorvell it happens before render and does not rely on the DOM. In particular the example uses localStorage and does some simple two-way syncing between the two. Doing that in updated() might cause a re-render on first initialization

@e111077 e111077 requested a review from sorvell December 3, 2024 21:28
@e111077
Copy link
Collaborator Author

e111077 commented Dec 3, 2024

ping @justinfagnani @sorvell @augustjk for a review

If ready to merge, we should also prepare socials as I no longer have access


{% aside "warn" %}

By turning off shadow DOM you lose the benefits of encapsulation, DOM scoping, and `<slot>` elements.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
By turning off shadow DOM you lose the benefits of encapsulation, DOM scoping, and `<slot>` elements.
This is generally not recommended, but it may sometimes be worthwhile for integration with older systems or libraries that may not be updated to work with Shadow DOM.
By turning off shadow DOM you lose the benefits of encapsulation, DOM scoping, and `<slot>` elements.


By turning off shadow DOM you lose the benefits of encapsulation, DOM scoping, and `<slot>` elements.

Since the Shadow root no longer exists, Lit will no longer handle the `static styles` property for you. You must decide how to handle your styles.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Since the Shadow root no longer exists, Lit will no longer handle the `static styles` property for you. You must decide how to handle your styles.
Since the Shadow root no longer exists, `<slot>` does not work and Lit will no longer handle the `static styles` property for you. You must decide how to handle your styles.

// localStorage is only available in the browser so we put this reactive
// property reconciliation in an update() method.
if (changed.has('savedString')) {
localStorage.setItem('savedString', this.savedString);
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
localStorage.setItem('savedString', this.savedString);
window.localStorage.setItem('savedString', this.savedString);

localStorage.setItem('savedString', this.savedString);
}

if (localStorage.get('savedString') !== this.savedString) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (localStorage.get('savedString') !== this.savedString) {
if (window.localStorage.getItem('savedString') !== this.savedString) {

}

if (localStorage.get('savedString') !== this.savedString) {
this.savedString = localStorage.getItem('savedString') ?? '';
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
this.savedString = localStorage.getItem('savedString') ?? '';
this.savedString = window.localStorage.getItem('savedString') ?? '';

- You can't use the `@query` decorator (or its JS equivalent)
- You cannot determine when an element will be rendered
- You need to pass element references from a child to a parent component (not common)
- You're migrating from another framework like React
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
- You're migrating from another framework like React
- You're migrating from another framework like React
- You need to run a function when the referenced element changes


{% aside "warn" %}

Effects implemented in this way are not compatible with the `watch()` directive.
Copy link
Member

Choose a reason for hiding this comment

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

What does this mean?

I think this section is confusing and should be limited to just referencing the effect in signal-utils.

render() {
return html`
${
// NOTE: the live() directive prevents setting the .value property if
Copy link
Member

Choose a reason for hiding this comment

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

I would remove live here and the comment. As long as the tag doesn't change, the expense is minimal.

// This is important since static html templates should not be thrashed
// due to performance concerns.
staticHTML`
<${this.tagLiteral}
Copy link
Member

Choose a reason for hiding this comment

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

Why doesn't this use unsafeStatic or literal?


{% aside "warn" %}

Be careful when using static HTML templates as changing values of a static
Copy link
Member

Choose a reason for hiding this comment

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

They are cached but the caching is slightly more expensive. Instead I would just draw attention to the cost of changing element tags.

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.

5 participants