@notionhq/custom-blocks 0.1.19 → 0.1.21

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 (38) hide show
  1. package/README.md +2 -2
  2. package/dist/bridge/SandboxBridge.d.ts +13 -2
  3. package/dist/bridge/SandboxBridge.d.ts.map +1 -1
  4. package/dist/bridge/SandboxBridge.js +79 -8
  5. package/dist/bridge/hostState.d.ts +2 -2
  6. package/dist/bridge/hostState.d.ts.map +1 -1
  7. package/dist/bridge/sandboxClient.d.ts +1 -0
  8. package/dist/bridge/sandboxClient.d.ts.map +1 -1
  9. package/dist/bridge/sandboxClient.js +3 -0
  10. package/dist/protocol/index.d.ts +1 -0
  11. package/dist/protocol/index.d.ts.map +1 -1
  12. package/dist/protocol/index.js +1 -0
  13. package/dist/protocol/messagePayload.d.ts +20 -0
  14. package/dist/protocol/messagePayload.d.ts.map +1 -0
  15. package/dist/protocol/messagePayload.js +1 -0
  16. package/dist/protocol/messages/initResult.d.ts +2 -0
  17. package/dist/protocol/messages/initResult.d.ts.map +1 -1
  18. package/dist/protocol/messages/initResult.js +3 -0
  19. package/dist/protocol/messages/sandboxToHost.d.ts +1 -0
  20. package/dist/protocol/messages/sandboxToHost.d.ts.map +1 -1
  21. package/dist/react/NotionCustomBlock.d.ts +3 -4
  22. package/dist/react/NotionCustomBlock.d.ts.map +1 -1
  23. package/dist/react/NotionCustomBlock.js +12 -2
  24. package/dist/react/useCustomBlockAutoResize.d.ts +4 -8
  25. package/dist/react/useCustomBlockAutoResize.d.ts.map +1 -1
  26. package/dist/react/useCustomBlockAutoResize.js +4 -8
  27. package/dist/types.d.ts +19 -51
  28. package/dist/types.d.ts.map +1 -1
  29. package/dist/version.js +1 -1
  30. package/docs/data-sources.md +2 -1
  31. package/docs/lifecycle.md +18 -23
  32. package/package.json +1 -1
  33. package/src/bridge/SandboxBridge.ts +94 -10
  34. package/src/bridge/hostState.ts +2 -2
  35. package/src/bridge/sandboxClient.ts +4 -0
  36. package/src/react/NotionCustomBlock.tsx +16 -6
  37. package/src/react/useCustomBlockAutoResize.ts +4 -8
  38. package/src/types.ts +46 -50
package/README.md CHANGED
@@ -81,7 +81,7 @@ export function App() {
81
81
  }
82
82
  ```
83
83
 
84
- `<NotionCustomBlock>` runs the SDK ↔ host handshake (`connect` → `init` → `initResult`) and only mounts `children` once it resolves. Inside the wrapper, every hook returns non-nullable values — there's no separate gating component to write. It also runs `useCustomBlockAutoResize` for you by default; pass `autoResize={false}` to opt out.
84
+ `<NotionCustomBlock>` runs the SDK ↔ host handshake (`connect` → `init` → `initResult`) and only mounts `children` once the host state is available. It measures the initial content before sending `initResult`, so the host can reveal the iframe at its correct height. Inside the wrapper, every hook returns non-nullable values — there's no separate gating component to write. It continues observing content height changes automatically.
85
85
 
86
86
  ## Notion design tokens
87
87
 
@@ -97,7 +97,7 @@ The stylesheet is scoped rather than installed globally. Render portals inside `
97
97
 
98
98
  API surface, one page per category. Import framework-neutral APIs from `@notionhq/custom-blocks`; import React hooks and components from `@notionhq/custom-blocks/react`. Hover docs in your editor cover the per-field detail; these pages cover usage shape and the gotchas.
99
99
 
100
- - [`docs/lifecycle.md`](./docs/lifecycle.md) — `<NotionCustomBlock>`, `useCustomBlockInit`, `initCustomBlock`, `customBlock.autoResize`, `NotInIframeError`, `useCustomBlockAutoResize`. The handshake, the React wrapper, sizing.
100
+ - [`docs/lifecycle.md`](./docs/lifecycle.md) — `<NotionCustomBlock>`, `useCustomBlockInit`, `initCustomBlock`, `NotInIframeError`, `useCustomBlockAutoResize`. The handshake, the React wrapper, sizing.
101
101
  - [`docs/block-location.md`](./docs/block-location.md) — `useBlockId`, `useParent`, `usePage`, `useTheme`, and `useContrastMode`. Where the block sits and how to read the host's appearance.
102
102
  - [`docs/data-sources.md`](./docs/data-sources.md) — `useDataSource`, `useManifest`, `customBlock.getManifest`, the row, property, and date-value types, plus a worked example.
103
103
  - [`docs/pages.md`](./docs/pages.md) — `pages.create / get / update / delete`, parent variants (including the recommended `data_source_key`), property input shapes.
@@ -1,6 +1,6 @@
1
1
  import type { NotionDataSource } from "../protocol/dataSources/dataSource.js";
2
2
  import { type InitMessage } from "../protocol/messages/init.js";
3
- import type { CreatePageArgs, CreatePageResult, GetPageResult, GetUserResult, ListUsersArgs, ListUsersResult, NotionDataSourcePageUpdateArgs, NotionDataSourcePageUpdateResult, NotionPageId, NotionUserId, UpdatePageArgs, UpdatePageResult, UseDataSourceOptions } from "../types.js";
3
+ import type { CreatePageArgs, CreatePageResult, GetPageResult, GetUserResult, ListUsersArgs, ListUsersResult, NotionDataSourcePageUpdateArgs, NotionPageId, NotionUserId, UpdatePageArgs, UpdatePageResult, UseDataSourceOptions } from "../types.js";
4
4
  import { type CustomBlockHostState } from "./hostState.js";
5
5
  import type { ManifestLoadResult } from "./loadManifest.js";
6
6
  /**
@@ -26,6 +26,8 @@ export declare class SandboxBridge {
26
26
  private hasSentConnect;
27
27
  private hasReceivedInit;
28
28
  private initializationId;
29
+ private hasSentInitResult;
30
+ private pendingOutboundMessages;
29
31
  private latestDataSourceBindings;
30
32
  private isMockState;
31
33
  private isListening;
@@ -40,6 +42,9 @@ export declare class SandboxBridge {
40
42
  awaitInit(signal?: AbortSignal): Promise<void>;
41
43
  sendConnect(manifestResult: ManifestLoadResult): void;
42
44
  private postToHost;
45
+ private sendToHost;
46
+ private flushPendingOutboundMessages;
47
+ private getMessageType;
43
48
  private notify;
44
49
  private handleMessage;
45
50
  subscribe(listener: () => void): () => boolean;
@@ -51,7 +56,13 @@ export declare class SandboxBridge {
51
56
  * of why it's being seeded.
52
57
  */
53
58
  setMockState(message: InitMessage): void;
59
+ completeInitialization(): void;
54
60
  private applyInit;
61
+ /**
62
+ * Lets the initial application render commit before we acknowledge init. The host keeps the
63
+ * iframe covered throughout this frame, so it can apply the measured height before first paint.
64
+ */
65
+ private scheduleInitResult;
55
66
  queryDataSource(key: string, options?: UseDataSourceOptions): void;
56
67
  private setDataSourceQueryError;
57
68
  postResize(height: number): void;
