diff --git a/README.md b/README.md
index 227ba96d..ad42a5aa 100644
--- a/README.md
+++ b/README.md
@@ -255,6 +255,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):
@@ -263,16 +264,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!"); };
@@ -283,6 +284,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..ed753884
--- /dev/null
+++ b/django_components/types.py
@@ -0,0 +1,21 @@
+try:
+ from typing import Annotated
+except ImportError:
+
+ 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"]
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!");
});