@opengeni/react 3.3.2 → 3.4.1-canary.38960406141001
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 +769 -22
- package/dist/accounts.js +2 -0
- package/dist/accounts.js.map +1 -1
- package/dist/approvals.d.ts +2 -1
- package/dist/artifacts-document.js +5 -3
- package/dist/artifacts-presentation.js +5 -3
- package/dist/artifacts-spreadsheet.d.ts +1 -1
- package/dist/artifacts-spreadsheet.js +5 -3
- package/dist/artifacts.d.ts +5 -1
- package/dist/artifacts.js +536 -42
- package/dist/artifacts.js.map +1 -1
- package/dist/browser-viewer-ZWR6MWJ7.js +19 -0
- package/dist/capability-catalog-row.d.ts +20 -0
- package/dist/capability-logo-fallback.d.ts +3 -0
- package/dist/chat-interactive-block-4EUKJXUO.js +14 -0
- package/dist/chunk-2DDJ6YH6.js +41 -0
- package/dist/chunk-2DDJ6YH6.js.map +1 -0
- package/dist/chunk-2HVLQ26H.js +183 -0
- package/dist/chunk-2HVLQ26H.js.map +1 -0
- package/dist/{chunk-XYRDDSXF.js → chunk-2I6R3GCZ.js} +4285 -3980
- package/dist/chunk-2I6R3GCZ.js.map +1 -0
- package/dist/{chunk-JAQ5K7W6.js → chunk-2SFFYIH3.js} +1178 -166
- package/dist/chunk-2SFFYIH3.js.map +1 -0
- package/dist/chunk-3PVDYTTB.js +24 -0
- package/dist/chunk-3PVDYTTB.js.map +1 -0
- package/dist/chunk-3RJKUVCA.js +14068 -0
- package/dist/chunk-3RJKUVCA.js.map +1 -0
- package/dist/chunk-3UZCWK46.js +298 -0
- package/dist/chunk-3UZCWK46.js.map +1 -0
- package/dist/chunk-47CKUXTW.js +293 -0
- package/dist/chunk-47CKUXTW.js.map +1 -0
- package/dist/chunk-4QYP6QUI.js +109 -0
- package/dist/chunk-4QYP6QUI.js.map +1 -0
- package/dist/chunk-5EY26VZ7.js +1053 -0
- package/dist/chunk-5EY26VZ7.js.map +1 -0
- package/dist/chunk-5I4VRWBB.js +56 -0
- package/dist/chunk-5I4VRWBB.js.map +1 -0
- package/dist/chunk-5WOR7UCL.js +191 -0
- package/dist/chunk-5WOR7UCL.js.map +1 -0
- package/dist/chunk-5YJLGOM5.js +51 -0
- package/dist/chunk-5YJLGOM5.js.map +1 -0
- package/dist/chunk-6JFN3OWG.js +386 -0
- package/dist/chunk-6JFN3OWG.js.map +1 -0
- package/dist/chunk-7QJT5O4S.js +35 -0
- package/dist/chunk-7QJT5O4S.js.map +1 -0
- package/dist/chunk-A55KV72M.js +402 -0
- package/dist/chunk-A55KV72M.js.map +1 -0
- package/dist/chunk-ADWCLI4G.js +2028 -0
- package/dist/chunk-ADWCLI4G.js.map +1 -0
- package/dist/chunk-B27E3V37.js +29 -0
- package/dist/chunk-B27E3V37.js.map +1 -0
- package/dist/chunk-B7TC2A33.js +83 -0
- package/dist/chunk-B7TC2A33.js.map +1 -0
- package/dist/chunk-BLL56F7R.js +385 -0
- package/dist/chunk-BLL56F7R.js.map +1 -0
- package/dist/chunk-BOFEQC6K.js +162 -0
- package/dist/chunk-BOFEQC6K.js.map +1 -0
- package/dist/chunk-CM7LVUKC.js +35 -0
- package/dist/chunk-CM7LVUKC.js.map +1 -0
- package/dist/chunk-CORUP6JB.js +122 -0
- package/dist/chunk-CORUP6JB.js.map +1 -0
- package/dist/chunk-CSX5FFKZ.js +35 -0
- package/dist/chunk-CSX5FFKZ.js.map +1 -0
- package/dist/chunk-EGVHJKGJ.js +3125 -0
- package/dist/chunk-EGVHJKGJ.js.map +1 -0
- package/dist/{chunk-NEXLLTP4.js → chunk-G76LSA76.js} +6 -5
- package/dist/chunk-G76LSA76.js.map +1 -0
- package/dist/{chunk-PEI6RANI.js → chunk-GQMRL52F.js} +311 -75
- package/dist/chunk-GQMRL52F.js.map +1 -0
- package/dist/{chunk-ELIYWBZR.js → chunk-GUUXOISA.js} +1113 -457
- package/dist/chunk-GUUXOISA.js.map +1 -0
- package/dist/{chunk-HUIKIDM5.js → chunk-I7X2P4FU.js} +225 -116
- package/dist/chunk-I7X2P4FU.js.map +1 -0
- package/dist/chunk-IGFZFLI2.js +1390 -0
- package/dist/chunk-IGFZFLI2.js.map +1 -0
- package/dist/{chunk-4MDLEHXL.js → chunk-IMSUVYQB.js} +26 -13
- package/dist/chunk-IMSUVYQB.js.map +1 -0
- package/dist/chunk-IOYHDEP3.js +38 -0
- package/dist/chunk-IOYHDEP3.js.map +1 -0
- package/dist/chunk-IZV5FTJC.js +55 -0
- package/dist/chunk-IZV5FTJC.js.map +1 -0
- package/dist/chunk-KF33GTWN.js +343 -0
- package/dist/chunk-KF33GTWN.js.map +1 -0
- package/dist/chunk-KSGQ5ODA.js +457 -0
- package/dist/chunk-KSGQ5ODA.js.map +1 -0
- package/dist/{chunk-ZPBTI3TE.js → chunk-KZC6QRNR.js} +1513 -697
- package/dist/chunk-KZC6QRNR.js.map +1 -0
- package/dist/chunk-LJUMYUBO.js +218 -0
- package/dist/chunk-LJUMYUBO.js.map +1 -0
- package/dist/chunk-LSW2OJVV.js +380 -0
- package/dist/chunk-LSW2OJVV.js.map +1 -0
- package/dist/chunk-M357MHH3.js +2 -0
- package/dist/chunk-M357MHH3.js.map +1 -0
- package/dist/chunk-MK2TQO4Y.js +24 -0
- package/dist/chunk-MK2TQO4Y.js.map +1 -0
- package/dist/chunk-N7S72EXK.js +25 -0
- package/dist/chunk-N7S72EXK.js.map +1 -0
- package/dist/{chunk-YVCHAQZY.js → chunk-NKMYZFHA.js} +616 -621
- package/dist/chunk-NKMYZFHA.js.map +1 -0
- package/dist/chunk-NX4ADH73.js +14 -0
- package/dist/chunk-NX4ADH73.js.map +1 -0
- package/dist/chunk-O7F6UJO4.js +71 -0
- package/dist/chunk-O7F6UJO4.js.map +1 -0
- package/dist/chunk-OYQQJL3J.js +16 -0
- package/dist/chunk-OYQQJL3J.js.map +1 -0
- package/dist/{chunk-H5YGYNXS.js → chunk-P4BNUO57.js} +60 -17
- package/dist/chunk-P4BNUO57.js.map +1 -0
- package/dist/{chunk-JVYQRRC4.js → chunk-PEHTX3V7.js} +21 -1
- package/dist/chunk-PEHTX3V7.js.map +1 -0
- package/dist/chunk-PMV53IMM.js +26 -0
- package/dist/chunk-PMV53IMM.js.map +1 -0
- package/dist/{chunk-KCGXPP5V.js → chunk-PYEOPA4M.js} +13 -7
- package/dist/chunk-PYEOPA4M.js.map +1 -0
- package/dist/{chunk-KZ73RL76.js → chunk-QHUE7E4N.js} +8 -3
- package/dist/chunk-QHUE7E4N.js.map +1 -0
- package/dist/chunk-QV3DJVRZ.js +11 -0
- package/dist/chunk-QV3DJVRZ.js.map +1 -0
- package/dist/chunk-R5SBNG7S.js +810 -0
- package/dist/chunk-R5SBNG7S.js.map +1 -0
- package/dist/chunk-RI42H5IU.js +326 -0
- package/dist/chunk-RI42H5IU.js.map +1 -0
- package/dist/chunk-S2QH6EZ5.js +211 -0
- package/dist/chunk-S2QH6EZ5.js.map +1 -0
- package/dist/chunk-SHLZMAJN.js +304 -0
- package/dist/chunk-SHLZMAJN.js.map +1 -0
- package/dist/chunk-TGXK4BAZ.js +293 -0
- package/dist/chunk-TGXK4BAZ.js.map +1 -0
- package/dist/{chunk-5YK2ZDIG.js → chunk-TNEZNMSN.js} +4 -10
- package/dist/chunk-TNEZNMSN.js.map +1 -0
- package/dist/{chunk-22KP6LR5.js → chunk-TXS65BB2.js} +3 -1
- package/dist/{chunk-22KP6LR5.js.map → chunk-TXS65BB2.js.map} +1 -1
- package/dist/chunk-UNJPZGNK.js +63 -0
- package/dist/chunk-UNJPZGNK.js.map +1 -0
- package/dist/{chunk-IOLVN74D.js → chunk-V5ZUJT2T.js} +175 -42
- package/dist/chunk-V5ZUJT2T.js.map +1 -0
- package/dist/chunk-WBJY57A3.js +402 -0
- package/dist/chunk-WBJY57A3.js.map +1 -0
- package/dist/chunk-WIUKB3LD.js +1911 -0
- package/dist/chunk-WIUKB3LD.js.map +1 -0
- package/dist/{chunk-ICA6R6TW.js → chunk-WNN7NO2N.js} +1451 -355
- package/dist/chunk-WNN7NO2N.js.map +1 -0
- package/dist/{chunk-3AGBGTRT.js → chunk-X5UVUIMF.js} +1712 -1174
- package/dist/chunk-X5UVUIMF.js.map +1 -0
- package/dist/chunk-XDA5QJE7.js +402 -0
- package/dist/chunk-XDA5QJE7.js.map +1 -0
- package/dist/{chunk-VZTQ73XT.js → chunk-XEA5BCMA.js} +3 -1
- package/dist/{chunk-VZTQ73XT.js.map → chunk-XEA5BCMA.js.map} +1 -1
- package/dist/chunk-XHF7OYAN.js +1150 -0
- package/dist/chunk-XHF7OYAN.js.map +1 -0
- package/dist/chunk-YSRBFJMQ.js +43 -0
- package/dist/chunk-YSRBFJMQ.js.map +1 -0
- package/dist/chunk-ZOZAPAUO.js +174 -0
- package/dist/chunk-ZOZAPAUO.js.map +1 -0
- package/dist/chunk-ZQV5W7YC.js +809 -0
- package/dist/chunk-ZQV5W7YC.js.map +1 -0
- package/dist/chunk-ZUWF4NF7.js +13 -0
- package/dist/chunk-ZUWF4NF7.js.map +1 -0
- package/dist/client.d.ts +16 -7
- package/dist/clipboard.js +3 -1
- package/dist/commands/types.d.ts +2 -0
- package/dist/components/anthropic-mark.d.ts +3 -0
- package/dist/components/approval-surface.d.ts +19 -6
- package/dist/components/artifacts/artifact-chrome.d.ts +120 -0
- package/dist/components/artifacts/artifact-sandbox.d.ts +30 -0
- package/dist/components/artifacts/artifact-surface.d.ts +4 -2
- package/dist/components/artifacts/chat-interactive-block.d.ts +29 -0
- package/dist/components/artifacts/deferred-chat-media.d.ts +15 -0
- package/dist/components/artifacts/document-editor.d.ts +4 -2
- package/dist/components/artifacts/editable-artifact-ui.d.ts +2 -1
- package/dist/components/artifacts/editable-artifact-view.d.ts +48 -0
- package/dist/components/artifacts/editable-document.d.ts +1 -1
- package/dist/components/artifacts/editable-presentation.d.ts +2 -2
- package/dist/components/artifacts/editable-spreadsheet.d.ts +8 -3
- package/dist/components/artifacts/index.d.ts +9 -2
- package/dist/components/artifacts/inline-html-document.d.ts +2 -0
- package/dist/components/artifacts/latest-task-runner.d.ts +15 -0
- package/dist/components/artifacts/presentation-editor.d.ts +6 -2
- package/dist/components/artifacts/published-html-artifact-frame.d.ts +23 -3
- package/dist/components/artifacts/session-artifact-viewer.d.ts +39 -0
- package/dist/components/artifacts/site-view.d.ts +26 -0
- package/dist/components/artifacts/spreadsheet-command-queue.d.ts +20 -0
- package/dist/components/artifacts/spreadsheet-download.d.ts +7 -0
- package/dist/components/artifacts/spreadsheet-general-display.d.ts +24 -0
- package/dist/components/artifacts/spreadsheet-grid.d.ts +10 -3
- package/dist/components/artifacts/spreadsheet-resize.d.ts +50 -0
- package/dist/components/artifacts/spreadsheet-submissions.d.ts +9 -0
- package/dist/components/artifacts/visualization-assets.gen.d.ts +2 -0
- package/dist/components/browser-select-control.d.ts +16 -0
- package/dist/components/browser-viewer.d.ts +11 -2
- package/dist/components/chat-composer.d.ts +21 -3
- package/dist/components/child-session-link.d.ts +9 -0
- package/dist/components/claude-mark.d.ts +3 -0
- package/dist/components/code-editor.d.ts +1 -4
- package/dist/components/composer-transcription-control.d.ts +7 -0
- package/dist/components/composer.d.ts +34 -67
- package/dist/components/computer-viewer.d.ts +1 -1
- package/dist/components/copy-button.d.ts +3 -1
- package/dist/components/desktop-viewer.d.ts +1 -1
- package/dist/components/grok-mark.d.ts +26 -0
- package/dist/components/human-input-form.d.ts +28 -32
- package/dist/components/human-input-surface.d.ts +7 -2
- package/dist/components/linkified-text.d.ts +18 -0
- package/dist/components/machine-input-display.d.ts +22 -1
- package/dist/components/machines/agent-status-icon.d.ts +6 -0
- package/dist/components/machines/machine-detail.d.ts +7 -1
- package/dist/components/machines/machine-status.d.ts +48 -0
- package/dist/components/markdown-table-layout.d.ts +18 -0
- package/dist/components/markdown.d.ts +37 -4
- package/dist/components/message-timeline.d.ts +86 -7
- package/dist/components/model-mark.d.ts +29 -0
- package/dist/components/model-policy-picker-menu.d.ts +9 -0
- package/dist/components/model-policy-picker.d.ts +35 -28
- package/dist/components/new-conversation.d.ts +32 -0
- package/dist/components/open-geni-chat.d.ts +73 -0
- package/dist/components/open-geni-links.d.ts +68 -0
- package/dist/components/openrouter-mark.d.ts +6 -0
- package/dist/components/opper-mark.d.ts +7 -0
- package/dist/components/preview-loading.d.ts +2 -0
- package/dist/components/provider-recovery-notice.d.ts +16 -0
- package/dist/components/queue-item-content.d.ts +9 -0
- package/dist/components/rehype-secret-refs.d.ts +23 -0
- package/dist/components/remark-soft-line-breaks.d.ts +38 -0
- package/dist/components/sandbox-files.d.ts +3 -1
- package/dist/components/sandbox-workspace.d.ts +18 -0
- package/dist/components/secret-question-field.d.ts +31 -0
- package/dist/components/secret-ref-chip.d.ts +35 -0
- package/dist/components/session-capability-frame.d.ts +37 -0
- package/dist/components/session-chrome.d.ts +57 -8
- package/dist/components/session-commands-panel.d.ts +6 -0
- package/dist/components/session-commands.d.ts +6 -0
- package/dist/components/session-connection-request.d.ts +8 -0
- package/dist/components/session-conversation.d.ts +157 -0
- package/dist/components/session-list.d.ts +39 -0
- package/dist/components/session-mcp-capability-card.d.ts +41 -0
- package/dist/components/session-proxy-scope.d.ts +35 -0
- package/dist/components/session-status.d.ts +4 -1
- package/dist/components/session-usage-limit-notice.d.ts +39 -0
- package/dist/components/timeline-anchor.d.ts +24 -0
- package/dist/components/timeline-annotation-chrome.d.ts +25 -0
- package/dist/components/timeline-annotation-layout.d.ts +42 -0
- package/dist/components/timeline-annotation-markers.d.ts +8 -0
- package/dist/components/timeline-annotation-reveal-context.d.ts +4 -0
- package/dist/components/timeline-annotation-shared.d.ts +31 -0
- package/dist/components/timeline-annotations-dialog.d.ts +3 -2
- package/dist/components/timeline-annotations.d.ts +13 -3
- package/dist/components/timeline-reading-progress.d.ts +11 -0
- package/dist/components/timeline-search.d.ts +34 -0
- package/dist/components/timeline-settlement.d.ts +16 -0
- package/dist/components/tool-action-review.d.ts +47 -0
- package/dist/components/tool-review-history.d.ts +25 -0
- package/dist/components/usage-limit-notice.d.ts +49 -0
- package/dist/components/usage-member-list.d.ts +91 -0
- package/dist/components/usage-meter.d.ts +73 -0
- package/dist/components/use-viewer-menu-dismiss.d.ts +2 -0
- package/dist/components/user-message-body.d.ts +10 -1
- package/dist/composer-messages.d.ts +74 -0
- package/dist/composer-messages.js +9 -0
- package/dist/composer-messages.js.map +1 -0
- package/dist/composer-voice-events.d.ts +8 -0
- package/dist/composer.d.ts +5 -4
- package/dist/composer.js +26 -13
- package/dist/computer-viewer-GMLDXPON.js +20 -0
- package/dist/computer-viewer-GMLDXPON.js.map +1 -0
- package/dist/connect-account-identity.d.ts +8 -0
- package/dist/connect-accounts.d.ts +15 -0
- package/dist/connect-chooser.d.ts +18 -0
- package/dist/connect-panel.d.ts +18 -0
- package/dist/connect-setup.d.ts +18 -0
- package/dist/connect.d.ts +21 -0
- package/dist/connect.js +2149 -0
- package/dist/connect.js.map +1 -0
- package/dist/connection-catalog.d.ts +38 -0
- package/dist/connection-discovery.d.ts +12 -0
- package/dist/connection-installed.d.ts +17 -0
- package/dist/connection-logo.d.ts +9 -0
- package/dist/connection-service-logo.d.ts +8 -0
- package/dist/connection-service-presentation.d.ts +13 -0
- package/dist/connection-skeleton.d.ts +5 -0
- package/dist/connection-type-picker.d.ts +6 -0
- package/dist/conversation-timeline.d.ts +5 -0
- package/dist/desktop.d.ts +7 -0
- package/dist/desktop.js +27 -0
- package/dist/desktop.js.map +1 -0
- package/dist/device-authorization.d.ts +23 -0
- package/dist/diffs.d.ts +8 -0
- package/dist/diffs.js +15 -0
- package/dist/diffs.js.map +1 -0
- package/dist/discovery-cache.d.ts +5 -0
- package/dist/editor.d.ts +7 -0
- package/dist/editor.js +22 -0
- package/dist/editor.js.map +1 -0
- package/dist/embedded-new-voice-OCRNT6U5.js +18 -0
- package/dist/embedded-new-voice-OCRNT6U5.js.map +1 -0
- package/dist/embedded-voice-RPHPYVBT.js +18 -0
- package/dist/embedded-voice-RPHPYVBT.js.map +1 -0
- package/dist/{fleet-decision-row-GGCAT4E4.js → fleet-decision-row-SI63O5V4.js} +4 -1
- package/dist/fleet-decision-row-SI63O5V4.js.map +1 -0
- package/dist/hooks/latest-question.d.ts +25 -0
- package/dist/hooks/shared-machines-list.d.ts +4 -0
- package/dist/hooks/shared-query.d.ts +113 -0
- package/dist/hooks/use-attached-browsers.d.ts +1 -1
- package/dist/hooks/use-auth-runs.d.ts +1 -4
- package/dist/hooks/use-available-models.d.ts +1 -1
- package/dist/hooks/use-browser-frame-stream.d.ts +1 -1
- package/dist/hooks/use-browser-session.d.ts +12 -1
- package/dist/hooks/use-client-config-flags.d.ts +49 -0
- package/dist/hooks/use-codex-accounts.d.ts +59 -10
- package/dist/hooks/use-composer.d.ts +24 -2
- package/dist/hooks/use-computer-frame-stream.d.ts +1 -1
- package/dist/hooks/use-computer-input-posture.d.ts +13 -0
- package/dist/hooks/use-computer-session.d.ts +4 -0
- package/dist/hooks/use-connect.d.ts +23 -0
- package/dist/hooks/use-desktop-stream.d.ts +1 -1
- package/dist/hooks/use-file-attachments.d.ts +12 -0
- package/dist/hooks/use-goal.d.ts +2 -1
- package/dist/hooks/use-last-started-turn-policy.d.ts +5 -1
- package/dist/hooks/use-new-conversation.d.ts +56 -0
- package/dist/hooks/use-new-session-draft.d.ts +74 -0
- package/dist/hooks/use-realtime-voice-models.d.ts +7 -0
- package/dist/hooks/use-sandbox-files.d.ts +4 -1
- package/dist/hooks/use-session-conversation.d.ts +49 -0
- package/dist/hooks/use-session-events.d.ts +26 -5
- package/dist/hooks/use-session-mcp-approval-policy.d.ts +2 -2
- package/dist/hooks/use-session-model-account.d.ts +48 -0
- package/dist/hooks/use-supergrok-accounts.d.ts +7 -1
- package/dist/hooks/use-terminal-stream.d.ts +11 -5
- package/dist/hooks/use-usage.d.ts +40 -0
- package/dist/hooks/use-vaults.d.ts +53 -0
- package/dist/hooks/use-voice-input.d.ts +8 -1
- package/dist/hooks/use-workspace-edit.d.ts +4 -0
- package/dist/hooks/use-workspace-sessions.d.ts +24 -5
- package/dist/human-input-model.d.ts +122 -0
- package/dist/identity-link-accounts.d.ts +11 -0
- package/dist/identity-link-consent.d.ts +18 -0
- package/dist/index.d.ts +82 -20
- package/dist/index.js +2340 -6603
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +1 -1
- package/dist/interaction.js +14 -24
- package/dist/interaction.js.map +1 -1
- package/dist/latest-question-R77KWSUP.js +118 -0
- package/dist/latest-question-R77KWSUP.js.map +1 -0
- package/dist/lib/clipboard.d.ts +7 -0
- package/dist/lib/error-message.d.ts +7 -0
- package/dist/lib/format.d.ts +58 -4
- package/dist/lib/host-theme.d.ts +77 -0
- package/dist/lib/interaction-errors.d.ts +3 -0
- package/dist/lib/menu-styles.d.ts +22 -0
- package/dist/lib/notify-observer.d.ts +2 -0
- package/dist/lib/pierre-diffs-loader.d.ts +20 -0
- package/dist/lib/provider-recovery.d.ts +55 -0
- package/dist/lib/scrollbars.d.ts +11 -0
- package/dist/lib/terminal-input-readiness.d.ts +11 -0
- package/dist/lib/transient-retry.d.ts +25 -0
- package/dist/lib/workbench-peers.d.ts +36 -0
- package/dist/lib/xterm-theme.d.ts +7 -5
- package/dist/machines.js +9 -5
- package/dist/markdown-table-layout-3PV2UAAH.js +113 -0
- package/dist/markdown-table-layout-3PV2UAAH.js.map +1 -0
- package/dist/mcp-connection-status.d.ts +14 -0
- package/dist/model-mark-paths.d.ts +34 -0
- package/dist/model-mark-paths.js +16 -0
- package/dist/model-mark-paths.js.map +1 -0
- package/dist/model-picker-model.d.ts +111 -0
- package/dist/model-picker-model.js +25 -0
- package/dist/model-picker-model.js.map +1 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js +17 -0
- package/dist/model-policy-picker-menu-7GJ5URPR.js.map +1 -0
- package/dist/model-policy.d.ts +30 -3
- package/dist/model-policy.js +14 -1
- package/dist/native-previews.d.ts +28 -0
- package/dist/native-previews.js +82 -0
- package/dist/native-previews.js.map +1 -0
- package/dist/new-session-draft.d.ts +7 -0
- package/dist/new-session-draft.js +639 -0
- package/dist/new-session-draft.js.map +1 -0
- package/dist/notification-text.d.ts +27 -0
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js → noto-sans-arabic-loader-XSH2KYWJ.js} +3 -1
- package/dist/{noto-sans-arabic-loader-IA2T4X2A.js.map → noto-sans-arabic-loader-XSH2KYWJ.js.map} +1 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js → noto-sans-jp-loader.generated-MR5L6V7K.js} +3 -1
- package/dist/{noto-sans-jp-loader.generated-HFGLYBR3.js.map → noto-sans-jp-loader.generated-MR5L6V7K.js.map} +1 -1
- package/dist/older-history.d.ts +3 -2
- package/dist/organization-model.d.ts +32 -0
- package/dist/organization-model.js +65 -0
- package/dist/organization-model.js.map +1 -0
- package/dist/{platform-activity-row-BJHUHXAT.js → platform-activity-row-5OCKOQWZ.js} +16 -78
- package/dist/platform-activity-row-5OCKOQWZ.js.map +1 -0
- package/dist/plugin-details.d.ts +14 -0
- package/dist/plugin-discovery.d.ts +25 -0
- package/dist/preview-loading-paint.d.ts +20 -0
- package/dist/provider.d.ts +25 -2
- package/dist/queue-presentation-model.d.ts +72 -0
- package/dist/queue-presentation-model.js +38 -0
- package/dist/queue-presentation-model.js.map +1 -0
- package/dist/{queue-surface-implementation-BSKUWHRI.js → queue-surface-implementation-GJBH7NKO.js} +65 -265
- package/dist/queue-surface-implementation-GJBH7NKO.js.map +1 -0
- package/dist/realtime/embedded-new-voice.d.ts +1 -0
- package/dist/realtime/embedded-voice.d.ts +1 -0
- package/dist/realtime/realtime-control.d.ts +4 -65
- package/dist/realtime/session-realtime.d.ts +78 -0
- package/dist/realtime.js +25 -1333
- package/dist/realtime.js.map +1 -1
- package/dist/sandbox-files-O27IPOZW.js +21 -0
- package/dist/sandbox-files-O27IPOZW.js.map +1 -0
- package/dist/sandbox-label-model.d.ts +30 -0
- package/dist/sandbox-label-model.js +20 -0
- package/dist/sandbox-label-model.js.map +1 -0
- package/dist/scrollbars.d.ts +1 -0
- package/dist/scrollbars.js +10 -0
- package/dist/scrollbars.js.map +1 -0
- package/dist/secret-reference-label.d.ts +14 -0
- package/dist/secrets-ui.d.ts +57 -0
- package/dist/session-agents-model.d.ts +10 -0
- package/dist/session-agents-model.js +25 -0
- package/dist/session-agents-model.js.map +1 -0
- package/dist/session-attention-model.d.ts +8 -0
- package/dist/session-attention-model.js +47 -0
- package/dist/session-attention-model.js.map +1 -0
- package/dist/session-auth-recommendation.d.ts +5 -0
- package/dist/session-capability-policy.d.ts +31 -0
- package/dist/session-feedback-model.d.ts +20 -0
- package/dist/session-feedback-model.js +56 -0
- package/dist/session-feedback-model.js.map +1 -0
- package/dist/session-list-model.d.ts +138 -0
- package/dist/session-list-model.js +274 -0
- package/dist/session-list-model.js.map +1 -0
- package/dist/session-realtime-7DJOIHQW.js +21 -0
- package/dist/session-realtime-7DJOIHQW.js.map +1 -0
- package/dist/session-realtime.d.ts +7 -0
- package/dist/session-realtime.js +19 -0
- package/dist/session-realtime.js.map +1 -0
- package/dist/session-status-model.d.ts +36 -0
- package/dist/session-ui.d.ts +39 -1
- package/dist/session-ui.js +126 -12
- package/dist/session-ui.js.map +1 -1
- package/dist/session.d.ts +8 -2
- package/dist/session.js +35 -20
- package/dist/site-snapshot.d.ts +14 -0
- package/dist/sites-ui.d.ts +24 -0
- package/dist/sites.d.ts +3 -0
- package/dist/sites.js +14 -0
- package/dist/sites.js.map +1 -0
- package/dist/skill-discovery.d.ts +47 -0
- package/dist/terminal.d.ts +8 -0
- package/dist/terminal.js +32 -0
- package/dist/terminal.js.map +1 -0
- package/dist/testing/session-scenarios.d.ts +10 -0
- package/dist/testing/session-scenarios.js +367 -0
- package/dist/testing/session-scenarios.js.map +1 -0
- package/dist/timeline/activity-rail.d.ts +11 -2
- package/dist/timeline/agent-identity.d.ts +30 -0
- package/dist/timeline/agent-row.d.ts +31 -0
- package/dist/timeline/allowance-exhausted-row.d.ts +24 -0
- package/dist/timeline/compaction-copy.d.ts +46 -0
- package/dist/timeline/focus-sequence.d.ts +9 -0
- package/dist/timeline/genie-copy.d.ts +3 -0
- package/dist/timeline/genie-loading.d.ts +47 -0
- package/dist/timeline/index.d.ts +10 -5
- package/dist/timeline/knowledge-receipt.d.ts +17 -0
- package/dist/timeline/message-sender.d.ts +19 -0
- package/dist/timeline/notice-presentation.d.ts +13 -0
- package/dist/timeline/parsers.d.ts +11 -0
- package/dist/timeline/patch-apply-command.d.ts +18 -0
- package/dist/timeline/platform-activity-presentation.d.ts +21 -0
- package/dist/timeline/platform-activity-row.d.ts +1 -2
- package/dist/timeline/presented-image.d.ts +11 -0
- package/dist/timeline/projection.d.ts +31 -2
- package/dist/timeline/provider-logo.d.ts +15 -0
- package/dist/timeline/question-nav-model.d.ts +23 -0
- package/dist/timeline/registry.d.ts +12 -1
- package/dist/timeline/retained-image.d.ts +18 -0
- package/dist/timeline/retained-loaders.d.ts +27 -0
- package/dist/timeline/rolling-activity.d.ts +11 -0
- package/dist/timeline/screenshot-lightbox.d.ts +23 -1
- package/dist/timeline/session-usage-limit-row.d.ts +11 -0
- package/dist/timeline/shared.d.ts +4 -1
- package/dist/timeline/startup-dispatch-details.d.ts +5 -0
- package/dist/timeline/startup-preference.d.ts +3 -0
- package/dist/timeline/startup-timings.d.ts +4 -0
- package/dist/timeline/tool-display-name.d.ts +5 -2
- package/dist/timeline/tool-presentation.d.ts +172 -0
- package/dist/timeline/turn-summary-model.d.ts +95 -0
- package/dist/timeline/turn-summary.d.ts +20 -54
- package/dist/timeline/types.d.ts +179 -7
- package/dist/timeline/work-presentation.d.ts +60 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js +166 -0
- package/dist/timeline-annotation-markers-U3G66KUD.js.map +1 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js +242 -0
- package/dist/timeline-annotation-selection-BI7QTPTZ.js.map +1 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js +274 -0
- package/dist/timeline-annotations-dialog-FOMHSDTE.js.map +1 -0
- package/dist/timeline-model.d.ts +29 -0
- package/dist/timeline-model.js +254 -0
- package/dist/timeline-model.js.map +1 -0
- package/dist/usage/allowance-copy.d.ts +25 -0
- package/dist/usage/session-usage-limit.d.ts +88 -0
- package/dist/usage/summary.d.ts +35 -0
- package/dist/usage.d.ts +17 -0
- package/dist/usage.js +1187 -0
- package/dist/usage.js.map +1 -0
- package/dist/voice-recording-owner.d.ts +7 -0
- package/package.json +106 -7
- package/src/approvals.ts +8 -1
- package/src/artifacts-spreadsheet.ts +1 -0
- package/src/artifacts.ts +44 -0
- package/src/assets/README.md +8 -0
- package/src/assets/gmail.ico +0 -0
- package/src/assets/outlook.ico +0 -0
- package/src/capability-catalog-row.tsx +94 -0
- package/src/capability-logo-fallback.ts +22 -0
- package/src/client.ts +20 -31
- package/src/commands/registry.ts +18 -15
- package/src/commands/types.ts +2 -0
- package/src/components/anthropic-mark.tsx +10 -0
- package/src/components/approval-surface.tsx +401 -138
- package/src/components/artifacts/artifact-chrome.tsx +413 -0
- package/src/components/artifacts/artifact-sandbox.tsx +193 -0
- package/src/components/artifacts/artifact-surface.tsx +40 -20
- package/src/components/artifacts/chat-interactive-block.tsx +260 -0
- package/src/components/artifacts/deferred-chat-media.tsx +67 -0
- package/src/components/artifacts/document-editor.tsx +141 -16
- package/src/components/artifacts/editable-artifact-ui.tsx +4 -2
- package/src/components/artifacts/editable-artifact-view.tsx +197 -0
- package/src/components/artifacts/editable-artifact-workbench.tsx +5 -2
- package/src/components/artifacts/editable-document.tsx +37 -36
- package/src/components/artifacts/editable-presentation.tsx +36 -18
- package/src/components/artifacts/editable-spreadsheet.tsx +543 -103
- package/src/components/artifacts/index.ts +45 -0
- package/src/components/artifacts/inline-html-document.ts +24 -0
- package/src/components/artifacts/latest-task-runner.ts +49 -0
- package/src/components/artifacts/presentation-editor.tsx +323 -67
- package/src/components/artifacts/published-html-artifact-frame.tsx +122 -5
- package/src/components/artifacts/session-artifact-viewer.tsx +378 -0
- package/src/components/artifacts/site-view.tsx +121 -0
- package/src/components/artifacts/spreadsheet-canvas.ts +5 -10
- package/src/components/artifacts/spreadsheet-command-queue.ts +184 -0
- package/src/components/artifacts/spreadsheet-download.tsx +109 -0
- package/src/components/artifacts/spreadsheet-general-display.ts +43 -0
- package/src/components/artifacts/spreadsheet-grid.tsx +344 -144
- package/src/components/artifacts/spreadsheet-resize.tsx +421 -0
- package/src/components/artifacts/spreadsheet-submissions.tsx +46 -0
- package/src/components/artifacts/visualization-assets/base.css +1015 -0
- package/src/components/artifacts/visualization-assets/helpers.html +349 -0
- package/src/components/artifacts/visualization-assets.gen.ts +3 -0
- package/src/components/browser-select-control.tsx +312 -0
- package/src/components/browser-viewer.tsx +778 -318
- package/src/components/chat-composer.tsx +47 -5
- package/src/components/child-session-link.tsx +36 -0
- package/src/components/claude-mark.tsx +11 -0
- package/src/components/code-editor.tsx +13 -16
- package/src/components/composer-transcription-control.tsx +128 -30
- package/src/components/composer.tsx +404 -195
- package/src/components/computer-viewer.tsx +880 -253
- package/src/components/copy-button.tsx +13 -5
- package/src/components/desktop-viewer.tsx +1 -1
- package/src/components/enrollment-consent.tsx +1 -1
- package/src/components/enrollment-device-flow.tsx +1 -1
- package/src/components/file-browser.tsx +10 -14
- package/src/components/fleet-tile.tsx +5 -3
- package/src/components/generated-video-player.tsx +4 -2
- package/src/components/grok-mark.tsx +34 -0
- package/src/components/human-input-form.tsx +590 -283
- package/src/components/human-input-surface.tsx +11 -0
- package/src/components/interaction-intervention-banner.tsx +2 -2
- package/src/components/linkified-text.tsx +79 -0
- package/src/components/machine-card.tsx +35 -78
- package/src/components/machine-dock-bar.tsx +1 -1
- package/src/components/machine-input-display.ts +197 -3
- package/src/components/machines/agent-status-icon.tsx +31 -0
- package/src/components/machines/machine-detail.tsx +200 -31
- package/src/components/machines/machine-operation-policy.tsx +1 -1
- package/src/components/machines/machine-status.ts +241 -0
- package/src/components/machines-dashboard.tsx +2 -17
- package/src/components/markdown-table-layout.ts +143 -0
- package/src/components/markdown.tsx +466 -129
- package/src/components/message-timeline.tsx +2370 -667
- package/src/components/model-mark.tsx +102 -0
- package/src/components/model-picker.tsx +15 -4
- package/src/components/model-policy-picker-menu.tsx +371 -0
- package/src/components/model-policy-picker.tsx +252 -429
- package/src/components/new-conversation.tsx +221 -0
- package/src/components/open-geni-chat.tsx +309 -0
- package/src/components/open-geni-links.tsx +179 -0
- package/src/components/openrouter-mark.tsx +13 -0
- package/src/components/opper-mark.tsx +18 -0
- package/src/components/pierre-diff.tsx +41 -16
- package/src/components/pierre-file.tsx +35 -10
- package/src/components/preview-loading.tsx +109 -0
- package/src/components/provider-recovery-notice.tsx +49 -0
- package/src/components/queue-item-content.ts +14 -0
- package/src/components/queue-surface-implementation.tsx +51 -356
- package/src/components/queue-surface-state.tsx +3 -1
- package/src/components/rehype-secret-refs.ts +98 -0
- package/src/components/remark-soft-line-breaks.ts +166 -0
- package/src/components/sandbox-files.tsx +91 -15
- package/src/components/sandbox-terminal.tsx +84 -13
- package/src/components/sandbox-workspace.tsx +147 -51
- package/src/components/secret-question-field.tsx +324 -0
- package/src/components/secret-ref-chip.tsx +185 -0
- package/src/components/session-capability-frame.tsx +197 -0
- package/src/components/session-chrome.tsx +842 -251
- package/src/components/session-commands-panel.tsx +126 -0
- package/src/components/session-commands.tsx +18 -0
- package/src/components/session-connection-request.tsx +97 -0
- package/src/components/session-conversation.tsx +876 -0
- package/src/components/session-list.tsx +257 -0
- package/src/components/session-mcp-capability-card.tsx +680 -0
- package/src/components/session-proxy-scope.tsx +153 -0
- package/src/components/session-status.tsx +26 -17
- package/src/components/session-usage-limit-notice.tsx +174 -0
- package/src/components/timeline-anchor.tsx +119 -0
- package/src/components/timeline-annotation-chrome.tsx +196 -0
- package/src/components/timeline-annotation-layout.ts +268 -0
- package/src/components/timeline-annotation-markers.tsx +185 -0
- package/src/components/timeline-annotation-reveal-context.ts +9 -0
- package/src/components/timeline-annotation-selection.tsx +106 -54
- package/src/components/timeline-annotation-shared.ts +245 -0
- package/src/components/timeline-annotations-dialog.tsx +185 -128
- package/src/components/timeline-annotations.tsx +189 -45
- package/src/components/timeline-reading-progress.ts +80 -0
- package/src/components/timeline-search.tsx +168 -0
- package/src/components/timeline-settlement.ts +60 -0
- package/src/components/tool-action-review.tsx +650 -0
- package/src/components/tool-review-history.tsx +88 -0
- package/src/components/usage-limit-notice.tsx +179 -0
- package/src/components/usage-member-list.tsx +792 -0
- package/src/components/usage-meter.tsx +382 -0
- package/src/components/use-viewer-menu-dismiss.ts +33 -0
- package/src/components/user-message-body.tsx +27 -2
- package/src/components/workspace-dock.tsx +18 -1
- package/src/composer-messages.ts +150 -0
- package/src/composer-voice-events.ts +12 -0
- package/src/composer.ts +6 -1
- package/src/connect-account-identity.tsx +34 -0
- package/src/connect-accounts.tsx +233 -0
- package/src/connect-chooser.tsx +336 -0
- package/src/connect-panel.tsx +99 -0
- package/src/connect-setup.tsx +355 -0
- package/src/connect.ts +60 -0
- package/src/connection-assets.d.ts +4 -0
- package/src/connection-catalog.tsx +162 -0
- package/src/connection-discovery.tsx +238 -0
- package/src/connection-installed.tsx +51 -0
- package/src/connection-logo.tsx +37 -0
- package/src/connection-service-logo.tsx +55 -0
- package/src/connection-service-presentation.ts +46 -0
- package/src/connection-skeleton.tsx +16 -0
- package/src/connection-type-picker.tsx +36 -0
- package/src/conversation-timeline.ts +92 -0
- package/src/desktop.ts +24 -0
- package/src/device-authorization.tsx +98 -0
- package/src/diffs.ts +16 -0
- package/src/discovery-cache.ts +42 -0
- package/src/editor.ts +13 -0
- package/src/hooks/internal.ts +3 -2
- package/src/hooks/latest-question.ts +164 -0
- package/src/hooks/shared-machines-list.ts +34 -1
- package/src/hooks/shared-query.ts +721 -0
- package/src/hooks/use-attached-browsers.ts +1 -1
- package/src/hooks/use-auth-runs.ts +0 -27
- package/src/hooks/use-available-models.ts +2 -2
- package/src/hooks/use-browser-frame-stream.ts +19 -2
- package/src/hooks/use-browser-session.ts +680 -205
- package/src/hooks/use-browser-sessions.ts +32 -1
- package/src/hooks/use-client-config-flags.ts +118 -0
- package/src/hooks/use-codex-accounts.ts +247 -47
- package/src/hooks/use-composer.ts +227 -44
- package/src/hooks/use-computer-frame-stream.ts +25 -7
- package/src/hooks/use-computer-input-posture.ts +94 -0
- package/src/hooks/use-computer-session.ts +409 -95
- package/src/hooks/use-connect.ts +23 -0
- package/src/hooks/use-desktop-stream.ts +19 -28
- package/src/hooks/use-file-attachments.ts +80 -4
- package/src/hooks/use-goal.ts +79 -9
- package/src/hooks/use-last-started-turn-policy.ts +37 -11
- package/src/hooks/use-machines.ts +4 -0
- package/src/hooks/use-new-conversation.ts +374 -0
- package/src/hooks/use-new-session-draft.ts +813 -0
- package/src/hooks/use-realtime-voice-models.ts +46 -0
- package/src/hooks/use-sandbox-files.ts +68 -20
- package/src/hooks/use-session-background-commands.ts +22 -11
- package/src/hooks/use-session-capabilities.ts +3 -2
- package/src/hooks/use-session-conversation.ts +150 -0
- package/src/hooks/use-session-events.ts +531 -335
- package/src/hooks/use-session-mcp-approval-policy.ts +13 -5
- package/src/hooks/use-session-model-account.ts +174 -0
- package/src/hooks/use-session.ts +30 -2
- package/src/hooks/use-slash-commands.ts +6 -11
- package/src/hooks/use-supergrok-accounts.ts +22 -8
- package/src/hooks/use-terminal-stream.ts +153 -27
- package/src/hooks/use-transcription.ts +6 -0
- package/src/hooks/use-turn-queue.ts +2 -1
- package/src/hooks/use-usage.ts +100 -0
- package/src/hooks/use-vaults.ts +153 -0
- package/src/hooks/use-video-artifact-playback.ts +1 -1
- package/src/hooks/use-voice-input.ts +127 -19
- package/src/hooks/use-workspace-capture.ts +3 -2
- package/src/hooks/use-workspace-edit.ts +23 -5
- package/src/hooks/use-workspace-sessions.ts +74 -7
- package/src/human-input-model.ts +359 -0
- package/src/identity-link-accounts.tsx +148 -0
- package/src/identity-link-consent.tsx +192 -0
- package/src/index.ts +262 -16
- package/src/interaction.ts +1 -0
- package/src/lib/clipboard.ts +29 -0
- package/src/lib/error-message.ts +37 -0
- package/src/lib/format.ts +205 -10
- package/src/lib/host-theme.ts +529 -0
- package/src/lib/interaction-errors.ts +15 -0
- package/src/lib/menu-styles.ts +44 -0
- package/src/lib/notify-observer.ts +15 -0
- package/src/lib/pierre-diffs-loader.ts +53 -0
- package/src/lib/provider-recovery.ts +243 -0
- package/src/lib/scrollbars.ts +30 -0
- package/src/lib/terminal-input-readiness.ts +51 -0
- package/src/lib/transient-retry.ts +99 -0
- package/src/lib/workbench-peers.ts +62 -0
- package/src/lib/xterm-theme.ts +23 -21
- package/src/mcp-connection-status.ts +35 -0
- package/src/model-mark-paths.ts +53 -0
- package/src/model-picker-model.ts +330 -0
- package/src/model-policy.ts +299 -74
- package/src/native-previews.ts +100 -0
- package/src/new-session-draft.ts +22 -0
- package/src/notification-text.ts +81 -0
- package/src/older-history.ts +22 -4
- package/src/organization-model.ts +118 -0
- package/src/plugin-details.tsx +185 -0
- package/src/plugin-discovery.tsx +196 -0
- package/src/preview-loading-paint.ts +68 -0
- package/src/provider.tsx +74 -15
- package/src/queue-presentation-model.ts +464 -0
- package/src/realtime/dropdown-menu.tsx +19 -12
- package/src/realtime/embedded-new-voice.tsx +1 -0
- package/src/realtime/embedded-voice.tsx +3 -0
- package/src/realtime/realtime-control.tsx +138 -550
- package/src/realtime/session-realtime.ts +566 -0
- package/src/sandbox-label-model.ts +53 -0
- package/src/scrollbars.ts +3 -0
- package/src/secret-reference-label.ts +43 -0
- package/src/secrets-ui.tsx +59 -0
- package/src/session-agents-model.ts +33 -0
- package/src/session-attention-model.ts +62 -0
- package/src/session-auth-recommendation.ts +48 -0
- package/src/session-capability-policy.ts +196 -0
- package/src/session-context.ts +3 -4
- package/src/session-feedback-model.ts +95 -0
- package/src/session-list-model.ts +434 -0
- package/src/session-realtime.ts +18 -0
- package/src/session-status-model.ts +99 -0
- package/src/session-ui.ts +98 -1
- package/src/session.ts +17 -1
- package/src/site-snapshot.ts +74 -0
- package/src/sites-ui.tsx +348 -0
- package/src/sites.ts +3 -0
- package/src/skill-discovery.tsx +208 -0
- package/src/terminal.ts +26 -0
- package/src/testing/session-scenarios.ts +404 -0
- package/src/timeline/activity-rail.tsx +242 -101
- package/src/timeline/agent-identity.tsx +84 -0
- package/src/timeline/agent-row.tsx +231 -0
- package/src/timeline/allowance-exhausted-row.tsx +86 -0
- package/src/timeline/compaction-copy.ts +115 -0
- package/src/timeline/fleet-decision-projection.ts +2 -1
- package/src/timeline/fleet-decision-row.tsx +1 -0
- package/src/timeline/focus-sequence.ts +44 -0
- package/src/timeline/genie-copy.ts +19 -0
- package/src/timeline/genie-loading.tsx +143 -0
- package/src/timeline/index.ts +30 -2
- package/src/timeline/knowledge-receipt.tsx +100 -0
- package/src/timeline/message-sender.tsx +71 -0
- package/src/timeline/notice-presentation.ts +48 -0
- package/src/timeline/parsers.ts +42 -2
- package/src/timeline/patch-apply-command.tsx +135 -0
- package/src/timeline/platform-activity-presentation.ts +166 -0
- package/src/timeline/platform-activity-row.tsx +15 -90
- package/src/timeline/presented-image.ts +63 -0
- package/src/timeline/projection.ts +1742 -76
- package/src/timeline/provider-logo.tsx +53 -0
- package/src/timeline/question-nav-model.ts +28 -0
- package/src/timeline/registry.ts +26 -4
- package/src/timeline/retained-image.ts +97 -0
- package/src/timeline/retained-loaders.ts +91 -0
- package/src/timeline/rolling-activity.tsx +80 -0
- package/src/timeline/screenshot-lightbox.tsx +228 -5
- package/src/timeline/session-usage-limit-row.tsx +42 -0
- package/src/timeline/shared.tsx +42 -15
- package/src/timeline/startup-dispatch-details.tsx +36 -0
- package/src/timeline/startup-preference.ts +33 -0
- package/src/timeline/startup-timings.tsx +145 -0
- package/src/timeline/tool-display-name.ts +19 -7
- package/src/timeline/tool-presentation.ts +1316 -0
- package/src/timeline/tool-renderers.tsx +835 -1138
- package/src/timeline/turn-summary-model.ts +343 -0
- package/src/timeline/turn-summary.tsx +272 -365
- package/src/timeline/types.ts +189 -6
- package/src/timeline/work-presentation.ts +189 -0
- package/src/timeline-model.ts +143 -0
- package/src/usage/allowance-copy.ts +64 -0
- package/src/usage/session-usage-limit.ts +266 -0
- package/src/usage/summary.ts +93 -0
- package/src/usage.ts +70 -0
- package/src/voice-recording-owner.ts +22 -0
- package/styles/compiled.css +2319 -748
- package/styles/connect.css +290 -0
- package/styles/connect.d.ts +1 -0
- package/styles/effective-tokens.css +1 -0
- package/styles/index.css +309 -9
- package/styles/responsive.css +99 -7
- package/styles/session-capability.css +44 -0
- package/styles/tokens.css +134 -66
- package/dist/browser-viewer-MKKFRRRV.js +0 -14
- package/dist/chunk-2DZVYHVO.js +0 -470
- package/dist/chunk-2DZVYHVO.js.map +0 -1
- package/dist/chunk-3AGBGTRT.js.map +0 -1
- package/dist/chunk-4MDLEHXL.js.map +0 -1
- package/dist/chunk-5YK2ZDIG.js.map +0 -1
- package/dist/chunk-7EAFGICR.js +0 -302
- package/dist/chunk-7EAFGICR.js.map +0 -1
- package/dist/chunk-ELIYWBZR.js.map +0 -1
- package/dist/chunk-H5YGYNXS.js.map +0 -1
- package/dist/chunk-HUIKIDM5.js.map +0 -1
- package/dist/chunk-ICA6R6TW.js.map +0 -1
- package/dist/chunk-IOLVN74D.js.map +0 -1
- package/dist/chunk-JAQ5K7W6.js.map +0 -1
- package/dist/chunk-JVYQRRC4.js.map +0 -1
- package/dist/chunk-KCGXPP5V.js.map +0 -1
- package/dist/chunk-KZ73RL76.js.map +0 -1
- package/dist/chunk-NEXLLTP4.js.map +0 -1
- package/dist/chunk-PEI6RANI.js.map +0 -1
- package/dist/chunk-VTOREEXF.js +0 -142
- package/dist/chunk-VTOREEXF.js.map +0 -1
- package/dist/chunk-WSK7G5LE.js +0 -170
- package/dist/chunk-WSK7G5LE.js.map +0 -1
- package/dist/chunk-X4A66EWZ.js +0 -223
- package/dist/chunk-X4A66EWZ.js.map +0 -1
- package/dist/chunk-XYRDDSXF.js.map +0 -1
- package/dist/chunk-YG4QEQF5.js +0 -9557
- package/dist/chunk-YG4QEQF5.js.map +0 -1
- package/dist/chunk-YVCHAQZY.js.map +0 -1
- package/dist/chunk-ZPBTI3TE.js.map +0 -1
- package/dist/computer-viewer-FWEZISW4.js +0 -16
- package/dist/fleet-decision-row-GGCAT4E4.js.map +0 -1
- package/dist/hooks/use-environments.d.ts +0 -41
- package/dist/hooks/use-packs.d.ts +0 -32
- package/dist/platform-activity-row-BJHUHXAT.js.map +0 -1
- package/dist/queue-surface-implementation-BSKUWHRI.js.map +0 -1
- package/dist/timeline-annotation-selection-3L7LHGG2.js +0 -187
- package/dist/timeline-annotation-selection-3L7LHGG2.js.map +0 -1
- package/dist/timeline-annotations-dialog-U7EVLR75.js +0 -196
- package/dist/timeline-annotations-dialog-U7EVLR75.js.map +0 -1
- package/src/hooks/use-environments.ts +0 -182
- package/src/hooks/use-packs.ts +0 -157
- /package/dist/{browser-viewer-MKKFRRRV.js.map → browser-viewer-ZWR6MWJ7.js.map} +0 -0
- /package/dist/{computer-viewer-FWEZISW4.js.map → chat-interactive-block-4EUKJXUO.js.map} +0 -0
|
@@ -1,26 +1,186 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import {
|
|
2
3
|
ArtifactSurface,
|
|
3
4
|
EditableArtifactMessage,
|
|
4
5
|
editableArtifactAccessRevoked,
|
|
5
6
|
editableArtifactStatusLabel,
|
|
6
7
|
useEditableArtifactView
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-PYEOPA4M.js";
|
|
9
|
+
import {
|
|
10
|
+
ArtifactButton
|
|
11
|
+
} from "./chunk-TGXK4BAZ.js";
|
|
8
12
|
import {
|
|
9
13
|
cn
|
|
10
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-TXS65BB2.js";
|
|
11
15
|
|
|
12
16
|
// src/components/artifacts/spreadsheet-grid.tsx
|
|
13
17
|
import { PlusIcon } from "lucide-react";
|
|
14
18
|
import {
|
|
15
|
-
useCallback,
|
|
16
|
-
useEffect,
|
|
19
|
+
useCallback as useCallback3,
|
|
20
|
+
useEffect as useEffect3,
|
|
17
21
|
useId,
|
|
18
22
|
useLayoutEffect,
|
|
19
|
-
useMemo,
|
|
20
|
-
useRef,
|
|
21
|
-
useState
|
|
23
|
+
useMemo as useMemo2,
|
|
24
|
+
useRef as useRef3,
|
|
25
|
+
useState as useState3
|
|
22
26
|
} from "react";
|
|
23
27
|
|
|
28
|
+
// src/components/artifacts/spreadsheet-command-queue.ts
|
|
29
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
30
|
+
function overlaps(a, b) {
|
|
31
|
+
return a.top <= b.bottom && a.bottom >= b.top && a.left <= b.right && a.right >= b.left;
|
|
32
|
+
}
|
|
33
|
+
function contains(a, b) {
|
|
34
|
+
return a.top <= b.top && a.bottom >= b.bottom && a.left <= b.left && a.right >= b.right;
|
|
35
|
+
}
|
|
36
|
+
function useSpreadsheetCommandQueue({
|
|
37
|
+
scopeKey,
|
|
38
|
+
enabled,
|
|
39
|
+
onCommandError
|
|
40
|
+
}) {
|
|
41
|
+
const [pendingCount, setPendingCount] = useState(0);
|
|
42
|
+
const [failures, setFailures] = useState([]);
|
|
43
|
+
const commandsRef = useRef(/* @__PURE__ */ new Map());
|
|
44
|
+
const nextIdRef = useRef(0);
|
|
45
|
+
const mountedRef = useRef(true);
|
|
46
|
+
const optionsRef = useRef({ scopeKey, enabled, onCommandError });
|
|
47
|
+
optionsRef.current = { scopeKey, enabled, onCommandError };
|
|
48
|
+
const scopeRef = useRef({ key: scopeKey, epoch: 0 });
|
|
49
|
+
if (scopeRef.current.key !== scopeKey) {
|
|
50
|
+
scopeRef.current = { key: scopeKey, epoch: scopeRef.current.epoch + 1 };
|
|
51
|
+
}
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
mountedRef.current = true;
|
|
54
|
+
return () => {
|
|
55
|
+
mountedRef.current = false;
|
|
56
|
+
};
|
|
57
|
+
}, []);
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
commandsRef.current.clear();
|
|
60
|
+
setPendingCount(0);
|
|
61
|
+
setFailures([]);
|
|
62
|
+
}, [scopeKey]);
|
|
63
|
+
const refreshFailures = useCallback(() => {
|
|
64
|
+
setFailures(
|
|
65
|
+
[...commandsRef.current.values()].filter(
|
|
66
|
+
(command) => command.message !== void 0 && !command.covered
|
|
67
|
+
)
|
|
68
|
+
);
|
|
69
|
+
}, []);
|
|
70
|
+
const clearPreflightFailure = useCallback(() => {
|
|
71
|
+
let changed = false;
|
|
72
|
+
for (const previous of commandsRef.current.values()) {
|
|
73
|
+
if (previous.target === null && previous.message !== void 0) {
|
|
74
|
+
commandsRef.current.delete(previous.id);
|
|
75
|
+
changed = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (changed) refreshFailures();
|
|
79
|
+
}, [refreshFailures]);
|
|
80
|
+
const run = useCallback(
|
|
81
|
+
(invoke, retry, rollback, target, accepted) => {
|
|
82
|
+
if (!optionsRef.current.enabled) return;
|
|
83
|
+
const scope = optionsRef.current.scopeKey;
|
|
84
|
+
const epoch = scopeRef.current.epoch;
|
|
85
|
+
const id = ++nextIdRef.current;
|
|
86
|
+
clearPreflightFailure();
|
|
87
|
+
const command = { id, target: null, overlapped: false, covered: false };
|
|
88
|
+
commandsRef.current.set(id, command);
|
|
89
|
+
const current = () => mountedRef.current && optionsRef.current.scopeKey === scope && scopeRef.current.epoch === epoch;
|
|
90
|
+
const fail = (cause) => {
|
|
91
|
+
if (!current()) return;
|
|
92
|
+
rollback(id);
|
|
93
|
+
if (command.covered) {
|
|
94
|
+
commandsRef.current.delete(id);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
98
|
+
command.message = error.message || "Spreadsheet change failed";
|
|
99
|
+
command.retry = () => {
|
|
100
|
+
if (!current() || !optionsRef.current.enabled || command.overlapped) return;
|
|
101
|
+
commandsRef.current.delete(id);
|
|
102
|
+
refreshFailures();
|
|
103
|
+
retry();
|
|
104
|
+
};
|
|
105
|
+
refreshFailures();
|
|
106
|
+
optionsRef.current.onCommandError?.(error);
|
|
107
|
+
};
|
|
108
|
+
let result;
|
|
109
|
+
try {
|
|
110
|
+
command.target = typeof target === "function" ? target() : target ?? null;
|
|
111
|
+
if (command.target) {
|
|
112
|
+
for (const previous of commandsRef.current.values()) {
|
|
113
|
+
if (previous.id === id || !previous.target || !overlaps(command.target, previous.target))
|
|
114
|
+
continue;
|
|
115
|
+
previous.overlapped = true;
|
|
116
|
+
previous.covered ||= contains(command.target, previous.target);
|
|
117
|
+
if (previous.covered && previous.message !== void 0)
|
|
118
|
+
commandsRef.current.delete(previous.id);
|
|
119
|
+
}
|
|
120
|
+
refreshFailures();
|
|
121
|
+
}
|
|
122
|
+
result = invoke(id);
|
|
123
|
+
} catch (cause) {
|
|
124
|
+
fail(cause);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const succeed = () => {
|
|
128
|
+
if (!current()) return;
|
|
129
|
+
commandsRef.current.delete(id);
|
|
130
|
+
accepted?.(id);
|
|
131
|
+
};
|
|
132
|
+
if (!result || typeof result.then !== "function") {
|
|
133
|
+
succeed();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
setPendingCount((count) => count + 1);
|
|
137
|
+
void Promise.resolve(result).then(
|
|
138
|
+
() => {
|
|
139
|
+
if (!current()) return;
|
|
140
|
+
setPendingCount((count) => Math.max(0, count - 1));
|
|
141
|
+
succeed();
|
|
142
|
+
},
|
|
143
|
+
(cause) => {
|
|
144
|
+
if (!current()) return;
|
|
145
|
+
setPendingCount((count) => Math.max(0, count - 1));
|
|
146
|
+
fail(cause);
|
|
147
|
+
}
|
|
148
|
+
);
|
|
149
|
+
},
|
|
150
|
+
[clearPreflightFailure, refreshFailures]
|
|
151
|
+
);
|
|
152
|
+
const first = failures[0];
|
|
153
|
+
return {
|
|
154
|
+
run,
|
|
155
|
+
clearPreflightFailure,
|
|
156
|
+
pendingCount,
|
|
157
|
+
error: first ? {
|
|
158
|
+
message: failures.length > 1 ? `${first.message} (${failures.length} changes not saved)` : first.message,
|
|
159
|
+
retry: enabled && !first.overlapped ? first.retry : void 0
|
|
160
|
+
} : null
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/components/artifacts/spreadsheet-general-display.ts
|
|
165
|
+
function formatSpreadsheetGeneralDisplay(value) {
|
|
166
|
+
if (value === null || value === void 0) return "";
|
|
167
|
+
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
|
|
168
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
169
|
+
if (typeof value === "number") {
|
|
170
|
+
if (Object.is(value, -0) || value === 0) return "0";
|
|
171
|
+
if (!Number.isFinite(value)) return String(value);
|
|
172
|
+
const rounded = Number(value.toPrecision(15));
|
|
173
|
+
return String(Number.isFinite(rounded) ? rounded : value);
|
|
174
|
+
}
|
|
175
|
+
return String(value);
|
|
176
|
+
}
|
|
177
|
+
function spreadsheetCellEditSource(value) {
|
|
178
|
+
if (value === null || value === void 0) return "";
|
|
179
|
+
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
|
|
180
|
+
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
181
|
+
return String(value);
|
|
182
|
+
}
|
|
183
|
+
|
|
24
184
|
// src/components/artifacts/spreadsheet-canvas.ts
|
|
25
185
|
var TILE_SIZE = 256;
|
|
26
186
|
var MAX_CACHE_PHYSICAL_PIXELS = 32e6;
|
|
@@ -266,7 +426,7 @@ var SpreadsheetCanvasRenderer = class {
|
|
|
266
426
|
paintTileGrid(context, input, tileLeft, tileTop, tileRight, tileBottom);
|
|
267
427
|
for (const cell of cells) {
|
|
268
428
|
const value = input.projection.valueAt(cell);
|
|
269
|
-
const text =
|
|
429
|
+
const text = formatSpreadsheetGeneralDisplay(value);
|
|
270
430
|
if (!text) continue;
|
|
271
431
|
paintCellText(context, input, cell, text, tileLeft, tileTop);
|
|
272
432
|
}
|
|
@@ -351,7 +511,7 @@ function paintSelection(context, input) {
|
|
|
351
511
|
const top = input.columnHeaderHeight + input.rows.offsetAt(selection.top) - input.logicalScrollTop;
|
|
352
512
|
const bottom = input.columnHeaderHeight + input.rows.offsetAt(selection.bottom + 1) - input.logicalScrollTop;
|
|
353
513
|
context.save();
|
|
354
|
-
setFill(context, input.theme.accent, "#
|
|
514
|
+
setFill(context, input.theme.accent, "#545454");
|
|
355
515
|
context.globalAlpha = 0.1;
|
|
356
516
|
context.fillRect(left, top, right - left, bottom - top);
|
|
357
517
|
context.restore();
|
|
@@ -360,7 +520,7 @@ function paintSelection(context, input) {
|
|
|
360
520
|
const activeWidth = input.columns.sizeAt(selection.focusColumn);
|
|
361
521
|
const activeHeight = input.rows.sizeAt(selection.focusRow);
|
|
362
522
|
context.save();
|
|
363
|
-
setStroke(context, input.theme.accent, "#
|
|
523
|
+
setStroke(context, input.theme.accent, "#545454");
|
|
364
524
|
context.lineWidth = 2;
|
|
365
525
|
context.strokeRect(
|
|
366
526
|
activeLeft + 1,
|
|
@@ -522,12 +682,6 @@ function ellipsize(context, input, maximumWidth) {
|
|
|
522
682
|
function finitePositive(value, fallback) {
|
|
523
683
|
return value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
|
|
524
684
|
}
|
|
525
|
-
function displayValue(value) {
|
|
526
|
-
if (value === null || value === void 0) return "";
|
|
527
|
-
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
|
|
528
|
-
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
529
|
-
return String(value);
|
|
530
|
-
}
|
|
531
685
|
function columnName(index) {
|
|
532
686
|
let value = index + 1;
|
|
533
687
|
let result = "";
|
|
@@ -542,8 +696,330 @@ function clamp(value, minimum, maximum) {
|
|
|
542
696
|
return Math.max(minimum, Math.min(maximum, value));
|
|
543
697
|
}
|
|
544
698
|
|
|
699
|
+
// src/components/artifacts/spreadsheet-resize.tsx
|
|
700
|
+
import {
|
|
701
|
+
useCallback as useCallback2,
|
|
702
|
+
useEffect as useEffect2,
|
|
703
|
+
useMemo,
|
|
704
|
+
useRef as useRef2,
|
|
705
|
+
useState as useState2
|
|
706
|
+
} from "react";
|
|
707
|
+
import { jsx } from "react/jsx-runtime";
|
|
708
|
+
var MIN_SIZE = 8;
|
|
709
|
+
var MAX_SIZE = 4096;
|
|
710
|
+
function keyOf(change) {
|
|
711
|
+
return `${change.axis}:${change.index}`;
|
|
712
|
+
}
|
|
713
|
+
function boundedSize(size) {
|
|
714
|
+
return Math.max(MIN_SIZE, Math.min(MAX_SIZE, Math.round(size)));
|
|
715
|
+
}
|
|
716
|
+
function useSpreadsheetResizing(options) {
|
|
717
|
+
const optionsRef = useRef2(options);
|
|
718
|
+
optionsRef.current = options;
|
|
719
|
+
const [gesture, setGesture] = useState2(null);
|
|
720
|
+
const [pending, setPending] = useState2([]);
|
|
721
|
+
const [inFlightCount, setInFlightCount] = useState2(0);
|
|
722
|
+
const [errors, setErrors] = useState2([]);
|
|
723
|
+
const errorsRef = useRef2(/* @__PURE__ */ new Map());
|
|
724
|
+
const activeRef = useRef2(null);
|
|
725
|
+
const pendingRef = useRef2(/* @__PURE__ */ new Map());
|
|
726
|
+
const frameRef = useRef2(null);
|
|
727
|
+
const nextIdRef = useRef2(0);
|
|
728
|
+
const scopeRef = useRef2(0);
|
|
729
|
+
const mountedRef = useRef2(true);
|
|
730
|
+
const clearError = useCallback2(() => {
|
|
731
|
+
errorsRef.current.clear();
|
|
732
|
+
setErrors([]);
|
|
733
|
+
}, []);
|
|
734
|
+
const cancelFrame = useCallback2(() => {
|
|
735
|
+
if (frameRef.current !== null) globalThis.cancelAnimationFrame?.(frameRef.current);
|
|
736
|
+
frameRef.current = null;
|
|
737
|
+
}, []);
|
|
738
|
+
const cancel = useCallback2(() => {
|
|
739
|
+
cancelFrame();
|
|
740
|
+
activeRef.current = null;
|
|
741
|
+
setGesture(null);
|
|
742
|
+
}, [cancelFrame]);
|
|
743
|
+
useEffect2(() => {
|
|
744
|
+
mountedRef.current = true;
|
|
745
|
+
return () => {
|
|
746
|
+
mountedRef.current = false;
|
|
747
|
+
scopeRef.current += 1;
|
|
748
|
+
cancelFrame();
|
|
749
|
+
};
|
|
750
|
+
}, [cancelFrame]);
|
|
751
|
+
useEffect2(() => {
|
|
752
|
+
scopeRef.current += 1;
|
|
753
|
+
cancel();
|
|
754
|
+
pendingRef.current.clear();
|
|
755
|
+
setPending([]);
|
|
756
|
+
setInFlightCount(0);
|
|
757
|
+
clearError();
|
|
758
|
+
}, [cancel, clearError, options.enabled, options.generationId, options.sheetId]);
|
|
759
|
+
const authoritativeSize = useCallback2((axis, index) => {
|
|
760
|
+
const current = optionsRef.current;
|
|
761
|
+
const entries = axis === "row" ? current.rowHeights : current.columnWidths;
|
|
762
|
+
return entries.find(([at]) => at === index)?.[1] ?? (axis === "row" ? current.defaultRowHeight : current.defaultColumnWidth);
|
|
763
|
+
}, []);
|
|
764
|
+
useEffect2(() => {
|
|
765
|
+
let changed = false;
|
|
766
|
+
for (const [key, entry] of pendingRef.current) {
|
|
767
|
+
if (entry.settled && (authoritativeSize(entry.axis, entry.index) === entry.size || options.revision !== entry.baseRevision)) {
|
|
768
|
+
pendingRef.current.delete(key);
|
|
769
|
+
changed = true;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
if (changed) setPending([...pendingRef.current.values()]);
|
|
773
|
+
}, [authoritativeSize, options.columnWidths, options.revision, options.rowHeights, pending]);
|
|
774
|
+
const submit = useCallback2((change) => {
|
|
775
|
+
const current = optionsRef.current;
|
|
776
|
+
if (!current.enabled || !current.commit || change.sheetId !== current.sheetId) return;
|
|
777
|
+
const scope = scopeRef.current;
|
|
778
|
+
const id = ++nextIdRef.current;
|
|
779
|
+
const key = keyOf(change);
|
|
780
|
+
const entry = { ...change, id, baseRevision: current.revision, settled: false };
|
|
781
|
+
pendingRef.current.set(key, entry);
|
|
782
|
+
setPending([...pendingRef.current.values()]);
|
|
783
|
+
errorsRef.current.delete(key);
|
|
784
|
+
setErrors([...errorsRef.current.values()]);
|
|
785
|
+
current.onStart?.();
|
|
786
|
+
let asynchronous = false;
|
|
787
|
+
const settle = (failed, cause) => {
|
|
788
|
+
if (!mountedRef.current || scopeRef.current !== scope) return;
|
|
789
|
+
if (asynchronous) setInFlightCount((count) => Math.max(0, count - 1));
|
|
790
|
+
const latest = pendingRef.current.get(key);
|
|
791
|
+
if (latest?.id !== id) return;
|
|
792
|
+
if (failed) {
|
|
793
|
+
pendingRef.current.delete(key);
|
|
794
|
+
const failure = cause instanceof Error ? cause : new Error(String(cause));
|
|
795
|
+
errorsRef.current.set(key, {
|
|
796
|
+
key,
|
|
797
|
+
message: failure.message || "Spreadsheet resize failed",
|
|
798
|
+
retry: () => {
|
|
799
|
+
if (!mountedRef.current || scopeRef.current !== scope) return;
|
|
800
|
+
submit(change);
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
setErrors([...errorsRef.current.values()]);
|
|
804
|
+
optionsRef.current.onCommandError?.(failure);
|
|
805
|
+
} else {
|
|
806
|
+
pendingRef.current.set(key, {
|
|
807
|
+
...entry,
|
|
808
|
+
baseRevision: optionsRef.current.revision,
|
|
809
|
+
settled: true
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
setPending([...pendingRef.current.values()]);
|
|
813
|
+
};
|
|
814
|
+
try {
|
|
815
|
+
const result = current.commit(change);
|
|
816
|
+
if (result && typeof result.then === "function") {
|
|
817
|
+
asynchronous = true;
|
|
818
|
+
setInFlightCount((count) => count + 1);
|
|
819
|
+
void Promise.resolve(result).then(
|
|
820
|
+
() => settle(false),
|
|
821
|
+
(cause) => settle(true, cause)
|
|
822
|
+
);
|
|
823
|
+
} else {
|
|
824
|
+
settle(false);
|
|
825
|
+
}
|
|
826
|
+
} catch (cause) {
|
|
827
|
+
settle(true, cause);
|
|
828
|
+
}
|
|
829
|
+
}, []);
|
|
830
|
+
const update = useCallback2((next) => {
|
|
831
|
+
activeRef.current = next;
|
|
832
|
+
if (frameRef.current !== null) return;
|
|
833
|
+
if (typeof globalThis.requestAnimationFrame !== "function") {
|
|
834
|
+
setGesture(next);
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
frameRef.current = globalThis.requestAnimationFrame(() => {
|
|
838
|
+
frameRef.current = null;
|
|
839
|
+
if (mountedRef.current) setGesture(activeRef.current);
|
|
840
|
+
});
|
|
841
|
+
}, []);
|
|
842
|
+
const finish = useCallback2(() => {
|
|
843
|
+
const active = activeRef.current;
|
|
844
|
+
cancel();
|
|
845
|
+
if (!active || active.size === active.startSize) return;
|
|
846
|
+
submit({ sheetId: active.sheetId, axis: active.axis, index: active.index, size: active.size });
|
|
847
|
+
}, [cancel, submit]);
|
|
848
|
+
const begin = useCallback2(
|
|
849
|
+
(axis, index, pointerId, position) => {
|
|
850
|
+
const current = optionsRef.current;
|
|
851
|
+
if (!current.enabled || !current.commit) return;
|
|
852
|
+
const existing = pendingRef.current.get(keyOf({ axis, index }));
|
|
853
|
+
const size = existing?.size ?? authoritativeSize(axis, index);
|
|
854
|
+
cancel();
|
|
855
|
+
const next = {
|
|
856
|
+
sheetId: current.sheetId,
|
|
857
|
+
axis,
|
|
858
|
+
index,
|
|
859
|
+
size,
|
|
860
|
+
startSize: size,
|
|
861
|
+
startPosition: position,
|
|
862
|
+
pointerId
|
|
863
|
+
};
|
|
864
|
+
activeRef.current = next;
|
|
865
|
+
setGesture(next);
|
|
866
|
+
current.onStart?.();
|
|
867
|
+
},
|
|
868
|
+
[authoritativeSize, cancel]
|
|
869
|
+
);
|
|
870
|
+
const handleProps = useCallback2(
|
|
871
|
+
(axis, index) => ({
|
|
872
|
+
onPointerDown(event) {
|
|
873
|
+
if (event.button !== 0 || event.isPrimary === false) return;
|
|
874
|
+
event.preventDefault();
|
|
875
|
+
event.stopPropagation();
|
|
876
|
+
event.currentTarget.focus({ preventScroll: true });
|
|
877
|
+
begin(axis, index, event.pointerId, axis === "column" ? event.clientX : event.clientY);
|
|
878
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
879
|
+
},
|
|
880
|
+
onPointerMove(event) {
|
|
881
|
+
const active = activeRef.current;
|
|
882
|
+
if (!active || active.pointerId !== event.pointerId || active.axis !== axis || active.index !== index)
|
|
883
|
+
return;
|
|
884
|
+
event.preventDefault();
|
|
885
|
+
event.stopPropagation();
|
|
886
|
+
const position = axis === "column" ? event.clientX : event.clientY;
|
|
887
|
+
update({
|
|
888
|
+
...active,
|
|
889
|
+
size: boundedSize(active.startSize + position - active.startPosition)
|
|
890
|
+
});
|
|
891
|
+
},
|
|
892
|
+
onPointerUp(event) {
|
|
893
|
+
const active = activeRef.current;
|
|
894
|
+
if (!active || active.pointerId !== event.pointerId || active.axis !== axis || active.index !== index)
|
|
895
|
+
return;
|
|
896
|
+
event.preventDefault();
|
|
897
|
+
event.stopPropagation();
|
|
898
|
+
const position = axis === "column" ? event.clientX : event.clientY;
|
|
899
|
+
activeRef.current = {
|
|
900
|
+
...active,
|
|
901
|
+
size: boundedSize(active.startSize + position - active.startPosition)
|
|
902
|
+
};
|
|
903
|
+
finish();
|
|
904
|
+
if (event.currentTarget.hasPointerCapture?.(event.pointerId)) {
|
|
905
|
+
event.currentTarget.releasePointerCapture?.(event.pointerId);
|
|
906
|
+
}
|
|
907
|
+
},
|
|
908
|
+
onPointerCancel(event) {
|
|
909
|
+
const active = activeRef.current;
|
|
910
|
+
if (active?.pointerId === event.pointerId && active.axis === axis && active.index === index)
|
|
911
|
+
cancel();
|
|
912
|
+
event.stopPropagation();
|
|
913
|
+
},
|
|
914
|
+
onLostPointerCapture(event) {
|
|
915
|
+
const active = activeRef.current;
|
|
916
|
+
if (active?.pointerId === event.pointerId && active.axis === axis && active.index === index)
|
|
917
|
+
cancel();
|
|
918
|
+
},
|
|
919
|
+
onKeyDown(event) {
|
|
920
|
+
event.stopPropagation();
|
|
921
|
+
if (event.key === "Escape") {
|
|
922
|
+
event.preventDefault();
|
|
923
|
+
cancel();
|
|
924
|
+
return;
|
|
925
|
+
}
|
|
926
|
+
if (event.key === "Enter") {
|
|
927
|
+
event.preventDefault();
|
|
928
|
+
finish();
|
|
929
|
+
return;
|
|
930
|
+
}
|
|
931
|
+
const negative = axis === "column" ? "ArrowLeft" : "ArrowUp";
|
|
932
|
+
const positive = axis === "column" ? "ArrowRight" : "ArrowDown";
|
|
933
|
+
if (event.key !== negative && event.key !== positive && event.key !== "Home") return;
|
|
934
|
+
event.preventDefault();
|
|
935
|
+
if (activeRef.current?.pointerId !== null || activeRef.current.axis !== axis || activeRef.current.index !== index) {
|
|
936
|
+
begin(axis, index, null, 0);
|
|
937
|
+
}
|
|
938
|
+
const active = activeRef.current;
|
|
939
|
+
if (!active) return;
|
|
940
|
+
const current = optionsRef.current;
|
|
941
|
+
const size = event.key === "Home" ? axis === "row" ? current.defaultRowHeight : current.defaultColumnWidth : active.size + (event.key === negative ? -1 : 1) * (event.shiftKey ? 1 : 8);
|
|
942
|
+
update({ ...active, size: boundedSize(size) });
|
|
943
|
+
},
|
|
944
|
+
onKeyUp(event) {
|
|
945
|
+
event.stopPropagation();
|
|
946
|
+
const active = activeRef.current;
|
|
947
|
+
if (active?.axis === axis && active.index === index && (event.key === "Home" || event.key.startsWith("Arrow")))
|
|
948
|
+
finish();
|
|
949
|
+
},
|
|
950
|
+
onBlur() {
|
|
951
|
+
const active = activeRef.current;
|
|
952
|
+
if (active?.pointerId === null && active.axis === axis && active.index === index) finish();
|
|
953
|
+
}
|
|
954
|
+
}),
|
|
955
|
+
[begin, cancel, finish, update]
|
|
956
|
+
);
|
|
957
|
+
const pendingRows = useMemo(() => pending.filter((entry) => entry.axis === "row"), [pending]);
|
|
958
|
+
const pendingColumns = useMemo(
|
|
959
|
+
() => pending.filter((entry) => entry.axis === "column"),
|
|
960
|
+
[pending]
|
|
961
|
+
);
|
|
962
|
+
const rowGesture = gesture?.axis === "row" ? gesture : null;
|
|
963
|
+
const columnGesture = gesture?.axis === "column" ? gesture : null;
|
|
964
|
+
const rowHeights = useMemo(
|
|
965
|
+
() => previewDimensions(options.rowHeights, pendingRows, rowGesture),
|
|
966
|
+
[options.rowHeights, pendingRows, rowGesture]
|
|
967
|
+
);
|
|
968
|
+
const columnWidths = useMemo(
|
|
969
|
+
() => previewDimensions(options.columnWidths, pendingColumns, columnGesture),
|
|
970
|
+
[options.columnWidths, pendingColumns, columnGesture]
|
|
971
|
+
);
|
|
972
|
+
const previewKey = [
|
|
973
|
+
...pending.map((entry) => `${entry.axis}:${entry.index}:${entry.size}`),
|
|
974
|
+
...gesture ? [`${gesture.axis}:${gesture.index}:${gesture.size}`] : []
|
|
975
|
+
].join(";");
|
|
976
|
+
return {
|
|
977
|
+
rowHeights,
|
|
978
|
+
columnWidths,
|
|
979
|
+
previewKey,
|
|
980
|
+
handleProps,
|
|
981
|
+
pendingCount: inFlightCount,
|
|
982
|
+
error: errors[0] ? { message: errors[0].message, retry: options.enabled ? errors[0].retry : void 0 } : null,
|
|
983
|
+
clearError
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function previewDimensions(entries, pending, gesture) {
|
|
987
|
+
if (!pending.length && !gesture) return entries;
|
|
988
|
+
const projected = new Map(entries);
|
|
989
|
+
for (const entry of pending) projected.set(entry.index, entry.size);
|
|
990
|
+
if (gesture) projected.set(gesture.index, gesture.size);
|
|
991
|
+
return [...projected.entries()];
|
|
992
|
+
}
|
|
993
|
+
function SpreadsheetResizeHandle({
|
|
994
|
+
axis,
|
|
995
|
+
label,
|
|
996
|
+
size,
|
|
997
|
+
...handlers
|
|
998
|
+
}) {
|
|
999
|
+
return /* @__PURE__ */ jsx(
|
|
1000
|
+
"div",
|
|
1001
|
+
{
|
|
1002
|
+
...handlers,
|
|
1003
|
+
role: "separator",
|
|
1004
|
+
tabIndex: 0,
|
|
1005
|
+
"aria-label": label,
|
|
1006
|
+
"aria-orientation": axis === "column" ? "vertical" : "horizontal",
|
|
1007
|
+
"aria-valuemin": MIN_SIZE,
|
|
1008
|
+
"aria-valuemax": MAX_SIZE,
|
|
1009
|
+
"aria-valuenow": size,
|
|
1010
|
+
"aria-valuetext": `${size} pixels`,
|
|
1011
|
+
"data-og-resize-axis": axis,
|
|
1012
|
+
style: { [axis === "column" ? "right" : "bottom"]: "calc(var(--spacing) * -1)" },
|
|
1013
|
+
className: cn(
|
|
1014
|
+
"pointer-events-auto absolute z-40 touch-none outline-hidden hover:bg-og-accent/20 focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-og-accent",
|
|
1015
|
+
axis === "column" ? "top-0 h-full w-2 cursor-col-resize" : "left-0 h-2 w-full cursor-row-resize"
|
|
1016
|
+
)
|
|
1017
|
+
}
|
|
1018
|
+
);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
545
1021
|
// src/components/artifacts/spreadsheet-grid.tsx
|
|
546
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1022
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
547
1023
|
var MAX_ROWS = 1048576;
|
|
548
1024
|
var MAX_COLUMNS = 16384;
|
|
549
1025
|
var ROW_HEADER_WIDTH = 48;
|
|
@@ -556,7 +1032,8 @@ var MAX_MOUNTED_AXIS_ITEMS = 512;
|
|
|
556
1032
|
var MAX_MOUNTED_GRID_CELLS = 2048;
|
|
557
1033
|
var MAX_CLIPBOARD_INPUT_BYTES = 4 * 1024 * 1024;
|
|
558
1034
|
var MAX_CLIPBOARD_CELLS = 65536;
|
|
559
|
-
var
|
|
1035
|
+
var EMPTY_DIMENSIONS = [];
|
|
1036
|
+
var useClientLayoutEffect = typeof window === "undefined" ? useEffect3 : useLayoutEffect;
|
|
560
1037
|
function boundedInteger(value, fallback, max) {
|
|
561
1038
|
if (value === void 0) return fallback;
|
|
562
1039
|
if (!Number.isFinite(value)) return fallback;
|
|
@@ -795,12 +1272,6 @@ function isCellSelected(selection, row, col) {
|
|
|
795
1272
|
const normalized = normalizeSelection(selection);
|
|
796
1273
|
return row >= normalized.top && row <= normalized.bottom && col >= normalized.left && col <= normalized.right;
|
|
797
1274
|
}
|
|
798
|
-
function displayValue2(value) {
|
|
799
|
-
if (value === null || value === void 0) return "";
|
|
800
|
-
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toLocaleDateString();
|
|
801
|
-
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
802
|
-
return String(value);
|
|
803
|
-
}
|
|
804
1275
|
function parseCellInput(input) {
|
|
805
1276
|
if (input === "") return null;
|
|
806
1277
|
const normalized = input.trim();
|
|
@@ -909,7 +1380,7 @@ function spreadsheetCanvasTheme(element) {
|
|
|
909
1380
|
const border = computedToken(style, "--og-color-border", "#d1d5db");
|
|
910
1381
|
const foreground = style.color || computedToken(style, "--og-color-fg", "#111827");
|
|
911
1382
|
const mutedForeground = computedToken(style, "--og-color-fg-muted", "#6b7280");
|
|
912
|
-
const accent = computedToken(style, "--og-color-accent", "#
|
|
1383
|
+
const accent = computedToken(style, "--og-color-accent", "#545454");
|
|
913
1384
|
const error = computedToken(style, "--og-color-status-failed", "#dc2626");
|
|
914
1385
|
const fontFamily = style.fontFamily || computedToken(
|
|
915
1386
|
style,
|
|
@@ -944,11 +1415,11 @@ function spreadsheetCanvasTheme(element) {
|
|
|
944
1415
|
};
|
|
945
1416
|
}
|
|
946
1417
|
function useWorkbookViewState(workbook) {
|
|
947
|
-
const [view, setView] =
|
|
1418
|
+
const [view, setView] = useState3(() => ({
|
|
948
1419
|
revision: workbook.revision,
|
|
949
1420
|
dimensionRevision: 0
|
|
950
1421
|
}));
|
|
951
|
-
|
|
1422
|
+
useEffect3(() => {
|
|
952
1423
|
setView(
|
|
953
1424
|
(current) => current.revision === workbook.revision ? current : { revision: workbook.revision, dimensionRevision: current.dimensionRevision + 1 }
|
|
954
1425
|
);
|
|
@@ -985,20 +1456,20 @@ function SpreadsheetArtifactSurface({
|
|
|
985
1456
|
return availableSheets[0];
|
|
986
1457
|
}
|
|
987
1458
|
})();
|
|
988
|
-
const [activeSheetId, setActiveSheetId] =
|
|
1459
|
+
const [activeSheetId, setActiveSheetId] = useState3(initial?.id ?? null);
|
|
989
1460
|
const activeSheet = availableSheets.find((sheet) => sheet.id === activeSheetId) ?? availableSheets[0] ?? null;
|
|
990
|
-
|
|
1461
|
+
useEffect3(() => {
|
|
991
1462
|
if (!activeSheet && activeSheetId !== null) setActiveSheetId(null);
|
|
992
1463
|
else if (activeSheet && activeSheet.id !== activeSheetId) setActiveSheetId(activeSheet.id);
|
|
993
1464
|
}, [activeSheet, activeSheetId, revision]);
|
|
994
|
-
const selectSheet =
|
|
1465
|
+
const selectSheet = useCallback3(
|
|
995
1466
|
(sheet) => {
|
|
996
1467
|
workbook.worksheets.setActiveWorksheet(sheet);
|
|
997
1468
|
setActiveSheetId(sheet.id);
|
|
998
1469
|
},
|
|
999
1470
|
[workbook]
|
|
1000
1471
|
);
|
|
1001
|
-
const addSheet =
|
|
1472
|
+
const addSheet = useCallback3(() => {
|
|
1002
1473
|
const sheet = workbook.worksheets.add(nextAvailableSheetName(workbook));
|
|
1003
1474
|
selectSheet(sheet);
|
|
1004
1475
|
}, [selectSheet, workbook]);
|
|
@@ -1009,7 +1480,7 @@ function SpreadsheetArtifactSurface({
|
|
|
1009
1480
|
role: "tablist",
|
|
1010
1481
|
"aria-label": "Worksheets",
|
|
1011
1482
|
children: [
|
|
1012
|
-
availableSheets.map((sheet) => /* @__PURE__ */
|
|
1483
|
+
availableSheets.map((sheet) => /* @__PURE__ */ jsx2(
|
|
1013
1484
|
"button",
|
|
1014
1485
|
{
|
|
1015
1486
|
type: "button",
|
|
@@ -1024,20 +1495,20 @@ function SpreadsheetArtifactSurface({
|
|
|
1024
1495
|
},
|
|
1025
1496
|
sheet.id
|
|
1026
1497
|
)),
|
|
1027
|
-
!readOnly && allowAddSheet ? /* @__PURE__ */
|
|
1498
|
+
!readOnly && allowAddSheet ? /* @__PURE__ */ jsx2(
|
|
1028
1499
|
"button",
|
|
1029
1500
|
{
|
|
1030
1501
|
type: "button",
|
|
1031
1502
|
onClick: addSheet,
|
|
1032
1503
|
"aria-label": "Add worksheet",
|
|
1033
1504
|
className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg [&>svg]:size-3.5",
|
|
1034
|
-
children: /* @__PURE__ */
|
|
1505
|
+
children: /* @__PURE__ */ jsx2(PlusIcon, {})
|
|
1035
1506
|
}
|
|
1036
1507
|
) : null
|
|
1037
1508
|
]
|
|
1038
1509
|
}
|
|
1039
1510
|
);
|
|
1040
|
-
return /* @__PURE__ */
|
|
1511
|
+
return /* @__PURE__ */ jsx2(
|
|
1041
1512
|
ArtifactSurface,
|
|
1042
1513
|
{
|
|
1043
1514
|
modality: "spreadsheet",
|
|
@@ -1045,7 +1516,7 @@ function SpreadsheetArtifactSurface({
|
|
|
1045
1516
|
subtitle: subtitle ?? (activeSheet ? `${availableSheets.length} sheet${availableSheets.length === 1 ? "" : "s"}` : "Empty workbook"),
|
|
1046
1517
|
actions,
|
|
1047
1518
|
footer,
|
|
1048
|
-
children: activeSheet ? /* @__PURE__ */
|
|
1519
|
+
children: activeSheet ? /* @__PURE__ */ jsx2(
|
|
1049
1520
|
SpreadsheetGrid,
|
|
1050
1521
|
{
|
|
1051
1522
|
...gridProps,
|
|
@@ -1054,19 +1525,19 @@ function SpreadsheetArtifactSurface({
|
|
|
1054
1525
|
readOnly
|
|
1055
1526
|
},
|
|
1056
1527
|
activeSheet.id
|
|
1057
|
-
) : /* @__PURE__ */
|
|
1528
|
+
) : /* @__PURE__ */ jsx2(
|
|
1058
1529
|
"div",
|
|
1059
1530
|
{
|
|
1060
1531
|
className: "grid h-full place-items-center bg-og-bg p-6 text-center",
|
|
1061
1532
|
style: { minHeight: 224 },
|
|
1062
1533
|
children: /* @__PURE__ */ jsxs("div", { children: [
|
|
1063
|
-
/* @__PURE__ */
|
|
1064
|
-
!readOnly && allowAddSheet ? /* @__PURE__ */
|
|
1534
|
+
/* @__PURE__ */ jsx2("p", { className: "text-og-base font-medium text-og-fg", children: "This workbook has no worksheets." }),
|
|
1535
|
+
!readOnly && allowAddSheet ? /* @__PURE__ */ jsx2(
|
|
1065
1536
|
"button",
|
|
1066
1537
|
{
|
|
1067
1538
|
type: "button",
|
|
1068
1539
|
onClick: addSheet,
|
|
1069
|
-
className: "mt-3 rounded-og-sm bg-og-
|
|
1540
|
+
className: "mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover",
|
|
1070
1541
|
children: "Add worksheet"
|
|
1071
1542
|
}
|
|
1072
1543
|
) : null
|
|
@@ -1086,12 +1557,13 @@ function SpreadsheetGrid({
|
|
|
1086
1557
|
overscanColumns = 2,
|
|
1087
1558
|
onSelectionChange,
|
|
1088
1559
|
onCommit,
|
|
1560
|
+
onResize,
|
|
1089
1561
|
onViewportChange,
|
|
1090
1562
|
className
|
|
1091
1563
|
}) {
|
|
1092
1564
|
const { revision, dimensionRevision } = useWorkbookViewState(workbook);
|
|
1093
1565
|
const boundedProjection = requestedRowCount !== void 0 || requestedColumnCount !== void 0;
|
|
1094
|
-
const usedRange =
|
|
1566
|
+
const usedRange = useMemo2(() => {
|
|
1095
1567
|
void revision;
|
|
1096
1568
|
return boundedProjection ? worksheet.usedRangeAddress() : null;
|
|
1097
1569
|
}, [boundedProjection, revision, worksheet]);
|
|
@@ -1111,15 +1583,15 @@ function SpreadsheetGrid({
|
|
|
1111
1583
|
MAX_COLUMNS,
|
|
1112
1584
|
MAX_COLUMNS
|
|
1113
1585
|
);
|
|
1114
|
-
const rowHeights =
|
|
1586
|
+
const rowHeights = useMemo2(() => {
|
|
1115
1587
|
void dimensionRevision;
|
|
1116
1588
|
return [...worksheet.rowHeightEntries()];
|
|
1117
1589
|
}, [dimensionRevision, worksheet]);
|
|
1118
|
-
const columnWidths =
|
|
1590
|
+
const columnWidths = useMemo2(() => {
|
|
1119
1591
|
void dimensionRevision;
|
|
1120
1592
|
return [...worksheet.columnWidthEntries()];
|
|
1121
1593
|
}, [dimensionRevision, worksheet]);
|
|
1122
|
-
const projection =
|
|
1594
|
+
const projection = useMemo2(() => {
|
|
1123
1595
|
void dimensionRevision;
|
|
1124
1596
|
const cells = new SparseSpreadsheetCellIndex(
|
|
1125
1597
|
function* projectedCells() {
|
|
@@ -1153,7 +1625,7 @@ function SpreadsheetGrid({
|
|
|
1153
1625
|
const data = worksheet.cellData(row, col);
|
|
1154
1626
|
return {
|
|
1155
1627
|
value: data.formula ? workbook.valueAt(worksheet, { row, col }) : data.value,
|
|
1156
|
-
input: data.formula ??
|
|
1628
|
+
input: data.formula ?? spreadsheetCellEditSource(data.value),
|
|
1157
1629
|
format: data.format
|
|
1158
1630
|
};
|
|
1159
1631
|
}
|
|
@@ -1169,7 +1641,7 @@ function SpreadsheetGrid({
|
|
|
1169
1641
|
workbook,
|
|
1170
1642
|
worksheet
|
|
1171
1643
|
]);
|
|
1172
|
-
const commit =
|
|
1644
|
+
const commit = useCallback3(
|
|
1173
1645
|
(next) => {
|
|
1174
1646
|
const target = worksheet.getCell(next.cell.row, next.cell.col);
|
|
1175
1647
|
if (next.kind === "formula") target.formulas = [[next.input]];
|
|
@@ -1178,7 +1650,7 @@ function SpreadsheetGrid({
|
|
|
1178
1650
|
},
|
|
1179
1651
|
[onCommit, worksheet]
|
|
1180
1652
|
);
|
|
1181
|
-
const commitRange =
|
|
1653
|
+
const commitRange = useCallback3(
|
|
1182
1654
|
(next) => {
|
|
1183
1655
|
if (next.rows * next.columns !== next.inputs.length) {
|
|
1184
1656
|
throw new Error("Spreadsheet paste shape is invalid");
|
|
@@ -1199,7 +1671,7 @@ function SpreadsheetGrid({
|
|
|
1199
1671
|
},
|
|
1200
1672
|
[workbook, worksheet]
|
|
1201
1673
|
);
|
|
1202
|
-
const clear =
|
|
1674
|
+
const clear = useCallback3(
|
|
1203
1675
|
(next) => {
|
|
1204
1676
|
const normalized = normalizeSelection(next);
|
|
1205
1677
|
worksheet.getRangeByIndexes(
|
|
@@ -1211,7 +1683,15 @@ function SpreadsheetGrid({
|
|
|
1211
1683
|
},
|
|
1212
1684
|
[worksheet]
|
|
1213
1685
|
);
|
|
1214
|
-
|
|
1686
|
+
const resize = useCallback3(
|
|
1687
|
+
(change) => {
|
|
1688
|
+
if (change.axis === "column") worksheet.setColumnWidth(change.index, change.size);
|
|
1689
|
+
else worksheet.setRowHeight(change.index, change.size);
|
|
1690
|
+
onResize?.(change);
|
|
1691
|
+
},
|
|
1692
|
+
[onResize, worksheet]
|
|
1693
|
+
);
|
|
1694
|
+
return /* @__PURE__ */ jsx2(
|
|
1215
1695
|
SpreadsheetProjectionGrid,
|
|
1216
1696
|
{
|
|
1217
1697
|
projection,
|
|
@@ -1222,6 +1702,7 @@ function SpreadsheetGrid({
|
|
|
1222
1702
|
commit,
|
|
1223
1703
|
commitRange,
|
|
1224
1704
|
clear,
|
|
1705
|
+
resize,
|
|
1225
1706
|
onViewportChange,
|
|
1226
1707
|
className
|
|
1227
1708
|
}
|
|
@@ -1236,65 +1717,117 @@ function SpreadsheetProjectionGrid({
|
|
|
1236
1717
|
commit,
|
|
1237
1718
|
commitRange,
|
|
1238
1719
|
clear,
|
|
1720
|
+
resize,
|
|
1721
|
+
pendingTransactions = 0,
|
|
1722
|
+
syncStatus,
|
|
1723
|
+
syncError,
|
|
1239
1724
|
onCommandError,
|
|
1240
1725
|
onViewportChange,
|
|
1241
1726
|
className
|
|
1242
1727
|
}) {
|
|
1243
1728
|
const { revision, rowCount, columnCount } = projection;
|
|
1244
|
-
const dimensionRevision = projection.dimensionRevision ?? 0;
|
|
1245
1729
|
const editable = !readOnly && commit !== void 0;
|
|
1246
|
-
const
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1730
|
+
const commandQueue = useSpreadsheetCommandQueue({
|
|
1731
|
+
scopeKey: `${projection.sheetId}:${projection.generationId ?? "none"}`,
|
|
1732
|
+
enabled: editable,
|
|
1733
|
+
onCommandError
|
|
1734
|
+
});
|
|
1735
|
+
const [commandFailure, setCommandFailure] = useState3(null);
|
|
1736
|
+
const clearPreflightFailure = commandQueue.clearPreflightFailure;
|
|
1737
|
+
const clearCommandFailure = useCallback3(() => {
|
|
1738
|
+
setCommandFailure(null);
|
|
1739
|
+
clearPreflightFailure();
|
|
1740
|
+
}, [clearPreflightFailure]);
|
|
1741
|
+
const resizing = useSpreadsheetResizing({
|
|
1742
|
+
sheetId: projection.sheetId,
|
|
1743
|
+
generationId: projection.generationId,
|
|
1744
|
+
revision: projection.dimensionRevision ?? revision,
|
|
1745
|
+
rowHeights: projection.rowHeights ?? EMPTY_DIMENSIONS,
|
|
1746
|
+
columnWidths: projection.columnWidths ?? EMPTY_DIMENSIONS,
|
|
1747
|
+
defaultRowHeight: projection.defaultRowHeight ?? 24,
|
|
1748
|
+
defaultColumnWidth: projection.defaultColumnWidth ?? 96,
|
|
1749
|
+
enabled: !readOnly && resize !== void 0,
|
|
1750
|
+
commit: resize,
|
|
1751
|
+
onCommandError,
|
|
1752
|
+
onStart: clearCommandFailure
|
|
1753
|
+
});
|
|
1754
|
+
const dimensionRevision = `${projection.dimensionRevision ?? 0}:${resizing.previewKey}`;
|
|
1755
|
+
const rows = useMemo2(() => {
|
|
1756
|
+
return buildAxis(rowCount, projection.defaultRowHeight ?? 24, resizing.rowHeights);
|
|
1757
|
+
}, [projection.defaultRowHeight, resizing.rowHeights, rowCount]);
|
|
1758
|
+
const columns = useMemo2(() => {
|
|
1759
|
+
return buildAxis(columnCount, projection.defaultColumnWidth ?? 96, resizing.columnWidths);
|
|
1760
|
+
}, [columnCount, resizing.columnWidths, projection.defaultColumnWidth]);
|
|
1761
|
+
const canvasRows = useMemo2(() => canvasAxis(rows), [rows]);
|
|
1762
|
+
const canvasColumns = useMemo2(() => canvasAxis(columns), [columns]);
|
|
1763
|
+
const [selection, setSelection] = useState3(() => ({
|
|
1261
1764
|
sheetId: projection.sheetId,
|
|
1262
1765
|
anchor: { row: 0, col: 0 },
|
|
1263
1766
|
focus: { row: 0, col: 0 }
|
|
1264
1767
|
}));
|
|
1265
|
-
const [editMode, setEditMode] =
|
|
1266
|
-
const [draft, setDraft] =
|
|
1768
|
+
const [editMode, setEditMode] = useState3(null);
|
|
1769
|
+
const [draft, setDraft] = useState3(
|
|
1267
1770
|
() => projection.readCell(selection.focus.row, selection.focus.col)?.input ?? ""
|
|
1268
1771
|
);
|
|
1269
|
-
const
|
|
1270
|
-
const
|
|
1271
|
-
const
|
|
1772
|
+
const visibleCommandFailure = resizing.error ?? commandQueue.error ?? commandFailure ?? (syncError ? { message: syncError, retry: void 0 } : null);
|
|
1773
|
+
const pendingCommandCount = commandQueue.pendingCount + resizing.pendingCount + pendingTransactions;
|
|
1774
|
+
const visibleSyncStatus = pendingCommandCount > 0 && (!syncStatus || syncStatus === "Saved" || syncStatus === "Read only") ? "Saving\u2026" : syncStatus;
|
|
1775
|
+
const runQueuedCommand = commandQueue.run;
|
|
1776
|
+
const [viewport, setViewport] = useState3({
|
|
1272
1777
|
width: FALLBACK_VIEWPORT_WIDTH,
|
|
1273
1778
|
height: FALLBACK_VIEWPORT_HEIGHT,
|
|
1274
1779
|
scrollLeft: 0,
|
|
1275
1780
|
scrollTop: 0,
|
|
1276
1781
|
devicePixelRatio: 1
|
|
1277
1782
|
});
|
|
1278
|
-
const [canvasReady, setCanvasReady] =
|
|
1279
|
-
const [canvasEpoch, setCanvasEpoch] =
|
|
1280
|
-
const viewportRef =
|
|
1281
|
-
const canvasRef =
|
|
1282
|
-
const editorRef =
|
|
1283
|
-
const selectionRef =
|
|
1284
|
-
const selectingRef =
|
|
1285
|
-
const committingRef =
|
|
1286
|
-
const composingRef =
|
|
1287
|
-
const commitAfterCompositionRef =
|
|
1288
|
-
const selectDraftOnFocusRef =
|
|
1289
|
-
const initialDraftRef =
|
|
1290
|
-
const
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
const
|
|
1294
|
-
const
|
|
1783
|
+
const [canvasReady, setCanvasReady] = useState3(false);
|
|
1784
|
+
const [canvasEpoch, setCanvasEpoch] = useState3(0);
|
|
1785
|
+
const viewportRef = useRef3(null);
|
|
1786
|
+
const canvasRef = useRef3(null);
|
|
1787
|
+
const editorRef = useRef3(null);
|
|
1788
|
+
const selectionRef = useRef3(selection);
|
|
1789
|
+
const selectingRef = useRef3(null);
|
|
1790
|
+
const committingRef = useRef3(false);
|
|
1791
|
+
const composingRef = useRef3(false);
|
|
1792
|
+
const commitAfterCompositionRef = useRef3(false);
|
|
1793
|
+
const selectDraftOnFocusRef = useRef3(true);
|
|
1794
|
+
const initialDraftRef = useRef3(draft);
|
|
1795
|
+
const optimisticInputsRef = useRef3(
|
|
1796
|
+
/* @__PURE__ */ new Map()
|
|
1797
|
+
);
|
|
1798
|
+
const [optimisticEpoch, setOptimisticEpoch] = useState3(0);
|
|
1799
|
+
const refreshOptimisticInputs = useCallback3(() => setOptimisticEpoch((value) => value + 1), []);
|
|
1800
|
+
const optimisticScope = `${projection.sheetId}:${projection.generationId ?? "none"}`;
|
|
1801
|
+
const optimisticScopeRef = useRef3(optimisticScope);
|
|
1802
|
+
if (optimisticScopeRef.current !== optimisticScope) {
|
|
1803
|
+
optimisticScopeRef.current = optimisticScope;
|
|
1804
|
+
optimisticInputsRef.current.clear();
|
|
1805
|
+
}
|
|
1806
|
+
const projectionRef = useRef3(projection);
|
|
1807
|
+
projectionRef.current = projection;
|
|
1808
|
+
const editModeRef = useRef3(editMode);
|
|
1809
|
+
editModeRef.current = editMode;
|
|
1810
|
+
const canvasRendererRef = useRef3(null);
|
|
1295
1811
|
if (!canvasRendererRef.current) canvasRendererRef.current = new SpreadsheetCanvasRenderer();
|
|
1296
1812
|
const reactId = useId().replaceAll(":", "");
|
|
1297
|
-
const
|
|
1813
|
+
const readEditInput = useCallback3(
|
|
1814
|
+
(cell) => optimisticInputsRef.current.get(`${cell.row}:${cell.col}`)?.input ?? projectionRef.current.readCell(cell.row, cell.col)?.input ?? "",
|
|
1815
|
+
[]
|
|
1816
|
+
);
|
|
1817
|
+
const forgetOptimisticInputs = useCallback3(
|
|
1818
|
+
(target) => {
|
|
1819
|
+
let changed = false;
|
|
1820
|
+
for (const [key, entry] of optimisticInputsRef.current) {
|
|
1821
|
+
if (entry.row >= target.top && entry.row <= target.bottom && entry.col >= target.left && entry.col <= target.right) {
|
|
1822
|
+
optimisticInputsRef.current.delete(key);
|
|
1823
|
+
changed = true;
|
|
1824
|
+
}
|
|
1825
|
+
}
|
|
1826
|
+
if (changed) refreshOptimisticInputs();
|
|
1827
|
+
},
|
|
1828
|
+
[refreshOptimisticInputs]
|
|
1829
|
+
);
|
|
1830
|
+
const updateSelection = useCallback3(
|
|
1298
1831
|
(next) => {
|
|
1299
1832
|
selectionRef.current = next;
|
|
1300
1833
|
setSelection(next);
|
|
@@ -1302,39 +1835,44 @@ function SpreadsheetProjectionGrid({
|
|
|
1302
1835
|
},
|
|
1303
1836
|
[onSelectionChange]
|
|
1304
1837
|
);
|
|
1305
|
-
|
|
1838
|
+
useEffect3(() => {
|
|
1306
1839
|
if (selection.sheetId === projection.sheetId) return;
|
|
1307
|
-
commandScopeRef.current += 1;
|
|
1308
|
-
latestCommandRef.current += 1;
|
|
1309
1840
|
const next = {
|
|
1310
1841
|
sheetId: projection.sheetId,
|
|
1311
1842
|
anchor: { row: 0, col: 0 },
|
|
1312
1843
|
focus: { row: 0, col: 0 }
|
|
1313
1844
|
};
|
|
1314
|
-
|
|
1315
|
-
setPendingCommands(0);
|
|
1845
|
+
optimisticInputsRef.current.clear();
|
|
1316
1846
|
setCommandFailure(null);
|
|
1317
1847
|
setEditMode(null);
|
|
1318
1848
|
updateSelection(next);
|
|
1319
1849
|
}, [projection.sheetId, selection.sheetId, updateSelection]);
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
return;
|
|
1850
|
+
useEffect3(() => {
|
|
1851
|
+
optimisticInputsRef.current.clear();
|
|
1852
|
+
refreshOptimisticInputs();
|
|
1853
|
+
}, [projection.generationId, projection.sheetId, refreshOptimisticInputs]);
|
|
1854
|
+
useClientLayoutEffect(() => {
|
|
1855
|
+
let changed = false;
|
|
1856
|
+
for (const [key, optimistic] of optimisticInputsRef.current) {
|
|
1857
|
+
const coverage = projection.coverage;
|
|
1858
|
+
const covered = !coverage || optimistic.row >= coverage.rowStart && optimistic.row < coverage.rowEnd && optimistic.col >= coverage.columnStart && optimistic.col < coverage.columnEnd;
|
|
1859
|
+
if (!optimistic.pending && covered && (projection.readCell(optimistic.row, optimistic.col)?.input === optimistic.input || revision !== optimistic.baseRevision)) {
|
|
1860
|
+
optimisticInputsRef.current.delete(key);
|
|
1861
|
+
changed = true;
|
|
1862
|
+
}
|
|
1334
1863
|
}
|
|
1335
|
-
if (
|
|
1336
|
-
setDraft(
|
|
1337
|
-
}, [
|
|
1864
|
+
if (changed) refreshOptimisticInputs();
|
|
1865
|
+
if (editMode === null) setDraft(readEditInput(selection.focus));
|
|
1866
|
+
}, [
|
|
1867
|
+
commandQueue.pendingCount,
|
|
1868
|
+
editMode,
|
|
1869
|
+
projection,
|
|
1870
|
+
readEditInput,
|
|
1871
|
+
revision,
|
|
1872
|
+
selection.focus,
|
|
1873
|
+
refreshOptimisticInputs,
|
|
1874
|
+
optimisticEpoch
|
|
1875
|
+
]);
|
|
1338
1876
|
useClientLayoutEffect(() => {
|
|
1339
1877
|
const element = viewportRef.current;
|
|
1340
1878
|
if (!element) return;
|
|
@@ -1355,10 +1893,10 @@ function SpreadsheetProjectionGrid({
|
|
|
1355
1893
|
globalThis.removeEventListener?.("resize", measure);
|
|
1356
1894
|
};
|
|
1357
1895
|
}, []);
|
|
1358
|
-
|
|
1896
|
+
useEffect3(() => {
|
|
1359
1897
|
return () => canvasRendererRef.current?.dispose();
|
|
1360
1898
|
}, []);
|
|
1361
|
-
|
|
1899
|
+
useEffect3(() => {
|
|
1362
1900
|
if (typeof document === "undefined") return;
|
|
1363
1901
|
let active = true;
|
|
1364
1902
|
void document.fonts?.ready.then(() => {
|
|
@@ -1383,7 +1921,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1383
1921
|
observer.disconnect();
|
|
1384
1922
|
};
|
|
1385
1923
|
}, []);
|
|
1386
|
-
|
|
1924
|
+
useEffect3(() => {
|
|
1387
1925
|
if (editMode !== "cell") return;
|
|
1388
1926
|
const editor = editorRef.current;
|
|
1389
1927
|
editor?.focus();
|
|
@@ -1391,7 +1929,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1391
1929
|
if (selectDraftOnFocusRef.current) editor.select();
|
|
1392
1930
|
else editor.setSelectionRange(editor.value.length, editor.value.length);
|
|
1393
1931
|
}, [editMode]);
|
|
1394
|
-
const ensureVisible =
|
|
1932
|
+
const ensureVisible = useCallback3(
|
|
1395
1933
|
(cell) => {
|
|
1396
1934
|
const element = viewportRef.current;
|
|
1397
1935
|
if (!element) return;
|
|
@@ -1428,7 +1966,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1428
1966
|
},
|
|
1429
1967
|
[columns, rows]
|
|
1430
1968
|
);
|
|
1431
|
-
const moveSelection =
|
|
1969
|
+
const moveSelection = useCallback3(
|
|
1432
1970
|
(rowDelta, colDelta, extend) => {
|
|
1433
1971
|
const focus = {
|
|
1434
1972
|
row: Math.max(0, Math.min(rowCount - 1, selection.focus.row + rowDelta)),
|
|
@@ -1444,45 +1982,14 @@ function SpreadsheetProjectionGrid({
|
|
|
1444
1982
|
},
|
|
1445
1983
|
[columnCount, ensureVisible, projection.sheetId, rowCount, selection, updateSelection]
|
|
1446
1984
|
);
|
|
1447
|
-
const runCommand =
|
|
1448
|
-
(invoke, retry, rollback) => {
|
|
1449
|
-
const commandId = latestCommandRef.current + 1;
|
|
1450
|
-
latestCommandRef.current = commandId;
|
|
1451
|
-
const scope = commandScopeRef.current;
|
|
1985
|
+
const runCommand = useCallback3(
|
|
1986
|
+
(invoke, retry, rollback, target, accepted) => {
|
|
1452
1987
|
setCommandFailure(null);
|
|
1453
|
-
|
|
1454
|
-
if (!mountedRef.current || commandScopeRef.current !== scope || latestCommandRef.current !== commandId) {
|
|
1455
|
-
return;
|
|
1456
|
-
}
|
|
1457
|
-
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
1458
|
-
rollback();
|
|
1459
|
-
setCommandFailure({ message: error.message || "Spreadsheet change failed", retry });
|
|
1460
|
-
onCommandError?.(error);
|
|
1461
|
-
};
|
|
1462
|
-
let result;
|
|
1463
|
-
try {
|
|
1464
|
-
result = invoke();
|
|
1465
|
-
} catch (cause) {
|
|
1466
|
-
fail(cause);
|
|
1467
|
-
return;
|
|
1468
|
-
}
|
|
1469
|
-
if (!result || typeof result.then !== "function") return;
|
|
1470
|
-
setPendingCommands((current) => current + 1);
|
|
1471
|
-
void Promise.resolve(result).then(
|
|
1472
|
-
() => {
|
|
1473
|
-
if (!mountedRef.current || commandScopeRef.current !== scope) return;
|
|
1474
|
-
setPendingCommands((current) => Math.max(0, current - 1));
|
|
1475
|
-
},
|
|
1476
|
-
(cause) => {
|
|
1477
|
-
if (!mountedRef.current || commandScopeRef.current !== scope) return;
|
|
1478
|
-
setPendingCommands((current) => Math.max(0, current - 1));
|
|
1479
|
-
fail(cause);
|
|
1480
|
-
}
|
|
1481
|
-
);
|
|
1988
|
+
runQueuedCommand(invoke, retry, rollback, target, accepted);
|
|
1482
1989
|
},
|
|
1483
|
-
[
|
|
1990
|
+
[runQueuedCommand]
|
|
1484
1991
|
);
|
|
1485
|
-
const reportCommandFailure =
|
|
1992
|
+
const reportCommandFailure = useCallback3(
|
|
1486
1993
|
(cause) => {
|
|
1487
1994
|
const error = cause instanceof Error ? cause : new Error(String(cause));
|
|
1488
1995
|
setCommandFailure({ message: error.message || "Spreadsheet action failed" });
|
|
@@ -1490,7 +1997,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1490
1997
|
},
|
|
1491
1998
|
[onCommandError]
|
|
1492
1999
|
);
|
|
1493
|
-
const commitDraft =
|
|
2000
|
+
const commitDraft = useCallback3(
|
|
1494
2001
|
(input = draft) => {
|
|
1495
2002
|
if (committingRef.current) return;
|
|
1496
2003
|
committingRef.current = true;
|
|
@@ -1516,21 +2023,41 @@ function SpreadsheetProjectionGrid({
|
|
|
1516
2023
|
kind: input.startsWith("=") ? "formula" : "value"
|
|
1517
2024
|
};
|
|
1518
2025
|
const execute = () => {
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
baseRevision: revision
|
|
1525
|
-
};
|
|
1526
|
-
setDraft(input);
|
|
2026
|
+
const retryFocus = selectionRef.current.focus;
|
|
2027
|
+
if (editModeRef.current === null && retryFocus.row === next.cell.row && retryFocus.col === next.cell.col) {
|
|
2028
|
+
setDraft(input);
|
|
2029
|
+
}
|
|
2030
|
+
const key = `${next.cell.row}:${next.cell.col}`;
|
|
1527
2031
|
runCommand(
|
|
1528
|
-
() =>
|
|
2032
|
+
(commandId) => {
|
|
2033
|
+
optimisticInputsRef.current.set(key, {
|
|
2034
|
+
...next.cell,
|
|
2035
|
+
input,
|
|
2036
|
+
baseRevision: revision,
|
|
2037
|
+
commandId,
|
|
2038
|
+
pending: true
|
|
2039
|
+
});
|
|
2040
|
+
refreshOptimisticInputs();
|
|
2041
|
+
return commit(next);
|
|
2042
|
+
},
|
|
1529
2043
|
execute,
|
|
1530
|
-
() => {
|
|
1531
|
-
|
|
2044
|
+
(commandId) => {
|
|
2045
|
+
if (optimisticInputsRef.current.get(key)?.commandId !== commandId) return;
|
|
2046
|
+
optimisticInputsRef.current.delete(key);
|
|
2047
|
+
refreshOptimisticInputs();
|
|
1532
2048
|
const current = selectionRef.current.focus;
|
|
1533
|
-
|
|
2049
|
+
if (editModeRef.current === null && current.row === next.cell.row && current.col === next.cell.col) {
|
|
2050
|
+
setDraft(readEditInput(current));
|
|
2051
|
+
}
|
|
2052
|
+
},
|
|
2053
|
+
{ top: next.cell.row, bottom: next.cell.row, left: next.cell.col, right: next.cell.col },
|
|
2054
|
+
(commandId) => {
|
|
2055
|
+
const optimistic = optimisticInputsRef.current.get(key);
|
|
2056
|
+
if (optimistic?.commandId === commandId) {
|
|
2057
|
+
optimistic.pending = false;
|
|
2058
|
+
optimistic.baseRevision = projectionRef.current.revision;
|
|
2059
|
+
refreshOptimisticInputs();
|
|
2060
|
+
}
|
|
1534
2061
|
}
|
|
1535
2062
|
);
|
|
1536
2063
|
};
|
|
@@ -1542,36 +2069,64 @@ function SpreadsheetProjectionGrid({
|
|
|
1542
2069
|
committingRef.current = false;
|
|
1543
2070
|
});
|
|
1544
2071
|
},
|
|
1545
|
-
[
|
|
2072
|
+
[
|
|
2073
|
+
commit,
|
|
2074
|
+
draft,
|
|
2075
|
+
editable,
|
|
2076
|
+
projection,
|
|
2077
|
+
readEditInput,
|
|
2078
|
+
revision,
|
|
2079
|
+
runCommand,
|
|
2080
|
+
selection.focus,
|
|
2081
|
+
refreshOptimisticInputs
|
|
2082
|
+
]
|
|
1546
2083
|
);
|
|
1547
|
-
const clearSelection =
|
|
2084
|
+
const clearSelection = useCallback3(() => {
|
|
1548
2085
|
if (!editable || !clear) return;
|
|
1549
2086
|
const current = selection;
|
|
2087
|
+
const target = normalizeSelection(current);
|
|
1550
2088
|
const execute = () => runCommand(
|
|
1551
|
-
() =>
|
|
2089
|
+
() => {
|
|
2090
|
+
forgetOptimisticInputs(target);
|
|
2091
|
+
return clear(current);
|
|
2092
|
+
},
|
|
1552
2093
|
execute,
|
|
1553
2094
|
() => {
|
|
1554
|
-
}
|
|
2095
|
+
},
|
|
2096
|
+
target
|
|
1555
2097
|
);
|
|
1556
2098
|
execute();
|
|
1557
|
-
}, [clear, editable, runCommand, selection]);
|
|
1558
|
-
const pasteClipboard =
|
|
2099
|
+
}, [clear, editable, forgetOptimisticInputs, runCommand, selection]);
|
|
2100
|
+
const pasteClipboard = useCallback3(
|
|
1559
2101
|
(event) => {
|
|
1560
2102
|
if (!editable || editMode !== null) return;
|
|
1561
2103
|
const clipboardText = event.clipboardData.getData("text/plain");
|
|
1562
2104
|
if (!clipboardText && !event.clipboardData.types.includes("text/plain")) return;
|
|
1563
2105
|
event.preventDefault();
|
|
2106
|
+
const previousSelection = selectionRef.current;
|
|
2107
|
+
const anchor = previousSelection.focus;
|
|
1564
2108
|
const execute = () => {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
if (anchor.row +
|
|
2109
|
+
let prepared;
|
|
2110
|
+
let target;
|
|
2111
|
+
const prepare = () => {
|
|
2112
|
+
prepared = parseSpreadsheetClipboard(clipboardText);
|
|
2113
|
+
if (anchor.row + prepared.rows > rowCount || anchor.col + prepared.columns > columnCount) {
|
|
1570
2114
|
throw new Error("Clipboard range does not fit in this worksheet");
|
|
1571
2115
|
}
|
|
1572
|
-
if (!commitRange &&
|
|
2116
|
+
if (!commitRange && prepared.inputs.length !== 1) {
|
|
1573
2117
|
throw new Error("This spreadsheet adapter does not support rectangular paste");
|
|
1574
2118
|
}
|
|
2119
|
+
target = {
|
|
2120
|
+
top: anchor.row,
|
|
2121
|
+
left: anchor.col,
|
|
2122
|
+
bottom: anchor.row + prepared.rows - 1,
|
|
2123
|
+
right: anchor.col + prepared.columns - 1
|
|
2124
|
+
};
|
|
2125
|
+
return target;
|
|
2126
|
+
};
|
|
2127
|
+
const invoke = () => {
|
|
2128
|
+
const parsed = prepared;
|
|
2129
|
+
forgetOptimisticInputs(target);
|
|
1575
2130
|
const bottomRight = {
|
|
1576
2131
|
row: anchor.row + parsed.rows - 1,
|
|
1577
2132
|
col: anchor.col + parsed.columns - 1
|
|
@@ -1599,7 +2154,17 @@ function SpreadsheetProjectionGrid({
|
|
|
1599
2154
|
kind: input.startsWith("=") ? "formula" : "value"
|
|
1600
2155
|
});
|
|
1601
2156
|
};
|
|
1602
|
-
runCommand(
|
|
2157
|
+
runCommand(
|
|
2158
|
+
invoke,
|
|
2159
|
+
execute,
|
|
2160
|
+
() => {
|
|
2161
|
+
const current = selectionRef.current;
|
|
2162
|
+
if (target && current.anchor.row === anchor.row && current.anchor.col === anchor.col && current.focus.row === target.bottom && current.focus.col === target.right) {
|
|
2163
|
+
updateSelection(previousSelection);
|
|
2164
|
+
}
|
|
2165
|
+
},
|
|
2166
|
+
prepare
|
|
2167
|
+
);
|
|
1603
2168
|
};
|
|
1604
2169
|
execute();
|
|
1605
2170
|
},
|
|
@@ -1610,13 +2175,14 @@ function SpreadsheetProjectionGrid({
|
|
|
1610
2175
|
editMode,
|
|
1611
2176
|
editable,
|
|
1612
2177
|
ensureVisible,
|
|
2178
|
+
forgetOptimisticInputs,
|
|
1613
2179
|
projection.sheetId,
|
|
1614
2180
|
rowCount,
|
|
1615
2181
|
runCommand,
|
|
1616
2182
|
updateSelection
|
|
1617
2183
|
]
|
|
1618
2184
|
);
|
|
1619
|
-
const copySelection =
|
|
2185
|
+
const copySelection = useCallback3(
|
|
1620
2186
|
(event) => {
|
|
1621
2187
|
if (editMode !== null) return;
|
|
1622
2188
|
const selected = normalizeSelection(selectionRef.current);
|
|
@@ -1647,19 +2213,19 @@ function SpreadsheetProjectionGrid({
|
|
|
1647
2213
|
},
|
|
1648
2214
|
[editMode, projection, reportCommandFailure]
|
|
1649
2215
|
);
|
|
1650
|
-
const beginEditing =
|
|
2216
|
+
const beginEditing = useCallback3(
|
|
1651
2217
|
(initial, cell = selectionRef.current.focus) => {
|
|
1652
2218
|
if (!editable) return;
|
|
1653
2219
|
ensureVisible(cell);
|
|
1654
|
-
const current =
|
|
2220
|
+
const current = readEditInput(cell);
|
|
1655
2221
|
initialDraftRef.current = current;
|
|
1656
2222
|
selectDraftOnFocusRef.current = initial === void 0;
|
|
1657
2223
|
setDraft(initial ?? current);
|
|
1658
2224
|
setEditMode("cell");
|
|
1659
2225
|
},
|
|
1660
|
-
[editable, ensureVisible,
|
|
2226
|
+
[editable, ensureVisible, readEditInput]
|
|
1661
2227
|
);
|
|
1662
|
-
const onGridKeyDown =
|
|
2228
|
+
const onGridKeyDown = useCallback3(
|
|
1663
2229
|
(event) => {
|
|
1664
2230
|
if (editMode !== null) return;
|
|
1665
2231
|
if (event.nativeEvent.isComposing || event.nativeEvent.keyCode === 229) return;
|
|
@@ -1733,7 +2299,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1733
2299
|
projection.usedRange
|
|
1734
2300
|
]
|
|
1735
2301
|
);
|
|
1736
|
-
const onEditorKeyDown =
|
|
2302
|
+
const onEditorKeyDown = useCallback3(
|
|
1737
2303
|
(event) => {
|
|
1738
2304
|
if (composingRef.current || event.nativeEvent.isComposing) return;
|
|
1739
2305
|
if (event.key === "Enter") {
|
|
@@ -1742,7 +2308,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1742
2308
|
} else if (event.key === "Escape") {
|
|
1743
2309
|
event.preventDefault();
|
|
1744
2310
|
committingRef.current = true;
|
|
1745
|
-
setDraft(
|
|
2311
|
+
setDraft(readEditInput(selection.focus));
|
|
1746
2312
|
setEditMode(null);
|
|
1747
2313
|
viewportRef.current?.focus();
|
|
1748
2314
|
queueMicrotask(() => {
|
|
@@ -1750,12 +2316,12 @@ function SpreadsheetProjectionGrid({
|
|
|
1750
2316
|
});
|
|
1751
2317
|
}
|
|
1752
2318
|
},
|
|
1753
|
-
[commitDraft,
|
|
2319
|
+
[commitDraft, readEditInput, selection.focus]
|
|
1754
2320
|
);
|
|
1755
|
-
const onEditorCompositionStart =
|
|
2321
|
+
const onEditorCompositionStart = useCallback3(() => {
|
|
1756
2322
|
composingRef.current = true;
|
|
1757
2323
|
}, []);
|
|
1758
|
-
const onEditorCompositionEnd =
|
|
2324
|
+
const onEditorCompositionEnd = useCallback3(
|
|
1759
2325
|
(input) => {
|
|
1760
2326
|
composingRef.current = false;
|
|
1761
2327
|
if (!commitAfterCompositionRef.current) return;
|
|
@@ -1764,7 +2330,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1764
2330
|
},
|
|
1765
2331
|
[commitDraft]
|
|
1766
2332
|
);
|
|
1767
|
-
const commitEditorOnBlur =
|
|
2333
|
+
const commitEditorOnBlur = useCallback3(
|
|
1768
2334
|
(mode, input) => {
|
|
1769
2335
|
if (editMode !== mode) return;
|
|
1770
2336
|
if (composingRef.current) {
|
|
@@ -1775,7 +2341,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1775
2341
|
},
|
|
1776
2342
|
[commitDraft, editMode]
|
|
1777
2343
|
);
|
|
1778
|
-
const selectCell =
|
|
2344
|
+
const selectCell = useCallback3(
|
|
1779
2345
|
(cell, extend) => {
|
|
1780
2346
|
const current = selectionRef.current;
|
|
1781
2347
|
const next = {
|
|
@@ -1789,7 +2355,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1789
2355
|
},
|
|
1790
2356
|
[projection.sheetId, updateSelection]
|
|
1791
2357
|
);
|
|
1792
|
-
const hitTestCell =
|
|
2358
|
+
const hitTestCell = useCallback3(
|
|
1793
2359
|
(clientX, clientY) => {
|
|
1794
2360
|
const element = viewportRef.current;
|
|
1795
2361
|
if (!element) return null;
|
|
@@ -1815,7 +2381,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1815
2381
|
},
|
|
1816
2382
|
[columnCount, columns, rowCount, rows]
|
|
1817
2383
|
);
|
|
1818
|
-
const onGridPointerDown =
|
|
2384
|
+
const onGridPointerDown = useCallback3(
|
|
1819
2385
|
(event) => {
|
|
1820
2386
|
if (event.button !== 0) return;
|
|
1821
2387
|
const cell = hitTestCell(event.clientX, event.clientY);
|
|
@@ -1834,7 +2400,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1834
2400
|
},
|
|
1835
2401
|
[hitTestCell, projection.sheetId, updateSelection]
|
|
1836
2402
|
);
|
|
1837
|
-
const onGridPointerMove =
|
|
2403
|
+
const onGridPointerMove = useCallback3(
|
|
1838
2404
|
(event) => {
|
|
1839
2405
|
const selecting = selectingRef.current;
|
|
1840
2406
|
if (!selecting || selecting.pointerId !== event.pointerId) return;
|
|
@@ -1846,11 +2412,11 @@ function SpreadsheetProjectionGrid({
|
|
|
1846
2412
|
},
|
|
1847
2413
|
[hitTestCell, projection.sheetId, updateSelection]
|
|
1848
2414
|
);
|
|
1849
|
-
const stopPointerSelection =
|
|
2415
|
+
const stopPointerSelection = useCallback3((pointerId) => {
|
|
1850
2416
|
if (pointerId !== void 0 && selectingRef.current?.pointerId !== pointerId) return;
|
|
1851
2417
|
selectingRef.current = null;
|
|
1852
2418
|
}, []);
|
|
1853
|
-
|
|
2419
|
+
useEffect3(() => {
|
|
1854
2420
|
if (typeof window === "undefined") return;
|
|
1855
2421
|
const stopSelecting = () => stopPointerSelection();
|
|
1856
2422
|
window.addEventListener("pointerup", stopSelecting);
|
|
@@ -1906,7 +2472,7 @@ function SpreadsheetProjectionGrid({
|
|
|
1906
2472
|
const activeCellVisible = selection.focus.row >= rowWindow.start && selection.focus.row < rowWindow.end && selection.focus.col >= columnWindow.start && selection.focus.col < columnWindow.end;
|
|
1907
2473
|
const activeCellId = `${reactId}-cell-${selection.focus.row}-${selection.focus.col}`;
|
|
1908
2474
|
const hiddenActiveValue = activeCellVisible ? null : projection.readCell(selection.focus.row, selection.focus.col)?.value;
|
|
1909
|
-
|
|
2475
|
+
useEffect3(() => {
|
|
1910
2476
|
if (!onViewportChange) return;
|
|
1911
2477
|
const next = {
|
|
1912
2478
|
sheetId: projection.sheetId,
|
|
@@ -2016,11 +2582,11 @@ function SpreadsheetProjectionGrid({
|
|
|
2016
2582
|
"div",
|
|
2017
2583
|
{
|
|
2018
2584
|
className: cn("relative flex h-full min-w-0 flex-col bg-og-bg", className),
|
|
2019
|
-
"data-og-command-state":
|
|
2585
|
+
"data-og-command-state": visibleCommandFailure ? "error" : pendingCommandCount > 0 ? "pending" : "idle",
|
|
2020
2586
|
style: { minHeight: 256 },
|
|
2021
2587
|
children: [
|
|
2022
2588
|
/* @__PURE__ */ jsxs("div", { className: "flex min-h-9 shrink-0 items-center border-b border-og-border bg-og-surface-1", children: [
|
|
2023
|
-
/* @__PURE__ */
|
|
2589
|
+
/* @__PURE__ */ jsx2(
|
|
2024
2590
|
"output",
|
|
2025
2591
|
{
|
|
2026
2592
|
"aria-label": "Selected range",
|
|
@@ -2029,17 +2595,17 @@ function SpreadsheetProjectionGrid({
|
|
|
2029
2595
|
children: selectionName(selection)
|
|
2030
2596
|
}
|
|
2031
2597
|
),
|
|
2032
|
-
/* @__PURE__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2598
|
+
/* @__PURE__ */ jsx2("span", { "aria-hidden": true, className: "px-2 font-og-mono text-og-sm italic text-og-fg-subtle", children: "fx" }),
|
|
2599
|
+
/* @__PURE__ */ jsx2(
|
|
2034
2600
|
"input",
|
|
2035
2601
|
{
|
|
2036
2602
|
"aria-label": "Formula or value",
|
|
2037
2603
|
readOnly: !editable,
|
|
2038
|
-
"aria-invalid":
|
|
2604
|
+
"aria-invalid": visibleCommandFailure ? "true" : void 0,
|
|
2039
2605
|
value: draft,
|
|
2040
2606
|
onFocus: () => {
|
|
2041
2607
|
if (editable) {
|
|
2042
|
-
const current =
|
|
2608
|
+
const current = readEditInput(selection.focus);
|
|
2043
2609
|
initialDraftRef.current = current;
|
|
2044
2610
|
setDraft(current);
|
|
2045
2611
|
setEditMode("formula");
|
|
@@ -2052,22 +2618,30 @@ function SpreadsheetProjectionGrid({
|
|
|
2052
2618
|
onBlur: (event) => commitEditorOnBlur("formula", event.currentTarget.value),
|
|
2053
2619
|
className: "h-8 min-w-0 flex-1 bg-transparent px-1 font-mono text-og-sm text-og-fg outline-hidden placeholder:text-og-fg-subtle"
|
|
2054
2620
|
}
|
|
2055
|
-
)
|
|
2621
|
+
),
|
|
2622
|
+
visibleSyncStatus ? /* @__PURE__ */ jsx2(
|
|
2623
|
+
"output",
|
|
2624
|
+
{
|
|
2625
|
+
"aria-label": "Spreadsheet sync status",
|
|
2626
|
+
className: "shrink-0 px-2 text-og-xs text-og-fg-muted",
|
|
2627
|
+
children: visibleCommandFailure ? "Not saved" : visibleSyncStatus
|
|
2628
|
+
}
|
|
2629
|
+
) : null
|
|
2056
2630
|
] }),
|
|
2057
|
-
/* @__PURE__ */
|
|
2058
|
-
|
|
2631
|
+
/* @__PURE__ */ jsx2("div", { role: "status", "aria-live": "polite", className: "sr-only", children: visibleCommandFailure?.message ?? (pendingCommandCount > 0 ? "Saving spreadsheet changes" : "") }),
|
|
2632
|
+
visibleCommandFailure ? /* @__PURE__ */ jsxs(
|
|
2059
2633
|
"div",
|
|
2060
2634
|
{
|
|
2061
2635
|
role: "alert",
|
|
2062
2636
|
className: "absolute bottom-2 left-2 z-50 flex items-center gap-2 rounded-og-sm border border-og-status-failed/30 bg-og-surface-1/95 px-2 py-1 text-og-xs text-og-status-failed shadow-og-sm",
|
|
2063
2637
|
style: { maxWidth: "calc(100% - 1rem)" },
|
|
2064
2638
|
children: [
|
|
2065
|
-
/* @__PURE__ */
|
|
2066
|
-
|
|
2639
|
+
/* @__PURE__ */ jsx2("span", { className: "truncate", children: visibleCommandFailure.message }),
|
|
2640
|
+
visibleCommandFailure.retry ? /* @__PURE__ */ jsx2(
|
|
2067
2641
|
"button",
|
|
2068
2642
|
{
|
|
2069
2643
|
type: "button",
|
|
2070
|
-
onClick:
|
|
2644
|
+
onClick: visibleCommandFailure.retry,
|
|
2071
2645
|
className: "shrink-0 rounded-og-xs px-1.5 py-0.5 font-medium outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
2072
2646
|
children: "Retry"
|
|
2073
2647
|
}
|
|
@@ -2075,7 +2649,7 @@ function SpreadsheetProjectionGrid({
|
|
|
2075
2649
|
]
|
|
2076
2650
|
}
|
|
2077
2651
|
) : null,
|
|
2078
|
-
/* @__PURE__ */
|
|
2652
|
+
/* @__PURE__ */ jsx2(
|
|
2079
2653
|
"div",
|
|
2080
2654
|
{
|
|
2081
2655
|
ref: viewportRef,
|
|
@@ -2086,7 +2660,7 @@ function SpreadsheetProjectionGrid({
|
|
|
2086
2660
|
"aria-colcount": columnCount,
|
|
2087
2661
|
"aria-multiselectable": "true",
|
|
2088
2662
|
"aria-readonly": !editable,
|
|
2089
|
-
"aria-busy":
|
|
2663
|
+
"aria-busy": pendingCommandCount > 0 ? "true" : void 0,
|
|
2090
2664
|
"aria-activedescendant": activeCellId,
|
|
2091
2665
|
onKeyDown: onGridKeyDown,
|
|
2092
2666
|
onCopy: copySelection,
|
|
@@ -2120,10 +2694,14 @@ function SpreadsheetProjectionGrid({
|
|
|
2120
2694
|
className: "relative",
|
|
2121
2695
|
style: {
|
|
2122
2696
|
width: horizontalProjection.physicalTotal,
|
|
2123
|
-
height: verticalProjection.physicalTotal
|
|
2697
|
+
height: verticalProjection.physicalTotal,
|
|
2698
|
+
// Centered boundary handles must not enlarge the bounded scroll
|
|
2699
|
+
// extent at the final row/column. Unlike hidden, clip does not
|
|
2700
|
+
// create another scroll container for the sticky headers.
|
|
2701
|
+
overflow: "clip"
|
|
2124
2702
|
},
|
|
2125
2703
|
children: [
|
|
2126
|
-
/* @__PURE__ */
|
|
2704
|
+
/* @__PURE__ */ jsx2(
|
|
2127
2705
|
"canvas",
|
|
2128
2706
|
{
|
|
2129
2707
|
ref: canvasRef,
|
|
@@ -2138,7 +2716,7 @@ function SpreadsheetProjectionGrid({
|
|
|
2138
2716
|
}
|
|
2139
2717
|
}
|
|
2140
2718
|
),
|
|
2141
|
-
/* @__PURE__ */
|
|
2719
|
+
/* @__PURE__ */ jsx2(
|
|
2142
2720
|
"div",
|
|
2143
2721
|
{
|
|
2144
2722
|
"aria-hidden": true,
|
|
@@ -2150,12 +2728,12 @@ function SpreadsheetProjectionGrid({
|
|
|
2150
2728
|
}
|
|
2151
2729
|
}
|
|
2152
2730
|
),
|
|
2153
|
-
/* @__PURE__ */
|
|
2731
|
+
/* @__PURE__ */ jsx2("div", { role: "row", className: "contents", children: columnLayout.map(({ col, left, width }) => /* @__PURE__ */ jsxs(
|
|
2154
2732
|
"div",
|
|
2155
2733
|
{
|
|
2156
2734
|
role: "columnheader",
|
|
2157
2735
|
"aria-colindex": col + 1,
|
|
2158
|
-
className: "sticky top-0 z-30 grid select-none place-items-center
|
|
2736
|
+
className: "pointer-events-none sticky top-0 z-30 grid select-none place-items-center border-b border-r border-og-border bg-og-surface-2 text-og-xs font-medium text-og-fg-muted",
|
|
2159
2737
|
style: {
|
|
2160
2738
|
position: "absolute",
|
|
2161
2739
|
left,
|
|
@@ -2168,7 +2746,18 @@ function SpreadsheetProjectionGrid({
|
|
|
2168
2746
|
color: "transparent"
|
|
2169
2747
|
} : void 0
|
|
2170
2748
|
},
|
|
2171
|
-
children:
|
|
2749
|
+
children: [
|
|
2750
|
+
/* @__PURE__ */ jsx2("span", { className: "max-w-full overflow-hidden", children: columnName2(col) }),
|
|
2751
|
+
!readOnly && resize ? /* @__PURE__ */ jsx2(
|
|
2752
|
+
SpreadsheetResizeHandle,
|
|
2753
|
+
{
|
|
2754
|
+
axis: "column",
|
|
2755
|
+
label: `Resize column ${columnName2(col)}`,
|
|
2756
|
+
size: width,
|
|
2757
|
+
...resizing.handleProps("column", col)
|
|
2758
|
+
}
|
|
2759
|
+
) : null
|
|
2760
|
+
]
|
|
2172
2761
|
},
|
|
2173
2762
|
`header-${col}`
|
|
2174
2763
|
)) }),
|
|
@@ -2185,11 +2774,11 @@ function SpreadsheetProjectionGrid({
|
|
|
2185
2774
|
height
|
|
2186
2775
|
},
|
|
2187
2776
|
children: [
|
|
2188
|
-
/* @__PURE__ */
|
|
2777
|
+
/* @__PURE__ */ jsxs(
|
|
2189
2778
|
"div",
|
|
2190
2779
|
{
|
|
2191
2780
|
role: "rowheader",
|
|
2192
|
-
className: "sticky left-0 z-20 grid h-full select-none place-items-center border-b border-r border-og-border bg-og-surface-2 text-og-xs text-og-fg-muted",
|
|
2781
|
+
className: "pointer-events-none sticky left-0 z-20 grid h-full select-none place-items-center border-b border-r border-og-border bg-og-surface-2 text-og-xs text-og-fg-muted",
|
|
2193
2782
|
style: {
|
|
2194
2783
|
width: ROW_HEADER_WIDTH,
|
|
2195
2784
|
...canvasReady ? {
|
|
@@ -2198,7 +2787,18 @@ function SpreadsheetProjectionGrid({
|
|
|
2198
2787
|
color: "transparent"
|
|
2199
2788
|
} : void 0
|
|
2200
2789
|
},
|
|
2201
|
-
children:
|
|
2790
|
+
children: [
|
|
2791
|
+
row + 1,
|
|
2792
|
+
!readOnly && resize ? /* @__PURE__ */ jsx2(
|
|
2793
|
+
SpreadsheetResizeHandle,
|
|
2794
|
+
{
|
|
2795
|
+
axis: "row",
|
|
2796
|
+
label: `Resize row ${row + 1}`,
|
|
2797
|
+
size: height,
|
|
2798
|
+
...resizing.handleProps("row", row)
|
|
2799
|
+
}
|
|
2800
|
+
) : null
|
|
2801
|
+
]
|
|
2202
2802
|
}
|
|
2203
2803
|
),
|
|
2204
2804
|
columnLayout.map(({ col, left, width }) => {
|
|
@@ -2210,34 +2810,41 @@ function SpreadsheetProjectionGrid({
|
|
|
2210
2810
|
format: {}
|
|
2211
2811
|
};
|
|
2212
2812
|
const value = data.value;
|
|
2813
|
+
const optimistic = editable ? optimisticInputsRef.current.get(`${row}:${col}`) : void 0;
|
|
2814
|
+
const display = optimistic ? optimistic.input : formatSpreadsheetGeneralDisplay(value);
|
|
2213
2815
|
const address = cellName({ row, col });
|
|
2214
2816
|
const error = typeof value === "string" && value.startsWith("#");
|
|
2215
|
-
return /* @__PURE__ */
|
|
2817
|
+
return /* @__PURE__ */ jsx2(
|
|
2216
2818
|
"div",
|
|
2217
2819
|
{
|
|
2218
2820
|
id: `${reactId}-cell-${row}-${col}`,
|
|
2219
2821
|
role: "gridcell",
|
|
2220
2822
|
"aria-colindex": col + 1,
|
|
2221
2823
|
"aria-selected": selected,
|
|
2222
|
-
"aria-label": `${address}${
|
|
2824
|
+
"aria-label": `${address}${display ? `, ${display}` : ""}${optimistic ? optimistic.input.startsWith("=") ? ", pending formula, awaiting calculation" : ", pending edit" : ""}`,
|
|
2825
|
+
"data-og-pending-input": optimistic ? "true" : void 0,
|
|
2223
2826
|
"data-og-cell": address,
|
|
2224
2827
|
className: cn(
|
|
2225
2828
|
"pointer-events-none absolute top-0 flex h-full min-w-0 overflow-hidden border-b border-r border-og-border px-1.5 text-og-fg",
|
|
2226
|
-
!canvasReady && selected && !active && "bg-og-accent/10",
|
|
2227
|
-
!canvasReady && active && "z-10 bg-og-accent/10 ring-2 ring-inset ring-og-accent",
|
|
2829
|
+
(!canvasReady || optimistic) && selected && !active && "bg-og-accent/10",
|
|
2830
|
+
(!canvasReady || optimistic) && active && "z-10 bg-og-accent/10 ring-2 ring-inset ring-og-accent",
|
|
2228
2831
|
!canvasReady && error && "text-og-status-failed"
|
|
2229
2832
|
),
|
|
2230
2833
|
style: {
|
|
2231
2834
|
left,
|
|
2232
2835
|
width,
|
|
2233
2836
|
...cellStyle(data.format),
|
|
2234
|
-
...canvasReady ? {
|
|
2837
|
+
...canvasReady && !optimistic ? {
|
|
2235
2838
|
background: "transparent",
|
|
2236
2839
|
borderColor: "transparent",
|
|
2237
2840
|
color: "transparent"
|
|
2841
|
+
} : void 0,
|
|
2842
|
+
...optimistic ? {
|
|
2843
|
+
background: data.format.fill ?? "var(--og-color-surface-1)",
|
|
2844
|
+
zIndex: 10
|
|
2238
2845
|
} : void 0
|
|
2239
2846
|
},
|
|
2240
|
-
children: active && editMode === "cell" ? /* @__PURE__ */
|
|
2847
|
+
children: active && editMode === "cell" ? /* @__PURE__ */ jsx2(
|
|
2241
2848
|
"input",
|
|
2242
2849
|
{
|
|
2243
2850
|
ref: editorRef,
|
|
@@ -2251,7 +2858,7 @@ function SpreadsheetProjectionGrid({
|
|
|
2251
2858
|
onPointerDown: (event) => event.stopPropagation(),
|
|
2252
2859
|
className: "pointer-events-auto absolute inset-0 size-full bg-og-surface-1 px-1.5 font-mono text-og-sm text-og-fg outline-hidden ring-2 ring-inset ring-og-accent"
|
|
2253
2860
|
}
|
|
2254
|
-
) : /* @__PURE__ */
|
|
2861
|
+
) : /* @__PURE__ */ jsx2("span", { className: "block min-w-0 overflow-hidden text-ellipsis", children: display })
|
|
2255
2862
|
},
|
|
2256
2863
|
col
|
|
2257
2864
|
);
|
|
@@ -2261,14 +2868,14 @@ function SpreadsheetProjectionGrid({
|
|
|
2261
2868
|
`row-${row}`
|
|
2262
2869
|
);
|
|
2263
2870
|
}),
|
|
2264
|
-
!activeCellVisible ? /* @__PURE__ */
|
|
2871
|
+
!activeCellVisible ? /* @__PURE__ */ jsx2("div", { role: "row", "aria-rowindex": selection.focus.row + 1, className: "sr-only", children: /* @__PURE__ */ jsx2(
|
|
2265
2872
|
"div",
|
|
2266
2873
|
{
|
|
2267
2874
|
id: activeCellId,
|
|
2268
2875
|
role: "gridcell",
|
|
2269
2876
|
"aria-colindex": selection.focus.col + 1,
|
|
2270
2877
|
"aria-selected": "true",
|
|
2271
|
-
"aria-label": `${cellName(selection.focus)}${hiddenActiveValue == null ? "" : `, ${
|
|
2878
|
+
"aria-label": `${cellName(selection.focus)}${hiddenActiveValue == null ? "" : `, ${formatSpreadsheetGeneralDisplay(hiddenActiveValue)}`}`
|
|
2272
2879
|
}
|
|
2273
2880
|
) }) : null
|
|
2274
2881
|
]
|
|
@@ -2288,8 +2895,140 @@ import {
|
|
|
2288
2895
|
spreadsheetSheetId
|
|
2289
2896
|
} from "@opengeni/sdk/editable-artifacts";
|
|
2290
2897
|
import { PlusIcon as PlusIcon2 } from "lucide-react";
|
|
2291
|
-
import {
|
|
2292
|
-
|
|
2898
|
+
import {
|
|
2899
|
+
useCallback as useCallback4,
|
|
2900
|
+
useEffect as useEffect5,
|
|
2901
|
+
useId as useId2,
|
|
2902
|
+
useLayoutEffect as useLayoutEffect2,
|
|
2903
|
+
useMemo as useMemo3,
|
|
2904
|
+
useRef as useRef5,
|
|
2905
|
+
useState as useState6
|
|
2906
|
+
} from "react";
|
|
2907
|
+
|
|
2908
|
+
// src/components/artifacts/spreadsheet-download.tsx
|
|
2909
|
+
import { DownloadIcon, LoaderCircleIcon } from "lucide-react";
|
|
2910
|
+
import { useEffect as useEffect4, useRef as useRef4, useState as useState5, useSyncExternalStore } from "react";
|
|
2911
|
+
|
|
2912
|
+
// src/components/artifacts/spreadsheet-submissions.tsx
|
|
2913
|
+
import { createContext, useContext, useState as useState4 } from "react";
|
|
2914
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
2915
|
+
function createSubmissionQueue() {
|
|
2916
|
+
let pending = 0;
|
|
2917
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
2918
|
+
const emit = () => {
|
|
2919
|
+
for (const listener of listeners) listener();
|
|
2920
|
+
};
|
|
2921
|
+
return {
|
|
2922
|
+
getPending: () => pending,
|
|
2923
|
+
subscribe: (listener) => {
|
|
2924
|
+
listeners.add(listener);
|
|
2925
|
+
return () => {
|
|
2926
|
+
listeners.delete(listener);
|
|
2927
|
+
};
|
|
2928
|
+
},
|
|
2929
|
+
async run(invoke) {
|
|
2930
|
+
pending++;
|
|
2931
|
+
emit();
|
|
2932
|
+
try {
|
|
2933
|
+
return await invoke();
|
|
2934
|
+
} finally {
|
|
2935
|
+
pending--;
|
|
2936
|
+
emit();
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
};
|
|
2940
|
+
}
|
|
2941
|
+
var standaloneQueue = {
|
|
2942
|
+
getPending: () => 0,
|
|
2943
|
+
subscribe: (_listener) => () => {
|
|
2944
|
+
},
|
|
2945
|
+
run: (invoke) => invoke()
|
|
2946
|
+
};
|
|
2947
|
+
var SubmissionContext = createContext(null);
|
|
2948
|
+
function SpreadsheetSubmissionProvider({ children }) {
|
|
2949
|
+
const [queue] = useState4(createSubmissionQueue);
|
|
2950
|
+
return /* @__PURE__ */ jsx3(SubmissionContext.Provider, { value: queue, children });
|
|
2951
|
+
}
|
|
2952
|
+
function useSpreadsheetSubmissions() {
|
|
2953
|
+
return useContext(SubmissionContext) ?? standaloneQueue;
|
|
2954
|
+
}
|
|
2955
|
+
|
|
2956
|
+
// src/components/artifacts/spreadsheet-download.tsx
|
|
2957
|
+
import { Fragment, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2958
|
+
function SpreadsheetDownloadButton({
|
|
2959
|
+
session,
|
|
2960
|
+
title,
|
|
2961
|
+
download
|
|
2962
|
+
}) {
|
|
2963
|
+
const view = useEditableArtifactView(session);
|
|
2964
|
+
const submissions = useSpreadsheetSubmissions();
|
|
2965
|
+
const submitting = useSyncExternalStore(
|
|
2966
|
+
submissions.subscribe,
|
|
2967
|
+
submissions.getPending,
|
|
2968
|
+
submissions.getPending
|
|
2969
|
+
);
|
|
2970
|
+
const active = useRef4(null);
|
|
2971
|
+
const [busy, setBusy] = useState5(false);
|
|
2972
|
+
const [error, setError] = useState5(false);
|
|
2973
|
+
const ready = view.state === "live" && submitting === 0 && view.pendingTransactions === 0 && view.blockedPending.length === 0 && !view.authoringBlockedReason;
|
|
2974
|
+
useEffect4(() => () => active.current?.abort(), [session]);
|
|
2975
|
+
useEffect4(() => {
|
|
2976
|
+
if (view.state === "failed" || view.state === "closed") {
|
|
2977
|
+
active.current?.abort();
|
|
2978
|
+
active.current = null;
|
|
2979
|
+
setBusy(false);
|
|
2980
|
+
}
|
|
2981
|
+
}, [view.state]);
|
|
2982
|
+
const start = async () => {
|
|
2983
|
+
if (active.current || !ready || submissions.getPending()) return;
|
|
2984
|
+
const current = session.getView();
|
|
2985
|
+
if (current.state !== "live" || current.pendingTransactions || current.blockedPending.length || current.authoringBlockedReason)
|
|
2986
|
+
return;
|
|
2987
|
+
const controller = new AbortController();
|
|
2988
|
+
active.current = controller;
|
|
2989
|
+
setBusy(true);
|
|
2990
|
+
setError(false);
|
|
2991
|
+
try {
|
|
2992
|
+
const blob = await download(controller.signal);
|
|
2993
|
+
if (controller.signal.aborted) return;
|
|
2994
|
+
const url = URL.createObjectURL(blob);
|
|
2995
|
+
try {
|
|
2996
|
+
const anchor = document.createElement("a");
|
|
2997
|
+
anchor.href = url;
|
|
2998
|
+
anchor.download = `${title.replace(/[\\/:*?"<>|\u0000-\u001f]/g, "_").replace(/\.xlsx$/i, "").trim() || "Workbook"}.xlsx`;
|
|
2999
|
+
anchor.rel = "noopener";
|
|
3000
|
+
anchor.click();
|
|
3001
|
+
} finally {
|
|
3002
|
+
setTimeout(() => URL.revokeObjectURL(url), 0);
|
|
3003
|
+
}
|
|
3004
|
+
} catch {
|
|
3005
|
+
if (!controller.signal.aborted) setError(true);
|
|
3006
|
+
} finally {
|
|
3007
|
+
if (!controller.signal.aborted) {
|
|
3008
|
+
active.current = null;
|
|
3009
|
+
setBusy(false);
|
|
3010
|
+
}
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
3014
|
+
error ? /* @__PURE__ */ jsx4("span", { role: "alert", className: "text-og-xs text-og-fg-muted", children: "Download failed. Try again." }) : null,
|
|
3015
|
+
/* @__PURE__ */ jsxs2(
|
|
3016
|
+
ArtifactButton,
|
|
3017
|
+
{
|
|
3018
|
+
onClick: () => void start(),
|
|
3019
|
+
disabled: busy || !ready,
|
|
3020
|
+
title: ready ? "Download workbook as XLSX" : "Wait for workbook changes to sync",
|
|
3021
|
+
children: [
|
|
3022
|
+
busy ? /* @__PURE__ */ jsx4(LoaderCircleIcon, { className: "animate-spin", "aria-hidden": true }) : /* @__PURE__ */ jsx4(DownloadIcon, { "aria-hidden": true }),
|
|
3023
|
+
busy ? "Preparing\u2026" : "Download"
|
|
3024
|
+
]
|
|
3025
|
+
}
|
|
3026
|
+
)
|
|
3027
|
+
] });
|
|
3028
|
+
}
|
|
3029
|
+
|
|
3030
|
+
// src/components/artifacts/editable-spreadsheet.tsx
|
|
3031
|
+
import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
2293
3032
|
var EXCEL_MAX_ROWS = 1048576;
|
|
2294
3033
|
var EXCEL_MAX_COLUMNS = 16384;
|
|
2295
3034
|
var INITIAL_VIEWPORT_ROWS = 64;
|
|
@@ -2298,7 +3037,19 @@ var MAX_INTERACTIVE_QUERY_CELLS = 65536;
|
|
|
2298
3037
|
var MAX_INTERACTIVE_QUERY_BYTES = 8 * 1024 * 1024;
|
|
2299
3038
|
var EMPTY_FORMAT = Object.freeze({});
|
|
2300
3039
|
var EMPTY_SHEETS = [];
|
|
2301
|
-
|
|
3040
|
+
var useClientLayoutEffect2 = typeof window === "undefined" ? useEffect5 : useLayoutEffect2;
|
|
3041
|
+
var SESSION_KEYS = /* @__PURE__ */ new WeakMap();
|
|
3042
|
+
var nextSessionKey = 0;
|
|
3043
|
+
function EditableSpreadsheetGrid(props) {
|
|
3044
|
+
return /* @__PURE__ */ jsx5(
|
|
3045
|
+
EditableSpreadsheetGridSession,
|
|
3046
|
+
{
|
|
3047
|
+
...props
|
|
3048
|
+
},
|
|
3049
|
+
`${spreadsheetSessionKey(props.session)}:${props.sheet.sheetId}:${props.sheet.generationId ?? "pending"}`
|
|
3050
|
+
);
|
|
3051
|
+
}
|
|
3052
|
+
function EditableSpreadsheetGridSession({
|
|
2302
3053
|
session,
|
|
2303
3054
|
sheet,
|
|
2304
3055
|
metadataRevision,
|
|
@@ -2309,39 +3060,51 @@ function EditableSpreadsheetGrid({
|
|
|
2309
3060
|
overscanColumns = 2,
|
|
2310
3061
|
onSelectionChange,
|
|
2311
3062
|
onCommit,
|
|
3063
|
+
onResize,
|
|
2312
3064
|
onCommandError,
|
|
2313
3065
|
onViewportChange,
|
|
2314
3066
|
className
|
|
2315
3067
|
}) {
|
|
3068
|
+
const authoringLifetime = useSpreadsheetAuthoringLifetime();
|
|
3069
|
+
const submissions = useSpreadsheetSubmissions();
|
|
3070
|
+
const view = useEditableArtifactView(session);
|
|
2316
3071
|
const rowCount = boundedSheetCount(requestedRowCount, EXCEL_MAX_ROWS, sheet.usedBounds?.endRow);
|
|
2317
3072
|
const columnCount = boundedSheetCount(
|
|
2318
3073
|
requestedColumnCount,
|
|
2319
3074
|
EXCEL_MAX_COLUMNS,
|
|
2320
3075
|
sheet.usedBounds?.endColumn
|
|
2321
3076
|
);
|
|
2322
|
-
const [state, setState] =
|
|
3077
|
+
const [state, setState] = useState6(() => ({
|
|
3078
|
+
session,
|
|
3079
|
+
generationId: sheet.generationId,
|
|
2323
3080
|
query: initialViewportQuery(sheet.sheetId, rowCount, columnCount),
|
|
2324
3081
|
projection: null,
|
|
2325
3082
|
error: null
|
|
2326
3083
|
}));
|
|
2327
|
-
const activeCellRef =
|
|
2328
|
-
|
|
2329
|
-
setState(
|
|
2330
|
-
query
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
3084
|
+
const activeCellRef = useRef5({ row: 0, column: 0 });
|
|
3085
|
+
useEffect5(() => {
|
|
3086
|
+
setState(
|
|
3087
|
+
(current) => current.session === session && current.generationId === sheet.generationId && current.query.sheetId === sheet.sheetId ? current : {
|
|
3088
|
+
session,
|
|
3089
|
+
generationId: sheet.generationId,
|
|
3090
|
+
query: initialViewportQuery(sheet.sheetId, rowCount, columnCount),
|
|
3091
|
+
projection: null,
|
|
3092
|
+
error: null
|
|
3093
|
+
}
|
|
3094
|
+
);
|
|
2334
3095
|
activeCellRef.current = { row: 0, column: 0 };
|
|
2335
|
-
}, [columnCount, rowCount, session, sheet.sheetId]);
|
|
2336
|
-
|
|
3096
|
+
}, [columnCount, rowCount, session, sheet.generationId, sheet.sheetId]);
|
|
3097
|
+
useEffect5(() => {
|
|
2337
3098
|
const query = state.query;
|
|
2338
|
-
|
|
3099
|
+
const matchesScope = (current) => current.session === session && current.generationId === sheet.generationId && sameViewportQuery(current.query, query);
|
|
3100
|
+
let active = true;
|
|
3101
|
+
const unsubscribe = session.subscribeSpreadsheetViewport(
|
|
2339
3102
|
query,
|
|
2340
3103
|
(projection2) => {
|
|
2341
|
-
if (!sameViewport(projection2, query)) return;
|
|
3104
|
+
if (!active || !sameViewport(projection2, query)) return;
|
|
2342
3105
|
if (sheet.generationId !== null && projection2.generationId !== sheet.generationId) {
|
|
2343
3106
|
setState(
|
|
2344
|
-
(current) =>
|
|
3107
|
+
(current) => matchesScope(current) ? {
|
|
2345
3108
|
...current,
|
|
2346
3109
|
projection: null,
|
|
2347
3110
|
error: new Error("Spreadsheet generation changed; refreshing metadata")
|
|
@@ -2350,97 +3113,146 @@ function EditableSpreadsheetGrid({
|
|
|
2350
3113
|
return;
|
|
2351
3114
|
}
|
|
2352
3115
|
setState(
|
|
2353
|
-
(current) =>
|
|
3116
|
+
(current) => matchesScope(current) ? { ...current, projection: projection2, error: null } : current
|
|
2354
3117
|
);
|
|
2355
3118
|
},
|
|
2356
3119
|
{
|
|
2357
3120
|
onError(error) {
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
);
|
|
3121
|
+
if (!active) return;
|
|
3122
|
+
setState((current) => matchesScope(current) ? { ...current, error } : current);
|
|
2361
3123
|
}
|
|
2362
3124
|
}
|
|
2363
3125
|
);
|
|
3126
|
+
return () => {
|
|
3127
|
+
active = false;
|
|
3128
|
+
unsubscribe();
|
|
3129
|
+
};
|
|
2364
3130
|
}, [session, sheet.generationId, state.query]);
|
|
2365
|
-
const projection =
|
|
3131
|
+
const projection = useMemo3(
|
|
2366
3132
|
() => projectSdkViewport(
|
|
2367
3133
|
sheet,
|
|
2368
3134
|
metadataRevision,
|
|
2369
3135
|
state.query,
|
|
2370
|
-
state.projection,
|
|
3136
|
+
state.session === session && state.generationId === sheet.generationId ? state.projection : null,
|
|
2371
3137
|
rowCount,
|
|
2372
3138
|
columnCount
|
|
2373
3139
|
),
|
|
2374
|
-
[columnCount, metadataRevision, rowCount,
|
|
3140
|
+
[columnCount, metadataRevision, rowCount, session, sheet, state]
|
|
2375
3141
|
);
|
|
2376
|
-
const generation =
|
|
2377
|
-
const editable = !readOnly && generation !== null;
|
|
2378
|
-
const
|
|
3142
|
+
const generation = useMemo3(() => sheetGeneration(sheet), [sheet]);
|
|
3143
|
+
const editable = !readOnly && view.writable && !view.authoringBlockedReason && generation !== null;
|
|
3144
|
+
const syncStatus = view.authoringBlockedReason ? "Waiting for earlier edits\u2026" : view.state === "live" ? editable ? "Saved" : "Read only" : editableArtifactStatusLabel(view);
|
|
3145
|
+
const syncError = view.blockedPending.length > 0 ? "Some earlier changes could not sync." : view.lastError?.message;
|
|
3146
|
+
const resizable = editable && sheet.defaultRowHeight !== void 0 && sheet.defaultColumnWidth !== void 0;
|
|
3147
|
+
const handleCommit = useCallback4(
|
|
2379
3148
|
async (commit) => {
|
|
3149
|
+
const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
|
|
2380
3150
|
if (!generation) throw new Error("This sheet generation is not writable yet");
|
|
2381
3151
|
const input = spreadsheetCellInput(commit.input, commit.kind);
|
|
2382
|
-
await
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
3152
|
+
await submissions.run(
|
|
3153
|
+
() => session.applySpreadsheetCommands({
|
|
3154
|
+
version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
3155
|
+
commands: [
|
|
3156
|
+
{
|
|
3157
|
+
kind: "cells.set",
|
|
3158
|
+
sheet: generation,
|
|
3159
|
+
anchor: { row: commit.cell.row, column: commit.cell.col },
|
|
3160
|
+
rows: 1,
|
|
3161
|
+
columns: 1,
|
|
3162
|
+
cells: [input]
|
|
3163
|
+
}
|
|
3164
|
+
]
|
|
3165
|
+
})
|
|
3166
|
+
);
|
|
3167
|
+
if (authoringLifetime.current === lifetime) onCommit?.(commit);
|
|
2396
3168
|
},
|
|
2397
|
-
[generation, onCommit, session]
|
|
3169
|
+
[authoringLifetime, generation, onCommit, session, submissions]
|
|
2398
3170
|
);
|
|
2399
|
-
const handleClear =
|
|
3171
|
+
const handleClear = useCallback4(
|
|
2400
3172
|
async (selection) => {
|
|
3173
|
+
requireSpreadsheetAuthoringLifetime(authoringLifetime);
|
|
2401
3174
|
if (!generation) throw new Error("This sheet generation is not writable yet");
|
|
2402
3175
|
const top = Math.min(selection.anchor.row, selection.focus.row);
|
|
2403
3176
|
const bottom = Math.max(selection.anchor.row, selection.focus.row);
|
|
2404
3177
|
const left = Math.min(selection.anchor.col, selection.focus.col);
|
|
2405
3178
|
const right = Math.max(selection.anchor.col, selection.focus.col);
|
|
2406
|
-
await
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
3179
|
+
await submissions.run(
|
|
3180
|
+
() => session.applySpreadsheetCommands({
|
|
3181
|
+
version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
3182
|
+
commands: [
|
|
3183
|
+
{
|
|
3184
|
+
kind: "range.clear",
|
|
3185
|
+
sheet: generation,
|
|
3186
|
+
range: {
|
|
3187
|
+
start: { row: top, column: left },
|
|
3188
|
+
end: { row: bottom, column: right }
|
|
3189
|
+
}
|
|
2415
3190
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
3191
|
+
]
|
|
3192
|
+
})
|
|
3193
|
+
);
|
|
2419
3194
|
},
|
|
2420
|
-
[generation, session]
|
|
3195
|
+
[authoringLifetime, generation, session, submissions]
|
|
2421
3196
|
);
|
|
2422
|
-
const handleCommitRange =
|
|
3197
|
+
const handleCommitRange = useCallback4(
|
|
2423
3198
|
async (commit) => {
|
|
3199
|
+
requireSpreadsheetAuthoringLifetime(authoringLifetime);
|
|
2424
3200
|
if (!generation) throw new Error("This sheet generation is not writable yet");
|
|
2425
|
-
await
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
3201
|
+
await submissions.run(
|
|
3202
|
+
() => session.applySpreadsheetCommands({
|
|
3203
|
+
version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
3204
|
+
commands: [
|
|
3205
|
+
{
|
|
3206
|
+
kind: "cells.set",
|
|
3207
|
+
sheet: generation,
|
|
3208
|
+
anchor: { row: commit.anchor.row, column: commit.anchor.col },
|
|
3209
|
+
rows: commit.rows,
|
|
3210
|
+
columns: commit.columns,
|
|
3211
|
+
cells: commit.inputs.map(
|
|
3212
|
+
(input) => spreadsheetCellInput(input, input.startsWith("=") ? "formula" : "value")
|
|
3213
|
+
)
|
|
3214
|
+
}
|
|
3215
|
+
]
|
|
3216
|
+
})
|
|
3217
|
+
);
|
|
2440
3218
|
},
|
|
2441
|
-
[generation, session]
|
|
3219
|
+
[authoringLifetime, generation, session, submissions]
|
|
2442
3220
|
);
|
|
2443
|
-
const
|
|
3221
|
+
const handleResize = useCallback4(
|
|
3222
|
+
async (change) => {
|
|
3223
|
+
const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
|
|
3224
|
+
if (!generation) throw new Error("This sheet generation is not writable yet");
|
|
3225
|
+
await submissions.run(
|
|
3226
|
+
() => session.applySpreadsheetCommands({
|
|
3227
|
+
version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
3228
|
+
commands: [
|
|
3229
|
+
change.axis === "column" ? {
|
|
3230
|
+
kind: "column.width.set",
|
|
3231
|
+
sheet: generation,
|
|
3232
|
+
column: change.index,
|
|
3233
|
+
width: change.size === sheet.defaultColumnWidth ? null : change.size
|
|
3234
|
+
} : {
|
|
3235
|
+
kind: "row.height.set",
|
|
3236
|
+
sheet: generation,
|
|
3237
|
+
row: change.index,
|
|
3238
|
+
height: change.size === sheet.defaultRowHeight ? null : change.size
|
|
3239
|
+
}
|
|
3240
|
+
]
|
|
3241
|
+
})
|
|
3242
|
+
);
|
|
3243
|
+
if (authoringLifetime.current === lifetime) onResize?.(change);
|
|
3244
|
+
},
|
|
3245
|
+
[
|
|
3246
|
+
authoringLifetime,
|
|
3247
|
+
generation,
|
|
3248
|
+
onResize,
|
|
3249
|
+
session,
|
|
3250
|
+
sheet.defaultColumnWidth,
|
|
3251
|
+
sheet.defaultRowHeight,
|
|
3252
|
+
submissions
|
|
3253
|
+
]
|
|
3254
|
+
);
|
|
3255
|
+
const handleSelection = useCallback4(
|
|
2444
3256
|
(selection) => {
|
|
2445
3257
|
activeCellRef.current = {
|
|
2446
3258
|
row: selection.focus.row,
|
|
@@ -2449,6 +3261,7 @@ function EditableSpreadsheetGrid({
|
|
|
2449
3261
|
setState((current) => {
|
|
2450
3262
|
if (queryContains(current.query, selection.focus.row, selection.focus.col)) return current;
|
|
2451
3263
|
return {
|
|
3264
|
+
...current,
|
|
2452
3265
|
query: boundedViewportQuery(
|
|
2453
3266
|
sheet.sheetId,
|
|
2454
3267
|
selection.focus.row,
|
|
@@ -2467,7 +3280,7 @@ function EditableSpreadsheetGrid({
|
|
|
2467
3280
|
},
|
|
2468
3281
|
[columnCount, onSelectionChange, rowCount, sheet.sheetId]
|
|
2469
3282
|
);
|
|
2470
|
-
const handleViewport =
|
|
3283
|
+
const handleViewport = useCallback4(
|
|
2471
3284
|
(viewport) => {
|
|
2472
3285
|
const next = boundedViewportQuery(
|
|
2473
3286
|
sheet.sheetId,
|
|
@@ -2480,14 +3293,23 @@ function EditableSpreadsheetGrid({
|
|
|
2480
3293
|
activeCellRef.current
|
|
2481
3294
|
);
|
|
2482
3295
|
setState(
|
|
2483
|
-
(current) => sameViewportQuery(current.query, next) ? current : { query: next,
|
|
3296
|
+
(current) => sameViewportQuery(current.query, next) ? current : { ...current, query: next, error: null }
|
|
2484
3297
|
);
|
|
2485
3298
|
onViewportChange?.(viewport);
|
|
2486
3299
|
},
|
|
2487
3300
|
[columnCount, onViewportChange, rowCount, sheet.sheetId]
|
|
2488
3301
|
);
|
|
2489
|
-
|
|
2490
|
-
/* @__PURE__ */
|
|
3302
|
+
if (editableArtifactAccessRevoked(view)) {
|
|
3303
|
+
return /* @__PURE__ */ jsx5(
|
|
3304
|
+
EditableArtifactMessage,
|
|
3305
|
+
{
|
|
3306
|
+
title: "Spreadsheet unavailable",
|
|
3307
|
+
detail: "You no longer have access to this artifact"
|
|
3308
|
+
}
|
|
3309
|
+
);
|
|
3310
|
+
}
|
|
3311
|
+
return /* @__PURE__ */ jsxs3("div", { className: cn("relative h-full min-h-0", className), children: [
|
|
3312
|
+
/* @__PURE__ */ jsx5(
|
|
2491
3313
|
SpreadsheetProjectionGrid,
|
|
2492
3314
|
{
|
|
2493
3315
|
projection,
|
|
@@ -2498,11 +3320,15 @@ function EditableSpreadsheetGrid({
|
|
|
2498
3320
|
commit: editable ? handleCommit : void 0,
|
|
2499
3321
|
commitRange: editable ? handleCommitRange : void 0,
|
|
2500
3322
|
clear: editable ? handleClear : void 0,
|
|
3323
|
+
resize: resizable ? handleResize : void 0,
|
|
3324
|
+
pendingTransactions: view.pendingTransactions,
|
|
3325
|
+
syncStatus,
|
|
3326
|
+
syncError,
|
|
2501
3327
|
onCommandError,
|
|
2502
3328
|
onViewportChange: handleViewport
|
|
2503
3329
|
}
|
|
2504
3330
|
),
|
|
2505
|
-
state.error ? /* @__PURE__ */
|
|
3331
|
+
state.error && state.session === session && state.generationId === sheet.generationId ? /* @__PURE__ */ jsx5(
|
|
2506
3332
|
"output",
|
|
2507
3333
|
{
|
|
2508
3334
|
role: "status",
|
|
@@ -2513,65 +3339,73 @@ function EditableSpreadsheetGrid({
|
|
|
2513
3339
|
) : null
|
|
2514
3340
|
] });
|
|
2515
3341
|
}
|
|
2516
|
-
function EditableSpreadsheetArtifactSurface({
|
|
3342
|
+
function EditableSpreadsheetArtifactSurface(props) {
|
|
3343
|
+
return /* @__PURE__ */ jsx5(SpreadsheetSubmissionProvider, { children: /* @__PURE__ */ jsx5(EditableSpreadsheetArtifactSurfaceSession, { ...props }) }, spreadsheetSessionKey(props.session));
|
|
3344
|
+
}
|
|
3345
|
+
function EditableSpreadsheetArtifactSurfaceSession({
|
|
2517
3346
|
session,
|
|
2518
3347
|
title = "Workbook",
|
|
3348
|
+
showHeader,
|
|
2519
3349
|
subtitle,
|
|
2520
3350
|
actions,
|
|
3351
|
+
download,
|
|
2521
3352
|
initialSheetId,
|
|
2522
3353
|
allowAddSheet = true,
|
|
2523
3354
|
readOnly = false,
|
|
2524
3355
|
...gridProps
|
|
2525
3356
|
}) {
|
|
3357
|
+
const authoringLifetime = useSpreadsheetAuthoringLifetime();
|
|
3358
|
+
const submissions = useSpreadsheetSubmissions();
|
|
2526
3359
|
const { metadata, error: metadataError } = useSpreadsheetMetadata(session);
|
|
2527
3360
|
const view = useEditableArtifactView(session);
|
|
2528
|
-
const [activeSheetId, setActiveSheetId] =
|
|
2529
|
-
const [creatingSheet, setCreatingSheet] =
|
|
2530
|
-
const [surfaceError, setSurfaceError] =
|
|
3361
|
+
const [activeSheetId, setActiveSheetId] = useState6(initialSheetId ?? null);
|
|
3362
|
+
const [creatingSheet, setCreatingSheet] = useState6(false);
|
|
3363
|
+
const [surfaceError, setSurfaceError] = useState6(null);
|
|
2531
3364
|
const sheets = metadata?.sheets ?? EMPTY_SHEETS;
|
|
2532
3365
|
const activeSheet = sheets.find((sheet) => sheet.sheetId === activeSheetId) ?? (initialSheetId ? sheets.find((sheet) => sheet.sheetId === initialSheetId) : void 0) ?? sheets[0] ?? null;
|
|
2533
|
-
const writable = !readOnly && view.writable;
|
|
3366
|
+
const writable = !readOnly && view.writable && !view.authoringBlockedReason;
|
|
2534
3367
|
const accessRevoked = editableArtifactAccessRevoked(view);
|
|
2535
|
-
const addSheet =
|
|
3368
|
+
const addSheet = useCallback4(async () => {
|
|
2536
3369
|
if (!writable || creatingSheet) return;
|
|
3370
|
+
const lifetime = requireSpreadsheetAuthoringLifetime(authoringLifetime);
|
|
2537
3371
|
setCreatingSheet(true);
|
|
2538
3372
|
setSurfaceError(null);
|
|
2539
3373
|
try {
|
|
2540
3374
|
const after = activeSheet ? sheetGeneration(activeSheet) : null;
|
|
2541
|
-
const created = await
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
3375
|
+
const created = await submissions.run(
|
|
3376
|
+
() => session.createSpreadsheetSheet({
|
|
3377
|
+
name: nextAvailableSheetName2(sheets),
|
|
3378
|
+
after
|
|
3379
|
+
})
|
|
3380
|
+
);
|
|
3381
|
+
if (authoringLifetime.current === lifetime) setActiveSheetId(created.sheetId);
|
|
2546
3382
|
} catch (cause) {
|
|
2547
|
-
setSurfaceError(asError(cause));
|
|
3383
|
+
if (authoringLifetime.current === lifetime) setSurfaceError(asError(cause));
|
|
2548
3384
|
} finally {
|
|
2549
|
-
setCreatingSheet(false);
|
|
3385
|
+
if (authoringLifetime.current === lifetime) setCreatingSheet(false);
|
|
2550
3386
|
}
|
|
2551
|
-
}, [activeSheet, creatingSheet, session, sheets, writable]);
|
|
2552
|
-
const footer = /* @__PURE__ */
|
|
3387
|
+
}, [activeSheet, authoringLifetime, creatingSheet, session, sheets, submissions, writable]);
|
|
3388
|
+
const footer = /* @__PURE__ */ jsxs3(
|
|
2553
3389
|
"div",
|
|
2554
3390
|
{
|
|
2555
3391
|
className: "flex min-h-9 items-center gap-1 overflow-x-auto px-2",
|
|
2556
3392
|
role: "tablist",
|
|
2557
3393
|
"aria-label": "Worksheets",
|
|
2558
3394
|
children: [
|
|
2559
|
-
sheets.map((sheet) => /* @__PURE__ */
|
|
2560
|
-
|
|
3395
|
+
sheets.map((sheet) => /* @__PURE__ */ jsx5(
|
|
3396
|
+
EditableWorksheetTab,
|
|
2561
3397
|
{
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
),
|
|
2570
|
-
children: sheet.name
|
|
3398
|
+
session,
|
|
3399
|
+
sheet,
|
|
3400
|
+
sheets,
|
|
3401
|
+
selected: sheet.sheetId === activeSheet?.sheetId,
|
|
3402
|
+
writable,
|
|
3403
|
+
onSelect: () => setActiveSheetId(sheet.sheetId),
|
|
3404
|
+
onCommandError: gridProps.onCommandError
|
|
2571
3405
|
},
|
|
2572
3406
|
`${sheet.sheetId}:${sheet.generationId ?? "pending"}`
|
|
2573
3407
|
)),
|
|
2574
|
-
writable && allowAddSheet ? /* @__PURE__ */
|
|
3408
|
+
writable && allowAddSheet ? /* @__PURE__ */ jsx5(
|
|
2575
3409
|
"button",
|
|
2576
3410
|
{
|
|
2577
3411
|
type: "button",
|
|
@@ -2579,29 +3413,33 @@ function EditableSpreadsheetArtifactSurface({
|
|
|
2579
3413
|
disabled: creatingSheet,
|
|
2580
3414
|
"aria-label": creatingSheet ? "Adding worksheet" : "Add worksheet",
|
|
2581
3415
|
className: "grid size-7 shrink-0 place-items-center rounded-og-sm text-og-fg-muted outline-hidden hover:bg-og-surface-3 hover:text-og-fg focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50 [&>svg]:size-3.5",
|
|
2582
|
-
children: /* @__PURE__ */
|
|
3416
|
+
children: /* @__PURE__ */ jsx5(PlusIcon2, {})
|
|
2583
3417
|
}
|
|
2584
3418
|
) : null
|
|
2585
3419
|
]
|
|
2586
3420
|
}
|
|
2587
3421
|
);
|
|
2588
3422
|
const error = surfaceError ?? metadataError;
|
|
2589
|
-
return /* @__PURE__ */
|
|
3423
|
+
return /* @__PURE__ */ jsx5(
|
|
2590
3424
|
ArtifactSurface,
|
|
2591
3425
|
{
|
|
2592
3426
|
modality: "spreadsheet",
|
|
2593
3427
|
title,
|
|
3428
|
+
showHeader,
|
|
2594
3429
|
subtitle: subtitle ?? (accessRevoked ? editableArtifactStatusLabel(view) : metadata ? `${sheets.length} sheet${sheets.length === 1 ? "" : "s"}` : editableArtifactStatusLabel(view)),
|
|
2595
|
-
actions,
|
|
3430
|
+
actions: download ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3431
|
+
actions,
|
|
3432
|
+
/* @__PURE__ */ jsx5(SpreadsheetDownloadButton, { session, title, download })
|
|
3433
|
+
] }) : actions,
|
|
2596
3434
|
footer: accessRevoked ? void 0 : footer,
|
|
2597
3435
|
busy: !accessRevoked && !metadata && !error,
|
|
2598
|
-
children: accessRevoked ? /* @__PURE__ */
|
|
3436
|
+
children: accessRevoked ? /* @__PURE__ */ jsx5(
|
|
2599
3437
|
EditableArtifactMessage,
|
|
2600
3438
|
{
|
|
2601
3439
|
title: "Access changed",
|
|
2602
3440
|
detail: editableArtifactStatusLabel(view)
|
|
2603
3441
|
}
|
|
2604
|
-
) : activeSheet && metadata ? /* @__PURE__ */
|
|
3442
|
+
) : activeSheet && metadata ? /* @__PURE__ */ jsx5(
|
|
2605
3443
|
EditableSpreadsheetGrid,
|
|
2606
3444
|
{
|
|
2607
3445
|
...gridProps,
|
|
@@ -2611,19 +3449,19 @@ function EditableSpreadsheetArtifactSurface({
|
|
|
2611
3449
|
readOnly: !writable
|
|
2612
3450
|
},
|
|
2613
3451
|
`${activeSheet.sheetId}:${activeSheet.generationId ?? "pending"}`
|
|
2614
|
-
) : error ? /* @__PURE__ */
|
|
2615
|
-
/* @__PURE__ */
|
|
2616
|
-
writable && allowAddSheet ? /* @__PURE__ */
|
|
3452
|
+
) : error ? /* @__PURE__ */ jsx5(EditableArtifactMessage, { title: "Could not open this workbook", detail: error.message }) : metadata ? /* @__PURE__ */ jsx5("div", { className: "grid h-full place-items-center bg-og-bg p-6 text-center", children: /* @__PURE__ */ jsxs3("div", { children: [
|
|
3453
|
+
/* @__PURE__ */ jsx5("p", { className: "text-og-base font-medium text-og-fg", children: "This workbook has no worksheets." }),
|
|
3454
|
+
writable && allowAddSheet ? /* @__PURE__ */ jsx5(
|
|
2617
3455
|
"button",
|
|
2618
3456
|
{
|
|
2619
3457
|
type: "button",
|
|
2620
3458
|
onClick: () => void addSheet(),
|
|
2621
3459
|
disabled: creatingSheet,
|
|
2622
|
-
className: "mt-3 rounded-og-sm bg-og-
|
|
3460
|
+
className: "mt-3 rounded-og-sm border border-og-primary-border bg-og-primary text-og-primary-fg px-3 py-1.5 text-og-sm font-medium hover:bg-og-primary-hover outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50",
|
|
2623
3461
|
children: creatingSheet ? "Adding\u2026" : "Add worksheet"
|
|
2624
3462
|
}
|
|
2625
3463
|
) : null
|
|
2626
|
-
] }) }) : /* @__PURE__ */
|
|
3464
|
+
] }) }) : /* @__PURE__ */ jsx5(
|
|
2627
3465
|
EditableArtifactMessage,
|
|
2628
3466
|
{
|
|
2629
3467
|
title: "Opening workbook",
|
|
@@ -2633,18 +3471,272 @@ function EditableSpreadsheetArtifactSurface({
|
|
|
2633
3471
|
}
|
|
2634
3472
|
);
|
|
2635
3473
|
}
|
|
2636
|
-
function
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
3474
|
+
function EditableWorksheetTab({
|
|
3475
|
+
session,
|
|
3476
|
+
sheet,
|
|
3477
|
+
sheets,
|
|
3478
|
+
selected,
|
|
3479
|
+
writable,
|
|
3480
|
+
onSelect,
|
|
3481
|
+
onCommandError
|
|
3482
|
+
}) {
|
|
3483
|
+
const submissions = useSpreadsheetSubmissions();
|
|
3484
|
+
const [editing, setEditing] = useState6(false);
|
|
3485
|
+
const [name, setName] = useState6(sheet.name);
|
|
3486
|
+
const [saving, setSaving] = useState6(false);
|
|
3487
|
+
const [accepted, setAccepted] = useState6(false);
|
|
3488
|
+
const [error, setError] = useState6(null);
|
|
3489
|
+
const inputRef = useRef5(null);
|
|
3490
|
+
const tabRef = useRef5(null);
|
|
3491
|
+
const busyRef = useRef5(false);
|
|
3492
|
+
const mountedRef = useRef5(true);
|
|
3493
|
+
const latestRef = useRef5({ session, sheet, writable });
|
|
3494
|
+
latestRef.current = { session, sheet, writable };
|
|
3495
|
+
const errorId = useId2();
|
|
3496
|
+
const canRename = writable && sheet.generationId !== null;
|
|
3497
|
+
const scopeRef = useRef5({
|
|
3498
|
+
session,
|
|
3499
|
+
sheetId: sheet.sheetId,
|
|
3500
|
+
generationId: sheet.generationId,
|
|
3501
|
+
canRename
|
|
3502
|
+
});
|
|
3503
|
+
if (scopeRef.current.session !== session || scopeRef.current.sheetId !== sheet.sheetId || scopeRef.current.generationId !== sheet.generationId || scopeRef.current.canRename !== canRename) {
|
|
3504
|
+
scopeRef.current = {
|
|
3505
|
+
session,
|
|
3506
|
+
sheetId: sheet.sheetId,
|
|
3507
|
+
generationId: sheet.generationId,
|
|
3508
|
+
canRename
|
|
3509
|
+
};
|
|
3510
|
+
}
|
|
3511
|
+
useEffect5(() => {
|
|
3512
|
+
mountedRef.current = true;
|
|
3513
|
+
return () => {
|
|
3514
|
+
mountedRef.current = false;
|
|
3515
|
+
};
|
|
3516
|
+
}, []);
|
|
3517
|
+
useEffect5(() => {
|
|
3518
|
+
setEditing(false);
|
|
3519
|
+
setSaving(false);
|
|
3520
|
+
setAccepted(false);
|
|
3521
|
+
setError(null);
|
|
3522
|
+
busyRef.current = false;
|
|
3523
|
+
}, [session, sheet.generationId, sheet.sheetId, canRename]);
|
|
3524
|
+
useEffect5(() => {
|
|
3525
|
+
if (!editing) return;
|
|
3526
|
+
inputRef.current?.focus();
|
|
3527
|
+
inputRef.current?.select();
|
|
3528
|
+
}, [editing]);
|
|
3529
|
+
useEffect5(() => {
|
|
3530
|
+
if (!accepted || !editing || sheet.name !== name) return;
|
|
3531
|
+
const restoreFocus = document.activeElement === document.body || document.activeElement === inputRef.current;
|
|
3532
|
+
setEditing(false);
|
|
3533
|
+
setSaving(false);
|
|
3534
|
+
setAccepted(false);
|
|
3535
|
+
busyRef.current = false;
|
|
3536
|
+
if (restoreFocus) queueMicrotask(() => tabRef.current?.focus({ preventScroll: true }));
|
|
3537
|
+
}, [accepted, editing, name, sheet.name]);
|
|
3538
|
+
const start = () => {
|
|
3539
|
+
if (!canRename || busyRef.current) return;
|
|
3540
|
+
onSelect();
|
|
3541
|
+
setName(sheet.name);
|
|
3542
|
+
setError(null);
|
|
3543
|
+
setAccepted(false);
|
|
3544
|
+
setEditing(true);
|
|
3545
|
+
};
|
|
3546
|
+
const cancel = () => {
|
|
3547
|
+
if (busyRef.current) return;
|
|
3548
|
+
setEditing(false);
|
|
3549
|
+
setError(null);
|
|
3550
|
+
queueMicrotask(() => tabRef.current?.focus({ preventScroll: true }));
|
|
3551
|
+
};
|
|
3552
|
+
const rename = async () => {
|
|
3553
|
+
if (!canRename || busyRef.current) return;
|
|
3554
|
+
const generation = sheetGeneration(sheet);
|
|
3555
|
+
if (!generation) return;
|
|
3556
|
+
const next = name.trim();
|
|
3557
|
+
if (!next || next.length > 31 || /[\\/?*[\]:\0]/u.test(next)) {
|
|
3558
|
+
setError("Use 1\u201331 characters without \\ / ? * [ ] :.");
|
|
3559
|
+
return;
|
|
3560
|
+
}
|
|
3561
|
+
if (sheets.some((other) => other.sheetId !== sheet.sheetId && other.name === next)) {
|
|
3562
|
+
setError("A worksheet already has this name.");
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
if (next === sheet.name) {
|
|
3566
|
+
cancel();
|
|
3567
|
+
return;
|
|
3568
|
+
}
|
|
3569
|
+
setName(next);
|
|
3570
|
+
setError(null);
|
|
3571
|
+
setSaving(true);
|
|
3572
|
+
busyRef.current = true;
|
|
3573
|
+
const scope = scopeRef.current;
|
|
3574
|
+
const current = () => mountedRef.current && scopeRef.current === scope && latestRef.current.writable;
|
|
3575
|
+
try {
|
|
3576
|
+
await submissions.run(
|
|
3577
|
+
() => session.applySpreadsheetCommands({
|
|
3578
|
+
version: SPREADSHEET_ARTIFACT_COMMAND_VERSION,
|
|
3579
|
+
commands: [{ kind: "sheet.rename", sheet: generation, name: next }]
|
|
3580
|
+
})
|
|
3581
|
+
);
|
|
3582
|
+
if (current()) setAccepted(true);
|
|
3583
|
+
} catch (cause) {
|
|
3584
|
+
if (!current()) return;
|
|
3585
|
+
const failure = asError(cause);
|
|
3586
|
+
busyRef.current = false;
|
|
3587
|
+
setSaving(false);
|
|
3588
|
+
setError(failure.message || "Could not rename worksheet. Try again.");
|
|
3589
|
+
onCommandError?.(failure);
|
|
3590
|
+
queueMicrotask(() => inputRef.current?.focus());
|
|
3591
|
+
}
|
|
3592
|
+
};
|
|
3593
|
+
const tab = /* @__PURE__ */ jsx5(
|
|
3594
|
+
"button",
|
|
3595
|
+
{
|
|
3596
|
+
ref: tabRef,
|
|
3597
|
+
type: "button",
|
|
3598
|
+
role: "tab",
|
|
3599
|
+
tabIndex: editing && canRename ? -1 : void 0,
|
|
3600
|
+
"aria-selected": selected,
|
|
3601
|
+
"aria-keyshortcuts": canRename ? "F2" : void 0,
|
|
3602
|
+
title: canRename ? "Double-click or press F2 to rename" : void 0,
|
|
3603
|
+
onClick: onSelect,
|
|
3604
|
+
onDoubleClick: start,
|
|
3605
|
+
onKeyDown: (event) => {
|
|
3606
|
+
if (event.key === "F2") {
|
|
3607
|
+
event.preventDefault();
|
|
3608
|
+
start();
|
|
3609
|
+
}
|
|
3610
|
+
},
|
|
3611
|
+
className: cn(
|
|
3612
|
+
"h-7 shrink-0 rounded-og-sm px-2.5 text-og-sm outline-hidden transition-colors focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
3613
|
+
selected ? "bg-og-surface-3 font-medium text-og-fg" : "text-og-fg-muted hover:bg-og-surface-3 hover:text-og-fg"
|
|
3614
|
+
),
|
|
3615
|
+
children: sheet.name
|
|
3616
|
+
}
|
|
2643
3617
|
);
|
|
2644
|
-
return
|
|
3618
|
+
return editing && canRename ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3619
|
+
/* @__PURE__ */ jsx5("span", { className: "sr-only", children: tab }),
|
|
3620
|
+
/* @__PURE__ */ jsxs3(
|
|
3621
|
+
"form",
|
|
3622
|
+
{
|
|
3623
|
+
className: "flex min-w-0 flex-wrap items-center gap-1 py-1",
|
|
3624
|
+
style: { width: "min(18rem, 100%)" },
|
|
3625
|
+
onSubmit: (event) => {
|
|
3626
|
+
event.preventDefault();
|
|
3627
|
+
void rename();
|
|
3628
|
+
},
|
|
3629
|
+
children: [
|
|
3630
|
+
/* @__PURE__ */ jsx5(
|
|
3631
|
+
"input",
|
|
3632
|
+
{
|
|
3633
|
+
ref: inputRef,
|
|
3634
|
+
"aria-label": "Worksheet name",
|
|
3635
|
+
"aria-invalid": error ? "true" : void 0,
|
|
3636
|
+
"aria-describedby": error ? errorId : void 0,
|
|
3637
|
+
disabled: saving,
|
|
3638
|
+
value: name,
|
|
3639
|
+
onInput: (event) => {
|
|
3640
|
+
setName(event.currentTarget.value);
|
|
3641
|
+
setError(null);
|
|
3642
|
+
},
|
|
3643
|
+
onKeyDown: (event) => {
|
|
3644
|
+
if (event.nativeEvent.isComposing || event.keyCode === 229) return;
|
|
3645
|
+
if (event.key === "Escape") {
|
|
3646
|
+
event.preventDefault();
|
|
3647
|
+
cancel();
|
|
3648
|
+
}
|
|
3649
|
+
if (event.key === "Enter") {
|
|
3650
|
+
event.preventDefault();
|
|
3651
|
+
void rename();
|
|
3652
|
+
}
|
|
3653
|
+
},
|
|
3654
|
+
className: "h-7 w-40 rounded-og-sm border border-og-border bg-og-surface-1 px-2 text-og-sm text-og-fg outline-hidden focus-visible:ring-2 focus-visible:ring-og-accent disabled:opacity-50"
|
|
3655
|
+
}
|
|
3656
|
+
),
|
|
3657
|
+
saving ? /* @__PURE__ */ jsx5("span", { role: "status", className: "text-og-xs text-og-fg-muted", children: "Renaming\u2026" }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
3658
|
+
/* @__PURE__ */ jsx5(
|
|
3659
|
+
"button",
|
|
3660
|
+
{
|
|
3661
|
+
type: "submit",
|
|
3662
|
+
className: "rounded-og-sm px-2 py-1 text-og-xs text-og-fg outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
3663
|
+
children: "Save"
|
|
3664
|
+
}
|
|
3665
|
+
),
|
|
3666
|
+
/* @__PURE__ */ jsx5(
|
|
3667
|
+
"button",
|
|
3668
|
+
{
|
|
3669
|
+
type: "button",
|
|
3670
|
+
onClick: cancel,
|
|
3671
|
+
className: "rounded-og-sm px-2 py-1 text-og-xs text-og-fg-muted outline-hidden hover:bg-og-surface-3 focus-visible:ring-2 focus-visible:ring-og-accent",
|
|
3672
|
+
children: "Cancel"
|
|
3673
|
+
}
|
|
3674
|
+
)
|
|
3675
|
+
] }),
|
|
3676
|
+
error ? /* @__PURE__ */ jsx5(
|
|
3677
|
+
"span",
|
|
3678
|
+
{
|
|
3679
|
+
id: errorId,
|
|
3680
|
+
role: "alert",
|
|
3681
|
+
className: "text-og-xs text-og-status-failed",
|
|
3682
|
+
style: { flexBasis: "100%", overflowWrap: "anywhere" },
|
|
3683
|
+
children: error
|
|
3684
|
+
}
|
|
3685
|
+
) : null
|
|
3686
|
+
]
|
|
3687
|
+
}
|
|
3688
|
+
)
|
|
3689
|
+
] }) : tab;
|
|
3690
|
+
}
|
|
3691
|
+
function spreadsheetSessionKey(session) {
|
|
3692
|
+
let key = SESSION_KEYS.get(session);
|
|
3693
|
+
if (key === void 0) {
|
|
3694
|
+
key = ++nextSessionKey;
|
|
3695
|
+
SESSION_KEYS.set(session, key);
|
|
3696
|
+
}
|
|
3697
|
+
return key;
|
|
3698
|
+
}
|
|
3699
|
+
function useSpreadsheetAuthoringLifetime() {
|
|
3700
|
+
const lifetime = useRef5({});
|
|
3701
|
+
useClientLayoutEffect2(() => {
|
|
3702
|
+
lifetime.current = {};
|
|
3703
|
+
return () => {
|
|
3704
|
+
lifetime.current = null;
|
|
3705
|
+
};
|
|
3706
|
+
}, []);
|
|
3707
|
+
return lifetime;
|
|
3708
|
+
}
|
|
3709
|
+
function requireSpreadsheetAuthoringLifetime(lifetime) {
|
|
3710
|
+
if (!lifetime.current) throw new Error("Spreadsheet authoring session changed");
|
|
3711
|
+
return lifetime.current;
|
|
3712
|
+
}
|
|
3713
|
+
function useSpreadsheetMetadata(session) {
|
|
3714
|
+
const [state, setState] = useState6({ session, metadata: null, error: null });
|
|
3715
|
+
useEffect5(() => {
|
|
3716
|
+
let active = true;
|
|
3717
|
+
const unsubscribe = session.subscribeSpreadsheetMetadata(
|
|
3718
|
+
{},
|
|
3719
|
+
(metadata) => {
|
|
3720
|
+
if (active) setState({ session, metadata, error: null });
|
|
3721
|
+
},
|
|
3722
|
+
{
|
|
3723
|
+
onError: (error) => {
|
|
3724
|
+
if (active)
|
|
3725
|
+
setState(
|
|
3726
|
+
(current) => current.session === session ? { ...current, error } : { session, metadata: null, error }
|
|
3727
|
+
);
|
|
3728
|
+
}
|
|
3729
|
+
}
|
|
3730
|
+
);
|
|
3731
|
+
return () => {
|
|
3732
|
+
active = false;
|
|
3733
|
+
unsubscribe();
|
|
3734
|
+
};
|
|
3735
|
+
}, [session]);
|
|
3736
|
+
return state.session === session ? state : { metadata: null, error: null };
|
|
2645
3737
|
}
|
|
2646
3738
|
function projectSdkViewport(sheet, metadataRevision, query, viewport, rowCount, columnCount) {
|
|
2647
|
-
const current = viewport &&
|
|
3739
|
+
const current = viewport && viewport.sheetId === sheet.sheetId && viewport.generationId === sheet.generationId ? viewport : null;
|
|
2648
3740
|
const projectedCells = (current?.cells ?? []).map((cell) => ({
|
|
2649
3741
|
row: cell.row,
|
|
2650
3742
|
col: cell.column,
|
|
@@ -2661,8 +3753,12 @@ function projectSdkViewport(sheet, metadataRevision, query, viewport, rowCount,
|
|
|
2661
3753
|
sheetId: sheet.sheetId,
|
|
2662
3754
|
sheetName: sheet.name,
|
|
2663
3755
|
generationId: current?.generationId ?? sheet.generationId,
|
|
2664
|
-
revision:
|
|
3756
|
+
revision: current?.revision.toString() ?? "loading",
|
|
2665
3757
|
dimensionRevision: metadataRevision.toString(),
|
|
3758
|
+
defaultRowHeight: sheet.defaultRowHeight,
|
|
3759
|
+
defaultColumnWidth: sheet.defaultColumnWidth,
|
|
3760
|
+
rowHeights: sheet.rowHeights,
|
|
3761
|
+
columnWidths: sheet.columnWidths,
|
|
2666
3762
|
rowCount,
|
|
2667
3763
|
columnCount,
|
|
2668
3764
|
usedRange: used ? {
|
|
@@ -2688,7 +3784,7 @@ function projectSdkViewport(sheet, metadataRevision, query, viewport, rowCount,
|
|
|
2688
3784
|
const cell = byCoordinate.get(`${row}:${column}`);
|
|
2689
3785
|
return cell ? {
|
|
2690
3786
|
value: cell.value,
|
|
2691
|
-
input: cell.formula ??
|
|
3787
|
+
input: cell.formula ?? displayValue(cell.value),
|
|
2692
3788
|
format: cell.format
|
|
2693
3789
|
} : null;
|
|
2694
3790
|
}
|
|
@@ -2799,7 +3895,7 @@ function boundedSheetCount(requested, maximum, usedEnd) {
|
|
|
2799
3895
|
const usedCount = usedEnd === void 0 || !Number.isSafeInteger(usedEnd) ? 1 : Math.max(1, Math.min(maximum, usedEnd + 1));
|
|
2800
3896
|
return Math.max(requestedCount, usedCount);
|
|
2801
3897
|
}
|
|
2802
|
-
function
|
|
3898
|
+
function displayValue(value) {
|
|
2803
3899
|
if (value === null || value === void 0) return "";
|
|
2804
3900
|
if (value instanceof Date) return Number.isNaN(value.getTime()) ? "" : value.toISOString();
|
|
2805
3901
|
if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
|
|
@@ -2825,4 +3921,4 @@ export {
|
|
|
2825
3921
|
EditableSpreadsheetGrid,
|
|
2826
3922
|
EditableSpreadsheetArtifactSurface
|
|
2827
3923
|
};
|
|
2828
|
-
//# sourceMappingURL=chunk-
|
|
3924
|
+
//# sourceMappingURL=chunk-WNN7NO2N.js.map
|