@casualoffice/sheets 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/api-BI2VLYQ6.d.cts +62 -0
  2. package/dist/api-BI2VLYQ6.d.ts +62 -0
  3. package/dist/chrome.cjs +2569 -0
  4. package/dist/chrome.cjs.map +1 -0
  5. package/dist/chrome.d.cts +96 -0
  6. package/dist/chrome.d.ts +96 -0
  7. package/dist/chrome.js +2556 -0
  8. package/dist/chrome.js.map +1 -0
  9. package/dist/collab.cjs +770 -0
  10. package/dist/collab.cjs.map +1 -0
  11. package/dist/collab.d.cts +248 -0
  12. package/dist/collab.d.ts +248 -0
  13. package/dist/collab.js +737 -0
  14. package/dist/collab.js.map +1 -0
  15. package/dist/embed/embed-runtime.js +128 -128
  16. package/dist/embed.cjs +166 -0
  17. package/dist/embed.cjs.map +1 -1
  18. package/dist/embed.d.cts +78 -3
  19. package/dist/embed.d.ts +78 -3
  20. package/dist/embed.js +166 -0
  21. package/dist/embed.js.map +1 -1
  22. package/dist/index.cjs +262 -165
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +4 -3
  25. package/dist/index.d.ts +4 -3
  26. package/dist/index.js +271 -168
  27. package/dist/index.js.map +1 -1
  28. package/dist/{protocol--KyBQUjU.d.cts → protocol-Cq4Cdoyi.d.cts} +19 -2
  29. package/dist/{protocol-cEzy7S0i.d.ts → protocol-DqDaG2yG.d.ts} +19 -2
  30. package/dist/sheets.cjs +102 -16
  31. package/dist/sheets.cjs.map +1 -1
  32. package/dist/sheets.d.cts +49 -63
  33. package/dist/sheets.d.ts +49 -63
  34. package/dist/sheets.js +111 -19
  35. package/dist/sheets.js.map +1 -1
  36. package/package.json +28 -3
  37. package/src/chrome/AutoSumPicker.tsx +176 -0
  38. package/src/chrome/BordersPicker.tsx +171 -0
  39. package/src/chrome/ChromeBottom.tsx +18 -0
  40. package/src/chrome/ChromeTop.tsx +21 -0
  41. package/src/chrome/ColorPicker.tsx +220 -0
  42. package/src/chrome/FindReplace.tsx +370 -0
  43. package/src/chrome/FormulaBar.tsx +378 -0
  44. package/src/chrome/Icon.tsx +43 -0
  45. package/src/chrome/MenuBar.tsx +336 -0
  46. package/src/chrome/NameBox.tsx +347 -0
  47. package/src/chrome/SheetTabs.tsx +346 -0
  48. package/src/chrome/StatusBar.tsx +232 -0
  49. package/src/chrome/Toolbar.tsx +401 -0
  50. package/src/chrome/fonts.ts +42 -0
  51. package/src/chrome/index.ts +24 -0
  52. package/src/collab/attachCollab.ts +151 -0
  53. package/src/collab/bridge-helpers.ts +97 -0
  54. package/src/collab/bridge.ts +885 -0
  55. package/src/collab/bridge.unit.test.ts +160 -0
  56. package/src/collab/index.ts +38 -0
  57. package/src/collab/replay-retry.ts +137 -0
  58. package/src/collab/replay-retry.unit.test.ts +223 -0
  59. package/src/collab/ws-url.ts +20 -0
  60. package/src/collab/ws-url.unit.test.ts +35 -0
  61. package/src/embed/EmbedHostTransport.ts +16 -1
  62. package/src/embed/EmbedTransport.ts +16 -0
  63. package/src/embed/EmbedTransport.unit.test.ts +88 -2
  64. package/src/embed/index.ts +7 -0
  65. package/src/embed/protocol.ts +34 -0
  66. package/src/embed-runtime/index.tsx +20 -0
  67. package/src/sheets/CasualSheets.tsx +204 -33