@@ -69,7 +80,7 @@ export declare class SandboxBridge {
69
80
  dataSource: NotionDataSource;
70
81
  pageId: NotionPageId;
71
82
  pageUpdateArgs: NotionDataSourcePageUpdateArgs;
72
- }): Promise<NotionDataSourcePageUpdateResult>;
83
+ }): Promise<UpdatePageResult>;
73
84
  /**
74
85
  * Translates the public `CreatePageArgs["parent"]` into the bridge-native
75
86
  * `CreatePageMessageParent`. The `data_source_key` variant is resolved sandbox-side against
@@ -1 +1 @@
1
- {"version":3,"file":"SandboxBridge.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/SandboxBridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SandboxBridge.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/SandboxBridge.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { resolveDataSources } from "./dataSources/resolve.js";
11
11
  import { resolvePropertyWriteMapForDataSource } from "./dataSources/resolveProperty.js";
12
12
  import { createEmptyDataSourceQueryState, } from "./hostState.js";
13
13
  import { PendingRequests } from "./pendingRequests.js";
14
+ const INIT_RESULT_TIMER_FALLBACK_MS = 100;
14
15
  export class SandboxBridge {
15
16
  constructor() {
16
17
  this.hostState = {
@@ -29,6 +30,8 @@ export class SandboxBridge {
29
30
  this.pendingUpdatePage = new PendingRequests("custom-block-update-page");
30
31
  this.hasSentConnect = false;
31
32
  this.hasReceivedInit = false;
33
+ this.hasSentInitResult = false;
34
+ this.pendingOutboundMessages = [];
32
35
  this.latestDataSourceBindings = {};
33
36
  this.isMockState = false;
34
37
  this.isListening = false;
@@ -343,10 +346,32 @@ export class SandboxBridge {
343
346
  this.postToHost(connectMessage);
344
347
  }
345
348
  postToHost(message) {
349
+ if (this.hostState.status === "initialized" &&
350
+ !this.hasSentInitResult &&
351
+ !this.isMockState &&
352
+ this.getMessageType(message) !== "initResult") {
353
+ this.pendingOutboundMessages.push(message);
354
+ return;
355
+ }
356
+ this.sendToHost(message);
357
+ }
358
+ sendToHost(message) {
346
359
  console.debug("[custom-blocks-sdk] outbound postMessage", message);
347
360
  this.logMessage("sent", message);
348
361
  window.parent.postMessage(message, "*");
349
362
  }
363
+ flushPendingOutboundMessages() {
364
+ const pendingMessages = this.pendingOutboundMessages;
365
+ this.pendingOutboundMessages = [];
366
+ for (const message of pendingMessages) {
367
+ this.sendToHost(message);
368
+ }
369
+ }
370
+ getMessageType(message) {
371
+ return typeof message === "object" && message !== null && "type" in message
372
+ ? message.type
373
+ : undefined;
374
+ }
350
375
  subscribe(listener) {
351
376
  this.listeners.add(listener);
352
377
  return () => this.listeners.delete(listener);
@@ -364,6 +389,22 @@ export class SandboxBridge {
364
389
  this.isMockState = true;
365
390
  this.applyInit(v.parse(initMessageSchema, message), false);
366
391
  }
392
+ completeInitialization() {
393
+ if (this.hasSentInitResult ||
394
+ this.initializationId === undefined ||
395
+ this.hostState.status !== "initialized") {
396
+ return;
397
+ }
398
+ const result = {
399
+ type: "initResult",
400
+ initializationId: this.initializationId,
401
+ status: "success",
402
+ initialHeight: getInitialContentHeight(),
403
+ };
404
+ this.hasSentInitResult = true;
405
+ this.postToHost(result);
406
+ this.flushPendingOutboundMessages();
407
+ }
367
408
  applyInit(message, postResult) {
368
409
  if (postResult) {
369
410
  this.isMockState = false;
@@ -424,14 +465,6 @@ export class SandboxBridge {
424
465
  contrastMode: message.contrastMode,
425
466
  });
426
467
  this.notify();
427
- if (postResult) {
428
- const result = {
429
- type: "initResult",
430
- initializationId: message.initializationId,
431
- status: "success",
432
- };
433
- this.postToHost(result);
434
- }
435
468
  // Resolve the awaitInit promise once. Subsequent `init` messages
436
469
  // (the host shouldn't send these, but be tolerant) update state but
437
470
  // don't re-resolve.
@@ -440,6 +473,34 @@ export class SandboxBridge {
440
473
  this.resolveInit = undefined;
441
474
  this.rejectInit = undefined;
442
475
  }
476
+ if (postResult) {
477
+ this.scheduleInitResult(message.initializationId);
478
+ }
479
+ }
480
+ /**
481
+ * Lets the initial application render commit before we acknowledge init. The host keeps the
482
+ * iframe covered throughout this frame, so it can apply the measured height before first paint.
483
+ */
484
+ scheduleInitResult(initializationId) {
485
+ let didAcknowledge = false;
486
+ let fallbackTimerId;
487
+ const acknowledge = () => {
488
+ if (didAcknowledge) {
489
+ return;
490
+ }
491
+ didAcknowledge = true;
492
+ if (fallbackTimerId !== undefined) {
493
+ window.clearTimeout(fallbackTimerId);
494
+ }
495
+ if (this.initializationId !== initializationId) {
496
+ return;
497
+ }
498
+ this.completeInitialization();
499
+ };
500
+ fallbackTimerId = window.setTimeout(acknowledge, INIT_RESULT_TIMER_FALLBACK_MS);
501
+ if (typeof requestAnimationFrame === "function") {
502
+ requestAnimationFrame(acknowledge);
503
+ }
443
504
  }
444
505
  queryDataSource(key, options = {}) {
445
506
  if (this.hostState.status !== "initialized") {
@@ -712,6 +773,16 @@ export class SandboxBridge {
712
773
  }
713
774
  }
714
775
  SandboxBridge.MAX_LOG_ENTRIES = 100;
776
+ function getInitialContentHeight() {
777
+ if (typeof document === "undefined") {
778
+ return 0;
779
+ }
780
+ const root = document.getElementById("root");
781
+ if (root === null) {
782
+ return 0;
783
+ }
784
+ return Math.ceil(root.getBoundingClientRect().height);
785
+ }
715
786
  /**
716
787
  * Makes the document canvas match the host appearance before acknowledging init.
717
788
  *
@@ -9,7 +9,7 @@ import type { CustomBlockPage, NotionPageId } from "../protocol/pages/page.js";
9
9
  import type { NotionParent } from "../protocol/parent.js";
10
10
  import type { NotionTheme } from "../protocol/theme.js";
11
11
  import type { NotionUser } from "../protocol/users/user.js";
12
- import type { NotionDataSourcePage, NotionDataSourcePageUpdateArgs, NotionDataSourcePageUpdateResult } from "../types.js";
12
+ import type { NotionDataSourcePage, NotionDataSourcePageUpdateArgs, UpdatePageResult } from "../types.js";
13
13
  export type CustomBlockHostState = UninitializedHostState | InitializedHostState;
14
14
  export type UninitializedHostState = {
15
15
  status: "uninitialized";
@@ -68,6 +68,6 @@ export type UpdateDataSourcePageFn = (args: {
68
68
  dataSource: NotionDataSource;
69
69
  pageId: NotionPageId;
70
70
  pageUpdateArgs: NotionDataSourcePageUpdateArgs;
71
- }) => Promise<NotionDataSourcePageUpdateResult>;
71
+ }) => Promise<UpdatePageResult>;
72
72
  export declare function getDataSourceQueryView(hostState: CustomBlockHostState, key: string, updateDataSourcePage: UpdateDataSourcePageFn): DataSourceQueryView;
73
73
  //# sourceMappingURL=hostState.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hostState.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/hostState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hostState.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/hostState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8CAA8C,CAAA;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4DAA4D,CAAA;AAClG,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,gEAAgE,CAAA;AAEhH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAA;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yCAAyC,CAAA;AAC5E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAA;AACvF,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,oEAAoE,CAAA;AAC7H,OAAO,KAAK,EACX,eAAe,EACf,YAAY,EACZ,MAAM,gDAAgD,CAAA;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAA;AAC9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAA;AAC5E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gDAAgD,CAAA;AAChF,OAAO,KAAK,EACX,oBAAoB,EACpB,8BAA8B,EAC9B,gBAAgB,EAChB,MAAM,aAAa,CAAA;AAEpB,MAAM,MAAM,oBAAoB,GAAG,sBAAsB,GAAG,oBAAoB,CAAA;AAEhF,MAAM,MAAM,sBAAsB,GAAG;IACpC,MAAM,EAAE,eAAe,CAAA;IACvB,KAAK,EAAE,WAAW,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;CAChC,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAClC,MAAM,EAAE,aAAa,CAAA;IACrB,KAAK,EAAE,WAAW,CAAA;IAClB,YAAY,EAAE,kBAAkB,CAAA;IAChC,OAAO,EAAE,aAAa,CAAA;IACtB,MAAM,EAAE,YAAY,CAAA;IACpB,IAAI,EAAE,eAAe,CAAA;IACrB,WAAW,EAAE,UAAU,CAAA;IACvB,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,WAAW,EAAE,gBAAgB,EAAE,CAAA;IAC/B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAA;CACrD,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAClC,iGAAiG;IACjG,KAAK,EAAE,0BAA0B,EAAE,CAAA;IACnC,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,mCAAmC,CAAA;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAgB,+BAA+B,IAAI,oBAAoB,CAMtE;AAED;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC,KAAK,EAAE,oBAAoB,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,kBAAkB,CAAC,CAAA;IACvD,mBAAmB,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,CAAA;KAAE,CAAA;IACnE,gBAAgB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;KAAE,CAAA;IACvD,oBAAoB,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS,CAAA;KAAE,CAAA;IACzE,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,mCAAmC,CAAA;CAC3C,CAAA;AAWD;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE;IAC3C,UAAU,EAAE,gBAAgB,CAAA;IAC5B,MAAM,EAAE,YAAY,CAAA;IACpB,cAAc,EAAE,8BAA8B,CAAA;CAC9C,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAA;AAE/B,wBAAgB,sBAAsB,CACrC,SAAS,EAAE,oBAAoB,EAC/B,GAAG,EAAE,MAAM,EACX,oBAAoB,EAAE,sBAAsB,GAC1C,mBAAmB,CAgErB"}
@@ -15,6 +15,7 @@ export declare const customBlockHost: {
15
15
  * standalone preview state.
16
16
  */
17
17
  setMockState: (message: InitMessage) => void;
18
+ completeInitialization: () => void;
18
19
  postResize: (height: number) => void;
19
20
  };
