@notionhq/custom-blocks 0.0.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HOST.md +171 -0
- package/README.md +57 -0
- package/bin/cli/attach.js +180 -0
- package/bin/cli/cli.js +248 -0
- package/bin/cli/create.js +106 -0
- package/bin/cli/datasources.js +255 -0
- package/bin/cli/deploy.js +109 -0
- package/bin/cli/ids.js +13 -0
- package/bin/cli/ntn.js +95 -0
- package/bin/cli/pullData.js +76 -0
- package/bin/cli/pullManifest.js +158 -0
- package/bin/cli/target.js +95 -0
- package/bin/src/bridge/dataSources/propertySchema.js +148 -0
- package/bin/src/bridge/manifest.js +40 -0
- package/dist/autoResize.d.ts +4 -0
- package/dist/autoResize.d.ts.map +1 -0
- package/dist/autoResize.js +71 -0
- package/dist/bridge/SandboxBridge.d.ts +92 -0
- package/dist/bridge/SandboxBridge.d.ts.map +1 -0
- package/dist/bridge/SandboxBridge.js +718 -0
- package/dist/bridge/dataSources/dataSource.d.ts +732 -0
- package/dist/bridge/dataSources/dataSource.d.ts.map +1 -0
- package/dist/bridge/dataSources/dataSource.js +37 -0
- package/dist/bridge/dataSources/dataSourcePage.d.ts +118 -0
- package/dist/bridge/dataSources/dataSourcePage.d.ts.map +1 -0
- package/dist/bridge/dataSources/dataSourcePage.js +14 -0
- package/dist/bridge/dataSources/dataSourceValue.d.ts +67 -0
- package/dist/bridge/dataSources/dataSourceValue.d.ts.map +1 -0
- package/dist/bridge/dataSources/dataSourceValue.js +14 -0
- package/dist/bridge/dataSources/dateValue.d.ts +158 -0
- package/dist/bridge/dataSources/dateValue.d.ts.map +1 -0
- package/dist/bridge/dataSources/dateValue.js +59 -0
- package/dist/bridge/dataSources/errors.d.ts +6 -0
- package/dist/bridge/dataSources/errors.d.ts.map +1 -0
- package/dist/bridge/dataSources/errors.js +4 -0
- package/dist/bridge/dataSources/propertySchema.d.ts +191 -0
- package/dist/bridge/dataSources/propertySchema.d.ts.map +1 -0
- package/dist/bridge/dataSources/propertySchema.js +148 -0
- package/dist/bridge/dataSources/recordPointer.d.ts +10 -0
- package/dist/bridge/dataSources/recordPointer.d.ts.map +1 -0
- package/dist/bridge/dataSources/recordPointer.js +8 -0
- package/dist/bridge/dataSources/resolve.d.ts +22 -0
- package/dist/bridge/dataSources/resolve.d.ts.map +1 -0
- package/dist/bridge/dataSources/resolve.js +65 -0
- package/dist/bridge/dataSources/resolveProperty.d.ts +41 -0
- package/dist/bridge/dataSources/resolveProperty.d.ts.map +1 -0
- package/dist/bridge/dataSources/resolveProperty.js +73 -0
- package/dist/bridge/errors.d.ts +12 -0
- package/dist/bridge/errors.d.ts.map +1 -0
- package/dist/bridge/errors.js +6 -0
- package/dist/bridge/hostState.d.ts +65 -0
- package/dist/bridge/hostState.d.ts.map +1 -0
- package/dist/bridge/hostState.js +65 -0
- package/dist/bridge/ids.d.ts +39 -0
- package/dist/bridge/ids.d.ts.map +1 -0
- package/dist/bridge/ids.js +5 -0
- package/dist/bridge/incomingType.d.ts +10 -0
- package/dist/bridge/incomingType.d.ts.map +1 -0
- package/dist/bridge/incomingType.js +17 -0
- package/dist/bridge/loadManifest.d.ts +25 -0
- package/dist/bridge/loadManifest.d.ts.map +1 -0
- package/dist/bridge/loadManifest.js +68 -0
- package/dist/bridge/manifest.d.ts +66 -0
- package/dist/bridge/manifest.d.ts.map +1 -0
- package/dist/bridge/manifest.js +40 -0
- package/dist/bridge/messages/createPage.d.ts +225 -0
- package/dist/bridge/messages/createPage.d.ts.map +1 -0
- package/dist/bridge/messages/createPage.js +46 -0
- package/dist/bridge/messages/createPageResult.d.ts +211 -0
- package/dist/bridge/messages/createPageResult.d.ts.map +1 -0
- package/dist/bridge/messages/createPageResult.js +28 -0
- package/dist/bridge/messages/currentUserChanged.d.ts +19 -0
- package/dist/bridge/messages/currentUserChanged.d.ts.map +1 -0
- package/dist/bridge/messages/currentUserChanged.js +9 -0
- package/dist/bridge/messages/dataSourcesChanged.d.ts +158 -0
- package/dist/bridge/messages/dataSourcesChanged.d.ts.map +1 -0
- package/dist/bridge/messages/dataSourcesChanged.js +13 -0
- package/dist/bridge/messages/getPage.d.ts +216 -0
- package/dist/bridge/messages/getPage.d.ts.map +1 -0
- package/dist/bridge/messages/getPage.js +33 -0
- package/dist/bridge/messages/getUser.d.ts +45 -0
- package/dist/bridge/messages/getUser.d.ts.map +1 -0
- package/dist/bridge/messages/getUser.js +32 -0
- package/dist/bridge/messages/hostToSandbox.d.ts +1089 -0
- package/dist/bridge/messages/hostToSandbox.d.ts.map +1 -0
- package/dist/bridge/messages/hostToSandbox.js +32 -0
- package/dist/bridge/messages/init.d.ts +209 -0
- package/dist/bridge/messages/init.d.ts.map +1 -0
- package/dist/bridge/messages/init.js +47 -0
- package/dist/bridge/messages/invalidHostMessage.d.ts +15 -0
- package/dist/bridge/messages/invalidHostMessage.d.ts.map +1 -0
- package/dist/bridge/messages/invalidHostMessage.js +13 -0
- package/dist/bridge/messages/invalidSandboxMessage.d.ts +15 -0
- package/dist/bridge/messages/invalidSandboxMessage.d.ts.map +1 -0
- package/dist/bridge/messages/invalidSandboxMessage.js +13 -0
- package/dist/bridge/messages/listUsers.d.ts +53 -0
- package/dist/bridge/messages/listUsers.d.ts.map +1 -0
- package/dist/bridge/messages/listUsers.js +33 -0
- package/dist/bridge/messages/pageChanged.d.ts +12 -0
- package/dist/bridge/messages/pageChanged.d.ts.map +1 -0
- package/dist/bridge/messages/pageChanged.js +9 -0
- package/dist/bridge/messages/parentChanged.d.ts +22 -0
- package/dist/bridge/messages/parentChanged.d.ts.map +1 -0
- package/dist/bridge/messages/parentChanged.js +9 -0
- package/dist/bridge/messages/queryDataSource.d.ts +20 -0
- package/dist/bridge/messages/queryDataSource.d.ts.map +1 -0
- package/dist/bridge/messages/queryDataSource.js +19 -0
- package/dist/bridge/messages/queryDataSourceResult.d.ts +90 -0
- package/dist/bridge/messages/queryDataSourceResult.d.ts.map +1 -0
- package/dist/bridge/messages/queryDataSourceResult.js +21 -0
- package/dist/bridge/messages/ready.d.ts +45 -0
- package/dist/bridge/messages/ready.d.ts.map +1 -0
- package/dist/bridge/messages/ready.js +37 -0
- package/dist/bridge/messages/resize.d.ts +12 -0
- package/dist/bridge/messages/resize.d.ts.map +1 -0
- package/dist/bridge/messages/resize.js +10 -0
- package/dist/bridge/messages/sandboxToHost.d.ts +410 -0
- package/dist/bridge/messages/sandboxToHost.d.ts.map +1 -0
- package/dist/bridge/messages/sandboxToHost.js +25 -0
- package/dist/bridge/messages/themeChanged.d.ts +11 -0
- package/dist/bridge/messages/themeChanged.d.ts.map +1 -0
- package/dist/bridge/messages/themeChanged.js +10 -0
- package/dist/bridge/messages/updatePage.d.ts +171 -0
- package/dist/bridge/messages/updatePage.d.ts.map +1 -0
- package/dist/bridge/messages/updatePage.js +15 -0
- package/dist/bridge/messages/updatePageResult.d.ts +210 -0
- package/dist/bridge/messages/updatePageResult.d.ts.map +1 -0
- package/dist/bridge/messages/updatePageResult.js +27 -0
- package/dist/bridge/pages/page.d.ts +600 -0
- package/dist/bridge/pages/page.d.ts.map +1 -0
- package/dist/bridge/pages/page.js +217 -0
- package/dist/bridge/parent.d.ts +25 -0
- package/dist/bridge/parent.d.ts.map +1 -0
- package/dist/bridge/parent.js +11 -0
- package/dist/bridge/pendingRequests.d.ts +14 -0
- package/dist/bridge/pendingRequests.d.ts.map +1 -0
- package/dist/bridge/pendingRequests.js +27 -0
- package/dist/bridge/sandboxClient.d.ts +63 -0
- package/dist/bridge/sandboxClient.d.ts.map +1 -0
- package/dist/bridge/sandboxClient.js +92 -0
- package/dist/bridge/theme.d.ts +4 -0
- package/dist/bridge/theme.d.ts.map +1 -0
- package/dist/bridge/theme.js +2 -0
- package/dist/bridge/users/user.d.ts +36 -0
- package/dist/bridge/users/user.d.ts.map +1 -0
- package/dist/bridge/users/user.js +19 -0
- package/dist/customBlock.d.ts +36 -0
- package/dist/customBlock.d.ts.map +1 -0
- package/dist/customBlock.js +65 -0
- package/dist/host/createCustomBlockHost.d.ts +34 -0
- package/dist/host/createCustomBlockHost.d.ts.map +1 -0
- package/dist/host/createCustomBlockHost.js +278 -0
- package/dist/host/lifecycle/initErrors.d.ts +10 -0
- package/dist/host/lifecycle/initErrors.d.ts.map +1 -0
- package/dist/host/lifecycle/initErrors.js +123 -0
- package/dist/host/lifecycle/ready.d.ts +8 -0
- package/dist/host/lifecycle/ready.d.ts.map +1 -0
- package/dist/host/lifecycle/ready.js +24 -0
- package/dist/host/lifecycle/types.d.ts +24 -0
- package/dist/host/lifecycle/types.d.ts.map +1 -0
- package/dist/host/lifecycle/types.js +1 -0
- package/dist/host/messages/invalidSandboxMessage.d.ts +7 -0
- package/dist/host/messages/invalidSandboxMessage.d.ts.map +1 -0
- package/dist/host/messages/invalidSandboxMessage.js +24 -0
- package/dist/host/messages/types.d.ts +60 -0
- package/dist/host/messages/types.d.ts.map +1 -0
- package/dist/host/messages/types.js +1 -0
- package/dist/host/queries/querySubscriptions.d.ts +20 -0
- package/dist/host/queries/querySubscriptions.d.ts.map +1 -0
- package/dist/host/queries/querySubscriptions.js +29 -0
- package/dist/host/queries/types.d.ts +9 -0
- package/dist/host/queries/types.d.ts.map +1 -0
- package/dist/host/queries/types.js +1 -0
- package/dist/host.d.ts +73 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +42 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/init.d.ts +53 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +87 -0
- package/dist/react/DebugMessageLog.d.ts +2 -0
- package/dist/react/DebugMessageLog.d.ts.map +1 -0
- package/dist/react/DebugMessageLog.js +22 -0
- package/dist/react/NotionCustomBlock.css +110 -0
- package/dist/react/NotionCustomBlock.d.ts +50 -0
- package/dist/react/NotionCustomBlock.d.ts.map +1 -0
- package/dist/react/NotionCustomBlock.js +81 -0
- package/dist/react/index.d.ts +14 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +13 -0
- package/dist/react/standalonePreview.d.ts +2 -0
- package/dist/react/standalonePreview.d.ts.map +1 -0
- package/dist/react/standalonePreview.js +26 -0
- package/dist/react/useCustomBlockAutoResize.d.ts +30 -0
- package/dist/react/useCustomBlockAutoResize.d.ts.map +1 -0
- package/dist/react/useCustomBlockAutoResize.js +35 -0
- package/dist/react/useCustomBlockInit.d.ts +43 -0
- package/dist/react/useCustomBlockInit.d.ts.map +1 -0
- package/dist/react/useCustomBlockInit.js +60 -0
- package/dist/react/useDataSource.d.ts +13 -0
- package/dist/react/useDataSource.d.ts.map +1 -0
- package/dist/react/useDataSource.js +37 -0
- package/dist/react/useHostState.d.ts +2 -0
- package/dist/react/useHostState.d.ts.map +1 -0
- package/dist/react/useHostState.js +5 -0
- package/dist/react/useRuntimeState.d.ts +66 -0
- package/dist/react/useRuntimeState.d.ts.map +1 -0
- package/dist/react/useRuntimeState.js +73 -0
- package/dist/types.d.ts +154 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +10 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/docs/block-location.md +83 -0
- package/docs/data-sources.md +186 -0
- package/docs/lifecycle.md +172 -0
- package/docs/manifest.md +42 -0
- package/docs/pages.md +143 -0
- package/docs/users.md +92 -0
- package/package.json +69 -0
- package/src/autoResize.ts +84 -0
- package/src/bridge/SandboxBridge.ts +921 -0
- package/src/bridge/dataSources/dataSource.ts +63 -0
- package/src/bridge/dataSources/dataSourcePage.ts +71 -0
- package/src/bridge/dataSources/dataSourceValue.ts +19 -0
- package/src/bridge/dataSources/dateValue.ts +96 -0
- package/src/bridge/dataSources/errors.ts +14 -0
- package/src/bridge/dataSources/propertySchema.ts +186 -0
- package/src/bridge/dataSources/recordPointer.ts +13 -0
- package/src/bridge/dataSources/resolve.ts +99 -0
- package/src/bridge/dataSources/resolveProperty.ts +130 -0
- package/src/bridge/errors.ts +13 -0
- package/src/bridge/hostState.ts +154 -0
- package/src/bridge/ids.ts +58 -0
- package/src/bridge/incomingType.ts +19 -0
- package/src/bridge/loadManifest.ts +89 -0
- package/src/bridge/manifest.ts +53 -0
- package/src/bridge/messages/createPage.ts +67 -0
- package/src/bridge/messages/createPageResult.ts +52 -0
- package/src/bridge/messages/currentUserChanged.ts +14 -0
- package/src/bridge/messages/dataSourcesChanged.ts +18 -0
- package/src/bridge/messages/getPage.ts +52 -0
- package/src/bridge/messages/getUser.ts +48 -0
- package/src/bridge/messages/hostToSandbox.ts +37 -0
- package/src/bridge/messages/init.ts +81 -0
- package/src/bridge/messages/invalidHostMessage.ts +16 -0
- package/src/bridge/messages/invalidSandboxMessage.ts +18 -0
- package/src/bridge/messages/listUsers.ts +49 -0
- package/src/bridge/messages/pageChanged.ts +12 -0
- package/src/bridge/messages/parentChanged.ts +14 -0
- package/src/bridge/messages/queryDataSource.ts +24 -0
- package/src/bridge/messages/queryDataSourceResult.ts +38 -0
- package/src/bridge/messages/ready.ts +41 -0
- package/src/bridge/messages/resize.ts +13 -0
- package/src/bridge/messages/sandboxToHost.ts +30 -0
- package/src/bridge/messages/themeChanged.ts +15 -0
- package/src/bridge/messages/updatePage.ts +22 -0
- package/src/bridge/messages/updatePageResult.ts +49 -0
- package/src/bridge/pages/page.ts +281 -0
- package/src/bridge/parent.ts +27 -0
- package/src/bridge/pendingRequests.ts +28 -0
- package/src/bridge/sandboxClient.ts +137 -0
- package/src/bridge/theme.ts +5 -0
- package/src/bridge/users/user.ts +31 -0
- package/src/css.d.ts +1 -0
- package/src/customBlock.ts +102 -0
- package/src/host/createCustomBlockHost.ts +392 -0
- package/src/host/lifecycle/initErrors.ts +132 -0
- package/src/host/lifecycle/ready.ts +36 -0
- package/src/host/lifecycle/types.ts +28 -0
- package/src/host/messages/invalidSandboxMessage.ts +38 -0
- package/src/host/messages/types.ts +67 -0
- package/src/host/queries/querySubscriptions.ts +52 -0
- package/src/host/queries/types.ts +16 -0
- package/src/host.ts +167 -0
- package/src/index.ts +115 -0
- package/src/init.ts +143 -0
- package/src/react/DebugMessageLog.tsx +30 -0
- package/src/react/NotionCustomBlock.css +110 -0
- package/src/react/NotionCustomBlock.tsx +151 -0
- package/src/react/index.ts +28 -0
- package/src/react/standalonePreview.ts +28 -0
- package/src/react/useCustomBlockAutoResize.ts +46 -0
- package/src/react/useCustomBlockInit.ts +91 -0
- package/src/react/useDataSource.ts +47 -0
- package/src/react/useHostState.ts +9 -0
- package/src/react/useRuntimeState.ts +85 -0
- package/src/types.ts +175 -0
- package/src/utils.ts +13 -0
- package/src/version.ts +8 -0
- package/vite-plugin/index.d.ts +46 -0
- package/vite-plugin/index.js +115 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { NotionCollectionSchema } from "./bridge/dataSources/dataSource.js";
|
|
2
|
+
import type { NotionDataSourcePage, NotionDataSourcePageUpdateInput, NotionDataSourcePageUpdateResult } from "./bridge/dataSources/dataSourcePage.js";
|
|
3
|
+
import type { NotionPropertySchema } from "./bridge/dataSources/propertySchema.js";
|
|
4
|
+
import type { CustomBlockErrorInfo } from "./bridge/errors.js";
|
|
5
|
+
import type { NotionDataSourceId } from "./bridge/ids.js";
|
|
6
|
+
import type { NotionCreatePagePosition } from "./bridge/messages/createPage.js";
|
|
7
|
+
import type { CustomBlockCreatePageErrorInfo } from "./bridge/messages/createPageResult.js";
|
|
8
|
+
import type { CustomBlockGetPageErrorInfo } from "./bridge/messages/getPage.js";
|
|
9
|
+
import type { CustomBlockGetUserErrorInfo } from "./bridge/messages/getUser.js";
|
|
10
|
+
import type { CustomBlockListUsersErrorInfo } from "./bridge/messages/listUsers.js";
|
|
11
|
+
import type { CustomBlockQueryDataSourceErrorInfo } from "./bridge/messages/queryDataSourceResult.js";
|
|
12
|
+
import type { CustomBlockUpdatePageErrorInfo } from "./bridge/messages/updatePageResult.js";
|
|
13
|
+
import type { NotionPage, NotionPageCover, NotionPageIcon, NotionPageId, NotionPagePropertyInputMap, NotionPagePropertyWriteMap } from "./bridge/pages/page.js";
|
|
14
|
+
import type { NotionUser, NotionUserList } from "./bridge/users/user.js";
|
|
15
|
+
export type { NotionDataSourceId, NotionSpaceId } from "./bridge/ids.js";
|
|
16
|
+
export type { NotionPageId } from "./bridge/pages/page.js";
|
|
17
|
+
export type { NotionUser, NotionUserId, NotionUserList, } from "./bridge/users/user.js";
|
|
18
|
+
export type { CustomBlockCreatePageErrorInfo, CustomBlockErrorInfo, CustomBlockGetPageErrorInfo, CustomBlockGetUserErrorInfo, CustomBlockListUsersErrorInfo, CustomBlockQueryDataSourceErrorInfo, CustomBlockUpdatePageErrorInfo, NotionDataSourcePageUpdateInput, NotionDataSourcePageUpdateResult, };
|
|
19
|
+
/**
|
|
20
|
+
* Return shape of `useDataSource`.
|
|
21
|
+
*
|
|
22
|
+
* - `items` — the rows the host has returned so far. Empty until the first response arrives.
|
|
23
|
+
* - `isLoading` — `true` while a query is in flight.
|
|
24
|
+
* - `hasMore` — `true` if the host indicated more rows are available beyond the current page.
|
|
25
|
+
* - `error` — structured error information if the most recent query failed.
|
|
26
|
+
*/
|
|
27
|
+
export type UseDataSourceResult = {
|
|
28
|
+
items: NotionDataSourcePage[];
|
|
29
|
+
/**
|
|
30
|
+
* Collection/data-source schema for the bound Notion data source, including raw property
|
|
31
|
+
* schemas. Undefined when the semantic data-source key has not been bound.
|
|
32
|
+
*/
|
|
33
|
+
collectionSchema?: NotionCollectionSchema;
|
|
34
|
+
/**
|
|
35
|
+
* Per-property schemas keyed by raw property ID, including the four synthetic built-ins
|
|
36
|
+
* (`created_time`, `last_edited_time`, `created_by`, `last_edited_by`).
|
|
37
|
+
*/
|
|
38
|
+
propertySchemasById: {
|
|
39
|
+
[propertyId: string]: NotionPropertySchema;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Per-property schemas keyed by user-defined keys from the data source's `propertyIdsByKey`.
|
|
43
|
+
* Built-ins are NOT included here. Keys mapped to `undefined` indicate a declared-but-unbound
|
|
44
|
+
* slot.
|
|
45
|
+
*/
|
|
46
|
+
propertySchemasByKey: {
|
|
47
|
+
[key: string]: NotionPropertySchema | undefined;
|
|
48
|
+
};
|
|
49
|
+
isLoading: boolean;
|
|
50
|
+
hasMore: boolean;
|
|
51
|
+
error?: CustomBlockQueryDataSourceErrorInfo;
|
|
52
|
+
};
|
|
53
|
+
export type UseDataSourceOptions = {
|
|
54
|
+
/**
|
|
55
|
+
* Maximum number of rows to request from the host. Defaults to 20.
|
|
56
|
+
*/
|
|
57
|
+
limit?: number;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Parent reference accepted by `sdk.pages.create`. Mirrors Notion's public `POST /v1/pages`
|
|
61
|
+
* parent shape; see https://developers.notion.com/reference/data-source.
|
|
62
|
+
*
|
|
63
|
+
* - `page_id`: Create a child page under the given Notion page.
|
|
64
|
+
* - `data_source_id`: Create a row inside the given Notion data source (aka the internal
|
|
65
|
+
* collection). The public API's `data_source_id` is the same UUID as the `collectionPointer.id`
|
|
66
|
+
* exposed in `dataSources`, so either value works here.
|
|
67
|
+
* - `data_source_key`: Create a row inside the data source that the custom block was configured with
|
|
68
|
+
* under this semantic key. The SDK resolves the key to a `data_source_id` locally before
|
|
69
|
+
* sending the request to the host.
|
|
70
|
+
*/
|
|
71
|
+
export type CreatePageParent = {
|
|
72
|
+
type: "page_id";
|
|
73
|
+
page_id: NotionPageId;
|
|
74
|
+
} | {
|
|
75
|
+
type: "data_source_id";
|
|
76
|
+
data_source_id: NotionDataSourceId;
|
|
77
|
+
} | {
|
|
78
|
+
type: "data_source_key";
|
|
79
|
+
key: string;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Input accepted by `sdk.pages.create`. Mirrors the Notion public API `POST /v1/pages` API.
|
|
83
|
+
*/
|
|
84
|
+
export type CreatePageInput = {
|
|
85
|
+
parent: CreatePageParent;
|
|
86
|
+
properties: NotionPagePropertyInputMap;
|
|
87
|
+
icon?: NotionPageIcon;
|
|
88
|
+
cover?: NotionPageCover;
|
|
89
|
+
position?: NotionCreatePagePosition;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The result of a `sdk.pages.create` API call.
|
|
93
|
+
*/
|
|
94
|
+
export type CreatePageResult = {
|
|
95
|
+
status: "success";
|
|
96
|
+
/** The newly created page. */
|
|
97
|
+
page: NotionPage;
|
|
98
|
+
} | {
|
|
99
|
+
status: "error";
|
|
100
|
+
error: CustomBlockCreatePageErrorInfo;
|
|
101
|
+
};
|
|
102
|
+
/**
|
|
103
|
+
* Input accepted by `sdk.pages.update`.
|
|
104
|
+
*
|
|
105
|
+
* `properties` is keyed by raw Notion property ID. To update a row with configured
|
|
106
|
+
* custom-block property keys, use the `update` helper on pages returned from
|
|
107
|
+
* `useDataSource`.
|
|
108
|
+
*/
|
|
109
|
+
export type UpdatePageInput = {
|
|
110
|
+
pageId: NotionPageId;
|
|
111
|
+
properties?: NotionPagePropertyWriteMap;
|
|
112
|
+
icon?: NotionPageIcon;
|
|
113
|
+
cover?: NotionPageCover;
|
|
114
|
+
archived?: boolean;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Result of `sdk.pages.get`.
|
|
118
|
+
*/
|
|
119
|
+
export type GetPageResult = {
|
|
120
|
+
status: "success";
|
|
121
|
+
page: NotionPage;
|
|
122
|
+
} | {
|
|
123
|
+
status: "error";
|
|
124
|
+
error: CustomBlockGetPageErrorInfo;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Result of `sdk.pages.update` / `sdk.pages.delete`.
|
|
128
|
+
*/
|
|
129
|
+
export type UpdatePageResult = {
|
|
130
|
+
status: "success";
|
|
131
|
+
page: NotionPage;
|
|
132
|
+
} | {
|
|
133
|
+
status: "error";
|
|
134
|
+
error: CustomBlockUpdatePageErrorInfo;
|
|
135
|
+
};
|
|
136
|
+
export type ListUsersInput = {
|
|
137
|
+
startCursor?: string;
|
|
138
|
+
pageSize?: number;
|
|
139
|
+
};
|
|
140
|
+
export type ListUsersResult = {
|
|
141
|
+
status: "success";
|
|
142
|
+
list: NotionUserList;
|
|
143
|
+
} | {
|
|
144
|
+
status: "error";
|
|
145
|
+
error: CustomBlockListUsersErrorInfo;
|
|
146
|
+
};
|
|
147
|
+
export type GetUserResult = {
|
|
148
|
+
status: "success";
|
|
149
|
+
user: NotionUser;
|
|
150
|
+
} | {
|
|
151
|
+
status: "error";
|
|
152
|
+
error: CustomBlockGetUserErrorInfo;
|
|
153
|
+
};
|
|
154
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../../../../Users/nsarkar/work/custom-blocks/sdk/src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal helpers shared across the SDK.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Throws an error when an unexpected value is encountered. This is used to ensure all code paths
|
|
6
|
+
* are covered when using discriminated unions.
|
|
7
|
+
*/
|
|
8
|
+
export declare function unreachable(value: never): never;
|
|
9
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../../../Users/nsarkar/work/custom-blocks/sdk/src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAI/C"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal helpers shared across the SDK.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Throws an error when an unexpected value is encountered. This is used to ensure all code paths
|
|
6
|
+
* are covered when using discriminated unions.
|
|
7
|
+
*/
|
|
8
|
+
export function unreachable(value) {
|
|
9
|
+
throw new Error(`[notion-custom-sdk] Unexpected value encountered: ${JSON.stringify(value)}`);
|
|
10
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime SDK package version. Sent over the bridge for host-side analytics only. Business logic
|
|
3
|
+
* should compare against the bridge protocol version instead of this value.
|
|
4
|
+
*
|
|
5
|
+
* This checked-in value intentionally stays generic for local development. The SDK publish build
|
|
6
|
+
* overwrites the compiled runtime module with package.json's semver before publishing.
|
|
7
|
+
*/
|
|
8
|
+
export declare const NCBLOCK_SDK_VERSION: string;
|
|
9
|
+
//# sourceMappingURL=version.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../../../../../Users/nsarkar/work/custom-blocks/sdk/src/version.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAgB,CAAA"}
|
package/dist/version.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime SDK package version. Sent over the bridge for host-side analytics only.
|
|
3
|
+
* Business logic should compare against the bridge protocol version instead of this value.
|
|
4
|
+
*
|
|
5
|
+
* WARNING: Generated during SDK publish. Do not edit in the published package.
|
|
6
|
+
*/
|
|
7
|
+
export const NCBLOCK_SDK_VERSION = "0.0.58"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Block Location & Theme
|
|
2
|
+
|
|
3
|
+
Every custom block runs inside a larger Notion document. These hooks expose the block's own ID, the container it sits inside, the nearest enclosing page ID, and how the surrounding Notion app is currently presented (e.g. light vs. dark theme).
|
|
4
|
+
|
|
5
|
+
## API
|
|
6
|
+
|
|
7
|
+
The host bridge carries these values as explicit `blockId`, `parent`, and `page` fields.
|
|
8
|
+
|
|
9
|
+
### `useBlockId()`
|
|
10
|
+
|
|
11
|
+
Returns the custom block's own ID.
|
|
12
|
+
|
|
13
|
+
Re-renders when the host sends a block location update.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
function useBlockId(): NotionBlockId;
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
For non-React renderers, use `customBlock.getBlockId()` after `initCustomBlock()` resolves:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
await initCustomBlock();
|
|
23
|
+
|
|
24
|
+
const blockId = customBlock.getBlockId();
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### `useParent()`
|
|
28
|
+
|
|
29
|
+
Returns the block's parent in the document tree.
|
|
30
|
+
|
|
31
|
+
Re-renders when the host sends a block location update.
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
function useParent(): NotionParent;
|
|
35
|
+
|
|
36
|
+
type NotionParent =
|
|
37
|
+
| { type: "page_id"; page_id: string } // inline custom block under a page
|
|
38
|
+
| { type: "block_id"; block_id: NotionBlockId } // inline custom block under a toggle/column/callout/...
|
|
39
|
+
| { type: "data_source_id"; data_source_id: string } // custom block backing a custom collection view
|
|
40
|
+
| { type: "workspace"; workspace: true }; // top-level block parented by a team / workspace
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For non-React renderers, use `customBlock.getParent()` after `initCustomBlock()` resolves.
|
|
44
|
+
|
|
45
|
+
### `usePage()`
|
|
46
|
+
|
|
47
|
+
Returns the nearest enclosing `page` / `collection_view_page` ancestor.
|
|
48
|
+
|
|
49
|
+
Re-renders when the host sends a block location update.
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
function usePage(): { id: NotionPageId };
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
For non-React renderers, use `customBlock.getPage()` after `initCustomBlock()` resolves.
|
|
56
|
+
|
|
57
|
+
### `useTheme()`
|
|
58
|
+
|
|
59
|
+
Returns the host's current theme.
|
|
60
|
+
|
|
61
|
+
Re-renders on every `themeChanged` message.
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
function useTheme(): NotionTheme; // "light" | "dark"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For non-React renderers, use `customBlock.getTheme()`:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
await initCustomBlock();
|
|
71
|
+
|
|
72
|
+
const theme = customBlock.getTheme();
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
```tsx
|
|
76
|
+
import { usePage, useTheme } from "@notionhq/custom-blocks";
|
|
77
|
+
|
|
78
|
+
export function Header() {
|
|
79
|
+
const page = usePage();
|
|
80
|
+
const theme = useTheme();
|
|
81
|
+
return <header data-theme={theme}>Page: {page.id}</header>;
|
|
82
|
+
}
|
|
83
|
+
```
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Data sources
|
|
2
|
+
|
|
3
|
+
A custom block declares its **data sources** — semantic keys like `people` or `tasks` — in `custom_blocks.json`.
|
|
4
|
+
|
|
5
|
+
Data source mapping - resolving keys to ids - is stored on the block itself. This can be read/written programmatically using the `ncblock` CLI (try `npx ncblock --help`) or in the Notion UI.
|
|
6
|
+
|
|
7
|
+
At runtime, your code references the semantic key and the SDK handles the lookup for you. Use `useDataSource(key)` for the rows themselves (it also exposes the resolved schema), and `useManifest()` when you need the declared data-source keys and their declarations (e.g. picking a default key, or rendering a key switcher). For non-React renderers, `customBlock.getManifest()` exposes the same manifest, but row querying is currently only exposed through the React `useDataSource` hook.
|
|
8
|
+
|
|
9
|
+
## Pages within a data source
|
|
10
|
+
|
|
11
|
+
Each row returned by `useDataSource` is a `NotionDataSourcePage` — `{ id, propertiesById, propertiesByKey, update }`. Read property values through either of the two views:
|
|
12
|
+
|
|
13
|
+
- `propertiesByKey[key]` — keyed by the semantic property keys you declared in the manifest.
|
|
14
|
+
- `propertiesById[propertyId]` — keyed by the raw Notion property ID.
|
|
15
|
+
|
|
16
|
+
The four built-ins (`created_time`, `last_edited_time`, `created_by`, `last_edited_by`) are always present in `propertiesById` (and `collectionSchema.propertiesById`), never in the `*ByKey` views — they don't have semantic keys.
|
|
17
|
+
|
|
18
|
+
### Updating a row
|
|
19
|
+
|
|
20
|
+
Each page carries its own `update` helper:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
await row.update({
|
|
24
|
+
properties: {
|
|
25
|
+
score: { type: "number", number: 8 }, // semantic key
|
|
26
|
+
},
|
|
27
|
+
icon: { type: "emoji", emoji: "✅" },
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Because the helper is bound to its data source, you can write property values keyed by **either** semantic keys or raw IDs — the SDK resolves them before sending the request. The input and result shapes are `NotionDataSourcePageUpdateInput` and `NotionDataSourcePageUpdateResult`.
|
|
32
|
+
|
|
33
|
+
Use `row.update(...)` whenever you already have a row in hand. For pages you don't have a row for (e.g. you only have a `pageId`), drop down to the top-level [`pages` API](./pages.md) — it covers create / get / update / delete and accepts raw property IDs only.
|
|
34
|
+
|
|
35
|
+
## API
|
|
36
|
+
|
|
37
|
+
### `useDataSource(key, options?)`
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
function useDataSource(key: string, options?: { limit?: number }): UseDataSourceResult;
|
|
41
|
+
|
|
42
|
+
type UseDataSourceResult = {
|
|
43
|
+
items: NotionDataSourcePage[];
|
|
44
|
+
collectionSchema?: NotionCollectionSchema;
|
|
45
|
+
propertySchemasById: { [propertyId: string]: NotionPropertySchema };
|
|
46
|
+
propertySchemasByKey: { [key: string]: NotionPropertySchema | undefined };
|
|
47
|
+
isLoading: boolean;
|
|
48
|
+
hasMore: boolean;
|
|
49
|
+
error?: CustomBlockQueryDataSourceErrorInfo;
|
|
50
|
+
};
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Reads the data source mapped to `key`. `limit` defaults to 20 and is capped at 999. To show more rows, keep the desired limit in your own component state and pass the larger value back into `useDataSource(key, { limit })`. `propertySchemasByKey` is `undefined` for declared-but-unbound slots. When the host reports a query failure, `error` is `{ code, message, isRetryable }` with `code` narrowed to `CustomBlockQueryDataSourceErrorCode`.
|
|
54
|
+
|
|
55
|
+
### `useManifest()`
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
function useManifest(): CustomBlockManifest | null;
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Returns the author-declared manifest loaded from `custom_blocks.json` — the semantic data-source keys plus their declared `name`, `description`, and property declarations. `null` when the block ships no manifest. This is the configuration the block _declared_, not host-resolved bindings; use `useDataSource(key)` for rows and resolved schema. Handy for enumerating declared keys:
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
const manifest = useManifest();
|
|
65
|
+
const keys = Object.keys(manifest?.dataSources ?? {});
|
|
66
|
+
const activeKey = keys[0] ?? "default";
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### `customBlock.getManifest()`
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
function customBlock.getManifest(): CustomBlockManifest | null;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Framework-neutral getter for the same manifest returned by `useManifest()`. The manifest is static for the lifetime of the sandbox, so there is nothing to subscribe to.
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
await initCustomBlock();
|
|
79
|
+
|
|
80
|
+
renderManifest(customBlock.getManifest());
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`customBlock` does not yet expose a non-React equivalent of `useDataSource(key)`: querying rows, tracking `isLoading` / `hasMore`, and using row-level `update` helpers still require the React hook.
|
|
84
|
+
|
|
85
|
+
## Example: querying a data source
|
|
86
|
+
|
|
87
|
+
A typical data-driven view picks a key, calls `useDataSource`, schema-checks the rows, and surfaces a setup hint when the mapped collection is missing the expected fields. Trimmed from `templates/radar-chart`:
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import type { NotionDataSourcePage } from "@notionhq/custom-blocks";
|
|
91
|
+
import { useDataSource } from "@notionhq/custom-blocks/react";
|
|
92
|
+
|
|
93
|
+
const KEY = "people";
|
|
94
|
+
|
|
95
|
+
function isComplete(item: NotionDataSourcePage): boolean {
|
|
96
|
+
return (
|
|
97
|
+
typeof item.propertiesByKey.name === "string" &&
|
|
98
|
+
typeof item.propertiesByKey.score === "number" &&
|
|
99
|
+
Number.isFinite(item.propertiesByKey.score)
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function ScoreList() {
|
|
104
|
+
const [limit, setLimit] = useState(20);
|
|
105
|
+
const { items, isLoading, hasMore, error } = useDataSource(KEY, { limit });
|
|
106
|
+
|
|
107
|
+
if (error) return <div role="alert">Couldn't load: {error.message}</div>;
|
|
108
|
+
if (isLoading && items.length === 0) return <div>Loading…</div>;
|
|
109
|
+
|
|
110
|
+
const ready = items.filter(isComplete);
|
|
111
|
+
if (ready.length === 0) {
|
|
112
|
+
return (
|
|
113
|
+
<div>
|
|
114
|
+
Map a data source with key <code>{KEY}</code> exposing <code>name</code>{" "}
|
|
115
|
+
(text) and <code>score</code> (number).
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div>
|
|
122
|
+
<ul>
|
|
123
|
+
{ready.map((item) => (
|
|
124
|
+
<li key={item.id}>
|
|
125
|
+
{String(item.propertiesByKey.name)} —{" "}
|
|
126
|
+
{Number(item.propertiesByKey.score)}
|
|
127
|
+
</li>
|
|
128
|
+
))}
|
|
129
|
+
</ul>
|
|
130
|
+
{hasMore ? (
|
|
131
|
+
<button type="button" onClick={() => setLimit(limit + 20)} disabled={isLoading}>
|
|
132
|
+
{isLoading ? "Loading…" : "Load more"}
|
|
133
|
+
</button>
|
|
134
|
+
) : null}
|
|
135
|
+
</div>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Types
|
|
141
|
+
|
|
142
|
+
### Rows & values
|
|
143
|
+
|
|
144
|
+
- `NotionDataSource` — a resolved data source: semantic key, `collectionSchema`, `propertyIdsByKey`, `propertySchemasById`.
|
|
145
|
+
- `NotionDataSourcePage` — a single row exposed to app code: `{ id, propertiesById, propertiesByKey, update }`.
|
|
146
|
+
- `NotionDataSourceValue` — the discriminated union of values that can appear inside `propertiesById[propertyId]`. Date values branch into the `NotionDateValue` union below.
|
|
147
|
+
- `NotionDataSourcePageUpdateInput` / `NotionDataSourcePageUpdateResult` — input and result for the per-page `update` helper.
|
|
148
|
+
- `UseDataSourceOptions` — options accepted by `useDataSource`, currently `{ limit?: number }`.
|
|
149
|
+
|
|
150
|
+
### Property schemas
|
|
151
|
+
|
|
152
|
+
- `NotionPropertySchema` — schema for a single property (type plus type-specific config like `select` options).
|
|
153
|
+
- `NotionPropertyType` — string-literal union of every supported property type.
|
|
154
|
+
- `NOTION_PROPERTY_TYPES` — runtime list of those literals (handy for switch coverage and validation).
|
|
155
|
+
- `NotionPropertyOption` — a single `select` / `multi_select` / `status` option (`{ id, name, color }`).
|
|
156
|
+
- `NotionPropertyColor` — the color literal used by options and groups.
|
|
157
|
+
- `NotionStatusGroup` — the `status` property's "To do / In progress / Done" grouping.
|
|
158
|
+
- `NotionDualProperty` — properties that have both a primary and a secondary axis (e.g. `unique_id` prefix + number).
|
|
159
|
+
- `NotionBuiltinPropertyId` — string-literal union of the four synthetic property IDs (`created_time`, `last_edited_time`, `created_by`, `last_edited_by`).
|
|
160
|
+
- `NOTION_BUILTIN_PROPERTY_IDS` — runtime list of the four built-in IDs.
|
|
161
|
+
|
|
162
|
+
### Collection schema & pointers
|
|
163
|
+
|
|
164
|
+
- `NotionCollectionSchema` — host-supplied schema for the bound collection, including raw property schemas.
|
|
165
|
+
- `NotionRecordPointer` — `{ id, table }`. Generic reference to any Notion record (page, block, collection row). Exported for convenience; `useDataSource` and the `pages` API don't take one as input.
|
|
166
|
+
|
|
167
|
+
### IDs
|
|
168
|
+
|
|
169
|
+
Branded string types — they're plain strings at runtime but TypeScript distinguishes them.
|
|
170
|
+
|
|
171
|
+
- `NotionDataSourceId`
|
|
172
|
+
- `NotionSpaceId`
|
|
173
|
+
|
|
174
|
+
### Date values
|
|
175
|
+
|
|
176
|
+
Returned wherever a date / date-range value appears (e.g. inside `propertiesByKey` for a `date` property). All-day values use `NotionDate*` shapes; values with a time component use `NotionDateTime*`.
|
|
177
|
+
|
|
178
|
+
- `NotionDateValue` — discriminated union covering every date-shaped value below.
|
|
179
|
+
- `NotionDate`
|
|
180
|
+
- `NotionDateRange`
|
|
181
|
+
- `NotionDateTime`
|
|
182
|
+
- `NotionDateTimeRange`
|
|
183
|
+
- `NotionDateReminder`
|
|
184
|
+
- `NotionDateTimeReminder`
|
|
185
|
+
- `NotionTimeReminder`
|
|
186
|
+
- `NotionNoReminder`
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# Lifecycle
|
|
2
|
+
|
|
3
|
+
The SDK ↔ host handshake, the React wrapper that runs it, and the auto-resize hook that keeps the iframe in sync with your content.
|
|
4
|
+
|
|
5
|
+
## Handshake
|
|
6
|
+
|
|
7
|
+
`initCustomBlock()` posts `ready` to `window.parent` and awaits the host's `init` (theme, block ID/parent/page ID, current user, and `dataSources: { bindings }` keyed by semantic data-source key, which the SDK resolves against the manifest). The promise resolves with the normalized initial state, captured in `CustomBlockInitial` — `await` it before mounting React so hooks always see populated state.
|
|
8
|
+
|
|
9
|
+
- Default `timeoutMs` is 15000; rejects with `CustomBlockInitError` code `init_timeout` if the host doesn't respond.
|
|
10
|
+
- 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.
|
|
11
|
+
- After init, `*Changed` events (e.g. `themeChanged`, `parentChanged`, `dataSourcesChanged`) push updates and the relevant hooks re-render.
|
|
12
|
+
- `initCustomBlock` is idempotent; subsequent calls return the same promise.
|
|
13
|
+
|
|
14
|
+
## Sizing
|
|
15
|
+
|
|
16
|
+
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.
|
|
17
|
+
|
|
18
|
+
- **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.
|
|
19
|
+
- Prefer container queries (`@container`) over viewport queries.
|
|
20
|
+
|
|
21
|
+
## API
|
|
22
|
+
|
|
23
|
+
Import framework-neutral APIs from `@notionhq/custom-blocks`; import React hooks and components from `@notionhq/custom-blocks/react`. The runtime APIs below assume `initCustomBlock()` has resolved — initialized-only hooks and `customBlock` getters throw if called before that. Inside `<NotionCustomBlock>` (or past the `isLoaded` gate of `useCustomBlockInit`), single-value hooks return non-nullable values.
|
|
24
|
+
|
|
25
|
+
### `<NotionCustomBlock>`
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
type NotionCustomBlockProps = InitCustomBlockOptions & {
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
fallback?: ReactNode;
|
|
31
|
+
errorFallback?: ReactNode | ((error: Error) => ReactNode);
|
|
32
|
+
autoResize?: boolean; // defaults to true
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
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.
|
|
37
|
+
|
|
38
|
+
### `useCustomBlockInit(opts?)`
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
function useCustomBlockInit(
|
|
42
|
+
opts?: InitCustomBlockOptions,
|
|
43
|
+
): UseCustomBlockInitResult;
|
|
44
|
+
|
|
45
|
+
type UseCustomBlockInitResult =
|
|
46
|
+
| { isLoaded: false; error: undefined }
|
|
47
|
+
| { isLoaded: false; error: CustomBlockInitFailure }
|
|
48
|
+
| { isLoaded: true; error: undefined; initial: CustomBlockInitial };
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
React wrapper around `initCustomBlock` for templates that prefer not to use top-level `await`. Multiple components calling it share the same handshake.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
function Root() {
|
|
55
|
+
const init = useCustomBlockInit();
|
|
56
|
+
if (init.error) return <p role="alert">Init failed: {init.error.message}</p>;
|
|
57
|
+
if (!init.isLoaded) return null;
|
|
58
|
+
return <App />;
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### `initCustomBlock(opts?)`
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
function initCustomBlock(
|
|
66
|
+
opts?: InitCustomBlockOptions,
|
|
67
|
+
): Promise<CustomBlockInitial>;
|
|
68
|
+
|
|
69
|
+
type InitCustomBlockOptions = { timeoutMs?: number };
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The lower-level promise API. `<NotionCustomBlock>` and `useCustomBlockInit` both call it for you. Reach for it directly only when you want to `await` init at module scope (e.g. before `ReactDOM.createRoot`). If the host replies with an init error, the promise rejects with `CustomBlockInitError`.
|
|
73
|
+
|
|
74
|
+
### `CustomBlockInitError`
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
class CustomBlockInitError extends Error {
|
|
78
|
+
code: CustomBlockInitErrorCode;
|
|
79
|
+
isRetryable: boolean;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
type CustomBlockErrorInfo<TCode extends string = string> = {
|
|
83
|
+
code: TCode;
|
|
84
|
+
message: string;
|
|
85
|
+
isRetryable: boolean;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
type CustomBlockInitErrorInfo = CustomBlockErrorInfo<CustomBlockInitErrorCode>;
|
|
89
|
+
|
|
90
|
+
type CustomBlockInitErrorCode =
|
|
91
|
+
| "no_ready"
|
|
92
|
+
| "invalid_ready"
|
|
93
|
+
| "manifest_unavailable"
|
|
94
|
+
| "manifest_invalid"
|
|
95
|
+
| "invalid_protocol_version"
|
|
96
|
+
| "unsupported_protocol_version"
|
|
97
|
+
| "context_unavailable"
|
|
98
|
+
| "current_user_unavailable"
|
|
99
|
+
| "missing_data_source_binding"
|
|
100
|
+
| "data_source_unavailable"
|
|
101
|
+
| "missing_property_binding"
|
|
102
|
+
| "invalid_property_binding"
|
|
103
|
+
| "not_in_iframe"
|
|
104
|
+
| "init_timeout"
|
|
105
|
+
| "unknown_error";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Thrown when the host rejects initialization instead of returning the initial theme, block location, current user, and data sources. `CustomBlockInitErrorInfo` uses the same structured error payload as every other API, with `code` narrowed to `CustomBlockInitErrorCode`. Use `error instanceof CustomBlockInitError`, `error.code`, and `error.isRetryable` to branch on host-reported setup failures.
|
|
109
|
+
|
|
110
|
+
Runtime APIs use the same `CustomBlockErrorInfo<TCode>` envelope with their own code unions, such as `CustomBlockCreatePageErrorCode`, `CustomBlockUpdatePageErrorCode`, and `CustomBlockQueryDataSourceErrorCode`.
|
|
111
|
+
|
|
112
|
+
The public API-specific runtime aliases are `CustomBlockCreatePageErrorInfo`, `CustomBlockGetPageErrorInfo`, `CustomBlockGetUserErrorInfo`, `CustomBlockListUsersErrorInfo`, `CustomBlockQueryDataSourceErrorInfo`, and `CustomBlockUpdatePageErrorInfo`. Their `code` fields are narrowed by `CustomBlockCreatePageErrorCode`, `CustomBlockGetPageErrorCode`, `CustomBlockGetUserErrorCode`, `CustomBlockListUsersErrorCode`, `CustomBlockQueryDataSourceErrorCode`, and `CustomBlockUpdatePageErrorCode`. Shared categories include `CustomBlockPropertyErrorCode` / `CustomBlockPropertyErrorInfo` and `CustomBlockDataSourceResolutionErrorCode` / `CustomBlockDataSourceResolutionErrorInfo`.
|
|
113
|
+
|
|
114
|
+
### `customBlock`
|
|
115
|
+
|
|
116
|
+
Framework-neutral runtime APIs for renderers that do not use React hooks. `customBlock.getState()` returns a `CustomBlockState` snapshot that hides internal query cache details. Initialized-only getters (`getTheme`, `getBlockId`, `getParent`, `getPage`, and `getCurrentUser`) throw until `initCustomBlock()` resolves. `getManifest()` is not gated on init — it returns the declared manifest (or `null`) regardless.
|
|
117
|
+
|
|
118
|
+
`customBlock` covers runtime state and sizing. Row querying still goes through `useDataSource`, while imperative APIs such as `pages.*` and `users.*` are already framework-neutral functions.
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
await initCustomBlock();
|
|
122
|
+
|
|
123
|
+
const theme = customBlock.getTheme();
|
|
124
|
+
const unsubscribe = customBlock.subscribe(() => {
|
|
125
|
+
render(customBlock.getState());
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
For non-React auto-resize, pass the element whose content height should drive the host iframe. The helper posts one initial measurement, observes later size changes when `ResizeObserver` is available, dedupes unchanged heights, and returns a cleanup function:
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
const stopAutoResize = customBlock.autoResize({
|
|
133
|
+
target: document.getElementById("root"),
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Later, if your renderer unmounts:
|
|
137
|
+
stopAutoResize();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### `NotInIframeError`
|
|
141
|
+
|
|
142
|
+
Thrown when `initCustomBlock` is called in a top-level tab (no parent frame). It has `code: "not_in_iframe"` and `isRetryable: false`. `<NotionCustomBlock>` catches it and falls back to a standalone preview with a warning banner; direct callers can `instanceof NotInIframeError` to apply their own policy.
|
|
143
|
+
|
|
144
|
+
### `useCustomBlockAutoResize({ enabled? })`
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
function useCustomBlockAutoResize(args?: { enabled?: boolean }): void;
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
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`.
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
<NotionCustomBlock autoResize={false}>
|
|
154
|
+
<App />
|
|
155
|
+
</NotionCustomBlock>;
|
|
156
|
+
|
|
157
|
+
function App() {
|
|
158
|
+
const [enabled, setEnabled] = useState(true);
|
|
159
|
+
useCustomBlockAutoResize({ enabled });
|
|
160
|
+
return <div>…</div>;
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Debug console
|
|
165
|
+
|
|
166
|
+
Press `\` while focused in a custom block to toggle a debug overlay that replaces the block's children with a `<pre>` log of every `postMessage` sent and received over the bridge. Each line is formatted as:
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
[ISO timestamp] sent/received: {"type":"ready", …}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The log is intentionally plain — no filtering or decoration — so it can be copied and pasted directly to a local coding agent for debugging.
|