socialcalc-ai 1.0.3 → 1.0.9

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 (48) hide show
  1. package/README.md +374 -8
  2. package/components/AgentModal/AgentModal.css +1260 -0
  3. package/components/AgentModal/AgentModal.tsx +1388 -0
  4. package/components/AgentPluginTest/AgentPluginTest.tsx +233 -0
  5. package/core/README.md +959 -0
  6. package/core/editor-widgets.js +3322 -0
  7. package/core/environment.js +582 -0
  8. package/core/format-number.js +2 -5944
  9. package/core/formula-functions.js +3908 -0
  10. package/core/formula.js +1797 -1367
  11. package/core/index.js +17 -7
  12. package/core/popup.js +1676 -0
  13. package/core/render.js +2288 -0
  14. package/core/{core.js → sheet.js} +2 -2641
  15. package/core/spreadsheet-control.js +8 -3288
  16. package/core/table-editor.js +3 -3289
  17. package/core/touch.js +422 -0
  18. package/core/workbook.js +2773 -0
  19. package/index.d.ts +103 -0
  20. package/index.js +4 -0
  21. package/modules/agent.js +1302 -0
  22. package/modules/device.js +3 -10
  23. package/modules/editable-cells.js +4 -9
  24. package/modules/events.js +363 -0
  25. package/modules/exporters.js +164 -11
  26. package/modules/formatting.js +156 -169
  27. package/modules/grid-lines.js +4 -9
  28. package/modules/history.js +13 -17
  29. package/modules/horizontal-scroll.js +4 -9
  30. package/modules/init.js +3 -9
  31. package/modules/invoice.js +4 -10
  32. package/modules/listeners.js +39 -61
  33. package/modules/logos.js +4 -11
  34. package/modules/pdf-export.js +408 -0
  35. package/modules/plugin-manager.js +13 -9
  36. package/modules/prompts.js +22 -48
  37. package/modules/row-col-headers.js +4 -9
  38. package/modules/runtime.js +544 -0
  39. package/modules/share.js +444 -0
  40. package/modules/sheets.js +18 -15
  41. package/modules/touch-scroll.js +4 -9
  42. package/modules/utils.js +10 -11
  43. package/modules/weight.js +4 -11
  44. package/package.json +35 -3
  45. package/pdf-export.d.ts +53 -0
  46. package/pdf-export.js +3 -0
  47. package/share.d.ts +96 -0
  48. package/share.js +3 -0
