pict-section-form 1.1.0 → 1.1.2

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 (45) hide show
  1. package/docs/_cover.md +3 -0
  2. package/docs/_sidebar.md +5 -0
  3. package/docs/_version.json +3 -3
  4. package/docs/examples/README.md +3 -0
  5. package/docs/examples/change_tracking/change_tracking.js +9437 -9427
  6. package/docs/examples/diagram_form/README.md +116 -0
  7. package/docs/examples/diagram_form/diagram_form_example.min.js +42 -0
  8. package/docs/examples/diagram_form/excalidraw-iframe-host.html +25 -0
  9. package/docs/examples/diagram_form/excalidraw-wrapper.css +1 -0
  10. package/docs/examples/diagram_form/excalidraw-wrapper.min.js +3327 -0
  11. package/docs/examples/diagram_form/index.html +116 -0
  12. package/docs/examples/diagram_form/manifest.json +13 -0
  13. package/docs/examples/diagram_form/react-vendor.min.js +9 -0
  14. package/docs/examples/dynamic_analysis/dynamic_analysis_application.js +6549 -6550
  15. package/docs/examples/gradebook/gradebook_application.min.js +2 -2
  16. package/docs/examples/ndt_field_test/ndt_field_test.js +9437 -9427
  17. package/docs/examples/richtext_form/README.md +132 -0
  18. package/docs/examples/richtext_form/index.html +82 -0
  19. package/docs/examples/richtext_form/richtext_form_example.min.js +42 -0
  20. package/docs/examples/scope_mathematics/scope_mathematics.js +9437 -9427
  21. package/docs/examples/simple_table/simple_tabular_application.min.js +2 -2
  22. package/docs/examples/superhero_studio/README.md +199 -0
  23. package/docs/examples/superhero_studio/excalidraw-iframe-host.html +25 -0
  24. package/docs/examples/superhero_studio/excalidraw-wrapper.css +1 -0
  25. package/docs/examples/superhero_studio/excalidraw-wrapper.min.js +3327 -0
  26. package/docs/examples/superhero_studio/index.html +166 -0
  27. package/docs/examples/superhero_studio/manifest.json +13 -0
  28. package/docs/examples/superhero_studio/react-vendor.min.js +9 -0
  29. package/docs/examples/superhero_studio/superhero_studio_example.min.js +42 -0
  30. package/docs/index.html +2 -2
  31. package/docs/retold-catalog.json +45 -1
  32. package/docs/retold-keyword-index.json +11843 -7677
  33. package/example_applications/diagram_form/DiagramForm-Example-Application.js +145 -0
  34. package/example_applications/diagram_form/html/index.html +116 -0
  35. package/example_applications/diagram_form/package.json +29 -0
  36. package/example_applications/richtext_form/RichTextForm-Example-Application.js +176 -0
  37. package/example_applications/richtext_form/html/index.html +82 -0
  38. package/example_applications/richtext_form/package.json +28 -0
  39. package/example_applications/superhero_studio/SuperheroStudio-Example-Application.js +313 -0
  40. package/example_applications/superhero_studio/html/index.html +166 -0
  41. package/example_applications/superhero_studio/package.json +29 -0
  42. package/example_applications/superhero_studio/superheroes/Superheroes.js +386 -0
  43. package/package.json +3 -9
  44. package/source/providers/inputs/Pict-Provider-Input-Diagram.js +1 -31
  45. package/source/providers/inputs/Pict-Provider-Input-RichText.js +1 -32
