@gramlot/gramlot-examples 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +4 -3
  2. package/package.json +3 -3
  3. package/src/gramlot_examples/catalog.json +42 -3
  4. package/src/gramlot_examples/gallery/dist/frame.js +1473 -5
  5. package/src/gramlot_examples/gallery/dist/gallery.js +3822 -17162
  6. package/src/gramlot_examples/gallery/dist/notices.json +2 -22
  7. package/src/gramlot_examples/gallery/dist/theme-styles.js +2 -0
  8. package/src/gramlot_examples/gallery/gallery-page.js +38 -67
  9. package/src/gramlot_examples/gallery/gallery.css +22 -94
  10. package/src/gramlot_examples/index.js +2 -1
  11. package/src/gramlot_examples/pages/README.md +87 -4
  12. package/src/gramlot_examples/pages/binding/01_pointers.js +9 -0
  13. package/src/gramlot_examples/pages/binding/01_pointers.md +56 -9
  14. package/src/gramlot_examples/pages/binding/02_variable_datapath.md +50 -4
  15. package/src/gramlot_examples/pages/binding/03_setters_and_defaults.md +45 -6
  16. package/src/gramlot_examples/pages/binding/04_native_editing.md +48 -6
  17. package/src/gramlot_examples/pages/binding/05_checkbox_radio.md +44 -4
  18. package/src/gramlot_examples/pages/binding/06_style_and_visibility.md +40 -6
  19. package/src/gramlot_examples/pages/binding/07_bound_svg.md +48 -3
  20. package/src/gramlot_examples/pages/binding/08_freeze.js +1 -1
  21. package/src/gramlot_examples/pages/binding/08_freeze.md +44 -6
  22. package/src/gramlot_examples/pages/binding/09_forms.js +2 -1
  23. package/src/gramlot_examples/pages/binding/09_forms.md +53 -7
  24. package/src/gramlot_examples/pages/binding/10_svg_shapes.md +50 -5
  25. package/src/gramlot_examples/pages/binding/11_complete_page.md +53 -7
  26. package/src/gramlot_examples/pages/binding/README.md +34 -0
  27. package/src/gramlot_examples/pages/controllers/01_formula.md +48 -7
  28. package/src/gramlot_examples/pages/controllers/02_controller.js +24 -2
  29. package/src/gramlot_examples/pages/controllers/02_controller.md +61 -6
  30. package/src/gramlot_examples/pages/controllers/03_named_logic.md +63 -7
  31. package/src/gramlot_examples/pages/controllers/04_inline_expressions.md +50 -7
  32. package/src/gramlot_examples/pages/controllers/05_node_methods.md +41 -7
  33. package/src/gramlot_examples/pages/controllers/06_button_controller.md +49 -6
  34. package/src/gramlot_examples/pages/controllers/07_events.md +45 -6
  35. package/src/gramlot_examples/pages/controllers/08_end_to_end.js +26 -1
  36. package/src/gramlot_examples/pages/controllers/08_end_to_end.md +138 -9
  37. package/src/gramlot_examples/pages/controllers/09_endpoint.md +47 -7
  38. package/src/gramlot_examples/pages/controllers/10_call_on_change.md +48 -8
  39. package/src/gramlot_examples/pages/controllers/11_call_on_click.js +6 -0
  40. package/src/gramlot_examples/pages/controllers/11_call_on_click.md +58 -6
  41. package/src/gramlot_examples/pages/controllers/12_remote.js +33 -0
  42. package/src/gramlot_examples/pages/controllers/12_remote.md +60 -0
  43. package/src/gramlot_examples/pages/controllers/13_cached_remote.js +44 -0
  44. package/src/gramlot_examples/pages/controllers/13_cached_remote.md +67 -0
  45. package/src/gramlot_examples/pages/controllers/14_data_remote.js +39 -0
  46. package/src/gramlot_examples/pages/controllers/14_data_remote.md +69 -0
  47. package/src/gramlot_examples/pages/controllers/15_lifecycle.js +51 -0
  48. package/src/gramlot_examples/pages/controllers/15_lifecycle.md +59 -0
  49. package/src/gramlot_examples/pages/controllers/16_attribute_projection.js +25 -0
  50. package/src/gramlot_examples/pages/controllers/16_attribute_projection.md +58 -0
  51. package/src/gramlot_examples/pages/controllers/17_data_exchange.js +51 -0
  52. package/src/gramlot_examples/pages/controllers/17_data_exchange.md +61 -0
  53. package/src/gramlot_examples/pages/controllers/README.md +57 -3
  54. package/src/gramlot_examples/pages/html_svg/01_hello_world.md +48 -4
  55. package/src/gramlot_examples/pages/html_svg/02_text_and_links.md +42 -4
  56. package/src/gramlot_examples/pages/html_svg/03_lists.md +45 -4
  57. package/src/gramlot_examples/pages/html_svg/04_semantic_page.md +44 -4
  58. package/src/gramlot_examples/pages/html_svg/05_tables.md +46 -4
  59. package/src/gramlot_examples/pages/html_svg/06_forms.md +48 -4
  60. package/src/gramlot_examples/pages/html_svg/07_native_disclosure.md +41 -4
  61. package/src/gramlot_examples/pages/html_svg/08_svg_shapes.md +45 -4
  62. package/src/gramlot_examples/pages/html_svg/09_svg_composition.md +44 -4
  63. package/src/gramlot_examples/pages/html_svg/10_cards_with_icons.md +42 -15
  64. package/src/gramlot_examples/pages/html_svg/11_static_report.md +37 -4
  65. package/src/gramlot_examples/pages/html_svg/12_complete_page.md +41 -4
  66. package/src/gramlot_examples/pages/html_svg/13_live_source.md +47 -16
  67. package/src/gramlot_examples/pages/html_svg/README.md +36 -0
