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

feat: add Media.extend #890

Merged
merged 7 commits into from
Jan 7, 2025

Conversation

JuroOravec
Copy link
Collaborator

@JuroOravec JuroOravec commented Jan 7, 2025

This PR:

  • Makes the Component.media instance to inherit the JS and CSS from parent components
  • Users can opt-out or configure the inheritance behaviour with the extend attribute on Component.Media, which behaves similarly to Django's Media.extend.
  • Clears up behaviour around subclassing components by documenting it

This addresses points 4. and 5. from this discussion.

Examples:

Normal media inheritance:

class ParentComponent(Component):
    class Media:
        js = ["parent.js"]

class MyComponent(ParentComponent):
    class Media:
        js = ["script.js"]

print(MyComponent.media._js)  # ["script.js", "parent.js"]

Disable media inheritance:

class ParentComponent(Component):
    class Media:
        js = ["parent.js"]

class MyComponent(ParentComponent):
    class Media:
        extend = False  # Don't inherit parent media
        js = ["script.js"]
print(MyComponent.media._js)  # ["script.js"]

Specific set of parent Media classes

In this case, the media files are inherited ONLY
from the specified components, and NOT from the original parent components:

class ParentComponent(Component):
    class Media:
        js = ["parent.js"]

class MyComponent(ParentComponent):
    class Media:
        # Only inherit from these, ignoring the files from the parent
        extend = [OtherComponent1, OtherComponent2]
        js = ["script.js"]

print(MyComponent.media._js)  # ["script.js", "other1.js", "other2.js"]

And some documentation :)

Screen.Recording.2025-01-07.at.20.18.19.mov
Screenshot 2025-01-07 at 20 19 11

media_cls = comp_media.media_class or MediaCls
media_js = getattr(comp_media.Media, "js", [])
media_css = getattr(comp_media.Media, "css", {})
comp_media.media = media_cls(js=media_js, css=media_css) if comp_media.Media is not None else None
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Previously, the media instance contained only the JS / CSS files from the current Component class, so it was enough to just instantiate it. Now, the _get_comp_cls_media travels up the Component's parent classes to find all the JS / CSS. And so the child component class end up inheriting them all.

@JuroOravec JuroOravec marked this pull request as ready for review January 7, 2025 19:46
Copy link
Collaborator

@EmilStenstrom EmilStenstrom left a comment

Choose a reason for hiding this comment

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

This looks awesome. Ready to merge. Really like the tests, simple and effective.

I think I remember you describing that we've implemented Media "except for the extends" somewhere in the docs, but I don't see that removed here?

@JuroOravec
Copy link
Collaborator Author

JuroOravec commented Jan 7, 2025

@EmilStenstrom Yeah that's true, thanks for reminding me that!

@JuroOravec JuroOravec merged commit ab037f2 into django-components:master Jan 7, 2025
15 checks passed
@JuroOravec JuroOravec deleted the jo-media-extend branch January 7, 2025 21:55
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.

2 participants