@@ -0,0 +1,132 @@
1
+ # RichText Form Input
2
+
3
+ <!-- docuserve:example-launch:start -->
4
+ > **[Launch the live app](examples/richtext%5Fform/index.html)** - runs in your browser, opens in a new tab.
5
+ <!-- docuserve:example-launch:end -->
6
+
7
+ **RichText Form Input** is the smallest demonstration of the new
8
+ `RichText` InputType: a pict-section-form with one field whose provider
9
+ pairs this module's markdown editor (edit mode) with rendered markdown
10
+ (view mode). Boots in view mode — no CodeMirror loaded until the first
11
+ toggle. Demonstrates the pluggable image-uploader hook in two flavors.
12
+
13
+ The `RichText` InputType + its provider class live in **pict-section-form**
14
+ (see [the Input Type doc](https://fable-retold.github.io/pict-section-form/#/page/input%5Fproviders/014-rich-text)).
15
+ The provider lazy-requires this module on the first edit toggle — that's why
16
+ the heavy CodeMirror bundle isn't fetched at boot.
17
+
18
+ For the same InputType inside a richer character-sheet form alongside
19
+ stock inputs and a Diagram, see
20
+ [Superhero Studio](../superhero%5Fstudio/README.md)
21
+ in the pict-section-excalidraw sister module.
22
+
23
+ ## What it demonstrates
24
+
25
+ | Capability | Where you see it |
26
+ |------------|------------------|
27
+ | `Pict-Input-RichText` provider registration | One `pict.addProvider(...)` call wires the InputType into the form |
28
+ | Per-field runtime mode toggle | `provider.toggleMode('Body', cb)` flips view ↔ edit; the editor bundle lazy-loads on the first edit |
29
+ | View-mode rendered markdown | `pict-section-content` renders headings, lists, code blocks, blockquotes into the slot — no editor present |
30
+ | `AllowImages: false` rejection | The checkbox toggles this off live; pasting an image surfaces a rejection rather than inserting a half-baked data URI |
31
+ | Pluggable `ImageUploader` | Pasting with the uploader on calls `pict.PictApplication.uploadImage(file, descriptor, cb)`; turning it off falls through to default base64 inline |
32
+
33
+ ## Key files
34
+
35
+ - `RichTextForm-Example-Application.js` — the app. Registers the RichText input provider, defines a one-field form manifest, stubs `uploadImage`, and exposes the mode-toggle + AllowImages-toggle controls.
36
+ - `html/index.html` — page chrome: the Edit/Done toggle, two checkboxes (`AllowImages` and `Use ImageUploader stub`), and the form container.
37
+
38
+ ## The form descriptor
39
+
40
+ ```javascript
41
+ 'Body': {
42
+ Name: 'Body',
43
+ Hash: 'Body',
44
+ DataType: 'String',
45
+ PictForm:
46
+ {
47
+ Section: 'Article',
48
+ Row: 1,
49
+ Width: 12,
50
+ InputType: 'RichText',
51
+ RichText:
52
+ {
53
+ AllowImages: true,
54
+ ImageUploader: 'uploadImage', // method name on pict.PictApplication
55
+ Height: '320px'
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ The provider auto-injects its templates into pict-section-form's `DynamicTemplates` registry on construction, so the form's render path finds `*-Template-Input-InputType-RichText` and emits the standard hidden input + display slot.
62
+
63
+ ## Feature 1 — View-by-default with lazy editor mount
64
+
65
+ On page load, the field's value is parsed as markdown and written into the slot — that's it. Inspect the DevTools Network tab: no `vendor`-side or `codemirror`-side requests fire.
66
+
67
+ The first time the user clicks Edit, `provider.setMode('Body', 'edit', cb)` runs:
68
+
69
+ 1. Tear down view-mode DOM (clear the slot).
70
+ 2. Instantiate a subclass of `Pict-Section-MarkdownEditor` with `TargetElementAddress` pointing at the slot.
71
+ 3. Seed it with the value the provider was last holding for this hash.
72
+ 4. Wire `onContentChange(segmentIndex, content)` so every keystroke writes through to the form's hidden `<input>` (and dispatches a `change` event so Informary updates AppData).
73
+
74
+ Clicking Done calls `setMode('Body', 'view', cb)`: the editor is destroyed, the slot is re-rendered from the latest value. The hidden input keeps the user's content across the toggle.
75
+
76
+ ## Feature 2 — `AllowImages: false` rejection
77
+
78
+ The provider subclass overrides `onImageUpload(file, segmentIndex, cb)`:
79
+
80
+ ```javascript
81
+ onImageUpload(pFile, pSegmentIndex, fImgCallback)
82
+ {
83
+ if (!tmpRichTextOpts.AllowImages)
84
+ {
85
+ fImgCallback('Image uploads are disabled for this field.');
86
+ return true; // claim the upload so the editor doesn't fall through
87
+ }
88
+ // ... uploader dispatch below
89
+ }
90
+ ```
91
+
92
+ Returning `true` and calling `fCallback(errMessage)` tells the editor "I handled this — and I refused it." No half-baked data URI ends up in the markdown. Toggle the page checkbox to see the live difference.
93
+
94
+ ## Feature 3 — Pluggable `ImageUploader`
95
+
96
+ When `AllowImages: true` AND `ImageUploader` is set, the provider dispatches the file to `pict.PictApplication[name](pFile, pInputDescriptor, fCallback)`:
97
+
98
+ ```javascript
99
+ uploadImage(pFile, pInputDescriptor, fCallback)
100
+ {
101
+ setTimeout(() =>
102
+ {
103
+ let tmpFakeURL = '/uploads/' + Date.now() + '-' + pFile.name.replace(/[^A-Za-z0-9._-]/g, '_');
104
+ fCallback(null, tmpFakeURL);
105
+ }, 600);
106
+ return true;
107
+ }
108
+ ```
109
+
110
+ The 600 ms `setTimeout` mimics a real upload round-trip. A production app would POST the file to its storage endpoint and call back with the permanent URL. With the page checkbox set to "off", the stub returns `false`, which tells the underlying editor "fall through to default" — and the default is `FileReader` → base64 data URI inline. Toggle and confirm.
111
+
112
+ ## Running the example
113
+
114
+ ```sh
115
+ cd modules/pict/pict-section-form/example_applications/richtext_form
116
+ npm install
117
+ npx quack build && npx quack copy
118
+ open dist/index.html
119
+ ```
120
+
121
+ ## Takeaways
122
+
123
+ 1. **The provider is the only registration step.** Once it's added to the Pict instance, every form on the instance can use `InputType: 'RichText'`.
124
+ 2. **Image handling is the host's contract.** Three knobs cover the realistic cases: forbid (`AllowImages: false`), accept and embed (`AllowImages: true`, no uploader), accept and store remotely (`AllowImages: true`, `ImageUploader: '<name>'`).
125
+ 3. **View-mode performance is free.** A form full of read-only RichText fields never touches CodeMirror until the user starts editing.
126
+
127
+ ## Related documentation
128
+
129
+ - [pict-section-markdowneditor API Reference ↗](https://fable-retold.github.io/pict-section-markdowneditor/#/page/api) — the markdown editor's public surface, on which the input provider depends.
130
+ - [pict-section-markdowneditor / Image Upload ↗](https://fable-retold.github.io/pict-section-markdowneditor/#/page/image%5Fupload) — the full `onImageUpload` contract (this is what `ImageUploader` proxies through).
131
+ - [Server Upload ↗](https://fable-retold.github.io/pict-section-markdowneditor/#/page/examples/server%5Fupload/README) — the editor's `onImageUpload` hook wired to a real Orator backend; useful when you want to build a real `ImageUploader` for the form provider.
132
+ - [Superhero Studio](../superhero%5Fstudio/README.md) — the RichText InputType inside a fuller form, alongside a Diagram InputType.
@@ -0,0 +1,82 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>RichText Form Input — Pict Example</title>
7
+
8
+ <style id="PICT-CSS"></style>
9
+ <style>
10
+ *, *::before, *::after { box-sizing: border-box; }
11
+ body { margin: 0; padding: 0; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; background: #FAF8F4; color: #2A2520; }
12
+
13
+ .pict-example-header { display: flex; align-items: stretch; background: #264653; border-bottom: 3px solid #E76F51; }
14
+ .pict-example-badge { background: #E76F51; color: #FAEDCD; padding: 0.6rem 1rem; font-size: 0.72rem; font-weight: 800; text-transform: uppercase; letter-spacing: 0.1em; }
15
+ .pict-example-app-name { padding: 0.6rem 1rem; color: #FAEDCD; font-size: 1.1rem; font-weight: 600; }
16
+ .pict-example-module { margin-left: auto; padding: 0.6rem 1rem; color: #D4A373; font-size: 0.75rem; letter-spacing: 0.03em; align-self: center; }
17
+
18
+ .page-content { padding: 2rem; max-width: 920px; margin: 0 auto; }
19
+ .intro { color: #5A4A3C; font-size: 0.9rem; line-height: 1.6; margin-bottom: 24px; }
20
+ .intro code { background: #F0E8DA; padding: 1px 6px; border-radius: 3px; font-family: 'SFMono-Regular', Menlo, monospace; font-size: 0.85em; }
21
+
22
+ .controls { background: #FFFFFF; border: 1px solid #D4C4A8; border-radius: 6px; padding: 14px 16px; margin-bottom: 20px; display: flex; flex-wrap: wrap; gap: 16px; align-items: center; font-size: 0.85rem; }
23
+ .controls label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
24
+ .controls button { padding: 6px 14px; font-size: 0.85rem; font-weight: 600; color: #FAEDCD; background: #264653; border: none; border-radius: 4px; cursor: pointer; }
25
+ .controls button:hover { background: #E76F51; }
26
+
27
+ #Pict-Form-Container { background: #FFFFFF; border: 1px solid #D4C4A8; border-radius: 6px; padding: 20px; }
28
+
29
+ /* The form has one section + one input. */
30
+ .notes { margin-top: 24px; padding: 14px 16px; background: #FFF8E7; border-left: 3px solid #E9C46A; border-radius: 3px; font-size: 0.82rem; color: #5A4A3C; }
31
+ .notes strong { color: #2A2520; }
32
+ </style>
33
+ </head>
34
+ <body>
35
+ <header class="pict-example-header">
36
+ <span class="pict-example-badge">Pict Example</span>
37
+ <span class="pict-example-app-name">RichText Form Input</span>
38
+ <span class="pict-example-module">pict-section-markdowneditor</span>
39
+ </header>
40
+
41
+ <main class="page-content">
42
+ <p class="intro">
43
+ A pict-section-form field whose <code>InputType</code> is <code>RichText</code>. Boots in
44
+ <strong>view</strong> mode — just rendered markdown, no CodeMirror loaded. Click <em>Edit</em>
45
+ to flip into the editor (lazy-loads the markdown editor bundle on first toggle).
46
+ </p>
47
+
48
+ <div class="controls">
49
+ <button id="toggle-Body" onclick="_Pict.PictApplication.demo_toggleMode('Body')">Edit</button>
50
+
51
+ <label>
52
+ <input type="checkbox" id="allow-images" checked onchange="_Pict.PictApplication.demo_setAllowImages('Body', this.checked)">
53
+ Allow image paste
54
+ </label>
55
+
56
+ <label>
57
+ <input type="checkbox" id="use-uploader" checked onchange="_Pict.PictApplication.demo_setUploaderEnabled(this.checked)">
58
+ Use ImageUploader stub
59
+ <span style="color:#8A7F72; margin-left:6px; font-size:0.75rem;">(off = base64 inline)</span>
60
+ </label>
61
+ </div>
62
+
63
+ <div id="Pict-Form-Container"></div>
64
+
65
+ <div class="notes">
66
+ <strong>Verifying:</strong>
67
+ Open DevTools → Network. With <em>Edit</em> never clicked, no CodeMirror request fires. Click <em>Edit</em>
68
+ once and the markdown-editor bundle loads. Click <em>Done</em> to return to view mode — the editor view
69
+ is torn down, but its content lives in the field's hidden form input.
70
+ </div>
71
+ </main>
72
+
73
+ <script src="https://cdn.jsdelivr.net/npm/pict@1/dist/pict.min.js"></script>
74
+ <script src="./richtext_form_example.min.js"></script>
75
+ <script>
76
+ Pict.safeOnDocumentReady(() =>
77
+ {
78
+ Pict.safeLoadPictApplication(window.RichtextFormExample || window.RichTextFormExample, 1);
79
+ });
80
+ </script>
81
+ </body>
82
+ </html>