diff --git a/apps/default/ui.json b/apps/default/ui.json
index 9e210de40..471d19b6d 100644
--- a/apps/default/ui.json
+++ b/apps/default/ui.json
@@ -1,6 +1,6 @@
{
"metadata": {
- "writer_version": "0.5.0"
+ "writer_version": "0.6.2rc3"
},
"components": {
"root": {
@@ -11,8 +11,7 @@
},
"isCodeManaged": false,
"position": 0,
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"c0f99a9e-5004-4e75-a6c6-36f17490b134": {
"id": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
@@ -23,8 +22,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "root",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"bebc5fe9-63a7-46a7-b0fa-62303555cfaf": {
"id": "bebc5fe9-63a7-46a7-b0fa-62303555cfaf",
@@ -35,8 +33,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"28d3885b-0fb8-4d41-97c6-978540015431": {
"id": "28d3885b-0fb8-4d41-97c6-978540015431",
@@ -48,8 +45,7 @@
"isCodeManaged": false,
"position": 1,
"parentId": "c0f99a9e-5004-4e75-a6c6-36f17490b134",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"9556c0e3-8584-4ac9-903f-908a775a33ec": {
"id": "9556c0e3-8584-4ac9-903f-908a775a33ec",
@@ -63,8 +59,7 @@
"parentId": "0d05bc9f-1655-4d0b-bc9b-c2f4c71a5117",
"handlers": {
"click": "increment"
- },
- "visible": true
+ }
},
"51d1554e-1b88-461c-9353-1419cba0053a": {
"id": "51d1554e-1b88-461c-9353-1419cba0053a",
@@ -78,8 +73,7 @@
"parentId": "0d05bc9f-1655-4d0b-bc9b-c2f4c71a5117",
"handlers": {
"click": "decrement"
- },
- "visible": true
+ }
},
"0d05bc9f-1655-4d0b-bc9b-c2f4c71a5117": {
"id": "0d05bc9f-1655-4d0b-bc9b-c2f4c71a5117",
@@ -90,8 +84,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "f3777e75-3659-4d44-8ef7-aeec0d06855b",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"172a14df-f73a-44fa-8fb1-e8648e7d32d2": {
"id": "172a14df-f73a-44fa-8fb1-e8648e7d32d2",
@@ -104,8 +97,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "c2519671-9ce7-44e7-ba4e-b0efda9cb20e",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"d4a5e62c-c6fe-49c4-80d4-33862af8727d": {
"id": "d4a5e62c-c6fe-49c4-80d4-33862af8727d",
@@ -114,8 +106,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "28d3885b-0fb8-4d41-97c6-978540015431",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"f3777e75-3659-4d44-8ef7-aeec0d06855b": {
"id": "f3777e75-3659-4d44-8ef7-aeec0d06855b",
@@ -129,8 +120,7 @@
"isCodeManaged": false,
"position": 2,
"parentId": "d4a5e62c-c6fe-49c4-80d4-33862af8727d",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"c2519671-9ce7-44e7-ba4e-b0efda9cb20e": {
"id": "c2519671-9ce7-44e7-ba4e-b0efda9cb20e",
@@ -141,8 +131,7 @@
"isCodeManaged": false,
"position": 0,
"parentId": "d4a5e62c-c6fe-49c4-80d4-33862af8727d",
- "handlers": {},
- "visible": true
+ "handlers": {}
},
"d4a71819-7444-4083-a1c7-7995452a7abf": {
"id": "d4a71819-7444-4083-a1c7-7995452a7abf",
@@ -151,8 +140,7 @@
"isCodeManaged": false,
"position": 1,
"parentId": "d4a5e62c-c6fe-49c4-80d4-33862af8727d",
- "handlers": {},
- "visible": true
+ "handlers": {}
}
}
}
\ No newline at end of file
diff --git a/apps/hello/ui.json b/apps/hello/ui.json
index 42858f31c..6db57e02f 100644
--- a/apps/hello/ui.json
+++ b/apps/hello/ui.json
@@ -1,6 +1,6 @@
{
"metadata": {
- "writer_version": "0.5.0"
+ "writer_version": "0.6.2rc3"
},
"components": {
"root": {
@@ -86,7 +86,12 @@
},
"isCodeManaged": false,
"position": 0,
- "parentId": "9c30af6d-4ee5-4782-9169-0f361d67fa76"
+ "parentId": "9c30af6d-4ee5-4782-9169-0f361d67fa76",
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"ee919cd6-8153-4f34-8c6a-bfc1153df360": {
"id": "ee919cd6-8153-4f34-8c6a-bfc1153df360",
@@ -623,7 +628,11 @@
"position": 0,
"parentId": "6a490318-239e-4fe9-a56b-f0f33d628c87",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"6d895924-e808-44aa-a119-f4e2d7f394f3": {
"id": "6d895924-e808-44aa-a119-f4e2d7f394f3",
@@ -661,7 +670,11 @@
"position": 0,
"parentId": "feb9ca67-6670-483d-a895-22b031426a13",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f": {
"id": "1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f",
@@ -671,7 +684,11 @@
"position": 0,
"parentId": "c6392876-7cfd-4680-8725-b04f43ff294f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"feb9ca67-6670-483d-a895-22b031426a13": {
"id": "feb9ca67-6670-483d-a895-22b031426a13",
@@ -683,7 +700,11 @@
"position": 0,
"parentId": "1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"3b325899-e560-40ea-ba54-9c55967af1e3": {
"id": "3b325899-e560-40ea-ba54-9c55967af1e3",
@@ -695,7 +716,11 @@
"position": 1,
"parentId": "1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"a0cd99db-0cbe-40ca-b9cb-b1670ec60dd8": {
"id": "a0cd99db-0cbe-40ca-b9cb-b1670ec60dd8",
@@ -707,7 +732,11 @@
"position": 2,
"parentId": "1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"5dcd137b-76bd-4a5f-ae5c-5b629035500e": {
"id": "5dcd137b-76bd-4a5f-ae5c-5b629035500e",
@@ -719,7 +748,11 @@
"position": 3,
"parentId": "1c05b2e7-3a31-40dd-b6b8-77ded7c6bc0f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"6a81f847-4d1d-4110-9cc1-12c716150e66": {
"id": "6a81f847-4d1d-4110-9cc1-12c716150e66",
@@ -734,7 +767,11 @@
"position": 0,
"parentId": "3b325899-e560-40ea-ba54-9c55967af1e3",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"8e54e9d2-a7c8-4f74-897f-fa5791cd82da": {
"id": "8e54e9d2-a7c8-4f74-897f-fa5791cd82da",
@@ -749,7 +786,11 @@
"position": 0,
"parentId": "a0cd99db-0cbe-40ca-b9cb-b1670ec60dd8",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"07f50628-4679-48a8-9a5d-07dcaf171afb": {
"id": "07f50628-4679-48a8-9a5d-07dcaf171afb",
@@ -764,7 +805,11 @@
"position": 0,
"parentId": "5dcd137b-76bd-4a5f-ae5c-5b629035500e",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"4cca0893-5ad7-4152-b805-5c87babc4dee": {
"id": "4cca0893-5ad7-4152-b805-5c87babc4dee",
@@ -774,7 +819,11 @@
"position": 1,
"parentId": "c6392876-7cfd-4680-8725-b04f43ff294f",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"23bc1387-26ed-4ff2-8565-b027c2960c3c": {
"id": "23bc1387-26ed-4ff2-8565-b027c2960c3c",
@@ -792,7 +841,11 @@
"position": 1,
"parentId": "root",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"1d195388-35a3-43e1-b825-1d263b100a28": {
"id": "1d195388-35a3-43e1-b825-1d263b100a28",
@@ -804,7 +857,11 @@
"position": 0,
"parentId": "23bc1387-26ed-4ff2-8565-b027c2960c3c",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"771dc336-69b2-400e-9ea3-e881e2332c9d": {
"id": "771dc336-69b2-400e-9ea3-e881e2332c9d",
@@ -816,7 +873,11 @@
"position": 0,
"parentId": "dfaae7f9-db20-4f70-a376-919bdc7b6010",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"9c77aee4-e2a0-4e8b-9c2b-377f939bb51e": {
"id": "9c77aee4-e2a0-4e8b-9c2b-377f939bb51e",
@@ -841,7 +902,11 @@
"handlers": {
"click": "$goToPage_main"
},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"8fe33adf-a5ea-4c7a-8d1d-59cc4dc14f05": {
"id": "8fe33adf-a5ea-4c7a-8d1d-59cc4dc14f05",
@@ -851,7 +916,11 @@
"position": 1,
"parentId": "23bc1387-26ed-4ff2-8565-b027c2960c3c",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"7402263c-cb8b-412d-b170-e6dc6ffcb706": {
"id": "7402263c-cb8b-412d-b170-e6dc6ffcb706",
@@ -863,7 +932,11 @@
"position": 1,
"parentId": "8fe33adf-a5ea-4c7a-8d1d-59cc4dc14f05",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"dfaae7f9-db20-4f70-a376-919bdc7b6010": {
"id": "dfaae7f9-db20-4f70-a376-919bdc7b6010",
@@ -875,7 +948,11 @@
"position": 0,
"parentId": "8fe33adf-a5ea-4c7a-8d1d-59cc4dc14f05",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"5bc38721-8b48-43d5-a454-ee5ebe713a4c": {
"id": "5bc38721-8b48-43d5-a454-ee5ebe713a4c",
@@ -908,7 +985,11 @@
"position": 2,
"parentId": "771dc336-69b2-400e-9ea3-e881e2332c9d",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"03f422ce-bc36-4000-8eb1-da1cc00948c9": {
"id": "03f422ce-bc36-4000-8eb1-da1cc00948c9",
@@ -923,7 +1004,11 @@
"handlers": {
"click": "$goToPage_story"
},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"2df56a4b-b6e7-423d-a7a1-5d23c77f65fa": {
"id": "2df56a4b-b6e7-423d-a7a1-5d23c77f65fa",
@@ -944,7 +1029,11 @@
"position": 0,
"parentId": "771dc336-69b2-400e-9ea3-e881e2332c9d",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"77cb256b-ef12-4a55-a051-500497f41302": {
"id": "77cb256b-ef12-4a55-a051-500497f41302",
@@ -956,7 +1045,11 @@
"position": 2,
"parentId": "5bc38721-8b48-43d5-a454-ee5ebe713a4c",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"ed010441-0cac-4aa5-9e6f-97228e0c3536": {
"id": "ed010441-0cac-4aa5-9e6f-97228e0c3536",
@@ -971,7 +1064,11 @@
"handlers": {
"click": "handle_story_download"
},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"e1ax8ctt8lrao0e4": {
"id": "e1ax8ctt8lrao0e4",
@@ -983,7 +1080,11 @@
"position": 3,
"parentId": "ee919cd6-8153-4f34-8c6a-bfc1153df360",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"j3jkho6tb97u0onr": {
"id": "j3jkho6tb97u0onr",
@@ -997,7 +1098,11 @@
"position": 0,
"parentId": "e1ax8ctt8lrao0e4",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"4wzaubf275w17gac": {
"id": "4wzaubf275w17gac",
@@ -1010,7 +1115,11 @@
"position": 0,
"parentId": "j3jkho6tb97u0onr",
"handlers": {},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"19binb4yi70gesho": {
"id": "19binb4yi70gesho",
@@ -1042,7 +1151,11 @@
"wf-change-page": "handle_paginated_members_page_change",
"wf-change-page-size": "handle_paginated_members_page_size_change"
},
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"b27lw9ex8ig3x17p": {
"id": "b27lw9ex8ig3x17p",
@@ -1054,7 +1167,11 @@
"isCodeManaged": false,
"position": 2,
"parentId": "9c30af6d-4ee5-4782-9169-0f361d67fa76",
- "visible": true
+ "visible": {
+ "expression": true,
+ "binding": "",
+ "reversed": false
+ }
},
"804e15bf-11a7-463d-8082-f46ea3acac1b": {
"id": "804e15bf-11a7-463d-8082-f46ea3acac1b",
diff --git a/docs/framework/application-state.mdx b/docs/framework/application-state.mdx
index 50b65383f..0b200f8f2 100644
--- a/docs/framework/application-state.mdx
+++ b/docs/framework/application-state.mdx
@@ -113,3 +113,33 @@ The front-end cannot directly display complex data types such as Pandas datafram
Pandas dataframes are converted to JSON and can be used in _Dataframe_ components.
+
+## State schema
+
+State schema is a feature that allows you to define the structure of the state.
+This is useful for ensuring that the state is always in the expected format.
+
+Schema allows you to use features like
+
+* typing checking with mypy / ruff
+* autocomplete in IDEs
+* declare dictionaries
+* automatically calculate mutations on properties
+
+more into [Advanced > State schema](./state-schema)
+
+```python
+import writer as wf
+
+class AppSchema(wf.WriterState):
+ counter: int
+
+initial_state = wf.init_state({
+ "counter": 0
+}, schema=AppSchema)
+
+# Event handler
+# It receives the session state as an argument and mutates it
+def increment(state: AppSchema):
+ state.counter += 1
+```
diff --git a/docs/framework/event-handlers.mdx b/docs/framework/event-handlers.mdx
index 6617c8357..cbb41b5dd 100644
--- a/docs/framework/event-handlers.mdx
+++ b/docs/framework/event-handlers.mdx
@@ -136,6 +136,63 @@ def hande_click_cleaner(state):
```
+## Mutation event
+
+You can subscribe to mutations on a specific key in the state.
+This is useful when you want to trigger a function every time a specific key is mutated.
+
+