@@ -1,9 +1,53 @@
1
1
  # 01 · Hello world
2
2
 
3
- The smallest Gramlot page: one main landmark, heading and paragraph.
3
+ A small page with a heading and a greeting. You learn how to create elements and nest them to build a page.
4
4
 
5
- `main(root)` declares each element as a typed Source node. The Python and JavaScript Pages produce the same visible structure.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a second paragraph and compare the two Page modules.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The page has no state or interaction.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Explain how a Page produces a Source tree, then add one visible element.
14
+
15
+ **Before this lesson:** [setup and release sequence](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e01 · Hello World** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ `Page` extends `BasePage`; the adapter calls `main(root)`. Each element call adds a typed Source node. The browser renders that tree; the Python code does not manipulate DOM. `Page.css` selects the shared theme.
22
+
23
+ ```python
24
+ page.h1("Hello, Gramlot!")
25
+ page.p("This heading and paragraph come from a Source tree.")
26
+ ```
27
+
28
+ Here `page` is the local variable holding the main element, not the Page instance (`self`).
29
+
30
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
31
+
32
+ ## Try it and predict the result
33
+
34
+ 1. Open the page: expect one main landmark, one heading and one paragraph.
35
+ 2. Compare Python and JavaScript source: both declare that same hierarchy. There is no input or application state to change.
36
+
37
+ ## Change it and check yourself
38
+
39
+ Add `page.p("My second paragraph")` immediately after the existing paragraph. Predict the count, save and reload.
40
+
41
+ **Answer:** two paragraphs appear below the same heading. The new call created another Source child; no separate DOM insertion code is needed.
42
+
43
+ ## The same example across stages
44
+
45
+ Keep this static stage. Later, b01 replaces literal text with a Data pointer; the heading can then change without re-running `main`. That adds reactivity rather than making this two-line static example shorter.
46
+
47
+ ## Limits and next step
48
+
49
+ An element call inside `main` builds structure once. Changing the source file is not a live Data update. Text is literal, not HTML markup.
50
+
51
+ Continue with [e02 · Text and links](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/02_text_and_links.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
52
+
53
+ </details>
@@ -1,9 +1,47 @@
1
1
  # 02 · Text and links
2
2
 
3
- Text hierarchy, mixed inline content, quotation, code and two kinds of link.
3
+ Paragraphs, emphasis and links in one page. You learn how to combine text and elements, while keeping ordinary text safe to display.
4
4
 
5
- A paragraph combines literal text with strong, emphasis, span and anchor children. The pre/code pair displays escaped text.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add an abbreviation and another local destination.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The external standards link needs network access; the page itself fetches nothing.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Compose mixed text and links while preserving literal text.
14
+
15
+ **Before this lesson:** [e01 · Hello World](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/01_hello_world.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e02 · Text and links** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ The paragraph has text and `strong`, `em`, `span` and `a` children. The `pre().code(...)` pair presents code as text. A fragment link uses the HTML `id`, not a Source label.
22
+
23
+ ```python
24
+ page.h3("A local destination", id="destination")
25
+ page.a("Jump back to the heading", href="#destination")
26
+ ```
27
+
28
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
29
+
30
+ ## Try it and predict the result
31
+
32
+ 1. Find the literal `<tag>` text: it is displayed, not turned into an element.
33
+ 2. Activate “Jump back to the heading”: the browser moves to “A local destination”. The standards link opens an external page separately.
34
+
35
+ ## Change it and check yourself
36
+
37
+ Add `page.h3("More", id="more")` and `page.a("Read more", href="#more")`.
38
+
39
+ **Answer:** the new link jumps to the new heading. Changing only `href` to `#missing` does not create a destination: the two names must match.
40
+
41
+ ## Limits and next step
42
+
43
+ The external link needs a network connection. Local links are native browser navigation, not a Gramlot router or a request for remote Source.
44
+
45
+ Continue with [e03 · Lists](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/03_lists.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
46
+
47
+ </details>
@@ -1,9 +1,50 @@
1
1
  # 03 · Lists
2
2
 
3
- Ordered, unordered and description lists built from local data.
3
+ Bullet lists, numbered lists and terms with descriptions. You learn how a loop builds several elements from a set of values when the page is created.
4
4
 
5
- Loops add ordered steps, definition pairs and a nested list while Source preserves their structure.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a fourth step and another glossary term.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The list content is fixed when the Page builds Source.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Distinguish a Python build-time loop from reactive Data.
14
+
15
+ **Before this lesson:** [e01 · Hello World](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/01_hello_world.md), [e02 · Text and links](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/02_text_and_links.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e03 · Lists** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ `STEPS` drives an ordered list, `TERMS` drives paired `dt`/`dd` nodes, and a nested `ul` is a child of one `li`.
22
+
23
+ ```python
24
+ ordered = page.ol()
25
+ for step in STEPS:
26
+ ordered.li(step)
27
+ ```
28
+
29
+ The loop runs when the host builds Source; the list on screen is its result.
30
+
31
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
32
+
33
+ ## Try it and predict the result
34
+
35
+ 1. Count three ordered steps, two definition pairs and a nested list.
36
+ 2. Reload: the same constants produce the same nodes; no timer or subscription appends rows.
37
+
38
+ ## Change it and check yourself
39
+
40
+ Append `"Explain the result"` to `STEPS` and `("DOM", "The browser representation.")` to `TERMS`.
41
+
42
+ **Answer:** after reload there are four ordered items and three definition pairs. Existing nested items are unaffected because their loop uses another collection.
43
+
44
+ ## Limits and next step
45
+
46
+ A Python list constant is not a Data Bag subscription. Later changing a Data value does not rerun this Python loop.
47
+
48
+ Continue with [e04 · Semantic page](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/04_semantic_page.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
49
+
50
+ </details>
@@ -1,9 +1,49 @@
1
1
  # 04 · A semantic page
2
2
 
3
- Landmarks and sections give a small page a meaningful reading order.
3
+ A page with a header, navigation, main content and footer. You learn how HTML gives each part a role and how links lead to sections within the page.
4
4
 
5
- Header, navigation, main, article, aside and footer are authored as HTML Source. Section IDs serve as anchor targets.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add another article and a matching navigation link.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** Navigation uses native anchors; there is no client router.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Build semantic regions and connect navigation to their IDs.
14
+
15
+ **Before this lesson:** [e02 · Text and links](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/02_text_and_links.md), [e03 · Lists](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/03_lists.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e04 · Semantic page** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ The Source declares `header`, `nav`, a main landmark, an `article`, an `aside` and `footer`. `aria_label` names the navigation. The Story and Notes links target `id="story"` and `id="notes"`.
22
+
23
+ ```python
24
+ nav.a("Story", href="#story")
25
+ article = main.article(id="story", class_="stack")
26
+ ```
27
+
28
+ Here `main` is an element variable, distinct from the Page method `main(root)`.
29
+
30
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
31
+
32
+ ## Try it and predict the result
33
+
34
+ 1. Activate Notes, then Story. Each link targets its section inside the preview.
35
+ 2. Inspect the Source: visual cards and semantic landmarks are declarations, not a separate HTML template.
36
+
37
+ ## Change it and check yourself
38
+
39
+ Add `main.article(id="references").h2("References")` and a navigation link with `href="#references"`.
40
+
41
+ **Answer:** a third destination appears; the browser handles the jump. Adding a link alone would not create an article.
42
+
43
+ ## Limits and next step
44
+
45
+ Landmark markup does not by itself prove accessibility of an entire application. This lesson has no client router or database.
46
+
47
+ Continue with [e05 · Tables](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/05_tables.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
48
+
49
+ </details>
@@ -1,9 +1,51 @@
1
1
  # 05 · Tables
2
2
 
3
- A data table with a caption, scoped headings and a calculated total.
3
+ A table with headings, rows and a total. You learn how to turn a small dataset into a readable table without repeating the row declarations.
4
4
 
5
- One local row set feeds the table body and footer arithmetic.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a region and confirm the total changes in both languages.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** Values are fixed when Source is built.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Derive rows and totals from one fixed dataset.
14
+
15
+ **Before this lesson:** [e03 · Lists](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/03_lists.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e05 · Tables** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ `ROWS` contains North (12, 8), South (9, 11) and West (15, 6). `thead`, `tbody` and `tfoot` give the table structure; `scope` identifies row/column headings. Python computes `q1 + q2` before writing each cell.
22
+
23
+ ```python
24
+ for value in (q1, q2, q1 + q2):
25
+ row.td(str(value))
26
+ ```
27
+
28
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
29
+
30
+ ## Try it and predict the result
31
+
32
+ 1. Check row totals: 20, 20 and 21.
33
+ 2. Check the footer: Q1 = 36, Q2 = 25, total = 61. Explain why both totals use the same tuples.
34
+
35
+ ## Change it and check yourself
36
+
37
+ Add `("East", 2, 3)` to `ROWS` and reload.
38
+
39
+ **Answer:** the new row totals 5; the footer becomes 38, 28 and 66. No cell-specific arithmetic needs editing, because the loop and sums read the enlarged dataset.
40
+
41
+ ## The same example across stages
42
+
43
+ In the later 0.2.0 c01 lesson, the same idea of a computed total becomes `dataFormula`: inputs change Data and the framework schedules recomputation. The old static calculation remains valid for a fixed report.
44
+
45
+ ## Limits and next step
46
+
47
+ The totals are fixed in the built Source. Editing a constant requires a rebuild/reload; it does not establish live formulas.
48
+
49
+ Continue with [e06 · Forms](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/06_forms.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
50
+
51
+ </details>
@@ -1,9 +1,53 @@
1
1
  # 06 · Native forms
2
2
 
3
- Native fields, choices and buttons grouped in fieldsets.
3
+ A form with text fields, choices and a Reset button. Change the values and reset them to see what native HTML controls already do on their own. Later, **Forms with binding** revisits this form and connects its fields to shared Data.
4
4
 
5
- The browser owns editing and Reset. The Source grammar authors the HTML label with `html_label(...)`, because `label` is also a node property.
5
+ **Uses:** Source and native HTML controls — core 0.1.x. No Data binding or controllers.
6
6
 
7
- **Try it:** Change a default value, use Reset and add a select option.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** Submit is disabled because this page has no save endpoint or declared form handler.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Understand native editing and Reset before adding Data binding.
14
+
15
+ **Before this lesson:** [e04 · Semantic page](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/04_semantic_page.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e06 · Forms** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ The `field` helper declares a label and input. `html_label` selects the HTML element without confusing it with the Source node’s label. Initial values belong to HTML attributes/content in this stage.
22
+
23
+ ```python
24
+ self.field(identity, "Name", "name", "text", value="Ada Lovelace", required=True)
25
+ options.input(type="checkbox", id="updates", name="updates", checked=True)
26
+ ```
27
+
28
+ The select marks its initial option with `selected`; the textarea has literal content.
29
+
30
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
31
+
32
+ ## Try it and predict the result
33
+
34
+ 1. Change Name and uncheck Receive updates. The controls change natively; there is no Data record display.
35
+ 2. Click Reset values: Name returns to Ada Lovelace and Receive updates is checked. Submit stays disabled.
36
+
37
+ ## Change it and check yourself
38
+
39
+ Change the Name default to `"Grace Hopper"`, reload, type another name, then Reset.
40
+
41
+ **Answer:** Reset now restores Grace Hopper, because that is the new native default. It does not call an endpoint or restore a Gramlot Data Bag.
42
+
43
+ ## The same example across stages
44
+
45
+ Return in **core 0.2.0** at [b09 · Forms with binding](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/binding/09_forms.md). The same fieldsets move their defaults into one Data record and replace literal values/checked/selected flags with pointers. The control and the record display share that state; no separate display-update handler is authored. The bound version adds a capability, so the whole file is not claimed to be shorter. Keep this native Reset example as the earlier stage.
46
+
47
+ ## Limits and next step
48
+
49
+ File selection remains native. No persistence, upload, save endpoint or record/form framework is provided. Reset is safe here because there are no Data bindings.
50
+
51
+ Continue with [e07 · Native disclosure](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/07_native_disclosure.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
52
+
53
+ </details>
@@ -1,9 +1,46 @@
1
1
  # 07 · Disclosure and measures
2
2
 
3
- Expandable questions with static progress and meter values.
3
+ Expandable details, a progress bar and a meter. You learn how to declare controls whose basic behavior is already supplied by the browser.
4
4
 
5
- A loop creates details/summary pairs. Native browser behavior handles expansion; the measurements have explicit values and labels.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a question and change the fixed meter value.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The measurements do not update automatically.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Recognize behavior supplied by native HTML rather than application code.
14
+
15
+ **Before this lesson:** [e03 · Lists](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/03_lists.md), [e04 · Semantic page](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/04_semantic_page.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e07 · Native disclosure** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ Each `details` contains a `summary` and answer paragraph. The browser toggles the disclosure. `progress(value=70, max=100)` and `meter(value=8, max=10)` are fixed measurements, with explicit labels.
22
+
23
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
24
+
25
+ ## Try it and predict the result
26
+
27
+ 1. Open and close “What is Source?”. The answer changes visibility without an authored controller.
28
+ 2. Wait: Preparation remains 70% and Quality remains 8 of 10.
29
+
30
+ ## Change it and check yourself
31
+
32
+ Add another question/answer to the tuple and change the progress value to 80 **and** its label to “Preparation: 80%”.
33
+
34
+ **Answer:** another disclosure and an 80% bar appear after reload. Updating only the bar would leave a misleading label; this stage has no binding to keep them synchronized.
35
+
36
+ ## The same example across stages
37
+
38
+ Later b11 revisits the FAQ with `open="^.faq_open"`: one bound checkbox controls both disclosures. The framework projects that one value to each declaration; no list of manual open/close operations is needed.
39
+
40
+ ## Limits and next step
41
+
42
+ No live task or background progress is being measured. Native disclosure is not Data binding.
43
+
44
+ Continue with [e08 · SVG shapes](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/08_svg_shapes.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
45
+
46
+ </details>
@@ -1,9 +1,50 @@
1
1
  # 08 · SVG shapes
2
2
 
3
- Six SVG primitives in one accessible viewport.
3
+ Six SVG shapes with different sizes, fills and strokes. You learn how to describe a drawing alongside HTML. Later, **SVG shapes with binding** makes these shapes respond to controls.
4
4
 
5
- The SVG dialect nests below an HTML figure. Coordinates, fill and stroke are declared as SVG attributes.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Move a shape and compare its coordinates in both languages.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** This illustration has no animation or pointer behavior.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Read SVG geometry and distinguish Source attributes from CSS.
14
+
15
+ **Before this lesson:** [e01 · Hello World](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/01_hello_world.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e08 · SVG shapes** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ An HTML `figure` contains one SVG viewport (`viewBox="0 0 480 200"`), six shapes and a label. The SVG title supplies the accessible name. `cx`, `cy` and `r` describe the circle in viewBox coordinates.
22
+
23
+ ```python
24
+ art.circle(cx=172, cy=58, r=38, fill="var(--gramlot-warning)")
25
+ ```
26
+
27
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
28
+
29
+ ## Try it and predict the result
30
+
31
+ 1. Locate the circle between the rectangle and ellipse.
32
+ 2. Compare its radius 38 with the ellipse’s separate `rx=26` and `ry=38`: a circle has one radius, an ellipse has two.
33
+
34
+ ## Change it and check yourself
35
+
36
+ Change only the circle’s `cx` from 172 to 182 and reload.
37
+
38
+ **Answer:** its center moves ten viewBox units right; its radius and fill do not change. This is a new Source build, not animation.
39
+
40
+ ## The same example across stages
41
+
42
+ In **0.2.0**, [b10 · SVG shapes with binding](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/binding/10_svg_shapes.md) returns to these six shapes. `r=38` becomes `r="^.radius"`; a range and the circle share `.radius`. A pointer replaces explicit Source-attribute updates for each edit. The initial drawing is comparable, but interaction is new.
43
+
44
+ ## Limits and next step
45
+
46
+ Coordinates and SVG presentation attributes are not HTML style shortcuts. This stage has no controls or animation.
47
+
48
+ Continue with [e09 · SVG composition](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/09_svg_composition.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
49
+
50
+ </details>
@@ -1,9 +1,49 @@
1
1
  # 09 · SVG composition
2
2
 
3
- A scene assembled from repeated groups, paths and helper methods.
3
+ An SVG scene assembled from smaller parts. You learn how groups and reusable page-building methods keep a larger drawing easy to follow.
4
4
 
5
- House, tree and flower helpers add grouped shapes. Loops place repetitions, while theme tokens color the scene.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a third house or vary flower positions.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The scene is decorative and static.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Reuse Source-building methods to compose a scene.
14
+
15
+ **Before this lesson:** [e03 · Lists](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/03_lists.md), [e08 · SVG shapes](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/08_svg_shapes.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e09 · SVG composition** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ `house`, `tree` and `flower` populate a group in the same SVG. A transform moves the whole group, so its child coordinates stay local.
22
+
23
+ ```python
24
+ for x in (115, 330):
25
+ self.house(drawing, x)
26
+ # Inside house:
27
+ group = drawing.g(transform=f"translate({x} 0)")
28
+ ```
29
+
30
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
31
+
32
+ ## Try it and predict the result
33
+
34
+ 1. Count two houses, three trees and three flowers.
35
+ 2. Compare the two houses: their child declarations are shared; only the group translation differs.
36
+
37
+ ## Change it and check yourself
38
+
39
+ Change the house positions to `(115, 330, 210)` and reload.
40
+
41
+ **Answer:** three houses are built. The added one can overlap existing scenery: a loop reuses declarations but does not automatically solve layout. Try a wider viewBox or deliberate repositioning.
42
+
43
+ ## Limits and next step
44
+
45
+ These are ordinary Page helper methods building Source, not a recipe registry or component API. The scene is static.
46
+
47
+ Continue with [e10 · Cards with icons](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/10_cards_with_icons.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
48
+
49
+ </details>
@@ -1,21 +1,48 @@
1
1
  # 10 · Cards with icons and live Source
2
2
 
3
- Responsive HTML cards with SVG drawings. Click a card's × button to remove it
4
- without reloading the page.
3
+ Three cards, each with an SVG icon. You learn how to combine text and drawings. The × buttons add a later step: removing a card from Source also removes it from the screen. Return to the buttons after **Events**.
5
4
 
6
- The Builder gives the page, card container and each card a stable `node_label`.
7
- The button's short JavaScript action finds `main.page.cards` in the browser
8
- Builder's Source and calls `popNode` with the card label. Gramlot observes the
9
- Source deletion and removes the corresponding DOM branch, including its SVG.
10
- The action never removes a DOM element directly.
5
+ **Uses:** Source, HTML and SVG (0.1.x); removal uses browser actions (0.2.0) and the `src` name from 0.2.10.
11
6
 
12
- Python and JavaScript declare the same page and browser action. It also works
13
- in the static gallery of `gramlot-serverless gallery <folder>`, opened from disk,
14
- offline.
7
+ <details>
8
+ <summary>More detail</summary>
15
9
 
16
- **Try it:** Remove the middle card, then the others. Reload to restore all three.
17
- Add a fourth card to the local dataset and give it a matching icon branch.
18
10
 
19
- **Limit:** This is a small, explicit JavaScript action demonstrating live Source,
20
- not Data binding, persistence or server synchronization. The icons are decorative;
21
- card text and the labelled remove buttons carry the meaning.
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here. The interactive controls are a later 0.2.0 layer; return to them after c07. The src proxy spelling is from 0.2.10.
12
+
13
+ **Goal:** Remove a Source branch and let Gramlot remove the corresponding DOM.
14
+
15
+ **Before this lesson:** [e09 · SVG composition](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/09_svg_composition.md), [c07 · Events](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/controllers/07_events.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e10 · Cards with icons** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands. This lesson executes authored inline JavaScript and needs the gallery’s permissive CSP profile; a strict named-Logic starter needs the corresponding named form.
18
+
19
+ ## Read the page
20
+
21
+ Three cards use Source `node_label` values `structure`, `drawing` and `reading`. The inline click declaration finds the Source container `main.page.cards` and calls `popNode` with the selected card label. Its SVG disappears with the card.
22
+
23
+ `node_label` is a Bag path segment, `node_id` is a Source lookup identity, and HTML `id` identifies a DOM element; they are not interchangeable. `main` here is a **Source** path, not a Data prefix.
24
+
25
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
26
+
27
+ ## Try it and predict the result
28
+
29
+ 1. Click × on Drawing. Exactly that card disappears and the two others remain.
30
+ 2. Remove the others, then reload: all three return because the host builds the initial Source again.
31
+
32
+ ## Change it and check yourself
33
+
34
+ Add a fourth tuple to `CARDS` and a matching branch in `icon`. Give the tuple a new Source label, then reload and remove it.
35
+
36
+ **Answer:** four cards appear and removal still targets one label. Reusing another card’s label would not give it an independent stable identity.
37
+
38
+ ## The same example across stages
39
+
40
+ At the later binding stage, b08 and c08 wrap related Source operations in named Logic and combine them with Data. For values that merely change geometry/text, b07 replaces repeated Source writes with pointers; removing structure still uses Source operations.
41
+
42
+ ## Limits and next step
43
+
44
+ Changes are local, not persisted or synchronized to a server. The cards are Source-only; the button declaration is a later inline-behavior layer. The installed companion Logic is empty here.
45
+
46
+ Continue with [e11 · Static report](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/11_static_report.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
47
+
48
+ </details>
@@ -1,9 +1,42 @@
1
1
  # 11 · Static report
2
2
 
3
- A summary, SVG bar chart, visible legend and table from one dataset.
3
+ A report with a summary, chart and table, all built from the same data. You learn how to reuse those values to create consistent views.
4
4
 
5
- Page methods build each section. Chart lengths and exact figures derive from the same local values.
5
+ **Uses:** Source and native HTML/SVG — core 0.1.x. No Data binding.
6
6
 
7
- **Try it:** Add a region, then check summary, legend, chart and table.
7
+ <details>
8
+ <summary>More detail</summary>
8
9
 
9
- **Limit:** The report has no data service or live refresh.
10
+
11
+ **Release stage:** Source foundation (core 0.1.x); maintained syntax is used here.
12
+
13
+ **Goal:** Keep a summary, chart and table consistent with one dataset.
14
+
15
+ **Before this lesson:** [e05 · Tables](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/05_tables.md), [e08 · SVG shapes](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/08_svg_shapes.md), [e09 · SVG composition](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/09_svg_composition.md). These prerequisites support the release sequence; later comparisons are explicitly labelled below.
16
+
17
+ **Open and edit:** select **e11 · Static report** in your environment’s gallery. For source changes, copy/edit the matching page in your own project using the [setup guide](https://github.com/gramlot-org/gramlot/blob/main/docs/public/025-try.md); the gallery is a source viewer. Save, then reload/reopen as that guide explains. The snippets below are excerpts/edits within that Page, not standalone launch commands.
18
+
19
+ ## Read the page
20
+
21
+ `REGIONS` drives the summary, SVG bars, legend and table. Initially North = 12, South = 9 and West = 15, total 36. Each bar width is `value * 23`; the label’s position also uses that value. The SVG title is separate literal text.
22
+
23
+ Python builds Source on the server; its JavaScript counterpart builds it on Node/Bun or in a standalone Worker. Bindings, actions and any Logic execute in the browser; Python strings containing JavaScript are not executed by Python.
24
+
25
+ ## Try it and predict the result
26
+
27
+ 1. Check the total 36 and region count 3.
28
+ 2. Compare the longest bar with the table: West has 15, so its bar is 345 viewBox units wide.
29
+
30
+ ## Change it and check yourself
31
+
32
+ Change North from 12 to 14. Update the literal SVG title from “North 12” to “North 14”, then reload.
33
+
34
+ **Answer:** total 38, still three regions, and North’s bar width 322. The visible table/chart recompute from the tuple; the accessible title needed an explicit edit because it is literal.
35
+
36
+ ## Limits and next step
37
+
38
+ This is a static report. Do not call it a live data service, and do not leave the accessible description stale when changing its dataset.
39
+
40
+ Continue with [e12 · Complete page](https://github.com/gramlot-org/gramlot-examples/blob/main/src/gramlot_examples/pages/html_svg/12_complete_page.md). The [authoring reference](https://github.com/gramlot-org/gramlot/blob/main/docs/public/095-writing-pages.md) explains the full contract.
41
+
42
+ </details>