package/dist/index.d.cts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { CapturedSignature, DrawnSignaturePad, DrawnSignaturePadProps, SigningController, SigningPane, SigningPaneProps, SigningProvider, SigningProviderProps, SigningSnapshot, TypedSignatureField, TypedSignatureFieldProps, UploadedSignatureField, UploadedSignatureFieldProps, createSigningController, useSigning } from './signing.cjs';
2
2
  export { C as CancelReason, D as DocAnchor, S as SheetAnchor, a as SignatureAnchor, b as SignatureCompletePayload, c as SignatureField, d as SignatureMethod, e as SignatureMode, f as SignedFieldPayload, g as SigningSessionConfig } from './types-s_O0u6Cg.cjs';
3
- export { EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions } from './embed.cjs';
4
- export { C as CasualApp, a as CasualEnvelope, d as CommandSetLocaleData, e as CommandSetReadOnlyData, f as CommandSetThemeData, E as EditorHelloData, H as HostHelloData, L as LoadRequestData, h as LoadResponseData, i as LoadResponseDataErr, j as LoadResponseDataOk, k as LockLostData, S as SaveRequestData, l as SaveResponseData, m as SaveResponseDataErr, n as SaveResponseDataOk, o as SelectionChangedData, q as SignatureCancelData, r as SignatureCompleteData, s as SignatureFieldSignedData, t as SignatureRequestAckData, u as SignatureRequestData, T as TelemetryEventData, v as isCasualEnvelope } from './protocol--KyBQUjU.cjs';
5
- export { CasualSheets, CasualSheetsAPI, CasualSheetsIframe, CasualSheetsIframeProps, CasualSheetsIframeRef, CasualSheetsProps, HostFileBridge, RangeRef, createCasualSheetsAPI } from './sheets.cjs';
3
+ export { EmbedHostHandlers, EmbedHostTransport, EmbedHostTransportOptions, EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions } from './embed.cjs';
4
+ export { C as CasualApp, a as CasualEnvelope, d as CommandSetLocaleData, e as CommandSetReadOnlyData, f as CommandSetThemeData, E as EditorHelloData, h as ExitData, H as HostHelloData, L as LoadRequestData, i as LoadResponseData, j as LoadResponseDataErr, k as LoadResponseDataOk, l as LockLostData, S as SaveNotifyData, m as SaveRequestData, n as SaveResponseData, o as SaveResponseDataErr, p as SaveResponseDataOk, q as SelectionChangedData, s as SignatureCancelData, t as SignatureCompleteData, u as SignatureFieldSignedData, v as SignatureRequestAckData, w as SignatureRequestData, T as TelemetryEventData, x as isCasualEnvelope } from './protocol-Cq4Cdoyi.cjs';
5
+ export { CasualSheets, CasualSheetsIframe, CasualSheetsIframeProps, CasualSheetsIframeRef, CasualSheetsProps, HostFileBridge } from './sheets.cjs';
6
+ export { C as CasualSheetsAPI, R as RangeRef, c as createCasualSheetsAPI } from './api-BI2VLYQ6.cjs';
6
7
  import 'react';
7
8
  import '@univerjs/core';
8
9
  import '@univerjs/themes';
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { CapturedSignature, DrawnSignaturePad, DrawnSignaturePadProps, SigningController, SigningPane, SigningPaneProps, SigningProvider, SigningProviderProps, SigningSnapshot, TypedSignatureField, TypedSignatureFieldProps, UploadedSignatureField, UploadedSignatureFieldProps, createSigningController, useSigning } from './signing.js';
2
2
  export { C as CancelReason, D as DocAnchor, S as SheetAnchor, a as SignatureAnchor, b as SignatureCompletePayload, c as SignatureField, d as SignatureMethod, e as SignatureMode, f as SignedFieldPayload, g as SigningSessionConfig } from './types-s_O0u6Cg.js';