20
21
  export declare const customBlockDataSources: {
@@ -1 +1 @@
1
- {"version":3,"file":"sandboxClient.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/sandboxClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mDAAmD,CAAA;AACpF,OAAO,KAAK,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAExB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAiB,MAAM,oBAAoB,CAAA;AAExE,YAAY,EAAE,eAAe,EAAE,CAAA;AAW/B,eAAO,MAAM,eAAe;;kCAKG,kBAAkB;yBAI3B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC;0BAI1B,MAAM,IAAI;oBAIlB,oBAAoB;IAIlC;;;OAGG;4BACqB,WAAW;yBAId,MAAM;CAG3B,CAAA;AAED,eAAO,MAAM,sBAAsB;iBACrB,MAAM,YAAY,oBAAoB;yBAKvC,oBAAoB,OAC1B,MAAM,KACT,mBAAmB;CAKtB,CAAA;AAED,eAAO,MAAM,UAAU;uBACL,SAAS,eAAe,EAAE;0BAIrB,MAAM,IAAI;CAGhC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IACjB;;OAEG;oBACa,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;IAI1D;;OAEG;kBACW,YAAY,KAAG,OAAO,CAAC,aAAa,CAAC;IAInD;;OAEG;oBACa,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;IAI1D;;OAEG;qBACc,YAAY,KAAG,OAAO,CAAC,gBAAgB,CAAC;CAGzD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IACjB;;OAEG;mBACY,aAAa,KAAG,OAAO,CAAC,eAAe,CAAC;IAIvD;;OAEG;kBACW,YAAY,KAAG,OAAO,CAAC,aAAa,CAAC;CAGnD,CAAA"}
1
+ {"version":3,"file":"sandboxClient.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/bridge/sandboxClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mDAAmD,CAAA;AACpF,OAAO,KAAK,EACX,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EAExB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,KAAK,eAAe,EAAiB,MAAM,oBAAoB,CAAA;AAExE,YAAY,EAAE,eAAe,EAAE,CAAA;AAW/B,eAAO,MAAM,eAAe;;kCAKG,kBAAkB;yBAI3B,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC;0BAI1B,MAAM,IAAI;oBAIlB,oBAAoB;IAIlC;;;OAGG;4BACqB,WAAW;;yBAQd,MAAM;CAG3B,CAAA;AAED,eAAO,MAAM,sBAAsB;iBACrB,MAAM,YAAY,oBAAoB;yBAKvC,oBAAoB,OAC1B,MAAM,KACT,mBAAmB;CAKtB,CAAA;AAED,eAAO,MAAM,UAAU;uBACL,SAAS,eAAe,EAAE;0BAIrB,MAAM,IAAI;CAGhC,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IACjB;;OAEG;oBACa,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;IAI1D;;OAEG;kBACW,YAAY,KAAG,OAAO,CAAC,aAAa,CAAC;IAInD;;OAEG;oBACa,cAAc,KAAG,OAAO,CAAC,gBAAgB,CAAC;IAI1D;;OAEG;qBACc,YAAY,KAAG,OAAO,CAAC,gBAAgB,CAAC;CAGzD,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,KAAK;IACjB;;OAEG;mBACY,aAAa,KAAG,OAAO,CAAC,eAAe,CAAC;IAIvD;;OAEG;kBACW,YAAY,KAAG,OAAO,CAAC,aAAa,CAAC;CAGnD,CAAA"}
@@ -30,6 +30,9 @@ export const customBlockHost = {
30
30
  setMockState: (message) => {
31
31
  getBridge().setMockState(message);
32
32
  },
33
+ completeInitialization: () => {
34
+ getBridge().completeInitialization();
35
+ },
33
36
  postResize: (height) => {
34
37
  getBridge().postResize(height);
35
38
  },
@@ -17,6 +17,7 @@ export * from "./errors.js";
17
17
  export * from "./ids.js";
18
18
  export * from "./incomingType.js";
19
19
  export * from "./manifest.js";
20
+ export * from "./messagePayload.js";
20
21
  export * from "./messages/connect.js";
21
22
  export * from "./messages/contrastModeChanged.js";
22
23
  export * from "./messages/createPage.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,uBAAuB,CAAA;AACrC,cAAc,mCAAmC,CAAA;AACjD,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,qCAAqC,CAAA;AACnD,cAAc,sBAAsB,CAAA;AACpC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,cAAc,eAAe,CAAA;AAC7B,cAAc,6BAA6B,CAAA;AAC3C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,kCAAkC,CAAA;AAChD,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,iCAAiC,CAAA;AAC/C,cAAc,gCAAgC,CAAA;AAC9C,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,mBAAmB,CAAA;AACjC,cAAc,eAAe,CAAA;AAC7B,cAAc,qBAAqB,CAAA;AACnC,cAAc,uBAAuB,CAAA;AACrC,cAAc,mCAAmC,CAAA;AACjD,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,kCAAkC,CAAA;AAChD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uBAAuB,CAAA;AACrC,cAAc,uBAAuB,CAAA;AACrC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,oBAAoB,CAAA;AAClC,cAAc,0BAA0B,CAAA;AACxC,cAAc,kCAAkC,CAAA;AAChD,cAAc,qCAAqC,CAAA;AACnD,cAAc,yBAAyB,CAAA;AACvC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,+BAA+B,CAAA;AAC7C,cAAc,qCAAqC,CAAA;AACnD,cAAc,sBAAsB,CAAA;AACpC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,0BAA0B,CAAA;AACxC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,sBAAsB,CAAA;AACpC,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
@@ -17,6 +17,7 @@ export * from "./errors.js";
17
17
  export * from "./ids.js";
18
18
  export * from "./incomingType.js";
19
19
  export * from "./manifest.js";
20
+ export * from "./messagePayload.js";
20
21
  export * from "./messages/connect.js";
21
22
  export * from "./messages/contrastModeChanged.js";
22
23
  export * from "./messages/createPage.js";
@@ -0,0 +1,20 @@
1
+ import type { CustomBlockErrorInfo } from "./errors.js";
2
+ type WithTypedErrorInfo<T, TErrorInfo extends CustomBlockErrorInfo | undefined> = TErrorInfo extends CustomBlockErrorInfo ? T extends {
3
+ error: CustomBlockErrorInfo;
4
+ } ? Omit<T, "error"> & {
5
+ error: TErrorInfo;
6
+ } : T : T;
7
+ /**
8
+ * Removes bridge envelope fields from every member of a message union.
9
+ *
10
+ * The conditional type makes the operation distributive, preserving
11
+ * success/error-specific fields such as `page` and `error`.
12
+ *
13
+ * Pass an API-specific error-info type to preserve its known error-code
14
+ * literals while still accepting unknown string codes at runtime.
15
+ */
16
+ export type BridgeMessagePayload<T extends {
17
+ type: string;
18
+ }, TErrorInfo extends CustomBlockErrorInfo | undefined = undefined> = T extends unknown ? WithTypedErrorInfo<Omit<T, "type" | "requestId" | "subscriptionId">, TErrorInfo> : never;
19
+ export {};
20
+ //# sourceMappingURL=messagePayload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messagePayload.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/messagePayload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,KAAK,kBAAkB,CACtB,CAAC,EACD,UAAU,SAAS,oBAAoB,GAAG,SAAS,IAChD,UAAU,SAAS,oBAAoB,GACxC,CAAC,SAAS;IAAE,KAAK,EAAE,oBAAoB,CAAA;CAAE,GACxC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,GACxC,CAAC,GACF,CAAC,CAAA;AAEJ;;;;;;;;GAQG;AACH,MAAM,MAAM,oBAAoB,CAC/B,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC1B,UAAU,SAAS,oBAAoB,GAAG,SAAS,GAAG,SAAS,IAC5D,CAAC,SAAS,OAAO,GAClB,kBAAkB,CAClB,IAAI,CAAC,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,gBAAgB,CAAC,EAChD,UAAU,CACV,GACA,KAAK,CAAA"}
@@ -0,0 +1 @@
1
+ export {};
@@ -15,6 +15,8 @@ export declare const initResultMessageSchema: v.VariantSchema<"status", [v.Objec
15
15
  readonly type: v.LiteralSchema<"initResult", undefined>;
16
16
  readonly initializationId: v.StringSchema<undefined>;
17
17
  readonly status: v.LiteralSchema<"success", undefined>;
18
+ /** Height of the initial rendered custom-block content, in CSS pixels. */
19
+ readonly initialHeight: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.FiniteAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
18
20
  }, undefined>, v.ObjectSchema<{
19
21
  readonly type: v.LiteralSchema<"initResult", undefined>;
20
22
  readonly initializationId: v.StringSchema<undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"initResult.d.ts","sourceRoot":"","sources":["../../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/messages/initResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAI9E,eAAO,MAAM,oCAAoC,2BAAa,CAAA;AAE9D,MAAM,MAAM,8BAA8B,GACzC,oBAAoB,CAAC,uBAAuB,CAAC,CAAA;AAE9C,MAAM,MAAM,8BAA8B,GACzC,oBAAoB,CAAC,8BAA8B,CAAC,CAAA;AAErD,eAAO,MAAM,oCAAoC;;;;aAI/C,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;0BAYlC,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
1
+ {"version":3,"file":"initResult.d.ts","sourceRoot":"","sources":["../../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/messages/initResult.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAI9E,eAAO,MAAM,oCAAoC,2BAAa,CAAA;AAE9D,MAAM,MAAM,8BAA8B,GACzC,oBAAoB,CAAC,uBAAuB,CAAC,CAAA;AAE9C,MAAM,MAAM,8BAA8B,GACzC,oBAAoB,CAAC,8BAA8B,CAAC,CAAA;AAErD,eAAO,MAAM,oCAAoC;;;;aAI/C,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;IAKlC,0EAA0E;;;;;;;;;;;0BAU1E,CAAA;AAEF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,uBAAuB,CAAC,CAAA"}
@@ -15,6 +15,9 @@ export const initResultMessageSchema = v.variant("status", [
15
15
  type: v.literal("initResult"),
16
16
  initializationId: v.string(),
17
17
  status: v.literal("success"),
18
+ /** Height of the initial rendered custom-block content, in CSS pixels. */
19
+ // TODO(custom-blocks): Make this required when bumping bridge protocol version 4.
20
+ initialHeight: v.optional(v.pipe(v.number(), v.finite(), v.minValue(0))),
18
21
  }),
19
22
  v.object({
20
23
  type: v.literal("initResult"),
@@ -43,6 +43,7 @@ export declare const sandboxToHostMessageSchema: v.UnionSchema<[v.VariantSchema<
43
43
  readonly type: v.LiteralSchema<"initResult", undefined>;
44
44
  readonly initializationId: v.StringSchema<undefined>;
45
45
  readonly status: v.LiteralSchema<"success", undefined>;
46
+ readonly initialHeight: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.FiniteAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
46
47
  }, undefined>, v.ObjectSchema<{
47
48
  readonly type: v.LiteralSchema<"initResult", undefined>;
48
49
  readonly initializationId: v.StringSchema<undefined>;
@@ -1 +1 @@
1
- {"version":3,"file":"sandboxToHost.d.ts","sourceRoot":"","sources":["../../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/messages/sandboxToHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAY5B;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAWrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAC/C,OAAO,0BAA0B,CACjC,CAAA"}
1
+ {"version":3,"file":"sandboxToHost.d.ts","sourceRoot":"","sources":["../../../../../home/runner/work/custom-blocks/custom-blocks/protocol/src/messages/sandboxToHost.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAY5B;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAWrC,CAAA;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAC/C,OAAO,0BAA0B,CACjC,CAAA"}
@@ -18,10 +18,9 @@ export type NotionCustomBlockProps = InitCustomBlockOptions & {
18
18
  */
19
19
  errorFallback?: ReactNode | ((error: Error) => ReactNode);
20
20
  /**
21
- * Whether the provider should automatically post resize messages so the
22
- * host iframe matches the content height of `#root`. Defaults to `true`.
23
- * Pass `false` when you want to use the default block size and are ok
24
- * with scrollbars within the Notion client.
21
+ * Whether to post resize messages after initialization and dynamically resize the block.
22
+ *
23
+ * @deprecated TODO(custom-blocks): Remove this prop when bumping the SDK version to 0.2.0.
25
24
  *
26
25
  * @default true
27
26
  */
@@ -1 +1 @@
1
- {"version":3,"file":"NotionCustomBlock.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/react/NotionCustomBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAA;AAC3D,OAAO,EAAE,KAAK,sBAAsB,EAAoB,MAAM,aAAa,CAAA;AAM3E,OAAO,yBAAyB,CAAA;AAEhC;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,sBAAsB,GAAG;IAC7D,QAAQ,EAAE,SAAS,CAAA;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAA;IACzD;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,EACjC,QAAQ,EACR,SAAS,EACT,QAAe,EACf,aAAa,EACb,UAAiB,GACjB,EAAE,sBAAsB,2CA4DxB"}
1
+ {"version":3,"file":"NotionCustomBlock.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/react/NotionCustomBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAwC,MAAM,OAAO,CAAA;AAE5E,OAAO,EAAE,KAAK,sBAAsB,EAAoB,MAAM,aAAa,CAAA;AAM3E,OAAO,yBAAyB,CAAA;AAEhC;;GAEG;AACH,MAAM,MAAM,sBAAsB,GAAG,sBAAsB,GAAG;IAC7D,QAAQ,EAAE,SAAS,CAAA;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB;;;;OAIG;IACH,aAAa,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAA;IACzD;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAAC,EACjC,QAAQ,EACR,SAAS,EACT,QAAe,EACf,aAAa,EACb,UAAiB,GACjB,EAAE,sBAAsB,2CAsExB"}
@@ -1,5 +1,6 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
2
+ import { useEffect, useLayoutEffect, useState } from "react";
3
+ import { customBlockHost } from "../bridge/sandboxClient.js";
3
4
  import { NotInIframeError } from "../index.js";
4
5
  import { DebugMessageLog } from "./DebugMessageLog.js";
5
6
  import { seedStandalonePreviewState } from "./standalonePreview.js";
@@ -28,7 +29,8 @@ import "./NotionCustomBlock.css";
28
29
  */
29
30
  export function NotionCustomBlock({ children, timeoutMs, fallback = null, errorFallback, autoResize = true, }) {
30
31
  const init = useCustomBlockInit({ timeoutMs });
31
- useCustomBlockAutoResize({ enabled: autoResize });
32
+ useCustomBlockAutoResize({ enabled: init.isLoaded && autoResize });
33
+ // True if the block has no host (i.e. it's running in standalone preview).
32
34
  const isStandalone = init.error instanceof NotInIframeError;
33
35
  const host = useCustomBlockHost();
34
36
  const [debugOpen, setDebugOpen] = useState(false);
@@ -48,6 +50,14 @@ export function NotionCustomBlock({ children, timeoutMs, fallback = null, errorF
48
50
  console.warn(`[custom-blocks-sdk] ${init.error?.message}`);
49
51
  seedStandalonePreviewState();
50
52
  }, [isStandalone, init.error]);
53
+ useLayoutEffect(() => {
54
+ if (!init.isLoaded || isStandalone) {
55
+ return;
56
+ }
57
+ // Send `initResult` *after* React renders the block so the SDK can report its rendered
58
+ // height to the host as part of the `initResult` message.
59
+ customBlockHost.completeInitialization();
60
+ }, [init.isLoaded, isStandalone]);
51
61
  if (debugOpen) {
52
62
  return _jsx(DebugMessageLog, {});
53
63
  }
@@ -2,16 +2,12 @@
2
2
  * Measures the sandbox's `#root` element and posts `resize` messages so the host iframe
3
3
  * matches the block's border-box height. Unchanged values are deduped.
4
4
  *
5
- * `<NotionCustomBlock>` calls this hook for you by default only reach for it directly
6
- * when you need to drive `enabled` yourself (e.g. behind a debug toggle). In that case,
7
- * pass `autoResize={false}` to the provider to avoid running it twice. For full-bleed
8
- * views that should fill their slot, pass `autoResize={false}` and skip the hook.
5
+ * `<NotionCustomBlock>` calls this hook for you. Only use it directly in a custom
6
+ * initialization wrapper that does not render `<NotionCustomBlock>`.
9
7
  *
10
- * @example
11
- * <NotionCustomBlock autoResize={false}>
12
- * <App />
13
- * </NotionCustomBlock>
8
+ * @deprecated Use CSS `max-height` and `overflow` to constrain block content instead.
14
9
  *
10
+ * @example
15
11
  * function App() {
16
12
  * const [enabled, setEnabled] = useState(true)
17
13
  * useCustomBlockAutoResize({ enabled })
@@ -1 +1 @@
1
- {"version":3,"file":"useCustomBlockAutoResize.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/react/useCustomBlockAutoResize.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,wBAAwB,CACvC,IAAI,GAAE;IACL;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACZ,GACJ,IAAI,CAYN"}
1
+ {"version":3,"file":"useCustomBlockAutoResize.d.ts","sourceRoot":"","sources":["../../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/react/useCustomBlockAutoResize.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,wBAAwB,CACvC,IAAI,GAAE;IACL;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CACZ,GACJ,IAAI,CAYN"}
@@ -4,16 +4,12 @@ import { customBlock } from "../index.js";
4
4
  * Measures the sandbox's `#root` element and posts `resize` messages so the host iframe
5
5
  * matches the block's border-box height. Unchanged values are deduped.
6
6
  *
7
- * `<NotionCustomBlock>` calls this hook for you by default only reach for it directly
8
- * when you need to drive `enabled` yourself (e.g. behind a debug toggle). In that case,
9
- * pass `autoResize={false}` to the provider to avoid running it twice. For full-bleed
10
- * views that should fill their slot, pass `autoResize={false}` and skip the hook.
7
+ * `<NotionCustomBlock>` calls this hook for you. Only use it directly in a custom
8
+ * initialization wrapper that does not render `<NotionCustomBlock>`.
11
9
  *
12
- * @example
13
- * <NotionCustomBlock autoResize={false}>
14
- * <App />
15
- * </NotionCustomBlock>
10
+ * @deprecated Use CSS `max-height` and `overflow` to constrain block content instead.
16
11
  *
12
+ * @example
17
13
  * function App() {
18
14
  * const [enabled, setEnabled] = useState(true)
19
15
  * useCustomBlockAutoResize({ enabled })
package/dist/types.d.ts CHANGED
@@ -2,16 +2,16 @@ import type { NotionCollectionSchema } from "./protocol/dataSources/dataSource.j
2
2
  import type { NotionDataSourceValue } from "./protocol/dataSources/dataSourceValue.js";
3
3
  import type { NotionPropertySchema } from "./protocol/dataSources/propertySchema.js";
4
4
  import type { NotionDataSourceId, NotionPageId } from "./protocol/ids.js";
5
+ import type { BridgeMessagePayload } from "./protocol/messagePayload.js";
5
6
  import type { NotionCreatePagePosition } from "./protocol/messages/createPage.js";
6
- import type { CustomBlockCreatePageErrorInfo } from "./protocol/messages/createPageResult.js";
7
- import type { CustomBlockGetPageErrorInfo } from "./protocol/messages/getPage.js";
8
- import type { CustomBlockGetUserErrorInfo } from "./protocol/messages/getUser.js";
9
- import type { CustomBlockListUsersErrorInfo, ListUsersMessage } from "./protocol/messages/listUsers.js";
7
+ import type { CreatePageResultMessage, CustomBlockCreatePageErrorInfo } from "./protocol/messages/createPageResult.js";
8
+ import type { CustomBlockGetPageErrorInfo, GetPageResultMessage } from "./protocol/messages/getPage.js";
9
+ import type { CustomBlockGetUserErrorInfo, GetUserResultMessage } from "./protocol/messages/getUser.js";
10
+ import type { CustomBlockListUsersErrorInfo, ListUsersMessage, ListUsersResultMessage } from "./protocol/messages/listUsers.js";
10
11
  import type { CustomBlockQueryDataSourceErrorInfo } from "./protocol/messages/queryDataSourceResult.js";
11
12
  import type { UpdatePageMessage } from "./protocol/messages/updatePage.js";
12
- import type { CustomBlockUpdatePageErrorInfo } from "./protocol/messages/updatePageResult.js";
13
- import type { NotionPage, NotionPageCover, NotionPageIcon, NotionPagePropertyValue } from "./protocol/pages/page.js";
14
- import type { NotionUser, NotionUserList } from "./protocol/users/user.js";
13
+ import type { CustomBlockUpdatePageErrorInfo, UpdatePageResultMessage } from "./protocol/messages/updatePageResult.js";
14
+ import type { NotionPageCover, NotionPageIcon, NotionPagePropertyValue } from "./protocol/pages/page.js";
15
15
  export type { CustomBlockErrorInfo } from "./protocol/errors.js";
16
16
  export type { NotionDataSourceId, NotionPageId, NotionSpaceId, } from "./protocol/ids.js";
17
17
  export type { NotionUser, NotionUserId, NotionUserList, } from "./protocol/users/user.js";
@@ -55,7 +55,7 @@ export type NotionDataSourcePage = {
55
55
  * Updates this page using the data source's property-key bindings. The SDK resolves property
56
56
  * keys to raw property IDs before sending the bridge message to the host.
57
57
  */
58
- update: (args: NotionDataSourcePageUpdateArgs) => Promise<NotionDataSourcePageUpdateResult>;
58
+ update: (args: NotionDataSourcePageUpdateArgs) => Promise<UpdatePageResult>;
59
59
  };
60
60
  export type NotionDataSourcePageUpdateArgs = {
61
61
  properties?: NotionPagePropertyInputMap;
@@ -69,13 +69,12 @@ export type NotionDataSourcePageUpdateArgs = {
69
69
  * TODO(custom-blocks): Remove this alias when bumping the SDK version to 0.2.0.
70
70
  */
71
71
  export type NotionDataSourcePageUpdateInput = NotionDataSourcePageUpdateArgs;
72
- export type NotionDataSourcePageUpdateResult = {
73
- status: "success";
74
- page: NotionPage;
75
- } | {
76
- status: "error";
77
- error: CustomBlockUpdatePageErrorInfo;
78
- };
72
+ /**
73
+ * @deprecated Use `UpdatePageResult` instead.
74
+ *
75
+ * TODO(custom-blocks): Remove this alias when bumping the SDK version to 0.2.0.
76
+ */
77
+ export type NotionDataSourcePageUpdateResult = UpdatePageResult;
79
78
  /**
80
79
  * Return shape of `useDataSource`.
81
80
  *
@@ -162,14 +161,7 @@ export type CreatePageInput = CreatePageArgs;
162
161
  /**
163
162
  * The result of a `sdk.pages.create` API call.
164
163
  */
165
- export type CreatePageResult = {
166
- status: "success";
167
- /** The newly created page. */
168
- page: NotionPage;
169
- } | {
170
- status: "error";
171
- error: CustomBlockCreatePageErrorInfo;
172
- };
164
+ export type CreatePageResult = BridgeMessagePayload<CreatePageResultMessage, CustomBlockCreatePageErrorInfo>;
173
165
  export type UpdatePageArgs = Omit<UpdatePageMessage, "type" | "requestId">;
174
166
  /**
175
167
  * @deprecated Use `UpdatePageArgs` instead.
@@ -180,23 +172,11 @@ export type UpdatePageInput = UpdatePageArgs;
180
172
  /**
181
173
  * Result of `sdk.pages.get`.
182
174
  */
183
- export type GetPageResult = {
184
- status: "success";
185
- page: NotionPage;
186
- } | {
187
- status: "error";
188
- error: CustomBlockGetPageErrorInfo;
189
- };
175
+ export type GetPageResult = BridgeMessagePayload<GetPageResultMessage, CustomBlockGetPageErrorInfo>;
190
176
  /**
191
177
  * Result of `sdk.pages.update` / `sdk.pages.delete`.
192
178
  */
193
- export type UpdatePageResult = {
194
- status: "success";
195
- page: NotionPage;
196
- } | {
197
- status: "error";
198
- error: CustomBlockUpdatePageErrorInfo;
199
- };
179
+ export type UpdatePageResult = BridgeMessagePayload<UpdatePageResultMessage, CustomBlockUpdatePageErrorInfo>;
200
180
  export type ListUsersArgs = Omit<ListUsersMessage, "type" | "requestId">;
201
181
  /**
202
182
  * @deprecated Use `ListUsersArgs` instead.
@@ -204,18 +184,6 @@ export type ListUsersArgs = Omit<ListUsersMessage, "type" | "requestId">;
204
184
  * TODO(custom-blocks): Remove this alias when bumping the SDK version to 0.2.0.
205
185
  */
206
186
  export type ListUsersInput = ListUsersArgs;
207
- export type ListUsersResult = {
208
- status: "success";
209
- list: NotionUserList;
210
- } | {
211
- status: "error";
212
- error: CustomBlockListUsersErrorInfo;
213
- };
214
- export type GetUserResult = {
215
- status: "success";
216
- user: NotionUser;
217
- } | {
218
- status: "error";
219
- error: CustomBlockGetUserErrorInfo;
220
- };
187
+ export type ListUsersResult = BridgeMessagePayload<ListUsersResultMessage, CustomBlockListUsersErrorInfo>;
188
+ export type GetUserResult = BridgeMessagePayload<GetUserResultMessage, CustomBlockGetUserErrorInfo>;
221
189
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../home/runner/work/custom-blocks/custom-blocks/sdk/src/types.ts"],"names":[],"mappings":"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"}
package/dist/version.js CHANGED
@@ -4,4 +4,4 @@
4
4
  *
5
5
  * WARNING: Generated during SDK publish. Do not edit in the published package.
6
6
  */
7
- export const CUSTOM_BLOCKS_SDK_VERSION = "0.1.19"
7
+ export const CUSTOM_BLOCKS_SDK_VERSION = "0.1.21"
@@ -158,8 +158,9 @@ export function ScoreList() {
158
158
  - `NotionDataSource` — a resolved data source: semantic key, `collectionSchema`, `propertyIdsByKey`, `propertySchemasById`.
159
159
  - `NotionDataSourcePage` — a single row exposed to app code: `{ id, propertiesById, propertiesByKey, update }`.
160
160
  - `NotionDataSourceValue` — the discriminated union of values that can appear inside `propertiesById[propertyId]`. Date values branch into the `NotionDateValue` union below.
161
- - `NotionDataSourcePageUpdateArgs` / `NotionDataSourcePageUpdateResult` — arguments and result for the per-page `update` helper.
161
+ - `NotionDataSourcePageUpdateArgs` / `UpdatePageResult` — arguments and result for the per-page `update` helper.
162
162
  - `NotionDataSourcePageUpdateInput` — deprecated alias for `NotionDataSourcePageUpdateArgs`.
163
+ - `NotionDataSourcePageUpdateResult` — deprecated alias for `UpdatePageResult`.
163
164
  - `UseDataSourceOptions` — options accepted by `useDataSource`, currently `{ limit?: number }`.
164
165
 
165
166
  ### Property schemas
package/docs/lifecycle.md CHANGED
@@ -4,13 +4,13 @@ The SDK ↔ host handshake, the React wrapper that runs it, and the auto-resize
4
4
 
5
5
  ## Handshake
6
6
 
7
- `initCustomBlock()` completes a three-message handshake:
7
+ `initCustomBlock()` handles three messages:
8
8
 
9
- 1. The SDK sends `connect` with a new initialization ID and some version info.
10
- 2. The host replies with `init`, echoing that initialization ID and providing the manifest, block context, current user, and data source bindings.
11
- 3. The SDK confirms that state is compatible and sends `initResult` with the same initialization ID.
9
+ 1. The SDK sends `connect` with a new initialization ID and version information.
10
+ 2. The host sends `init`. It includes the same ID, the manifest, block context, current user, and data source bindings.
11
+ 3. The SDK sends `initResult` with the ID and the initial block height.
12
12
 
13
- The promise resolves only after the SDK sends `initResult.success`. Await it before mounting React so hooks always see initialized state.
13
+ The promise resolves when the SDK applies the host state. Await it before React renders so hooks read initialized state. The SDK sends `initResult` after the initial render.
14
14
 
15
15
  - Rejects with `CustomBlockInitializationError` code `init_timeout` if the host doesn't respond.
16
16
  - In a top-level browser tab (no parent frame), rejects with `NotInIframeError` code `not_in_iframe`. `<NotionCustomBlock>` catches this, seeds placeholders, and renders `children` behind a warning banner so dev-time previews still work.
@@ -19,10 +19,16 @@ The promise resolves only after the SDK sends `initResult.success`. Await it bef
19
19
 
20
20
  ## Sizing
21
21
 
22
- The host owns width and height. Inside the iframe, `100vh` ≠ a screen and there's no meaningful "device width" — only iframe width. Layouts must reflow from a phone column to a desktop block.
22
+ All blocks resize to fit their content. The Notion app limits block height to 10,000 pixels.
23
23
 
24
- - **Self-sizing content** is the default — `<NotionCustomBlock>` measures `#root` and posts `resize` messages so the iframe tracks your content. Pass `autoResize={false}` for full-bleed views, or to drive `useCustomBlockAutoResize` yourself.
25
- - Prefer container queries (`@container`) over viewport queries.
24
+ To set a shorter height, set `max-height` and `overflow-y` on `#root`:
25
+
26
+ ```css
27
+ #root {
28
+ max-height: 600px;
29
+ overflow-y: auto;
30
+ }
31
+ ```
26
32
 
27
33
  ## API
28
34
 
@@ -35,11 +41,10 @@ type NotionCustomBlockProps = InitCustomBlockOptions & {
35
41
  children: ReactNode;
36
42
  fallback?: ReactNode;
37
43
  errorFallback?: ReactNode | ((error: Error) => ReactNode);
38
- autoResize?: boolean; // defaults to true
39
44
  };
40
45
  ```
41
46
 
42
- Top-level wrapper. Runs the handshake, gates `children`, and (by default) drives auto-resize. `fallback` replaces the loading view (default `null`); `errorFallback` replaces the inline `<p role="alert">` shown if init rejects. `timeoutMs` flows through to `initCustomBlock`. Pass `autoResize={false}` for full-bleed views or to call `useCustomBlockAutoResize` yourself.
47
+ Top-level wrapper. It starts the handshake and renders `children` after init. It measures `#root` before it shows the iframe and when content height changes. `fallback` replaces the loading view. Its default is `null`. `errorFallback` replaces the error message if init fails. `timeoutMs` passes to `initCustomBlock`.
43
48
 
44
49
  ### `useCustomBlockInit(opts?)`
45
50
 
@@ -120,23 +125,13 @@ Thrown when `initCustomBlock` is called in a top-level tab (no parent frame). It
120
125
 
121
126
  ### `useCustomBlockAutoResize({ enabled? })`
122
127
 
128
+ Deprecated. Blocks resize automatically. Use CSS `max-height` and `overflow` to set a shorter height.
129
+
123
130
  ```ts
124
131
  function useCustomBlockAutoResize(args?: { enabled?: boolean }): void;
125
132
  ```
126
133
 
127
- React wrapper around `customBlock.autoResize({ target: document.getElementById("root") })`. Measures `#root`'s height and posts `resize` messages, deduping unchanged values. `<NotionCustomBlock>` runs this for you — only call it directly when you want to drive `enabled` yourself (e.g. a debug toggle), and pair with `autoResize={false}` so it doesn't run twice. The target must have intrinsic height; do not give it `height: 100%` or `100vh`.
128
-
129
- ```tsx
130
- <NotionCustomBlock autoResize={false}>
131
- <App />
132
- </NotionCustomBlock>;
133
-
134
- function App() {
135
- const [enabled, setEnabled] = useState(true);
136
- useCustomBlockAutoResize({ enabled });
137
- return <div>…</div>;
138
- }
139
- ```
134
+ Deprecated React wrapper around `customBlock.autoResize({ target: document.getElementById("root") })`. It measures `#root`'s height and posts `resize` messages, deduping unchanged values. `<NotionCustomBlock>` runs this automatically.
140
135
 
141
136
  ## Debug console
142
137
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/custom-blocks",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "publishConfig": {
@@ -41,7 +41,6 @@ import type {
41
41
  ListUsersArgs,
42
42
  ListUsersResult,
43
43
  NotionDataSourcePageUpdateArgs,
44
- NotionDataSourcePageUpdateResult,
45
44
  NotionPageId,
46
45
  NotionUserId,
47
46
  UpdatePageArgs,
@@ -74,6 +73,8 @@ export type MessageLogEntry = {
74
73
  data: unknown
75
74
  }
76
75
 
76
+ const INIT_RESULT_TIMER_FALLBACK_MS = 100
77
+
77
78
  export class SandboxBridge {
78
79
  private hostState: CustomBlockHostState = {
79
80
  status: "uninitialized",
@@ -102,6 +103,8 @@ export class SandboxBridge {
102
103
  private hasSentConnect = false
103
104
  private hasReceivedInit = false
104
105
  private initializationId: string | undefined
106
+ private hasSentInitResult = false
107
+ private pendingOutboundMessages: unknown[] = []
105
108
  private latestDataSourceBindings: NotionDataSourceBindings = {}
106
109
  private isMockState = false
107
110
  private isListening = false
@@ -206,11 +209,38 @@ export class SandboxBridge {
206
209
  }
207
210
 
208
211
  private postToHost(message: unknown) {
212
+ if (
213
+ this.hostState.status === "initialized" &&
214
+ !this.hasSentInitResult &&
215
+ !this.isMockState &&
216
+ this.getMessageType(message) !== "initResult"
217
+ ) {
218
+ this.pendingOutboundMessages.push(message)
219
+ return
220
+ }
221
+ this.sendToHost(message)
222
+ }
223
+
224
+ private sendToHost(message: unknown) {
209
225
  console.debug("[custom-blocks-sdk] outbound postMessage", message)
210
226
  this.logMessage("sent", message)
211
227
  window.parent.postMessage(message, "*")
212
228
  }
213
229
 
230
+ private flushPendingOutboundMessages() {
231
+ const pendingMessages = this.pendingOutboundMessages
232
+ this.pendingOutboundMessages = []
233
+ for (const message of pendingMessages) {
234
+ this.sendToHost(message)
235
+ }
236
+ }
237
+
238
+ private getMessageType(message: unknown): unknown {
239
+ return typeof message === "object" && message !== null && "type" in message
240
+ ? message.type
241
+ : undefined
242
+ }
243
+
214
244
  private notify = () => {
215
245
  for (const listener of this.listeners) {
216
246
  listener()
@@ -505,6 +535,25 @@ export class SandboxBridge {
505
535
  this.applyInit(v.parse(initMessageSchema, message), false)
506
536
  }
507
537
 
538
+ completeInitialization() {
539
+ if (
540
+ this.hasSentInitResult ||
541
+ this.initializationId === undefined ||
542
+ this.hostState.status !== "initialized"
543
+ ) {
544
+ return
545
+ }
546
+ const result: InitResultMessage = {
547
+ type: "initResult",
548
+ initializationId: this.initializationId,
549
+ status: "success",
550
+ initialHeight: getInitialContentHeight(),
551
+ }
552
+ this.hasSentInitResult = true
553
+ this.postToHost(result)
554
+ this.flushPendingOutboundMessages()
555
+ }
556
+
508
557
  private applyInit(message: InitMessage, postResult: boolean) {
509
558
  if (postResult) {
510
559
  this.isMockState = false
@@ -569,14 +618,6 @@ export class SandboxBridge {
569
618
  contrastMode: message.contrastMode,
570
619
  })
571
620
  this.notify()
572
- if (postResult) {
573
- const result: InitResultMessage = {
574
- type: "initResult",
575
- initializationId: message.initializationId,
576
- status: "success",
577
- }
578
- this.postToHost(result)
579
- }
580
621
  // Resolve the awaitInit promise once. Subsequent `init` messages
581
622
  // (the host shouldn't send these, but be tolerant) update state but
582
623
  // don't re-resolve.
@@ -585,6 +626,38 @@ export class SandboxBridge {
585
626
  this.resolveInit = undefined
586
627
  this.rejectInit = undefined
587
628
  }
629
+ if (postResult) {
630
+ this.scheduleInitResult(message.initializationId)
631
+ }
632
+ }
633
+
634
+ /**
635
+ * Lets the initial application render commit before we acknowledge init. The host keeps the
636
+ * iframe covered throughout this frame, so it can apply the measured height before first paint.
637
+ */
638
+ private scheduleInitResult(initializationId: string) {
639
+ let didAcknowledge = false
640
+ let fallbackTimerId: number | undefined
641
+ const acknowledge = () => {
642
+ if (didAcknowledge) {
643
+ return
644
+ }
645
+ didAcknowledge = true
646
+ if (fallbackTimerId !== undefined) {
647
+ window.clearTimeout(fallbackTimerId)
648
+ }
649
+ if (this.initializationId !== initializationId) {
650
+ return
651
+ }
652
+ this.completeInitialization()
653
+ }
654
+ fallbackTimerId = window.setTimeout(
655
+ acknowledge,
656
+ INIT_RESULT_TIMER_FALLBACK_MS,
657
+ )
658
+ if (typeof requestAnimationFrame === "function") {
659
+ requestAnimationFrame(acknowledge)
660
+ }
588
661
  }
589
662
 
590
663
  queryDataSource(key: string, options: UseDataSourceOptions = {}) {
@@ -807,7 +880,7 @@ export class SandboxBridge {
807
880
  dataSource: NotionDataSource
808
881
  pageId: NotionPageId
809
882
  pageUpdateArgs: NotionDataSourcePageUpdateArgs
810
- }): Promise<NotionDataSourcePageUpdateResult> {
883
+ }): Promise<UpdatePageResult> {
811
884
  const { dataSource, pageId, pageUpdateArgs } = args
812
885
  const resolvedProperties =
813
886
  pageUpdateArgs.properties === undefined
@@ -903,6 +976,17 @@ export class SandboxBridge {
903
976
  }
904
977
  }
905
978
 
979
+ function getInitialContentHeight(): number {
980
+ if (typeof document === "undefined") {
981
+ return 0
982
+ }
983
+ const root = document.getElementById("root")
984
+ if (root === null) {
985
+ return 0
986
+ }
987
+ return Math.ceil(root.getBoundingClientRect().height)
988
+ }
989
+
906
990
  /**
907
991
  * Makes the document canvas match the host appearance before acknowledging init.
908
992
  *
@@ -16,7 +16,7 @@ import type { NotionUser } from "@notionhq/custom-blocks-protocol/users/user.js"
16
16
  import type {
17
17
  NotionDataSourcePage,
18
18
  NotionDataSourcePageUpdateArgs,
19
- NotionDataSourcePageUpdateResult,
19
+ UpdatePageResult,
20
20
  } from "../types.js"
21
21
 
22
22
  export type CustomBlockHostState = UninitializedHostState | InitializedHostState
@@ -92,7 +92,7 @@ export type UpdateDataSourcePageFn = (args: {
92
92
  dataSource: NotionDataSource
93
93
  pageId: NotionPageId
94
94
  pageUpdateArgs: NotionDataSourcePageUpdateArgs
95
- }) => Promise<NotionDataSourcePageUpdateResult>
95
+ }) => Promise<UpdatePageResult>
96
96
 
97
97
  export function getDataSourceQueryView(
98
98
  hostState: CustomBlockHostState,
@@ -60,6 +60,10 @@ export const customBlockHost = {
60
60
  getBridge().setMockState(message)
61
61
  },
62
62
 
63
+ completeInitialization: () => {
64
+ getBridge().completeInitialization()
65
+ },
66
+
63
67
  postResize: (height: number) => {
64
68
  getBridge().postResize(height)
65
69
  },
@@ -1,4 +1,5 @@
1
- import { type ReactNode, useEffect, useState } from "react"
1
+ import { type ReactNode, useEffect, useLayoutEffect, useState } from "react"
2
+ import { customBlockHost } from "../bridge/sandboxClient.js"
2
3
  import { type InitCustomBlockOptions, NotInIframeError } from "../index.js"
3
4
  import { DebugMessageLog } from "./DebugMessageLog.js"
4
5
  import { seedStandalonePreviewState } from "./standalonePreview.js"
@@ -24,10 +25,9 @@ export type NotionCustomBlockProps = InitCustomBlockOptions & {
24
25
  */
25
26
  errorFallback?: ReactNode | ((error: Error) => ReactNode)
26
27
  /**
27
- * Whether the provider should automatically post resize messages so the
28
- * host iframe matches the content height of `#root`. Defaults to `true`.
29
- * Pass `false` when you want to use the default block size and are ok
30
- * with scrollbars within the Notion client.
28
+ * Whether to post resize messages after initialization and dynamically resize the block.
29
+ *
30
+ * @deprecated TODO(custom-blocks): Remove this prop when bumping the SDK version to 0.2.0.
31
31
  *
32
32
  * @default true
33
33
  */
@@ -61,7 +61,8 @@ export function NotionCustomBlock({
61
61
  autoResize = true,
62
62
  }: NotionCustomBlockProps) {
63
63
  const init = useCustomBlockInit({ timeoutMs })
64
- useCustomBlockAutoResize({ enabled: autoResize })
64
+ useCustomBlockAutoResize({ enabled: init.isLoaded && autoResize })
65
+ // True if the block has no host (i.e. it's running in standalone preview).
65
66
  const isStandalone = init.error instanceof NotInIframeError
66
67
  const host = useCustomBlockHost()
67
68
  const [debugOpen, setDebugOpen] = useState(false)
@@ -84,6 +85,15 @@ export function NotionCustomBlock({
84
85
  seedStandalonePreviewState()
85
86
  }, [isStandalone, init.error])
86
87
 
88
+ useLayoutEffect(() => {
89
+ if (!init.isLoaded || isStandalone) {
90
+ return
91
+ }
92
+ // Send `initResult` *after* React renders the block so the SDK can report its rendered
93
+ // height to the host as part of the `initResult` message.
94
+ customBlockHost.completeInitialization()
95
+ }, [init.isLoaded, isStandalone])
96
+
87
97
  if (debugOpen) {
88
98
  return <DebugMessageLog />
89
99
  }
@@ -5,16 +5,12 @@ import { customBlock } from "../index.js"
5
5
  * Measures the sandbox's `#root` element and posts `resize` messages so the host iframe
6
6
  * matches the block's border-box height. Unchanged values are deduped.
7
7
  *
8
- * `<NotionCustomBlock>` calls this hook for you by default only reach for it directly
9
- * when you need to drive `enabled` yourself (e.g. behind a debug toggle). In that case,
10
- * pass `autoResize={false}` to the provider to avoid running it twice. For full-bleed
11
- * views that should fill their slot, pass `autoResize={false}` and skip the hook.
8
+ * `<NotionCustomBlock>` calls this hook for you. Only use it directly in a custom
9
+ * initialization wrapper that does not render `<NotionCustomBlock>`.
12
10
  *
13
- * @example
14
- * <NotionCustomBlock autoResize={false}>
15
- * <App />
16
- * </NotionCustomBlock>
11
+ * @deprecated Use CSS `max-height` and `overflow` to constrain block content instead.
17
12
  *
13
+ * @example
18
14
  * function App() {
19
15
  * const [enabled, setEnabled] = useState(true)
20
16
  * useCustomBlockAutoResize({ enabled })
package/src/types.ts CHANGED
@@ -5,27 +5,36 @@ import type {
5
5
  NotionDataSourceId,
6
6
  NotionPageId,
7
7
  } from "@notionhq/custom-blocks-protocol/ids.js"
8
+ import type { BridgeMessagePayload } from "@notionhq/custom-blocks-protocol/messagePayload.js"
8
9
  import type { NotionCreatePagePosition } from "@notionhq/custom-blocks-protocol/messages/createPage.js"
9
- import type { CustomBlockCreatePageErrorInfo } from "@notionhq/custom-blocks-protocol/messages/createPageResult.js"
10
- import type { CustomBlockGetPageErrorInfo } from "@notionhq/custom-blocks-protocol/messages/getPage.js"
11
- import type { CustomBlockGetUserErrorInfo } from "@notionhq/custom-blocks-protocol/messages/getUser.js"
10
+ import type {
11
+ CreatePageResultMessage,
12
+ CustomBlockCreatePageErrorInfo,
13
+ } from "@notionhq/custom-blocks-protocol/messages/createPageResult.js"
14
+ import type {
15
+ CustomBlockGetPageErrorInfo,
16
+ GetPageResultMessage,
17
+ } from "@notionhq/custom-blocks-protocol/messages/getPage.js"
18
+ import type {
19
+ CustomBlockGetUserErrorInfo,
20
+ GetUserResultMessage,
21
+ } from "@notionhq/custom-blocks-protocol/messages/getUser.js"
12
22
  import type {
13
23
  CustomBlockListUsersErrorInfo,
14
24
  ListUsersMessage,
25
+ ListUsersResultMessage,
15
26
  } from "@notionhq/custom-blocks-protocol/messages/listUsers.js"
16
27
  import type { CustomBlockQueryDataSourceErrorInfo } from "@notionhq/custom-blocks-protocol/messages/queryDataSourceResult.js"
17
28
  import type { UpdatePageMessage } from "@notionhq/custom-blocks-protocol/messages/updatePage.js"
18
- import type { CustomBlockUpdatePageErrorInfo } from "@notionhq/custom-blocks-protocol/messages/updatePageResult.js"
19
29
  import type {
20
- NotionPage,
30
+ CustomBlockUpdatePageErrorInfo,
31
+ UpdatePageResultMessage,
32
+ } from "@notionhq/custom-blocks-protocol/messages/updatePageResult.js"
33
+ import type {
21
34
  NotionPageCover,
22
35
  NotionPageIcon,
23
36
  NotionPagePropertyValue,
24
37
  } from "@notionhq/custom-blocks-protocol/pages/page.js"
25
- import type {
26
- NotionUser,
27
- NotionUserList,
28
- } from "@notionhq/custom-blocks-protocol/users/user.js"
29
38
 
30
39
  export type { CustomBlockErrorInfo } from "@notionhq/custom-blocks-protocol/errors.js"
31
40
  export type {
@@ -84,9 +93,7 @@ export type NotionDataSourcePage = {
84
93
  * Updates this page using the data source's property-key bindings. The SDK resolves property
85
94
  * keys to raw property IDs before sending the bridge message to the host.
86
95
  */
87
- update: (
88
- args: NotionDataSourcePageUpdateArgs,
89
- ) => Promise<NotionDataSourcePageUpdateResult>
96
+ update: (args: NotionDataSourcePageUpdateArgs) => Promise<UpdatePageResult>
90
97
  }
91
98
 
92
99
  export type NotionDataSourcePageUpdateArgs = {
@@ -103,12 +110,12 @@ export type NotionDataSourcePageUpdateArgs = {
103
110
  */
104
111
  export type NotionDataSourcePageUpdateInput = NotionDataSourcePageUpdateArgs
105
112
 
106
- export type NotionDataSourcePageUpdateResult =
107
- | {
108
- status: "success"
109
- page: NotionPage
110
- }
111
- | { status: "error"; error: CustomBlockUpdatePageErrorInfo }
113
+ /**
114
+ * @deprecated Use `UpdatePageResult` instead.
115
+ *
116
+ * TODO(custom-blocks): Remove this alias when bumping the SDK version to 0.2.0.
117
+ */
118
+ export type NotionDataSourcePageUpdateResult = UpdatePageResult
112
119
 
113
120
  /**
114
121
  * Return shape of `useDataSource`.
@@ -190,13 +197,10 @@ export type CreatePageInput = CreatePageArgs
190
197
  /**
191
198
  * The result of a `sdk.pages.create` API call.
192
199
  */
193
- export type CreatePageResult =
194
- | {
195
- status: "success"
196
- /** The newly created page. */
197
- page: NotionPage
198
- }
199
- | { status: "error"; error: CustomBlockCreatePageErrorInfo }
200
+ export type CreatePageResult = BridgeMessagePayload<
201
+ CreatePageResultMessage,
202
+ CustomBlockCreatePageErrorInfo
203
+ >
200
204
 
201
205
  export type UpdatePageArgs = Omit<UpdatePageMessage, "type" | "requestId">
202
206
 
@@ -210,22 +214,18 @@ export type UpdatePageInput = UpdatePageArgs
210
214
  /**
211
215
  * Result of `sdk.pages.get`.
212
216
  */
213
- export type GetPageResult =
214
- | {
215
- status: "success"
216
- page: NotionPage
217
- }
218
- | { status: "error"; error: CustomBlockGetPageErrorInfo }
217
+ export type GetPageResult = BridgeMessagePayload<
218
+ GetPageResultMessage,
219
+ CustomBlockGetPageErrorInfo
220
+ >
219
221
 
220
222
  /**
221
223
  * Result of `sdk.pages.update` / `sdk.pages.delete`.
222
224
  */
223
- export type UpdatePageResult =
224
- | {
225
- status: "success"
226
- page: NotionPage
227
- }
228
- | { status: "error"; error: CustomBlockUpdatePageErrorInfo }
225
+ export type UpdatePageResult = BridgeMessagePayload<
226
+ UpdatePageResultMessage,
227
+ CustomBlockUpdatePageErrorInfo
228
+ >
229
229
 
230
230
  export type ListUsersArgs = Omit<ListUsersMessage, "type" | "requestId">
231
231
 
@@ -236,16 +236,12 @@ export type ListUsersArgs = Omit<ListUsersMessage, "type" | "requestId">
236
236
  */
237
237
  export type ListUsersInput = ListUsersArgs
238
238
 
239
- export type ListUsersResult =
240
- | {
241
- status: "success"
242
- list: NotionUserList
243
- }
244
- | { status: "error"; error: CustomBlockListUsersErrorInfo }
245
-
246
- export type GetUserResult =
247
- | {
248
- status: "success"
249
- user: NotionUser
250
- }
251
- | { status: "error"; error: CustomBlockGetUserErrorInfo }
239
+ export type ListUsersResult = BridgeMessagePayload<
240
+ ListUsersResultMessage,
241
+ CustomBlockListUsersErrorInfo
242
+ >
243
+
244
+ export type GetUserResult = BridgeMessagePayload<
245
+ GetUserResultMessage,
246
+ CustomBlockGetUserErrorInfo
247
+ >