package/README.md CHANGED
@@ -18,12 +18,14 @@ Derived from Dan Bricklin's proven, industrial-strength **SocialCalc** engine, `
18
18
  - [Quick Start in React / Ionic](#-quick-start-in-react--ionic)
19
19
  - [Quick Start in Vanilla JavaScript](#-quick-start-in-vanilla-javascript)
20
20
  - [Architecture Overview](#-architecture-overview)
21
+ - [Core Engine Reference (`core/README.md`)](core/README.md)
21
22
  - [UI Components](#-ui-components)
22
23
  - [CellEditModal](#1-celleditmodal)
23
24
  - [HorizontalScrollBar](#2-horizontalscrollbar)
24
25
  - [RowActionPopover](#3-rowactionpopover)
25
26
  - [EditableCellsModal](#4-editablecellsmodal)
26
27
  - [DemoVideosModal](#5-demovideosmodal)
28
+ - [AgentModal](#6-agentmodal)
27
29
  - [Plugins & Modules API](#-plugins--modules-api)
28
30
  - [Row & Column Headers](#1-row--column-headers-modulesrow-col-headersjs)
29
31
  - [Grid Lines](#2-grid-lines-modulesgrid-linesjs)
@@ -34,6 +36,10 @@ Derived from Dan Bricklin's proven, industrial-strength **SocialCalc** engine, `
34
36
  - [History & Undo/Redo](#7-history-undo--redo-moduleshistoryjs)
35
37
  - [Exporters & Sheets](#8-exporters--sheets-modulesexportersjs-modulessheetsjs)
36
38
  - [Invoice Utilities](#9-invoice-utilities-modulesinvoicejs)
39
+ - [AI Agent Plugin (Text Editor Agent)](#10-ai-agent-plugin-text-editor-agent-modulesagentjs)
40
+ - [Cell Formatting & Display Suite](#11-cell-formatting--display-suite)
41
+ - [Offline PDF Export Plugin](#12-offline-pdf-export-plugin-socialcalc-aipdf-export)
42
+ - [Share, Email & Print Plugin](#13-share-email--print-plugin-socialcalc-aishare)
37
43
  - [Event-Driven Architecture](#-event-driven-architecture)
38
44
  - [AI & MultiSheet Calc (MSC) Integration](#-ai--multisheet-calc-msc-integration)
39
45
  - [TypeScript Support](#-typescript-support)
@@ -226,14 +232,21 @@ socialcalc-ai/
226
232
  ├── index.js # Main entry point: aggregates core, modules & UI
227
233
  ├── index.d.ts # Complete TypeScript typings
228
234
  ├── package.json # Standalone package definition
229
- ├── core/ # Core calculation engine & DOM table rendering
230
- │ ├── constants.js # Formatting codes, default styles & limits
231
- │ ├── core.js # Spreadsheet sheet model, cell evaluation, formula AST
232
- │ ├── formula.js # Built-in math, logical, string, financial functions
233
- │ ├── format-number.js # Numeric and date formatting routines
234
- │ ├── spreadsheet-control.js # Spreadsheet control lifecycle & pane management
235
- │ ├── table-editor.js # DOM table editor layout & cursor rendering
236
- │ └── index.js # Assembled core SocialCalc singleton export
235
+ ├── core/ # Spreadsheet engine - full reference in core/README.md
236
+ │ ├── index.js # Imports the modules below in load order; exports the SocialCalc singleton
237
+ │ ├── constants.js # UI strings (localization), default styles & sizes
238
+ │ ├── sheet.js # Cell & Sheet model, save format, command language, recalc, undo, clipboard
239
+ │ ├── render.js # RenderContext (HTML table), coordinate/DOM helpers, value display, CSV/HTML conversion
240
+ │ ├── touch.js # Touch detection & gesture handling
241
+ │ ├── format-number.js # Excel-style number and date format strings
242
+ │ ├── formula.js # Formula tokenizer, parser, evaluator & function registry
243
+ │ ├── formula-functions.js # 109 built-in functions (stat, math, text, date, lookup, financial)
244
+ │ ├── popup.js # Popup list & color chooser widgets
245
+ │ ├── table-editor.js # Interactive grid: cursor, selection, scrolling, input box, cell actions
246
+ │ ├── editor-widgets.js # Cell handles, scrollbars, drag/tooltip/button/wheel registries, keyboard
247
+ │ ├── spreadsheet-control.js # Spreadsheet UI: toolbar tabs, formula bar, settings, save/load
248
+ │ ├── workbook.js # Multi-sheet WorkBook & WorkBookControl, sheet bar, MSC save/load
249
+ │ └── environment.js # Loaded last: JSON polyfill, app overrides, server/worker shims
237
250
  ├── modules/ # Modular functional features & plugins
238
251
  │ ├── plugin-manager.js # Central registry for dynamic SocialCalc plugins
239
252
  │ ├── grid-lines.js # Cell border grid-lines plugin
@@ -277,6 +290,16 @@ A modern, responsive bottom-sheet modal that replaces legacy browser `prompt()`
277
290
  - **Image Insertion**: Embed images into cells with automatic client-side compression via `imageCompressor.ts`.
278
291
  - **Fallback**: Automatically falls back to native inline input if modal mode is disabled.
279
292
 
293
+ <p align="center">
294
+ <img src="../public/screenshots/edit-cell-modal.png" alt="Cell Edit Modal Overview" width="48%" />
295
+ <img src="../public/screenshots/edit-cell-modal-features.png" alt="Cell Edit Modal Features" width="48%" />
296
+ </p>
297
+ <p align="center">
298
+ <img src="../public/screenshots/edit-cell-modal-text-color.png" alt="Font Color Palette" width="31%" />
299
+ <img src="../public/screenshots/edit-cell-modal-background-color.png" alt="Background Color Palette" width="31%" />
300
+ <img src="../public/screenshots/edit-cell-model-cell-borders.png" alt="Cell Borders Customizer" width="31%" />
301
+ </p>
302
+
280
303
  ```tsx
281
304
  <CellEditModal
282
305
  isOpen={isOpen}
@@ -301,6 +324,10 @@ A context popup that appears when clicking any row header index:
301
324
  - **Insert Row Below**: Inserts an empty row below the selected index.
302
325
  - **Delete Row**: Removes the selected row and cascades formula references.
303
326
 
327
+ <p align="center">
328
+ <img src="../public/screenshots/row-options.png" alt="Row Action Popover Menu" width="50%" />
329
+ </p>
330
+
304
331
  ```tsx
305
332
  <RowActionPopover
306
333
  isOpen={showPopover}
@@ -316,6 +343,10 @@ An administrative inspector for template creators:
316
343
  - Bind application field mappings (e.g., `vendor_name -> B4`) to spreadsheet coordinates.
317
344
  - Test template locking permissions.
318
345
 
346
+ <p align="center">
347
+ <img src="../public/screenshots/editable-cells-modal.png" alt="Editable Cells Modal" width="60%" />
348
+ </p>
349
+
319
350
  ```tsx
320
351
  <EditableCellsModal
321
352
  isOpen={showModal}
@@ -335,12 +366,152 @@ An interactive help and reference modal containing:
335
366
  />
336
367
  ```
337
368
 
369
+ ### 6. `AgentModal`
370
+ An interactive AI Agent Workbench and chat modal:
371
+ - Inspect active sheet context, dimensions, and detected `appMapping` fields.
372
+ - Test one-click quick actions (e.g. fill invoice header, populate table items, set formula).
373
+ - Execute custom JSON action arrays directly or copy LLM tool schemas (Gemini function declarations, OpenAI tools, and system prompts).
374
+ - View real-time action execution logs.
375
+
376
+ <p align="center">
377
+ <img src="../public/screenshots/agent-console.png" alt="SocialCalc AI Agent Workbench" width="65%" />
378
+ </p>
379
+
380
+ ```tsx
381
+ <AgentModal
382
+ isOpen={showAgentModal}
383
+ onClose={() => setShowAgentModal(false)}
384
+ appMapping={appMapping}
385
+ currentSheet="sheet1"
386
+ onExecute={(res) => console.log("Agent actions:", res)}
387
+ />
388
+ ```
389
+
390
+ #### Customizable Tab Combinations & Header Controls:
391
+ Developers can customize which tabs are visible, choose specific combinations, and optionally hide the tab headers bar:
392
+
393
+ ```tsx
394
+ // Example 1: Show only AI Copilot and Sheet Context
395
+ <AgentModal
396
+ isOpen={showAgentModal}
397
+ onClose={() => setShowAgentModal(false)}
398
+ enabledTabs={["actions", "context"]}
399
+ />
400
+
401
+ // Example 2: Minimalist AI Copilot with NO tab headers bar (pure chatbot view)
402
+ <AgentModal
403
+ isOpen={showAgentModal}
404
+ onClose={() => setShowAgentModal(false)}
405
+ enabledTabs={["actions"]}
406
+ hideTabHeaders={true}
407
+ />
408
+
409
+ // Example 4: Built-in Generic Spreadsheet Suggestions
410
+ <AgentModal
411
+ isOpen={showAgentModal}
412
+ onClose={() => setShowAgentModal(false)}
413
+ suggestions="generic"
414
+ suggestionsTitle="Helpful Prompts:"
415
+ />
416
+
417
+ // Example 5: Custom Developer Prompt Suggestions
418
+ <AgentModal
419
+ isOpen={showAgentModal}
420
+ onClose={() => setShowAgentModal(false)}
421
+ suggestionsTitle="Payroll Shortcuts:"
422
+ suggestions={[
423
+ { label: "Calculate Overtime", prompt: "Compute overtime pay at 1.5x for hours over 40." },
424
+ { label: "Format Currency", prompt: "Format all salary and total cells to USD currency." },
425
+ { label: "Summarize Depts", prompt: "Group departments and show total expenditure per department." },
426
+ ]}
427
+ promptPlaceholder="Ask AI to analyze payroll or edit cells..."
428
+ />
429
+
430
+ // Example 6: Custom Header Title, Icon, and Color/Gradient
431
+ <AgentModal
432
+ isOpen={showAgentModal}
433
+ onClose={() => setShowAgentModal(false)}
434
+ title="Financial Copilot"
435
+ headerIcon={calculatorOutline}
436
+ headerIconColor="#38bdf8"
437
+ headerColor="linear-gradient(135deg, #0284c7 0%, #0369a1 100%)"
438
+ headerTextColor="#ffffff"
439
+ versionTag="Finance v1.0"
440
+ // Example 7: Overall Modal Visual Themes
441
+ <AgentModal
442
+ isOpen={showAgentModal}
443
+ onClose={() => setShowAgentModal(false)}
444
+ theme="dark" // or "midnight" | "emerald" | "purple" | "slate" | "light" | "default"
445
+ />
446
+
447
+ // Example 8: Custom Theme Configuration Object
448
+ <AgentModal
449
+ isOpen={showAgentModal}
450
+ onClose={() => setShowAgentModal(false)}
451
+ theme={{
452
+ mode: "dark",
453
+ primaryColor: "#059669",
454
+ headerBackground: "linear-gradient(135deg, #064e3b, #047857)",
455
+ cardBackground: "#111827",
456
+ }}
457
+ />
458
+ ```
459
+
460
+ | Prop | Type | Default | Description |
461
+ |------|------|---------|-------------|
462
+ | `theme` | `"default" \| "dark" \| "midnight" \| "emerald" \| "purple" \| "slate" \| "light" \| AgentModalThemeConfig` | `"default"` | Controls the overall modal visual theme, supporting dark mode, emerald, purple, slate, or custom theme objects. |
463
+ | `title` / `headerTitle` | `string` | `"SocialCalc AI Agent Workbench"` | Custom title text for the modal window header. |
464
+ | `headerIcon` / `icon` | `any` | `sparklesOutline` | Custom Ionicon or React node for the modal header icon. Pass `false` or `null` to hide. |
465
+ | `headerIconColor` | `string` | `"#a855f7"` | Custom color for the modal header icon. |
466
+ | `headerColor` / `headerBackground` | `string` | Dark indigo gradient | Custom CSS background color or gradient for the modal toolbar (e.g. `"#0f172a"` or `linear-gradient(...)`). |
467
+ | `versionTag` / `headerSubtitle` | `string \| null \| false` | `undefined` (hidden) | Optional pill badge next to header title. Pass a string to display a custom tag. |
468
+ | `copilotTitle` | `string` | `"Agentic Text-Editor Copilot"` | Custom title displayed in the Copilot card header inside the Actions tab. |
469
+ | `copilotIcon` | `any` | `sparklesOutline` | Custom icon for the Copilot card header. Pass `false` or `null` to hide. |
470
+ | `enabledTabs` | `("actions" \| "context" \| "schemas" \| "console")[]` | `["actions", "context", "schemas", "console"]` | Specify the exact list and combination of tabs to display. |
471
+ | `showActionsTab` | `boolean` | `true` | Show or hide the AI Copilot & Actions tab. |
472
+ | `showContextTab` | `boolean` | `true` | Show or hide the Sheet Context tab. |
473
+ | `showSchemasTab` | `boolean` | `true` | Show or hide the LLM Schemas tab. |
474
+ | `showConsoleTab` | `boolean` | `true` | Show or hide the Live Agent Console tab. |
475
+ | `hideTabHeaders` | `boolean` | `false` | Completely hides the tab header bar (aliases: `hideHeaders`, `hideTabBar`). |
476
+ | `defaultTab` | `string` | First enabled tab | Sets the default active tab on opening. |
477
+ | `showPluginTest` | `boolean` | `true` | Show or remove the Direct Plugin Quick Actions & Custom JSON test component (`AgentPluginTest`). Set to `false` for a pure AI Copilot chat interface (aliases: `showQuickActions`, `hidePluginTest`). |
478
+ | `suggestions` | `AgentPromptSuggestion[] \| "generic" \| "invoice" \| boolean` | `undefined` | Configure prompt suggestions: pass `"generic"` for general spreadsheet suggestions, `"invoice"` for invoice actions, custom `[{ label, prompt }]` array, or leave unset/`false` for a clean interface without suggestion chips. |
479
+ | `suggestionsTitle` | `string` | `"Suggestions:"` | Title label displayed above the suggestion chips. |
480
+ | `showSuggestions` | `boolean` | `true` (when `suggestions` provided) | Explicitly show or hide the suggestion chips row. |
481
+ | `promptPlaceholder` | `string` | `"e.g. 'Fill cell C5 with Client Name...'"` | Custom placeholder text for the AI prompt textarea. |
482
+
483
+ ### 7. `AgentPluginTest` (`Agentplugintest`)
484
+ A standalone, removable component for testing direct spreadsheet plugin macros, mappings, and raw JSON actions:
485
+ - **Pre-configured Quick Actions**: Fill Acme invoice header, populate 3 line items, set `=SUM(...)` formula, or clear table.
486
+ - **Custom JSON Action Executor**: Test custom action arrays directly against the active spreadsheet.
487
+ - **Removable from `AgentModal`**: Can be removed from `AgentModal` via `showPluginTest={false}` or `hidePluginTest={true}`.
488
+ - **Usable Standalone**: Can be placed anywhere in your custom developer drawer, page, or modal.
489
+
490
+ ```tsx
491
+ import { AgentPluginTest, Agentplugintest } from "socialcalc";
492
+
493
+ // Use standalone anywhere in your app:
494
+ <AgentPluginTest
495
+ currentSheet="sheet1"
496
+ appMapping={appMapping}
497
+ onExecute={(res) => console.log("Actions applied:", res)}
498
+ onLog={(msg) => console.log("Log:", msg)}
499
+ showCustomJson={true}
500
+ />
501
+ ```
502
+
338
503
  ---
339
504
 
340
505
  ## 🔌 Plugins & Modules API
341
506
 
342
507
  ### 1. Row & Column Headers (`modules/row-col-headers.js`)
343
508
  Enables 123 row numbers and ABCD column headers with interactive column resizing:
509
+
510
+ <p align="center">
511
+ <img src="../public/screenshots/headers.png" alt="Row & Col Headers" width="48%" />
512
+ <img src="../public/screenshots/col-resize-picker.png" alt="Column Resize Handle" width="48%" />
513
+ </p>
514
+
344
515
  ```ts
345
516
  // Enable row/col headers
346
517
  AppGeneral.enableRowColHeaders();
@@ -444,6 +615,22 @@ AppGeneral.switchSheet("Sheet2");
444
615
  AppGeneral.addNewSheet("Expenses");
445
616
  AppGeneral.deleteSheet("Sheet3");
446
617
  AppGeneral.renameSheet("Sheet1", "Overview");
618
+
619
+ // CSV files (UTF-8 BOM so Excel opens them correctly)
620
+ await AppGeneral.exportCurrentSheetAsCSV({ filename: "invoice" }); // downloads invoice.csv
621
+ const csvBlob = await AppGeneral.exportCurrentSheetAsCSV({ returnBlob: true });
622
+ AppGeneral.cleanCSV(csvData); // drop blank lines
623
+ AppGeneral.convertToCSV([["Item", "Price"], ["Pen", 2]]);
624
+
625
+ // MSC workbook files
626
+ await AppGeneral.exportMSC({ filename: "workbook" }); // raw save data, workbook.msc
627
+ await AppGeneral.exportMSC({ extension: "json", includeAppMapping: true }); // { msc, appMapping } template
628
+ const { msc, appMapping } = AppGeneral.parseMSCFile(fileText); // accepts either form
629
+ AppGeneral.loadWorkbookData(msc);
630
+
631
+ // File helpers
632
+ AppGeneral.downloadBlob(blob, "file.pdf");
633
+ const base64 = await AppGeneral.blobToBase64(blob); // for Capacitor Filesystem.writeFile
447
634
  ```
448
635
 
449
636
  ### 9. Invoice Utilities (`modules/invoice.js`)
@@ -454,6 +641,176 @@ const coords = getInvoiceCoordinates();
454
641
  // Returns standard coordinates for billTo, from, invoiceDetails, items, totals
455
642
  ```
456
643
 
644
+ ### 10. AI Agent Plugin (Text Editor Agent) (`modules/agent.js`)
645
+ Provides an extensible AI agent layer to connect LLMs (Gemini, OpenAI, Anthropic) or custom backends (Node.js, Python Tornado) with the spreadsheet engine.
646
+
647
+ #### Key Features:
648
+ - **Intelligent Context Extraction**: Reads current sheet, bounding range, non-empty cells, and automatically parses template `appMapping` fields (e.g. `BillTo.Name` -> `C5`, `Items` table rows 21–33) or falls back to free-form mode if mappings are empty.
649
+ - **LLM-Ready Tool Schemas & Prompts**: Generates Gemini `functionDeclarations`, OpenAI `tool_calls`, and optimized system prompts out of the box.
650
+ - **Atomic Text Editor Actions**: Executes `SET_CELL`, `SET_CELLS`, `CLEAR_CELL`, `SET_MAPPING_FIELD`, `APPLY_MAPPING_DATA`, and `RAW_COMMAND`.
651
+ - **Extensible Action Handler Registry**: Ready for future styling, merge/unmerge, and dimension agents (`registerAgentActionHandler`).
652
+ - **Universal Compatibility**: Zero React/Ionic dependencies in the core module; works in browser client calls as well as server runtimes.
653
+
654
+ <p align="center">
655
+ <img src="../public/screenshots/agent-console.png" alt="AI Agent Execution Console" width="70%" />
656
+ </p>
657
+
658
+ #### Client-side Gemini Integration Example:
659
+ ```ts
660
+ import {
661
+ getAgentContext,
662
+ getAgentToolDefinitions,
663
+ generateAgentSystemPrompt,
664
+ executeAgentResponse,
665
+ } from "socialcalc-ai";
666
+
667
+ // 1. Extract context & tool declarations
668
+ const context = getAgentContext();
669
+ const tools = getAgentToolDefinitions({ format: "gemini" });
670
+ const systemPrompt = generateAgentSystemPrompt();
671
+
672
+ // 2. Call Gemini API (SDK or direct fetch)
673
+ const geminiResponse = await callGemini({
674
+ systemInstruction: systemPrompt,
675
+ contents: [{ role: "user", parts: [{ text: "Fill invoice for Acme Corp with $500 consulting" }] }],
676
+ tools,
677
+ });
678
+
679
+ // 3. Apply actions to SocialCalc sheet
680
+ const result = executeAgentResponse(geminiResponse);
681
+ console.log(`Executed ${result.count} actions atomically!`);
682
+ ```
683
+
684
+ #### Backend Integration Example (Node.js Express or Python Tornado):
685
+ ```ts
686
+ // Client sends exportable context to backend
687
+ const payload = exportAgentContext();
688
+ const res = await fetch("/api/agent/chat", {
689
+ method: "POST",
690
+ headers: { "Content-Type": "application/json" },
691
+ body: JSON.stringify({ message: "Update invoice date to today", context: payload }),
692
+ });
693
+
694
+ const { actions } = await res.json();
695
+ executeAgentActions(actions);
696
+ ```
697
+
698
+ ### 11. Cell Formatting & Display Suite
699
+ SocialCalc provides built-in formatters for commercial, financial, and date/time data types:
700
+
701
+ <p align="center">
702
+ <img src="../public/screenshots/cell-format-numbers.png" alt="Numeric Formatting" width="31%" />
703
+ <img src="../public/screenshots/cell-format-currency.png" alt="Currency Formatting" width="31%" />
704
+ <img src="../public/screenshots/cell-format-percent.png" alt="Percentage Formatting" width="31%" />
705
+ </p>
706
+ <p align="center">
707
+ <img src="../public/screenshots/cell-format-date.png" alt="Date Formatting" width="48%" />
708
+ <img src="../public/screenshots/cell-format-time.png" alt="Time Formatting" width="48%" />
709
+ </p>
710
+
711
+ - **Numeric Formats**: Precision decimal control, integer display, comma thousand grouping (`#,##0.00`).
712
+ - **Currency Formats**: Localized currency symbols (`$`, `€`, `₹`), negative parentheses notation.
713
+ - **Percentage Formats**: Automatic conversion of decimals/fractions into clean percentage percentages (`15.00%`).
714
+ - **Date & Time Formats**: ISO timestamps, short date (`MM/DD/YYYY`), medium date (`DD-MMM-YYYY`), and 12/24-hour clocks.
715
+
716
+ ### 12. Offline PDF Export Plugin (`socialcalc-ai/pdf-export`)
717
+ Generates PDFs of one sheet or the whole workbook on the device, with no server involved, so it works offline and inside Capacitor apps. Pages are split on row boundaries, chart canvases in the live editor are included, and every page gets a timestamp header, a footer label and `Page X of Y`.
718
+
719
+ The plugin is opt-in: it is not part of the main `socialcalc-ai` entry, so apps that do not import it do not need its dependencies. To use it, install the optional peer dependencies:
720
+
721
+ ```bash
722
+ npm install jspdf html2canvas
723
+ ```
724
+
725
+ ```ts
726
+ import * as AppGeneral from "socialcalc-ai";
727
+ import {
728
+ configurePdfExport,
729
+ exportHTMLAsPDF,
730
+ exportAllSheetsAsPDF,
731
+ exportCurrentSheetAsPDF,
732
+ exportWorkbookAsPDF,
733
+ pdfBlobToBase64,
734
+ } from "socialcalc-ai/pdf-export";
735
+
736
+ // Optional app-wide defaults (per-call options still win)
737
+ configurePdfExport({ footerText: "Invoice", format: "a4", margin: 10 });
738
+
739
+ // Download the active sheet as invoice.pdf
740
+ await exportCurrentSheetAsPDF({ filename: "invoice", onProgress: console.log });
741
+
742
+ // Or pass HTML yourself and get a Blob back (e.g. to share with Capacitor)
743
+ const blob = await exportHTMLAsPDF(AppGeneral.getCurrentHTMLContent(), { returnBlob: true });
744
+ const base64 = await pdfBlobToBase64(blob); // ready for Filesystem.writeFile
745
+
746
+ // All sheets into one PDF, each sheet starting on a new page
747
+ await exportWorkbookAsPDF({ filename: "all_invoices" });
748
+ await exportAllSheetsAsPDF(AppGeneral.getAllSheetsData(), { returnBlob: true });
749
+ ```
750
+
751
+ | Option | Default | Description |
752
+ |---|---|---|
753
+ | `filename` | `"document"` / `"all_sheets"` | File name without `.pdf` |
754
+ | `format` | `"a4"` | `"a4"`, `"letter"` or `"legal"` |
755
+ | `orientation` | `"portrait"` | `"portrait"` or `"landscape"` |
756
+ | `margin` | `10` | Page margin in mm |
757
+ | `quality` | `4` (one sheet) / `2` (all sheets) | html2canvas render scale |
758
+ | `headerText` | `null` | Top-left text; `null` prints the current date and time, `""` hides it |
759
+ | `footerText` | `""` | Bottom-left text on every page |
760
+ | `showPageNumbers` | `true` | Print `Page X of Y` bottom-right |
761
+ | `editorElementId` | `"tableeditor"` | Live editor element whose chart canvases are copied |
762
+ | `returnBlob` | `false` | Return a `Blob` instead of downloading the file |
763
+ | `onProgress` | — | Called with progress messages |
764
+
765
+ Importing the module registers it with the Plugin Manager as `"pdfExport"`, so `disablePlugin("pdfExport")` / `enablePlugin("pdfExport", defaults)` and `configurePlugin("pdfExport", defaults)` work too. Export calls reject while the plugin is disabled.
766
+
767
+ ### 13. Share, Email & Print Plugin (`socialcalc-ai/share`)
768
+ Saves, shares, emails and prints exports the right way for the platform the app is running on, detected from the Capacitor runtime:
769
+
770
+ | | `saveFile` | `shareFile` | `sendEmail` / `emailCurrentSheet` | `printHTML` / `printCurrentSheet` |
771
+ |---|---|---|---|---|
772
+ | **iOS** | Cache file + share sheet | Share sheet | Share sheet with the attachment (PDF by default) | Native printer (AirPrint); PDF first, then HTML |
773
+ | **Android** | Cache file + share sheet | Share sheet | EmailComposer with the attachment (HTML by default) | Native printer (PrintService); PDF first, then HTML |
774
+ | **Web** | Download | Web Share API with the file, else download | Web Share with the file, else `mailto:` plus a download of the attachment | Hidden iframe + print dialog (no pop-up) |
775
+
776
+ The plugin does not import any Capacitor packages. On iOS and Android, pass in the ones your app has installed. On the web it needs nothing:
777
+
778
+ ```bash
779
+ npm install @capacitor/filesystem @capacitor/share capacitor-email-composer @bcyesil/capacitor-plugin-printer
780
+ ```
781
+
782
+ ```ts
783
+ import { Filesystem, Directory, Encoding } from "@capacitor/filesystem";
784
+ import { Share } from "@capacitor/share";
785
+ import { EmailComposer } from "capacitor-email-composer";
786
+ import { Printer } from "@bcyesil/capacitor-plugin-printer";
787
+ import "socialcalc-ai/pdf-export"; // optional: lets email and print use PDFs
788
+ import {
789
+ configureShare, getShareCapabilities,
790
+ saveFile, shareFile, emailCurrentSheet, sendEmail, printCurrentSheet,
791
+ } from "socialcalc-ai/share";
792
+ import { exportCurrentSheetAsPDF } from "socialcalc-ai/pdf-export";
793
+
794
+ configureShare({ Filesystem, Directory, Encoding, Share, EmailComposer, Printer });
795
+
796
+ getShareCapabilities(); // { platform: "ios", emailMethod: "share-sheet", printMethod: "native-printer", ... }
797
+
798
+ // Export + deliver (download on the web, share sheet on devices)
799
+ const pdf = await exportCurrentSheetAsPDF({ returnBlob: true });
800
+ await saveFile({ blob: pdf, filename: "invoice.pdf", dialogTitle: "Share PDF" });
801
+
802
+ // Email the active sheet (attachment format chosen per platform, or set attachmentFormat)
803
+ await emailCurrentSheet({ filename: "INV-001", subject: "Your invoice", body: "Please find it attached." });
804
+
805
+ // Or any email / attachment
806
+ await sendEmail({ to: ["a@b.com"], subject: "Data", attachment: { text: csv, filename: "data.csv", mimeType: "text/csv" } });
807
+
808
+ // Print the active sheet
809
+ await printCurrentSheet({ name: "INV-001", orientation: "portrait" });
810
+ ```
811
+
812
+ Every call resolves to `{ method, platform }` (e.g. `{ method: "email-composer", platform: "android" }`), so the app can show the right message. Temporary cache files are deleted 60 s after sharing (`configureShare({ cleanupAfterMs })`). The plugin registers as `"share"` with the Plugin Manager, and calls reject while it is disabled.
813
+
457
814
  ---
458
815
 
459
816
  ## 📡 Event-Driven Architecture
@@ -467,6 +824,7 @@ const coords = getInvoiceCoordinates();
467
824
  | `socialcalc:cell-change` | `{ coord: string, value: string }` | Fired after a cell's value or formula is committed and recalculated. |
468
825
  | `socialcalc:horizontal-scroll`| `{ currentFirstCol: number, currentColName: string, totalCols: number }` | Fired whenever the horizontal viewport column changes. |
469
826
  | `socialcalc:plugin-change` | `{ pluginName: string, state: boolean, allStates: Record<string, boolean> }` | Fired whenever a plugin is registered, enabled, or disabled. |
827
+ | `socialcalc:agent-action` | `{ actions: Array, commands: string[], results: Array, timestamp: number }` | Fired whenever the AI Agent executes actions on the spreadsheet. |
470
828
 
471
829
  ### Event Listener Example:
472
830
 
@@ -532,6 +890,14 @@ import {
532
890
 
533
891
  ## 📦 Release Notes
534
892
 
893
+ ### v1.0.8
894
+ - **Share, Email & Print Plugin**: New opt-in `socialcalc-ai/share` entry for platform-aware (iOS / Android / web) file saving and sharing, email with attachments, and printing. Capacitor plugins are passed in with `configureShare()`.
895
+ - **CSV & MSC exporters**: `exportCurrentSheetAsCSV`, `exportCSV`, `cleanCSV`, `convertToCSV`, `exportMSC`, `parseMSCFile`, `downloadBlob` and `blobToBase64` in the main entry.
896
+ - **Plugin Manager**: `getPlugin(name)` returns a registered plugin, including the `api` it exposes.
897
+
898
+ ### v1.0.7
899
+ - **Offline PDF Export Plugin**: New opt-in `socialcalc-ai/pdf-export` entry that exports the active sheet or the whole workbook to PDF on the device (jsPDF + html2canvas as optional peer dependencies), registered as the `pdfExport` plugin.
900
+
535
901
  ### v1.0.3
536
902
  - **Node.js ESM & Runtime Compatibility**: Enhanced UMD root resolution across all core modules to support `globalThis`, eliminating undefined root errors in Node.js ES module loaders.
537
903
  - **TypeScript Declarations**: Bundled official type declarations (`index.d.ts`) covering all core exports, plugin modules, and React/Ionic UI modal components.