3
- export { EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions } from './embed.js';
4
- export { C as CasualApp, a as CasualEnvelope, d as CommandSetLocaleData, e as CommandSetReadOnlyData, f as CommandSetThemeData, E as EditorHelloData, H as HostHelloData, L as LoadRequestData, h as LoadResponseData, i as LoadResponseDataErr, j as LoadResponseDataOk, k as LockLostData, S as SaveRequestData, l as SaveResponseData, m as SaveResponseDataErr, n as SaveResponseDataOk, o as SelectionChangedData, q as SignatureCancelData, r as SignatureCompleteData, s as SignatureFieldSignedData, t as SignatureRequestAckData, u as SignatureRequestData, T as TelemetryEventData, v as isCasualEnvelope } from './protocol-cEzy7S0i.js';
5
- export { CasualSheets, CasualSheetsAPI, CasualSheetsIframe, CasualSheetsIframeProps, CasualSheetsIframeRef, CasualSheetsProps, HostFileBridge, RangeRef, createCasualSheetsAPI } from './sheets.js';
3
+ export { EmbedHostHandlers, EmbedHostTransport, EmbedHostTransportOptions, EmbedTransport, EmbedTransportHandlers, EmbedTransportOptions } from './embed.js';
4
+ export { C as CasualApp, a as CasualEnvelope, d as CommandSetLocaleData, e as CommandSetReadOnlyData, f as CommandSetThemeData, E as EditorHelloData, h as ExitData, H as HostHelloData, L as LoadRequestData, i as LoadResponseData, j as LoadResponseDataErr, k as LoadResponseDataOk, l as LockLostData, S as SaveNotifyData, m as SaveRequestData, n as SaveResponseData, o as SaveResponseDataErr, p as SaveResponseDataOk, q as SelectionChangedData, s as SignatureCancelData, t as SignatureCompleteData, u as SignatureFieldSignedData, v as SignatureRequestAckData, w as SignatureRequestData, T as TelemetryEventData, x as isCasualEnvelope } from './protocol-DqDaG2yG.js';
5
+ export { CasualSheets, CasualSheetsIframe, CasualSheetsIframeProps, CasualSheetsIframeRef, CasualSheetsProps, HostFileBridge } from './sheets.js';
6
+ export { C as CasualSheetsAPI, R as RangeRef, c as createCasualSheetsAPI } from './api-BI2VLYQ6.js';
6
7
  import 'react';
7
8
  import '@univerjs/core';
8
9
  import '@univerjs/themes';
