@squeed/flow-sdk 2.0.10 → 2.0.11

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.
package/README.md CHANGED
@@ -359,7 +359,8 @@ the source tree. Edit this single JSON source to keep the guide current.
359
359
  Inside a diagram, `useNodeViewActions()` (or `useFlowDiagramContext()`) exposes
360
360
  `allNodesIconLabel` and `setAllNodesIconLabel(boolean)`. The bulk action reuses
361
361
  `setNodeViewMode(id, "icon-label")` for objects/arrays and `onNodeCollapse` for
362
- parents. Disable it to restore default object views and reopen parents. Dots use
362
+ parents. Disable it to expand icon-label defaults into property views, restore
363
+ other default object views, and reopen parents. Dots use
363
364
  the same per-node actions and remain interactive; there is no global view lock.
364
365
  `allNodesIconLabel` reflects the current node modes.
365
366
 
@@ -470,6 +471,75 @@ property addressing. Custom `renderForm` implementations remain host-owned.
470
471
 
471
472
  ### Compose Your Own Controls
472
473
 
474
+ ### Upload Form Fields
475
+
476
+ Set `$control: "upload"` in `forms.bindings[nodeAddress].fields` (or the
477
+ document node's `$form.$fields`). A `string` property is a single-file field;
478
+ an `array` of strings is a multiple-file field. Values are stored URLs, never
479
+ `File` objects or temporary browser blob URLs. Upload arrays remain inline
480
+ controls even with `forms.structured: true`.
481
+
482
+ ```tsx
483
+ const formSchema = {
484
+ Attachments: {
485
+ kind: "object",
486
+ properties: {
487
+ cover: { type: { kind: "string" }, optional: true },
488
+ files: {
489
+ type: { kind: "array", items: { kind: "string" } },
490
+ optional: true,
491
+ },
492
+ },
493
+ },
494
+ } satisfies FormSchema;
495
+
496
+ <FlowDiagram
497
+ json={{ attachments: { $label: "Attachments", $view: "object" } }}
498
+ config={{ formSchema, editable: true }}
499
+ forms={{
500
+ state,
501
+ bindings: {
502
+ "root.attachments": {
503
+ address: "root.record",
504
+ type: "Attachments",
505
+ fields: {
506
+ cover: {
507
+ $control: "upload",
508
+ $upload: { accept: "image/*", maxSizeBytes: 5_000_000 },
509
+ },
510
+ files: { $control: "upload", $upload: { accept: "image/*,.pdf" } },
511
+ },
512
+ },
513
+ },
514
+ onStateChange: setState,
515
+ }}
516
+ callbacks={{
517
+ uploadFormFile: ({ file, address, nodeAddress, data, signal }) =>
518
+ uploadToStorage(file, { address, nodeAddress, data, signal }),
519
+ }}
520
+ />;
521
+ ```
522
+
523
+ `uploadToStorage` is your host's uploader, not an SDK service. The callback
524
+ receives a `FormUploadRequest` (file, field/node addresses, optional node ID,
525
+ read-only form data, and an abort signal) and must return an HTTP(S) file URL
526
+ without embedded credentials, synchronously or as a promise. The app's
527
+ `SDKTest` surface accepts the same optional `uploadFormFile` prop. No storage
528
+ endpoint, credentials, or automatic upload service is supplied.
529
+
530
+ Empty fields show a dashed rounded square with a centered plus; click or drop
531
+ files to upload. Single-file fields replace that square with one preview and
532
+ replace/remove controls. Multiple-file fields append previews in selection
533
+ order and retain an add-more square. Non-image files have a file-link fallback.
534
+ Uploading disables mutations on that field; failed batches preserve its prior
535
+ value. Closing the form, changing the bound value, or disabling editing aborts
536
+ pending work and ignores late results. Hosts should honor `signal` and handle
537
+ cleanup of files already stored during a failed/cancelled batch. Removing a URL
538
+ changes form data only; it does not delete the server file. File type/size checks
539
+ are optional client checks and must also be enforced by the host/server.
540
+
541
+ ### Compose Your Own Controls
542
+
473
543
  All reusable control components are exported from `@squeed/flow-sdk` through
474
544
  [src/index.ts](src/index.ts). Hide the default toolbar with `showBottomBar={false}`
475
545
  and mount your controls as children to share the diagram and form providers: