From 2ed3b40d053616ce55d6787dcb9cbc62dc28604a Mon Sep 17 00:00:00 2001 From: Dylan Castillo Date: Sat, 2 Mar 2024 14:39:26 +0100 Subject: [PATCH 1/2] Add type hints --- README.md | 9 ++++++--- django_components/types.py | 9 +++++++++ sampleproject/components/greeting.py | 7 ++++--- 3 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 django_components/types.py diff --git a/README.md b/README.md index bc18b94e..0dae5fab 100644 --- a/README.md +++ b/README.md @@ -251,6 +251,7 @@ Components can also be defined in a single file, which is useful for small compo ```python # In a file called [project root]/components/calendar.py from django_components import component +from django_components import types as t @component.register("calendar") class Calendar(component.Component): @@ -259,16 +260,16 @@ class Calendar(component.Component): "date": date, } - template = """ + template: t.django_html = """
Today's date is {{ date }}
""" - css = """ + css: t.css = """ .calendar-component { width: 200px; background: pink; } .calendar-component span { font-weight: bold; } """ - js = """ + js: t.js = """ (function(){ if (document.querySelector(".calendar-component")) { document.querySelector(".calendar-component").onclick = function(){ alert("Clicked calendar!"); }; @@ -279,6 +280,8 @@ class Calendar(component.Component): This makes it easy to create small components without having to create a separate template, CSS, and JS file. +Note that the `t.django_html`, `t.css`, and `t.js` types are used to specify the type of the template, CSS, and JS files, respectively. This is not necessary, but if you're using VSCode with the [Python Inline Source Syntax Highlighting](https://marketplace.visualstudio.com/items?itemName=samwillis.python-inline-source) extension, it will give you syntax highlighting for the template, CSS, and JS. + ## Using slots in templates _New in version 0.26_: diff --git a/django_components/types.py b/django_components/types.py new file mode 100644 index 00000000..bd9eac7d --- /dev/null +++ b/django_components/types.py @@ -0,0 +1,9 @@ +try: + from typing import Annotated +except ImportError: + from typing_extensions import Annotated + +html = Annotated[str, "html"] +css = Annotated[str, "css"] +django_html = Annotated[str, "django_html"] +js = Annotated[str, "js"] diff --git a/sampleproject/components/greeting.py b/sampleproject/components/greeting.py index 20fdd84d..57ebcb67 100644 --- a/sampleproject/components/greeting.py +++ b/sampleproject/components/greeting.py @@ -1,6 +1,7 @@ from typing import Any, Dict from django_components import component +from django_components import types as t @component.register("greeting") @@ -13,12 +14,12 @@ class Greeting(component.Component): def get_context_data(self, name, *args, **kwargs) -> Dict[str, Any]: return {"name": name} - template = """ + template: t.django_html = """
Hello, {{ name }}!
{% slot "message" %}{% endslot %} """ - css = """ + css: t.css = """ #greeting { display: inline-block; color: blue; @@ -26,7 +27,7 @@ class Greeting(component.Component): } """ - js = """ + js: t.js = """ document.getElementById("greeting").addEventListener("click", (event) => { alert("Hello!"); }); From b58100eb9da3d0c2497f6674f0479054eaebb89b Mon Sep 17 00:00:00 2001 From: Dylan Castillo Date: Tue, 5 Mar 2024 10:29:39 +0100 Subject: [PATCH 2/2] Remove typing-extensions --- django_components/types.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/django_components/types.py b/django_components/types.py index bd9eac7d..ed753884 100644 --- a/django_components/types.py +++ b/django_components/types.py @@ -1,9 +1,21 @@ try: from typing import Annotated except ImportError: - from typing_extensions import Annotated -html = Annotated[str, "html"] + class Annotated: + def __init__(self, type_, *args, **kwargs): + self.type_ = type_ + self.metadata = args, kwargs + + def __repr__(self): + return f"Annotated[{self.type_}, {self.metadata[0]!r}, {self.metadata[1]!r}]" + + def __getitem__(self, params): + if not isinstance(params, tuple): + params = (params,) + return Annotated(self.type_, *params, **self.metadata[1]) + + css = Annotated[str, "css"] django_html = Annotated[str, "django_html"] js = Annotated[str, "js"]