package/dist/index.js CHANGED
@@ -730,6 +730,18 @@ var EmbedTransport = class {
730
730
  async requestSave(req, timeoutMs = 3e4) {
731
731
  return this.request("casual.save.request", req, timeoutMs, [req.bytes]);
732
732
  }
733
+ /** Editor → Host: the user asked to save (Ctrl/Cmd+S or a host save
734
+ * command). Fire-and-forget snapshot notification — the lightweight
735
+ * mirror of the React `onSave` hook. The host persists however it
736
+ * likes; no response is awaited. */
737
+ sendSaveNotify(data) {
738
+ this.post("casual.save.notify", data);
739
+ }
740
+ /** Editor → Host: the editor is unmounting. Carries the final snapshot
741
+ * so the host can persist on exit. Mirror of the React `onExit` hook. */
742
+ sendExit(data) {
743
+ this.post("casual.exit", data);
744
+ }
733
745
  /** Editor → Host: selection moved. Fire-and-forget. */
734
746
  sendSelectionChanged(data) {
735
747
  this.post("casual.selection.changed", data);
@@ -872,8 +884,167 @@ function newRequestId() {
872
884
  return Math.random().toString(16).slice(2, 10);
873
885
  }
874
886
 
887
+ // src/embed/EmbedHostTransport.ts
888
+ var EmbedHostTransport = class {
889
+ constructor(opts) {
890
+ __publicField(this, "opts");
891
+ __publicField(this, "handlers", {});
892
+ __publicField(this, "boundOnMessage");
893
+ __publicField(this, "destroyed", false);
894
+ this.opts = opts;
895
+ this.boundOnMessage = this.onMessage.bind(this);
896
+ const target = opts.hostWindow ?? window;
897
+ target.addEventListener("message", this.boundOnMessage);
898
+ }
899
+ on(handlers) {
900
+ this.handlers = { ...this.handlers, ...handlers };
901
+ }
902
+ destroy() {
903
+ if (this.destroyed) return;
904
+ this.destroyed = true;
905
+ const target = this.opts.hostWindow ?? window;
906
+ target.removeEventListener("message", this.boundOnMessage);
907
+ }
908
+ sendHostHello(data) {
909
+ this.post("casual.hello", data);
910
+ }
911
+ sendSetViewMode(data) {
912
+ this.post("casual.command.set.viewmode", data);
913
+ }
914
+ sendSetReadOnly(data) {
915
+ this.post("casual.command.set.readonly", data);
916
+ }
917
+ sendSetTheme(data) {
918
+ this.post("casual.command.set.theme", data);
919
+ }
920
+ sendSetLocale(data) {
921
+ this.post("casual.command.set.locale", data);
922
+ }
923
+ sendCommandSave() {
924
+ this.post("casual.command.save", null);
925
+ }
926
+ sendCommandFocus() {
927
+ this.post("casual.command.focus", null);
928
+ }
929
+ /** Host → Editor: run a formatting / navigation command (bold,
930
+ * italic, undo, …) against the active selection. v0.6+. */
931
+ sendCommandExecute(data) {
932
+ this.post("casual.command.execute", data);
933
+ }
934
+ sendSignatureRequest(id, data) {
935
+ this.post("casual.signature.request", data, id);
936
+ }
937
+ sendSignatureCancel(data) {
938
+ this.post("casual.signature.cancel", data);
939
+ }
940
+ onMessage(ev) {
941
+ if (this.destroyed) return;
942
+ if (ev.origin !== this.opts.embedOrigin) return;
943
+ if (ev.source !== this.opts.iframeWindow) return;
944
+ if (!isCasualEnvelope(ev.data)) return;
945
+ if (ev.data.app !== this.opts.app) return;
946
+ void this.dispatch(ev.data);
947
+ }
948
+ async dispatch(env) {
949
+ switch (env.type) {
950
+ case "casual.ready":
951
+ this.handlers.onEditorReady?.(env.data);
952
+ return;
953
+ case "casual.load.request": {
954
+ if (!this.handlers.onLoadRequest) return;
955
+ const id = env.id ?? "";
956
+ try {
957
+ const resp = await this.handlers.onLoadRequest(env.data);
958
+ const transfer = resp.ok ? [resp.bytes] : [];
959
+ this.post("casual.load.response", resp, id, transfer);
960
+ } catch (err) {
961
+ this.post(
962
+ "casual.load.response",
963
+ {
964
+ ok: false,
965
+ code: "host_error",
966
+ message: err instanceof Error ? err.message : String(err)
967
+ },
968
+ id
969
+ );
970
+ }
971
+ return;
972
+ }
973
+ case "casual.save.request": {
974
+ if (!this.handlers.onSaveRequest) return;
975
+ const id = env.id ?? "";
976
+ try {
977
+ const resp = await this.handlers.onSaveRequest(env.data);
978
+ this.post("casual.save.response", resp, id);
979
+ } catch (err) {
980
+ this.post(
981
+ "casual.save.response",
982
+ {
983
+ ok: false,
984
+ code: "host_error",
985
+ message: err instanceof Error ? err.message : String(err)
986
+ },
987
+ id
988
+ );
989
+ }
990
+ return;
991
+ }
992
+ case "casual.save.notify":
993
+ this.handlers.onSaveNotify?.(env.data);
994
+ return;
995
+ case "casual.exit":
996
+ this.handlers.onExit?.(env.data);
997
+ return;
998
+ case "casual.selection.changed":
999
+ this.handlers.onSelectionChanged?.(env.data);
1000
+ return;
1001
+ case "casual.selection.format-state":
1002
+ this.handlers.onSelectionFormatState?.(env.data);
1003
+ return;
1004
+ case "casual.telemetry.event":
1005
+ this.handlers.onTelemetry?.(env.data);
1006
+ return;
1007
+ case "casual.signature.field.signed":
1008
+ this.handlers.onSignatureFieldSigned?.(env.data);
1009
+ return;
1010
+ case "casual.signature.complete":
1011
+ this.handlers.onSignatureComplete?.(env.data);
1012
+ return;
1013
+ case "casual.signature.cancel":
1014
+ this.handlers.onSignatureCancel?.(env.data);
1015
+ return;
1016
+ case "casual.signature.request.ack":
1017
+ return;
1018
+ case "casual.error":
1019
+ this.handlers.onError?.(env.data);
1020
+ return;
1021
+ default:
1022
+ return;
1023
+ }
1024
+ }
1025
+ post(type, data, id, transfer) {
1026
+ const env = {
1027
+ type,
1028
+ app: this.opts.app,
1029
+ v: 1,
1030
+ data,
1031
+ ...id ? { id } : {}
1032
+ };
1033
+ const send = this.opts.iframeWindow.postMessage.bind(
1034
+ this.opts.iframeWindow
1035
+ );
1036
+ send(env, this.opts.embedOrigin, transfer);
1037
+ }
1038
+ };
1039
+
875
1040
  // src/sheets/CasualSheets.tsx
876
- import { useEffect as useEffect4, useRef as useRef2 } from "react";
1041
+ import {
1042
+ lazy,
1043
+ Suspense,
1044
+ useEffect as useEffect4,
1045
+ useRef as useRef2,
1046
+ useState as useState4
1047
+ } from "react";
877
1048
  import {
878
1049
  ICommandService,
879
1050
  LocaleType,
@@ -891,7 +1062,7 @@ import { UniverDocsPlugin } from "@univerjs/docs";
891
1062
  import { UniverDocsUIPlugin } from "@univerjs/docs-ui";
892
1063
  import { UniverSheetsPlugin } from "@univerjs/sheets";
893
1064
  import { UniverSheetsUIPlugin } from "@univerjs/sheets-ui";
894
- import { UniverSheetsFormulaPlugin } from "@univerjs/sheets-formula";
1065
+ import { UniverSheetsFormulaPlugin, CalculationMode } from "@univerjs/sheets-formula";
895
1066
  import { UniverSheetsFormulaUIPlugin } from "@univerjs/sheets-formula-ui";
896
1067
  import { UniverSheetsNumfmtPlugin } from "@univerjs/sheets-numfmt";
897
1068
  import { UniverSheetsNumfmtUIPlugin } from "@univerjs/sheets-numfmt-ui";
@@ -1108,7 +1279,13 @@ function snapshotHasHyperlinks(snapshot) {
1108
1279
  }
1109
1280
 
1110
1281
  // src/sheets/CasualSheets.tsx
1111
- import { jsx as jsx4 } from "react/jsx-runtime";
1282
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
1283
+ var ChromeTop = lazy(
1284
+ () => import("@casualoffice/sheets/chrome").then((m) => ({ default: m.ChromeTop }))
1285
+ );
1286
+ var ChromeBottom = lazy(
1287
+ () => import("@casualoffice/sheets/chrome").then((m) => ({ default: m.ChromeBottom }))
1288
+ );
1112
1289
  var DEFAULT_STYLE = {
1113
1290
  width: "100%",
1114
1291
  height: "100%",
@@ -1125,13 +1302,18 @@ function CasualSheets({
1125
1302
  onReady,
1126
1303
  onChange,
1127
1304
  onChangeDebounceMs = 400,
1305
+ onSave,
1306
+ onExit,
1128
1307
  lazyPlugins = true,
1308
+ onBeforeCreateUnit,
1309
+ formula,
1129
1310
  locale = LocaleType.EN_US,
1130
1311
  locales,
1131
1312
  logLevel = LogLevel.WARN,
1132
1313
  ui,
1133
1314
  theme = defaultTheme,
1134
1315
  appearance = "light",
1316
+ chrome = "none",
1135
1317
  style,
1136
1318
  className,
1137
1319
  testId = "casual-sheets"
@@ -1140,7 +1322,12 @@ function CasualSheets({
1140
1322
  const onChangeRef = useRef2(onChange);
1141
1323
  onChangeRef.current = onChange;
1142
1324
  const hasOnChange = useRef2(!!onChange).current;
1325
+ const onSaveRef = useRef2(onSave);
1326
+ onSaveRef.current = onSave;
1327
+ const onExitRef = useRef2(onExit);
1328
+ onExitRef.current = onExit;
1143
1329
  const apiRef = useRef2(null);
1330
+ const [chromeApi, setChromeApi] = useState4(null);
1144
1331
  useEffect4(() => {
1145
1332
  const container = hostRef.current;
1146
1333
  if (!container) return;
@@ -1151,22 +1338,38 @@ function CasualSheets({
1151
1338
  logLevel
1152
1339
  });
1153
1340
  const uiOpts = { ...DEFAULT_UI, ...ui, container };
1154
- univer.registerPlugin(UniverRenderEnginePlugin);
1155
- univer.registerPlugin(UniverFormulaEnginePlugin);
1156
- univer.registerPlugin(UniverUIPlugin, uiOpts);
1157
- univer.registerPlugin(UniverDocsPlugin);
1158
- univer.registerPlugin(UniverDocsUIPlugin);
1159
- univer.registerPlugin(UniverSheetsPlugin);
1160
- univer.registerPlugin(UniverSheetsUIPlugin);
1161
- univer.registerPlugin(UniverSheetsFormulaPlugin);
1162
- univer.registerPlugin(UniverSheetsFormulaUIPlugin);
1163
- univer.registerPlugin(UniverSheetsNumfmtPlugin);
1164
- univer.registerPlugin(UniverSheetsNumfmtUIPlugin);
1165
- if (lazyPlugins) setUniverForLazyLoad(univer);
1341
+ const offMain = !!formula?.worker;
1166
1342
  let cancelled = false;
1167
1343
  let changeTimer = null;
1168
1344
  let changeSub;
1169
1345
  void (async () => {
1346
+ let RPCMainThreadPlugin = null;
1347
+ if (offMain && formula?.worker) {
1348
+ RPCMainThreadPlugin = (await import("@univerjs/rpc")).UniverRPCMainThreadPlugin;
1349
+ if (cancelled) return;
1350
+ }
1351
+ univer.registerPlugin(UniverRenderEnginePlugin);
1352
+ univer.registerPlugin(
1353
+ UniverFormulaEnginePlugin,
1354
+ offMain ? { notExecuteFormula: true } : void 0
1355
+ );
1356
+ if (RPCMainThreadPlugin && formula?.worker) {
1357
+ univer.registerPlugin(RPCMainThreadPlugin, { workerURL: formula.worker });
1358
+ }
1359
+ univer.registerPlugin(UniverUIPlugin, uiOpts);
1360
+ univer.registerPlugin(UniverDocsPlugin);
1361
+ univer.registerPlugin(UniverDocsUIPlugin);
1362
+ univer.registerPlugin(UniverSheetsPlugin, offMain ? { notExecuteFormula: true } : void 0);
1363
+ univer.registerPlugin(UniverSheetsUIPlugin);
1364
+ univer.registerPlugin(
1365
+ UniverSheetsFormulaPlugin,
1366
+ offMain ? { notExecuteFormula: true, initialFormulaComputing: CalculationMode.NO_CALCULATION } : void 0
1367
+ );
1368
+ univer.registerPlugin(UniverSheetsFormulaUIPlugin);
1369
+ univer.registerPlugin(UniverSheetsNumfmtPlugin);
1370
+ univer.registerPlugin(UniverSheetsNumfmtUIPlugin);
1371
+ if (lazyPlugins) setUniverForLazyLoad(univer);
1372
+ onBeforeCreateUnit?.(univer);
1170
1373
  if (lazyPlugins) {
1171
1374
  await eagerLoadForSnapshot(univer, initialData);
1172
1375
  if (cancelled) return;
@@ -1174,6 +1377,7 @@ function CasualSheets({
1174
1377
  univer.createUnit(UniverInstanceType.UNIVER_SHEET, initialData);
1175
1378
  const api = createCasualSheetsAPI(FUniver.newAPI(univer));
1176
1379
  apiRef.current = api;
1380
+ if (!cancelled && chrome !== "none") setChromeApi(api);
1177
1381
  applyAppearance(api, container, appearance);
1178
1382
  onReady?.(api);
1179
1383
  if (hasOnChange) {
@@ -1194,7 +1398,12 @@ function CasualSheets({
1194
1398
  cancelled = true;
1195
1399
  if (changeTimer) clearTimeout(changeTimer);
1196
1400
  changeSub?.dispose();
1401
+ if (onExitRef.current) {
1402
+ const snap = apiRef.current?.getSnapshot();
1403
+ if (snap) onExitRef.current(snap);
1404
+ }
1197
1405
  apiRef.current = null;
1406
+ setChromeApi(null);
1198
1407
  if (lazyPlugins) setUniverForLazyLoad(null);
1199
1408
  const toDispose = univer;
1200
1409
  queueMicrotask(() => toDispose.dispose());
@@ -1206,13 +1415,55 @@ function CasualSheets({
1206
1415
  if (!api || !container) return;
1207
1416
  applyAppearance(api, container, appearance);
1208
1417
  }, [appearance]);
1209
- return /* @__PURE__ */ jsx4(
1418
+ const onKeyDownCapture = (e) => {
1419
+ if ((e.metaKey || e.ctrlKey) && (e.key === "s" || e.key === "S")) {
1420
+ e.preventDefault();
1421
+ const snap = apiRef.current?.getSnapshot();
1422
+ if (snap) onSaveRef.current?.(snap);
1423
+ }
1424
+ };
1425
+ if (chrome === "none") {
1426
+ return /* @__PURE__ */ jsx4(
1427
+ "div",
1428
+ {
1429
+ ref: hostRef,
1430
+ onKeyDownCapture,
1431
+ style: { ...DEFAULT_STYLE, ...style },
1432
+ className,
1433
+ "data-testid": testId
1434
+ }
1435
+ );
1436
+ }
1437
+ const dark = appearance === "dark";
1438
+ const chromeVars = {
1439
+ "--cs-chrome-bg": dark ? "#2a2e35" : "#eef1f5",
1440
+ "--cs-chrome-fg": dark ? "#e6e6e6" : "#201f1e",
1441
+ "--cs-chrome-muted": dark ? "#b0b3ba" : "#605e5c",
1442
+ "--cs-chrome-border": dark ? "#32363d" : "#e6e9ee",
1443
+ "--cs-chrome-input-bg": dark ? "#23262c" : "#ffffff",
1444
+ "--cs-chrome-hover": dark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.06)",
1445
+ // accent (design-system #0e7490) for active toggle states.
1446
+ "--cs-chrome-active": dark ? "rgba(21,151,186,0.22)" : "#e6f3f7",
1447
+ "--cs-chrome-active-fg": dark ? "#7fd3e6" : "#0e7490"
1448
+ };
1449
+ return /* @__PURE__ */ jsxs3(
1210
1450
  "div",
1211
1451
  {
1212
- ref: hostRef,
1213
- style: { ...DEFAULT_STYLE, ...style },
1214
1452
  className,
1215
- "data-testid": testId
1453
+ "data-testid": testId,
1454
+ onKeyDownCapture,
1455
+ style: {
1456
+ ...DEFAULT_STYLE,
1457
+ ...chromeVars,
1458
+ ...style,
1459
+ display: "flex",
1460
+ flexDirection: "column"
1461
+ },
1462
+ children: [
1463
+ /* @__PURE__ */ jsx4(Suspense, { fallback: null, children: /* @__PURE__ */ jsx4(ChromeTop, { api: chromeApi }) }),
1464
+ /* @__PURE__ */ jsx4("div", { ref: hostRef, style: { flex: "1 1 auto", minHeight: 0, position: "relative" } }),
1465
+ /* @__PURE__ */ jsx4(Suspense, { fallback: null, children: /* @__PURE__ */ jsx4(ChromeBottom, { api: chromeApi }) })
1466
+ ]
1216
1467
  }
1217
1468
  );
1218
1469
  }
@@ -1234,155 +1485,6 @@ import {
1234
1485
  useEffect as useEffect5,
1235
1486
  useRef as useRef3
1236
1487
  } from "react";
1237
-
1238
- // src/embed/EmbedHostTransport.ts
1239
- var EmbedHostTransport = class {
1240
- constructor(opts) {
1241
- __publicField(this, "opts");
1242
- __publicField(this, "handlers", {});
1243
- __publicField(this, "boundOnMessage");
1244
- __publicField(this, "destroyed", false);
1245
- this.opts = opts;
1246
- this.boundOnMessage = this.onMessage.bind(this);
1247
- const target = opts.hostWindow ?? window;
1248
- target.addEventListener("message", this.boundOnMessage);
1249
- }
1250
- on(handlers) {
1251
- this.handlers = { ...this.handlers, ...handlers };
1252
- }
1253
- destroy() {
1254
- if (this.destroyed) return;
1255
- this.destroyed = true;
1256
- const target = this.opts.hostWindow ?? window;
1257
- target.removeEventListener("message", this.boundOnMessage);
1258
- }
1259
- sendHostHello(data) {
1260
- this.post("casual.hello", data);
1261
- }
1262
- sendSetViewMode(data) {
1263
- this.post("casual.command.set.viewmode", data);
1264
- }
1265
- sendSetReadOnly(data) {
1266
- this.post("casual.command.set.readonly", data);
1267
- }
1268
- sendSetTheme(data) {
1269
- this.post("casual.command.set.theme", data);
1270
- }
1271
- sendSetLocale(data) {
1272
- this.post("casual.command.set.locale", data);
1273
- }
1274
- sendCommandSave() {
1275
- this.post("casual.command.save", null);
1276
- }
1277
- sendCommandFocus() {
1278
- this.post("casual.command.focus", null);
1279
- }
1280
- /** Host → Editor: run a formatting / navigation command (bold,
1281
- * italic, undo, …) against the active selection. v0.6+. */
1282
- sendCommandExecute(data) {
1283
- this.post("casual.command.execute", data);
1284
- }
1285
- sendSignatureRequest(id, data) {
1286
- this.post("casual.signature.request", data, id);
1287
- }
1288
- sendSignatureCancel(data) {
1289
- this.post("casual.signature.cancel", data);
1290
- }
1291
- onMessage(ev) {
1292
- if (this.destroyed) return;
1293
- if (ev.origin !== this.opts.embedOrigin) return;
1294
- if (ev.source !== this.opts.iframeWindow) return;
1295
- if (!isCasualEnvelope(ev.data)) return;
1296
- if (ev.data.app !== this.opts.app) return;
1297
- void this.dispatch(ev.data);
1298
- }
1299
- async dispatch(env) {
1300
- switch (env.type) {
1301
- case "casual.ready":
1302
- this.handlers.onEditorReady?.(env.data);
1303
- return;
1304
- case "casual.load.request": {
1305
- if (!this.handlers.onLoadRequest) return;
1306
- const id = env.id ?? "";
1307
- try {
1308
- const resp = await this.handlers.onLoadRequest(env.data);
1309
- const transfer = resp.ok ? [resp.bytes] : [];
1310
- this.post("casual.load.response", resp, id, transfer);
1311
- } catch (err) {
1312
- this.post(
1313
- "casual.load.response",
1314
- {
1315
- ok: false,
1316
- code: "host_error",
1317
- message: err instanceof Error ? err.message : String(err)
1318
- },
1319
- id
1320
- );
1321
- }
1322
- return;
1323
- }
1324
- case "casual.save.request": {
1325
- if (!this.handlers.onSaveRequest) return;
1326
- const id = env.id ?? "";
1327
- try {
1328
- const resp = await this.handlers.onSaveRequest(env.data);
1329
- this.post("casual.save.response", resp, id);
1330
- } catch (err) {
1331
- this.post(
1332
- "casual.save.response",
1333
- {
1334
- ok: false,
1335
- code: "host_error",
1336
- message: err instanceof Error ? err.message : String(err)
1337
- },
1338
- id
1339
- );
1340
- }
1341
- return;
1342
- }
1343
- case "casual.selection.changed":
1344
- this.handlers.onSelectionChanged?.(env.data);
1345
- return;
1346
- case "casual.selection.format-state":
1347
- this.handlers.onSelectionFormatState?.(env.data);
1348
- return;
1349
- case "casual.telemetry.event":
1350
- this.handlers.onTelemetry?.(env.data);
1351
- return;
1352
- case "casual.signature.field.signed":
1353
- this.handlers.onSignatureFieldSigned?.(env.data);
1354
- return;
1355
- case "casual.signature.complete":
1356
- this.handlers.onSignatureComplete?.(env.data);
1357
- return;
1358
- case "casual.signature.cancel":
1359
- this.handlers.onSignatureCancel?.(env.data);
1360
- return;
1361
- case "casual.signature.request.ack":
1362
- return;
1363
- case "casual.error":
1364
- this.handlers.onError?.(env.data);
1365
- return;
1366
- default:
1367
- return;
1368
- }
1369
- }
1370
- post(type, data, id, transfer) {
1371
- const env = {
1372
- type,
1373
- app: this.opts.app,
1374
- v: 1,
1375
- data,
1376
- ...id ? { id } : {}
1377
- };
1378
- const send = this.opts.iframeWindow.postMessage.bind(
1379
- this.opts.iframeWindow
1380
- );
1381
- send(env, this.opts.embedOrigin, transfer);
1382
- }
1383
- };
1384
-
1385
- // src/sheets/CasualSheetsIframe.tsx
1386
1488
  import { jsx as jsx5 } from "react/jsx-runtime";
1387
1489
  var DEFAULT_STYLE2 = {
1388
1490
  width: "100%",
@@ -1517,6 +1619,7 @@ export {
1517
1619
  CasualSheets,
1518
1620
  CasualSheetsIframe,
1519
1621
  DrawnSignaturePad,
1622
+ EmbedHostTransport,
1520
1623
  EmbedTransport,
1521
1624
  SigningPane,
1522
1625
  SigningProvider,