@texonom/nreact 1.1.0 → 1.1.1

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.
@@ -1,2064 +0,0 @@
1
- import {
2
- __async,
3
- __commonJS,
4
- __objRest,
5
- __spreadProps,
6
- __spreadValues,
7
- __toESM
8
- } from "./chunk-723T62SD.js";
9
-
10
- // ../../node_modules/.pnpm/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js
11
- var require_lodash = __commonJS({
12
- "../../node_modules/.pnpm/lodash.throttle@4.1.1/node_modules/lodash.throttle/index.js"(exports, module) {
13
- var FUNC_ERROR_TEXT = "Expected a function";
14
- var NAN = 0 / 0;
15
- var symbolTag = "[object Symbol]";
16
- var reTrim = /^\s+|\s+$/g;
17
- var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
18
- var reIsBinary = /^0b[01]+$/i;
19
- var reIsOctal = /^0o[0-7]+$/i;
20
- var freeParseInt = parseInt;
21
- var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
22
- var freeSelf = typeof self == "object" && self && self.Object === Object && self;
23
- var root = freeGlobal || freeSelf || Function("return this")();
24
- var objectProto = Object.prototype;
25
- var objectToString = objectProto.toString;
26
- var nativeMax = Math.max;
27
- var nativeMin = Math.min;
28
- var now = function() {
29
- return root.Date.now();
30
- };
31
- function debounce(func, wait, options) {
32
- var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
33
- if (typeof func != "function") {
34
- throw new TypeError(FUNC_ERROR_TEXT);
35
- }
36
- wait = toNumber(wait) || 0;
37
- if (isObject(options)) {
38
- leading = !!options.leading;
39
- maxing = "maxWait" in options;
40
- maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
41
- trailing = "trailing" in options ? !!options.trailing : trailing;
42
- }
43
- function invokeFunc(time) {
44
- var args = lastArgs, thisArg = lastThis;
45
- lastArgs = lastThis = void 0;
46
- lastInvokeTime = time;
47
- result = func.apply(thisArg, args);
48
- return result;
49
- }
50
- function leadingEdge(time) {
51
- lastInvokeTime = time;
52
- timerId = setTimeout(timerExpired, wait);
53
- return leading ? invokeFunc(time) : result;
54
- }
55
- function remainingWait(time) {
56
- var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result2 = wait - timeSinceLastCall;
57
- return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2;
58
- }
59
- function shouldInvoke(time) {
60
- var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
61
- return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
62
- }
63
- function timerExpired() {
64
- var time = now();
65
- if (shouldInvoke(time)) {
66
- return trailingEdge(time);
67
- }
68
- timerId = setTimeout(timerExpired, remainingWait(time));
69
- }
70
- function trailingEdge(time) {
71
- timerId = void 0;
72
- if (trailing && lastArgs) {
73
- return invokeFunc(time);
74
- }
75
- lastArgs = lastThis = void 0;
76
- return result;
77
- }
78
- function cancel() {
79
- if (timerId !== void 0) {
80
- clearTimeout(timerId);
81
- }
82
- lastInvokeTime = 0;
83
- lastArgs = lastCallTime = lastThis = timerId = void 0;
84
- }
85
- function flush() {
86
- return timerId === void 0 ? result : trailingEdge(now());
87
- }
88
- function debounced() {
89
- var time = now(), isInvoking = shouldInvoke(time);
90
- lastArgs = arguments;
91
- lastThis = this;
92
- lastCallTime = time;
93
- if (isInvoking) {
94
- if (timerId === void 0) {
95
- return leadingEdge(lastCallTime);
96
- }
97
- if (maxing) {
98
- timerId = setTimeout(timerExpired, wait);
99
- return invokeFunc(lastCallTime);
100
- }
101
- }
102
- if (timerId === void 0) {
103
- timerId = setTimeout(timerExpired, wait);
104
- }
105
- return result;
106
- }
107
- debounced.cancel = cancel;
108
- debounced.flush = flush;
109
- return debounced;
110
- }
111
- function throttle3(func, wait, options) {
112
- var leading = true, trailing = true;
113
- if (typeof func != "function") {
114
- throw new TypeError(FUNC_ERROR_TEXT);
115
- }
116
- if (isObject(options)) {
117
- leading = "leading" in options ? !!options.leading : leading;
118
- trailing = "trailing" in options ? !!options.trailing : trailing;
119
- }
120
- return debounce(func, wait, {
121
- "leading": leading,
122
- "maxWait": wait,
123
- "trailing": trailing
124
- });
125
- }
126
- function isObject(value) {
127
- var type = typeof value;
128
- return !!value && (type == "object" || type == "function");
129
- }
130
- function isObjectLike(value) {
131
- return !!value && typeof value == "object";
132
- }
133
- function isSymbol(value) {
134
- return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
135
- }
136
- function toNumber(value) {
137
- if (typeof value == "number") {
138
- return value;
139
- }
140
- if (isSymbol(value)) {
141
- return NAN;
142
- }
143
- if (isObject(value)) {
144
- var other = typeof value.valueOf == "function" ? value.valueOf() : value;
145
- value = isObject(other) ? other + "" : other;
146
- }
147
- if (typeof value != "string") {
148
- return value === 0 ? value : +value;
149
- }
150
- value = value.replace(reTrim, "");
151
- var isBinary = reIsBinary.test(value);
152
- return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
153
- }
154
- module.exports = throttle3;
155
- }
156
- });
157
-
158
- // src/renderer.tsx
159
- import * as React29 from "react";
160
- import mediumZoom from "@fisch0920/medium-zoom";
161
-
162
- // src/block.tsx
163
- import * as React28 from "react";
164
- import {
165
- getBlockCollectionId,
166
- getBlockIcon as getBlockIcon2,
167
- getBlockParentPage as getBlockParentPage2,
168
- getPageTableOfContents,
169
- getTextContent as getTextContent2,
170
- uuidToId as uuidToId2
171
- } from "@3bases/notion-utils";
172
-
173
- // src/components/asset-wrapper.tsx
174
- import * as React20 from "react";
175
- import { parsePageId as parsePageId2 } from "@3bases/notion-utils";
176
-
177
- // src/utils.ts
178
- import { isUrl, formatDate, formatNotionDateTime } from "@3bases/notion-utils";
179
-
180
- // src/map-image-url.ts
181
- var defaultMapImageUrl = (url, block) => {
182
- if (!url)
183
- return null;
184
- if (url.startsWith("data:"))
185
- return url;
186
- if (url.startsWith("https://images.unsplash.com"))
187
- return url;
188
- try {
189
- const u = new URL(url);
190
- if (u.pathname.startsWith("/secure.notion-static.com") && u.hostname.endsWith(".amazonaws.com")) {
191
- if (u.searchParams.has("X-Amz-Credential") && u.searchParams.has("X-Amz-Signature") && u.searchParams.has("X-Amz-Algorithm"))
192
- return url;
193
- }
194
- } catch (e) {
195
- }
196
- if (url.startsWith("/images"))
197
- url = `https://www.notion.so${url}`;
198
- url = `https://www.notion.so${url.startsWith("/image") ? url : `/image/${encodeURIComponent(url)}`}`;
199
- const notionImageUrlV2 = new URL(url);
200
- let table = block.parent_table === "space" ? "block" : block.parent_table;
201
- if (table === "collection" || table === "team")
202
- table = "block";
203
- notionImageUrlV2.searchParams.set("table", table);
204
- notionImageUrlV2.searchParams.set("id", block.id);
205
- notionImageUrlV2.searchParams.set("cache", "v2");
206
- url = notionImageUrlV2.toString();
207
- return url;
208
- };
209
-
210
- // src/map-page-url.ts
211
- var defaultMapPageUrl = (rootPageId) => (pageId) => {
212
- pageId = (pageId || "").replace(/-/g, "");
213
- if (rootPageId && pageId === rootPageId)
214
- return "/";
215
- else
216
- return `/${pageId}`;
217
- };
218
-
219
- // src/utils.ts
220
- var cs = (...classes) => classes.filter((a) => !!a).join(" ");
221
- var groupBlockContent = (blockMap) => {
222
- const output = [];
223
- let lastType = void 0;
224
- let index = -1;
225
- Object.keys(blockMap).forEach((id) => {
226
- var _a, _b;
227
- const blockValue = (_a = blockMap[id]) == null ? void 0 : _a.value;
228
- if (blockValue)
229
- (_b = blockValue.content) == null ? void 0 : _b.forEach((blockId) => {
230
- var _a2, _b2;
231
- const blockType = (_b2 = (_a2 = blockMap[blockId]) == null ? void 0 : _a2.value) == null ? void 0 : _b2.type;
232
- if (blockType && blockType !== lastType) {
233
- index++;
234
- lastType = blockType;
235
- output[index] = [];
236
- }
237
- if (index > -1)
238
- output[index].push(blockId);
239
- });
240
- lastType = void 0;
241
- });
242
- return output;
243
- };
244
- var getListNumber = (blockId, blockMap) => {
245
- const groups = groupBlockContent(blockMap);
246
- const group = groups.find((g) => g.includes(blockId));
247
- if (!group)
248
- return;
249
- return group.indexOf(blockId) + 1;
250
- };
251
- var getHashFragmentValue = (url) => {
252
- return url.includes("#") ? url.replace(/^.+(#.+)$/, "$1") : "";
253
- };
254
- var isBrowser = typeof window !== "undefined";
255
- var youtubeDomains = /* @__PURE__ */ new Set([
256
- "youtu.be",
257
- "youtube.com",
258
- "www.youtube.com",
259
- "youtube-nocookie.com",
260
- "www.youtube-nocookie.com"
261
- ]);
262
- var getYoutubeId = (url) => {
263
- try {
264
- const { hostname } = new URL(url);
265
- if (!youtubeDomains.has(hostname))
266
- return null;
267
- const regExp = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/i;
268
- const match = url.match(regExp);
269
- if (match && match[2].length == 11)
270
- return match[2];
271
- } catch (e) {
272
- }
273
- return null;
274
- };
275
-
276
- // src/components/asset.tsx
277
- import * as React19 from "react";
278
- import { getTextContent } from "@3bases/notion-utils";
279
-
280
- // src/context.tsx
281
- import * as React17 from "react";
282
-
283
- // src/components/checkbox.tsx
284
- import * as React2 from "react";
285
-
286
- // src/icons/check.tsx
287
- import * as React from "react";
288
- function SvgCheck(props) {
289
- return /* @__PURE__ */ React.createElement("svg", __spreadValues({ viewBox: "0 0 14 14" }, props), /* @__PURE__ */ React.createElement("path", { d: "M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z" }));
290
- }
291
- var check_default = SvgCheck;
292
-
293
- // src/components/checkbox.tsx
294
- var Checkbox = ({ isChecked }) => {
295
- let content = null;
296
- if (isChecked)
297
- content = /* @__PURE__ */ React2.createElement("div", { className: "notion-property-checkbox-checked" }, /* @__PURE__ */ React2.createElement(check_default, null));
298
- else
299
- content = /* @__PURE__ */ React2.createElement("div", { className: "notion-property-checkbox-unchecked" });
300
- return /* @__PURE__ */ React2.createElement("span", { className: "notion-property notion-property-checkbox" }, content);
301
- };
302
-
303
- // src/components/header.tsx
304
- import * as React15 from "react";
305
- import { getPageBreadcrumbs } from "@3bases/notion-utils";
306
- import { useHotkeys } from "react-hotkeys-hook";
307
-
308
- // src/icons/search-icon.tsx
309
- import * as React3 from "react";
310
- var SearchIcon = (props) => {
311
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
312
- return /* @__PURE__ */ React3.createElement("svg", __spreadValues({ className: cs("notion-icon", className), viewBox: "0 0 17 17" }, rest), /* @__PURE__ */ React3.createElement("path", { d: "M6.78027 13.6729C8.24805 13.6729 9.60156 13.1982 10.709 12.4072L14.875 16.5732C15.0684 16.7666 15.3232 16.8633 15.5957 16.8633C16.167 16.8633 16.5713 16.4238 16.5713 15.8613C16.5713 15.5977 16.4834 15.3516 16.29 15.1582L12.1504 11.0098C13.0205 9.86719 13.5391 8.45215 13.5391 6.91406C13.5391 3.19629 10.498 0.155273 6.78027 0.155273C3.0625 0.155273 0.0214844 3.19629 0.0214844 6.91406C0.0214844 10.6318 3.0625 13.6729 6.78027 13.6729ZM6.78027 12.2139C3.87988 12.2139 1.48047 9.81445 1.48047 6.91406C1.48047 4.01367 3.87988 1.61426 6.78027 1.61426C9.68066 1.61426 12.0801 4.01367 12.0801 6.91406C12.0801 9.81445 9.68066 12.2139 6.78027 12.2139Z" }));
313
- };
314
-
315
- // src/components/page-icon.tsx
316
- import * as React6 from "react";
317
- import { getBlockIcon, getBlockTitle } from "@3bases/notion-utils";
318
-
319
- // src/icons/default-page-icon.tsx
320
- import * as React4 from "react";
321
- var DefaultPageIcon = (props) => {
322
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
323
- return /* @__PURE__ */ React4.createElement("svg", __spreadProps(__spreadValues({ className }, rest), { viewBox: "0 0 30 30", width: "16" }), /* @__PURE__ */ React4.createElement("path", { d: "M16,1H4v28h22V11L16,1z M16,3.828L23.172,11H16V3.828z M24,27H6V3h8v10h10V27z M8,17h14v-2H8V17z M8,21h14v-2H8V21z M8,25h14v-2H8V25z" }));
324
- };
325
-
326
- // src/components/lazy-image.tsx
327
- import * as React5 from "react";
328
- import { normalizeUrl } from "@3bases/notion-utils";
329
- var LazyImage = (_a) => {
330
- var _b = _a, { src, alt, className, style, zoomable = false, priority = false, height } = _b, rest = __objRest(_b, ["src", "alt", "className", "style", "zoomable", "priority", "height"]);
331
- var _a2, _b2, _c;
332
- const { recordMap, zoom, previewImages, forceCustomImages, components } = useNotionContext();
333
- const zoomRef = React5.useRef(zoom ? zoom.clone() : null);
334
- const previewImage = previewImages ? (_c = (_a2 = recordMap == null ? void 0 : recordMap.preview_images) == null ? void 0 : _a2[src]) != null ? _c : (_b2 = recordMap == null ? void 0 : recordMap.preview_images) == null ? void 0 : _b2[normalizeUrl(src)] : null;
335
- const onLoad = React5.useCallback(
336
- (e) => {
337
- if (zoomable && (e.target.src || e.target.srcset)) {
338
- if (zoomRef.current)
339
- zoomRef.current.attach(e.target);
340
- }
341
- },
342
- [zoomRef, zoomable]
343
- );
344
- const attachZoom = React5.useCallback(
345
- (image) => {
346
- if (zoomRef.current && image)
347
- zoomRef.current.attach(image);
348
- },
349
- [zoomRef]
350
- );
351
- const attachZoomRef = React5.useMemo(() => zoomable ? attachZoom : void 0, [zoomable, attachZoom]);
352
- if (previewImage && components.Image) {
353
- return /* @__PURE__ */ React5.createElement(
354
- components.Image,
355
- {
356
- src,
357
- alt,
358
- style,
359
- className,
360
- width: previewImage.originalWidth,
361
- height: previewImage.originalHeight,
362
- blurDataURL: previewImage.dataURIBase64,
363
- placeholder: "blur",
364
- priority,
365
- onLoad
366
- }
367
- );
368
- } else {
369
- if (components.Image && forceCustomImages)
370
- return /* @__PURE__ */ React5.createElement(
371
- components.Image,
372
- {
373
- src,
374
- alt,
375
- className,
376
- style,
377
- width: null,
378
- height: height || null,
379
- priority,
380
- onLoad
381
- }
382
- );
383
- return /* @__PURE__ */ React5.createElement(
384
- "img",
385
- __spreadValues({
386
- className,
387
- style,
388
- src,
389
- alt,
390
- ref: attachZoomRef,
391
- loading: "lazy",
392
- decoding: "async"
393
- }, rest)
394
- );
395
- }
396
- };
397
-
398
- // src/components/page-icon.tsx
399
- var isIconBlock = (value) => {
400
- return value.type === "page" || value.type === "callout" || value.type === "collection_view" || value.type === "collection_view_page";
401
- };
402
- var PageIconImpl = ({ block, className, inline = true, hideDefaultIcon = false, defaultIcon }) => {
403
- var _a;
404
- const { mapImageUrl, recordMap, darkMode } = useNotionContext();
405
- let isImage = false;
406
- let content = null;
407
- if (isIconBlock(block)) {
408
- const icon = ((_a = getBlockIcon(block, recordMap)) == null ? void 0 : _a.trim()) || defaultIcon;
409
- const title = getBlockTitle(block, recordMap);
410
- if (icon && isUrl(icon)) {
411
- const url = mapImageUrl(icon, block);
412
- isImage = true;
413
- content = /* @__PURE__ */ React6.createElement(LazyImage, { src: url, alt: title || "page icon", className: cs(className, "notion-page-icon") });
414
- } else if (icon && icon.startsWith("/icons/")) {
415
- const url = "https://www.notion.so" + icon + "?mode=" + (darkMode ? "dark" : "light");
416
- content = /* @__PURE__ */ React6.createElement(LazyImage, { src: url, alt: title || "page icon", className: cs(className, "notion-page-icon") });
417
- } else if (!icon) {
418
- if (!hideDefaultIcon) {
419
- isImage = true;
420
- content = /* @__PURE__ */ React6.createElement(DefaultPageIcon, { className: cs(className, "notion-page-icon"), alt: title ? title : "page icon" });
421
- }
422
- } else {
423
- isImage = false;
424
- content = /* @__PURE__ */ React6.createElement("span", { className: cs(className, "notion-page-icon"), role: "img", "aria-label": icon }, icon);
425
- }
426
- }
427
- if (!content)
428
- return null;
429
- return /* @__PURE__ */ React6.createElement(
430
- "div",
431
- {
432
- className: cs(
433
- inline ? "notion-page-icon-inline" : "notion-page-icon-hero",
434
- isImage ? "notion-page-icon-image" : "notion-page-icon-span"
435
- )
436
- },
437
- content
438
- );
439
- };
440
- var PageIcon = React6.memo(PageIconImpl);
441
-
442
- // src/components/search-dialog.tsx
443
- var import_lodash = __toESM(require_lodash(), 1);
444
- import * as React14 from "react";
445
- import { getBlockParentPage, getBlockTitle as getBlockTitle3 } from "@3bases/notion-utils";
446
-
447
- // src/icons/clear-icon.tsx
448
- import * as React7 from "react";
449
- var ClearIcon = (props) => {
450
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
451
- return /* @__PURE__ */ React7.createElement("svg", __spreadProps(__spreadValues({ className: cs("notion-icon", className) }, rest), { viewBox: "0 0 30 30" }), /* @__PURE__ */ React7.createElement("path", { d: "M15,0C6.716,0,0,6.716,0,15s6.716,15,15,15s15-6.716,15-15S23.284,0,15,0z M22,20.6L20.6,22L15,16.4L9.4,22L8,20.6l5.6-5.6 L8,9.4L9.4,8l5.6,5.6L20.6,8L22,9.4L16.4,15L22,20.6z" }));
452
- };
453
-
454
- // src/icons/loading-icon.tsx
455
- import * as React8 from "react";
456
- var LoadingIcon = (props) => {
457
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
458
- return /* @__PURE__ */ React8.createElement("svg", __spreadProps(__spreadValues({ className: cs("notion-icon", className) }, rest), { viewBox: "0 0 24 24" }), /* @__PURE__ */ React8.createElement("defs", null, /* @__PURE__ */ React8.createElement("linearGradient", { x1: "28.1542969%", y1: "63.7402344%", x2: "74.6289062%", y2: "17.7832031%", id: "linearGradient-1" }, /* @__PURE__ */ React8.createElement("stop", { stopColor: "rgba(164, 164, 164, 1)", offset: "0%" }), /* @__PURE__ */ React8.createElement("stop", { stopColor: "rgba(164, 164, 164, 0)", stopOpacity: "0", offset: "100%" }))), /* @__PURE__ */ React8.createElement("g", { id: "Page-1", stroke: "none", strokeWidth: "1", fill: "none" }, /* @__PURE__ */ React8.createElement("g", { transform: "translate(-236.000000, -286.000000)" }, /* @__PURE__ */ React8.createElement("g", { transform: "translate(238.000000, 286.000000)" }, /* @__PURE__ */ React8.createElement("circle", { id: "Oval-2", stroke: "url(#linearGradient-1)", strokeWidth: "4", cx: "10", cy: "12", r: "10" }), /* @__PURE__ */ React8.createElement("path", { d: "M10,2 C4.4771525,2 0,6.4771525 0,12", id: "Oval-2", stroke: "rgba(164, 164, 164, 1)", strokeWidth: "4" }), /* @__PURE__ */ React8.createElement("rect", { id: "Rectangle-1", fill: "rgba(164, 164, 164, 1)", x: "8", y: "0", width: "4", height: "4", rx: "8" })))));
459
- };
460
-
461
- // src/components/page-title.tsx
462
- import * as React13 from "react";
463
- import { getBlockTitle as getBlockTitle2 } from "@3bases/notion-utils";
464
-
465
- // src/components/text.tsx
466
- import * as React12 from "react";
467
- import { parsePageId } from "@3bases/notion-utils";
468
-
469
- // src/components/eoi.tsx
470
- import * as React10 from "react";
471
-
472
- // src/icons/type-github.tsx
473
- import * as React9 from "react";
474
- function SvgTypeGitHub(props) {
475
- return /* @__PURE__ */ React9.createElement("svg", __spreadValues({ viewBox: "0 0 260 260" }, props), /* @__PURE__ */ React9.createElement("g", null, /* @__PURE__ */ React9.createElement(
476
- "path",
477
- {
478
- d: "M128.00106,0 C57.3172926,0 0,57.3066942 0,128.00106 C0,184.555281 36.6761997,232.535542 87.534937,249.460899 C93.9320223,250.645779 96.280588,246.684165 96.280588,243.303333 C96.280588,240.251045 96.1618878,230.167899 96.106777,219.472176 C60.4967585,227.215235 52.9826207,204.369712 52.9826207,204.369712 C47.1599584,189.574598 38.770408,185.640538 38.770408,185.640538 C27.1568785,177.696113 39.6458206,177.859325 39.6458206,177.859325 C52.4993419,178.762293 59.267365,191.04987 59.267365,191.04987 C70.6837675,210.618423 89.2115753,204.961093 96.5158685,201.690482 C97.6647155,193.417512 100.981959,187.77078 104.642583,184.574357 C76.211799,181.33766 46.324819,170.362144 46.324819,121.315702 C46.324819,107.340889 51.3250588,95.9223682 59.5132437,86.9583937 C58.1842268,83.7344152 53.8029229,70.715562 60.7532354,53.0843636 C60.7532354,53.0843636 71.5019501,49.6441813 95.9626412,66.2049595 C106.172967,63.368876 117.123047,61.9465949 128.00106,61.8978432 C138.879073,61.9465949 149.837632,63.368876 160.067033,66.2049595 C184.49805,49.6441813 195.231926,53.0843636 195.231926,53.0843636 C202.199197,70.715562 197.815773,83.7344152 196.486756,86.9583937 C204.694018,95.9223682 209.660343,107.340889 209.660343,121.315702 C209.660343,170.478725 179.716133,181.303747 151.213281,184.472614 C155.80443,188.444828 159.895342,196.234518 159.895342,208.176593 C159.895342,225.303317 159.746968,239.087361 159.746968,243.303333 C159.746968,246.709601 162.05102,250.70089 168.53925,249.443941 C219.370432,232.499507 256,184.536204 256,128.00106 C256,57.3066942 198.691187,0 128.00106,0 Z M47.9405593,182.340212 C47.6586465,182.976105 46.6581745,183.166873 45.7467277,182.730227 C44.8183235,182.312656 44.2968914,181.445722 44.5978808,180.80771 C44.8734344,180.152739 45.876026,179.97045 46.8023103,180.409216 C47.7328342,180.826786 48.2627451,181.702199 47.9405593,182.340212 Z M54.2367892,187.958254 C53.6263318,188.524199 52.4329723,188.261363 51.6232682,187.366874 C50.7860088,186.474504 50.6291553,185.281144 51.2480912,184.70672 C51.8776254,184.140775 53.0349512,184.405731 53.8743302,185.298101 C54.7115892,186.201069 54.8748019,187.38595 54.2367892,187.958254 Z M58.5562413,195.146347 C57.7719732,195.691096 56.4895886,195.180261 55.6968417,194.042013 C54.9125733,192.903764 54.9125733,191.538713 55.713799,190.991845 C56.5086651,190.444977 57.7719732,190.936735 58.5753181,192.066505 C59.3574669,193.22383 59.3574669,194.58888 58.5562413,195.146347 Z M65.8613592,203.471174 C65.1597571,204.244846 63.6654083,204.03712 62.5716717,202.981538 C61.4524999,201.94927 61.1409122,200.484596 61.8446341,199.710926 C62.5547146,198.935137 64.0575422,199.15346 65.1597571,200.200564 C66.2704506,201.230712 66.6095936,202.705984 65.8613592,203.471174 Z M75.3025151,206.281542 C74.9930474,207.284134 73.553809,207.739857 72.1039724,207.313809 C70.6562556,206.875043 69.7087748,205.700761 70.0012857,204.687571 C70.302275,203.678621 71.7478721,203.20382 73.2083069,203.659543 C74.6539041,204.09619 75.6035048,205.261994 75.3025151,206.281542 Z M86.046947,207.473627 C86.0829806,208.529209 84.8535871,209.404622 83.3316829,209.4237 C81.8013,209.457614 80.563428,208.603398 80.5464708,207.564772 C80.5464708,206.498591 81.7483088,205.631657 83.2786917,205.606221 C84.8005962,205.576546 86.046947,206.424403 86.046947,207.473627 Z M96.6021471,207.069023 C96.7844366,208.099171 95.7267341,209.156872 94.215428,209.438785 C92.7295577,209.710099 91.3539086,209.074206 91.1652603,208.052538 C90.9808515,206.996955 92.0576306,205.939253 93.5413813,205.66582 C95.054807,205.402984 96.4092596,206.021919 96.6021471,207.069023 Z",
479
- fill: "#161614"
480
- }
481
- )));
482
- }
483
- var type_github_default = SvgTypeGitHub;
484
-
485
- // src/components/eoi.tsx
486
- var EOI = ({ block, inline, className }) => {
487
- var _a, _b, _c;
488
- const { components } = useNotionContext();
489
- const { original_url, attributes, domain } = (block == null ? void 0 : block.format) || {};
490
- if (!original_url || !attributes)
491
- return null;
492
- const title = (_a = attributes.find((attr) => attr.id === "title")) == null ? void 0 : _a.values[0];
493
- let owner = (_b = attributes.find((attr) => attr.id === "owner")) == null ? void 0 : _b.values[0];
494
- const lastUpdatedAt = (_c = attributes.find((attr) => attr.id === "updated_at")) == null ? void 0 : _c.values[0];
495
- const lastUpdated = lastUpdatedAt ? formatNotionDateTime(lastUpdatedAt) : null;
496
- let externalImage;
497
- switch (domain) {
498
- case "github.com":
499
- externalImage = /* @__PURE__ */ React10.createElement(type_github_default, null);
500
- if (owner) {
501
- const parts = owner.split("/");
502
- owner = parts[parts.length - 1];
503
- }
504
- break;
505
- default:
506
- if (true)
507
- console.info(`Unsupported external_object_instance domain "${domain}"`, JSON.stringify(block, null, 2));
508
- return null;
509
- }
510
- return /* @__PURE__ */ React10.createElement(
511
- components.Link,
512
- {
513
- target: "_blank",
514
- rel: "noopener noreferrer",
515
- href: original_url,
516
- className: cs("notion-external", inline ? "notion-external-mention" : "notion-external-block notion-row", className)
517
- },
518
- externalImage && /* @__PURE__ */ React10.createElement("div", { className: "notion-external-image" }, externalImage),
519
- /* @__PURE__ */ React10.createElement("div", { className: "notion-external-description" }, /* @__PURE__ */ React10.createElement("div", { className: "notion-external-title" }, title), (owner || lastUpdated) && /* @__PURE__ */ React10.createElement("div", { className: "notion-external-subtitle" }, owner && /* @__PURE__ */ React10.createElement("span", null, owner), owner && lastUpdated && /* @__PURE__ */ React10.createElement("span", null, " \u2022 "), lastUpdated && /* @__PURE__ */ React10.createElement("span", null, "Updated ", lastUpdated)))
520
- );
521
- };
522
-
523
- // src/components/graceful-image.tsx
524
- import * as React11 from "react";
525
- import { Img } from "react-image";
526
- var GracefulImage = (props) => {
527
- if (isBrowser)
528
- return /* @__PURE__ */ React11.createElement(Img, __spreadValues({}, props));
529
- else
530
- return /* @__PURE__ */ React11.createElement("img", __spreadValues({}, props));
531
- };
532
-
533
- // src/components/text.tsx
534
- var Text = ({ value, block, linkProps, linkProtocol }) => {
535
- const { components, recordMap, mapPageUrl, mapImageUrl, rootDomain } = useNotionContext();
536
- return /* @__PURE__ */ React12.createElement(React12.Fragment, null, value == null ? void 0 : value.map(([text, decorations], index) => {
537
- if (!decorations)
538
- if (text === ",")
539
- return /* @__PURE__ */ React12.createElement("span", { key: index, style: { padding: "0.5em" } });
540
- else
541
- return /* @__PURE__ */ React12.createElement(React12.Fragment, { key: index }, text);
542
- const formatted = decorations.reduce((element, decorator) => {
543
- var _a, _b, _c, _d, _e;
544
- switch (decorator[0]) {
545
- case "p": {
546
- const blockId = decorator[1];
547
- const linkedBlock = (_a = recordMap.block[blockId]) == null ? void 0 : _a.value;
548
- if (!linkedBlock) {
549
- console.info('"p" missing block', blockId);
550
- return null;
551
- }
552
- return /* @__PURE__ */ React12.createElement(components.PageLink, { className: "notion-link", href: mapPageUrl(blockId) }, /* @__PURE__ */ React12.createElement(PageTitle, { block: linkedBlock }));
553
- }
554
- case "\u2023": {
555
- const linkType = decorator[1][0];
556
- const id = decorator[1][1];
557
- switch (linkType) {
558
- case "u": {
559
- const user = (_b = recordMap.notion_user[id]) == null ? void 0 : _b.value;
560
- if (!user) {
561
- console.info('"\u2023" missing user', id);
562
- return null;
563
- }
564
- const name = [user.given_name, user.family_name].filter(Boolean).join(" ");
565
- return /* @__PURE__ */ React12.createElement(GracefulImage, { className: "notion-user", src: mapImageUrl(user.profile_photo, block), alt: name });
566
- }
567
- default: {
568
- const linkedBlock = (_c = recordMap.block[id]) == null ? void 0 : _c.value;
569
- if (!linkedBlock) {
570
- console.info('"\u2023" missing block', linkType, id);
571
- return null;
572
- }
573
- return /* @__PURE__ */ React12.createElement(
574
- components.PageLink,
575
- __spreadProps(__spreadValues({
576
- className: "notion-link",
577
- href: mapPageUrl(id)
578
- }, linkProps), {
579
- target: "_blank",
580
- rel: "noopener noreferrer"
581
- }),
582
- /* @__PURE__ */ React12.createElement(PageTitle, { block: linkedBlock })
583
- );
584
- }
585
- }
586
- }
587
- case "h":
588
- return /* @__PURE__ */ React12.createElement("span", { className: `notion-${decorator[1]}` }, element);
589
- case "c":
590
- return /* @__PURE__ */ React12.createElement("code", { className: "notion-inline-code" }, element);
591
- case "b":
592
- return /* @__PURE__ */ React12.createElement("b", null, element);
593
- case "i":
594
- return /* @__PURE__ */ React12.createElement("em", null, element);
595
- case "s":
596
- return /* @__PURE__ */ React12.createElement("s", null, element);
597
- case "_":
598
- return /* @__PURE__ */ React12.createElement("span", { className: "notion-inline-underscore" }, element);
599
- case "e":
600
- return /* @__PURE__ */ React12.createElement(components.Equation, { math: decorator[1], inline: true });
601
- case "m":
602
- return element;
603
- case "a": {
604
- const v = decorator[1];
605
- const pathname = v.substr(1);
606
- const id = parsePageId(pathname, { uuid: true });
607
- if ((v[0] === "/" || v.includes(rootDomain)) && id) {
608
- const href = v.includes(rootDomain) ? v : `${mapPageUrl(id)}${getHashFragmentValue(v)}`;
609
- return /* @__PURE__ */ React12.createElement(components.PageLink, __spreadValues({ className: "notion-link", href }, linkProps), element);
610
- } else {
611
- return /* @__PURE__ */ React12.createElement(
612
- components.Link,
613
- __spreadValues({
614
- className: "notion-link",
615
- href: linkProtocol ? `${linkProtocol}:${decorator[1]}` : decorator[1]
616
- }, linkProps),
617
- element
618
- );
619
- }
620
- }
621
- case "d": {
622
- const v = decorator[1];
623
- const type = v == null ? void 0 : v.type;
624
- if (type === "date") {
625
- const startDate = v.start_date;
626
- return formatDate(startDate);
627
- } else if (type === "daterange") {
628
- const startDate = v.start_date;
629
- const endDate = v.end_date;
630
- return `${formatDate(startDate)} \u2192 ${formatDate(endDate)}`;
631
- } else {
632
- return element;
633
- }
634
- }
635
- case "u": {
636
- const userId = decorator[1];
637
- const user = (_d = recordMap.notion_user[userId]) == null ? void 0 : _d.value;
638
- if (!user) {
639
- console.info("missing user", userId);
640
- return null;
641
- }
642
- const name = [user.given_name, user.family_name].filter(Boolean).join(" ");
643
- return /* @__PURE__ */ React12.createElement(GracefulImage, { className: "notion-user", src: mapImageUrl(user.profile_photo, block), alt: name });
644
- }
645
- case "eoi": {
646
- const blockId = decorator[1];
647
- const externalObjectInstance = (_e = recordMap.block[blockId]) == null ? void 0 : _e.value;
648
- return /* @__PURE__ */ React12.createElement(EOI, { block: externalObjectInstance, inline: true });
649
- }
650
- default:
651
- if (true)
652
- console.info("unsupported text format", decorator);
653
- return element;
654
- }
655
- }, /* @__PURE__ */ React12.createElement(React12.Fragment, null, text));
656
- return /* @__PURE__ */ React12.createElement(React12.Fragment, { key: index }, formatted);
657
- }));
658
- };
659
-
660
- // src/components/page-title.tsx
661
- var PageTitleImpl = (_a) => {
662
- var _b = _a, { block, className, defaultIcon } = _b, rest = __objRest(_b, ["block", "className", "defaultIcon"]);
663
- var _a2, _b2;
664
- const { recordMap } = useNotionContext();
665
- if (!block)
666
- return null;
667
- if (block.type === "collection_view_page" || block.type === "collection_view") {
668
- const title = getBlockTitle2(block, recordMap);
669
- if (!title)
670
- return null;
671
- const titleDecoration = [[title]];
672
- return /* @__PURE__ */ React13.createElement("span", __spreadValues({ className: cs("notion-page-title", className) }, rest), /* @__PURE__ */ React13.createElement(PageIcon, { block, defaultIcon, className: "notion-page-title-icon" }), /* @__PURE__ */ React13.createElement("span", { className: "notion-page-title-text" }, /* @__PURE__ */ React13.createElement(Text, { value: titleDecoration, block })));
673
- }
674
- if (!((_a2 = block.properties) == null ? void 0 : _a2.title))
675
- return null;
676
- return /* @__PURE__ */ React13.createElement("span", __spreadValues({ className: cs("notion-page-title", className) }, rest), /* @__PURE__ */ React13.createElement(PageIcon, { block, defaultIcon, className: "notion-page-title-icon" }), /* @__PURE__ */ React13.createElement("span", { className: "notion-page-title-text" }, /* @__PURE__ */ React13.createElement(Text, { value: (_b2 = block.properties) == null ? void 0 : _b2.title, block })));
677
- };
678
- var PageTitle = React13.memo(PageTitleImpl);
679
-
680
- // src/components/search-dialog.tsx
681
- var SearchDialog = class extends React14.Component {
682
- constructor(props) {
683
- super(props);
684
- this.state = {
685
- isLoading: false,
686
- query: "",
687
- searchResult: null,
688
- searchError: null
689
- };
690
- this._onAfterOpen = () => {
691
- if (this._inputRef.current)
692
- this._inputRef.current.focus();
693
- };
694
- this._onChangeQuery = (e) => {
695
- const query = e.target.value;
696
- this.setState({ query });
697
- if (!query.trim()) {
698
- this.setState({ isLoading: false, searchResult: null, searchError: null });
699
- return;
700
- } else {
701
- this._search();
702
- }
703
- };
704
- this._onClearQuery = () => {
705
- this._onChangeQuery({ target: { value: "" } });
706
- };
707
- this._warmupSearch = () => __async(this, null, function* () {
708
- const { searchNotion, rootBlockId } = this.props;
709
- yield searchNotion({
710
- query: "",
711
- ancestorId: rootBlockId
712
- });
713
- });
714
- this._searchImpl = () => __async(this, null, function* () {
715
- const { searchNotion, rootBlockId } = this.props;
716
- const { query } = this.state;
717
- if (!query.trim()) {
718
- this.setState({ isLoading: false, searchResult: null, searchError: null });
719
- return;
720
- }
721
- this.setState({ isLoading: true });
722
- const result = yield searchNotion({
723
- query,
724
- ancestorId: rootBlockId
725
- });
726
- console.info("search", query, result);
727
- let searchResult = null;
728
- let searchError = null;
729
- if (result.error || result.errorId) {
730
- searchError = result;
731
- } else {
732
- searchResult = __spreadValues({}, result);
733
- const results = searchResult.results.map((result2) => {
734
- var _a, _b;
735
- const block = (_a = searchResult.recordMap.block[result2.id]) == null ? void 0 : _a.value;
736
- if (!block)
737
- return;
738
- const title = getBlockTitle3(block, searchResult.recordMap);
739
- if (!title)
740
- return;
741
- result2.title = title;
742
- result2.block = block;
743
- result2.recordMap = searchResult.recordMap;
744
- result2.page = getBlockParentPage(block, searchResult.recordMap, {
745
- inclusive: true
746
- }) || block;
747
- if (!result2.page.id)
748
- return;
749
- if ((_b = result2.highlight) == null ? void 0 : _b.text)
750
- result2.highlight.html = result2.highlight.text.replace(/<gzkNfoUU>/gi, "<b>").replace(/<\/gzkNfoUU>/gi, "</b>");
751
- return result2;
752
- }).filter(Boolean);
753
- const searchResultsMap = results.reduce(
754
- (map, result2) => __spreadProps(__spreadValues({}, map), {
755
- [result2.page.id]: result2
756
- }),
757
- {}
758
- );
759
- searchResult.results = Object.values(searchResultsMap);
760
- }
761
- if (this.state.query === query)
762
- this.setState({ isLoading: false, searchResult, searchError });
763
- });
764
- this._inputRef = React14.createRef();
765
- }
766
- componentDidMount() {
767
- this._search = (0, import_lodash.default)(this._searchImpl.bind(this), 1e3);
768
- this._warmupSearch();
769
- }
770
- render() {
771
- const { isOpen, onClose } = this.props;
772
- const { isLoading, query, searchResult, searchError } = this.state;
773
- const hasQuery = !!query.trim();
774
- return /* @__PURE__ */ React14.createElement(NotionContextConsumer, null, (ctx2) => {
775
- const { components, defaultPageIcon, mapPageUrl } = ctx2;
776
- return /* @__PURE__ */ React14.createElement(
777
- components.Modal,
778
- {
779
- isOpen,
780
- contentLabel: "Search",
781
- className: "notion-search",
782
- overlayClassName: "notion-search-overlay",
783
- onRequestClose: onClose,
784
- onAfterOpen: this._onAfterOpen
785
- },
786
- /* @__PURE__ */ React14.createElement("div", { className: "quickFindMenu" }, /* @__PURE__ */ React14.createElement("div", { className: "searchBar" }, /* @__PURE__ */ React14.createElement("div", { className: "inlineIcon" }, isLoading ? /* @__PURE__ */ React14.createElement(LoadingIcon, { className: "loadingIcon" }) : /* @__PURE__ */ React14.createElement(SearchIcon, null)), /* @__PURE__ */ React14.createElement(
787
- "input",
788
- {
789
- className: "searchInput",
790
- placeholder: "Search",
791
- value: query,
792
- ref: this._inputRef,
793
- onChange: this._onChangeQuery
794
- }
795
- ), query && /* @__PURE__ */ React14.createElement("div", { role: "button", className: "clearButton", onClick: this._onClearQuery }, /* @__PURE__ */ React14.createElement(ClearIcon, { className: "clearIcon" }))), hasQuery && searchResult && /* @__PURE__ */ React14.createElement(React14.Fragment, null, searchResult.results.length ? /* @__PURE__ */ React14.createElement(NotionContextProvider, __spreadProps(__spreadValues({}, ctx2), { recordMap: searchResult.recordMap }), /* @__PURE__ */ React14.createElement("div", { className: "resultsPane" }, searchResult.results.map((result) => {
796
- var _a;
797
- return /* @__PURE__ */ React14.createElement(
798
- components.PageLink,
799
- {
800
- key: result.id,
801
- className: cs("result", "notion-page-link"),
802
- href: mapPageUrl(result.page.id, searchResult.recordMap)
803
- },
804
- /* @__PURE__ */ React14.createElement(PageTitle, { block: result.page, defaultIcon: defaultPageIcon }),
805
- ((_a = result.highlight) == null ? void 0 : _a.html) && /* @__PURE__ */ React14.createElement(
806
- "div",
807
- {
808
- className: "notion-search-result-highlight",
809
- dangerouslySetInnerHTML: {
810
- __html: result.highlight.html
811
- }
812
- }
813
- )
814
- );
815
- })), /* @__PURE__ */ React14.createElement("footer", { className: "resultsFooter" }, /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("span", { className: "resultsCount" }, searchResult.total), searchResult.total === 1 ? " result" : " results"))) : /* @__PURE__ */ React14.createElement("div", { className: "noResultsPane" }, /* @__PURE__ */ React14.createElement("div", { className: "noResults" }, "No results"), /* @__PURE__ */ React14.createElement("div", { className: "noResultsDetail" }, "Try different search terms"))), hasQuery && !searchResult && searchError && /* @__PURE__ */ React14.createElement("div", { className: "noResultsPane" }, /* @__PURE__ */ React14.createElement("div", { className: "noResults" }, "Search error")))
816
- );
817
- });
818
- }
819
- };
820
-
821
- // src/components/header.tsx
822
- var Header = ({ block }) => {
823
- return /* @__PURE__ */ React15.createElement("header", { className: "notion-header" }, /* @__PURE__ */ React15.createElement("div", { className: "notion-nav-header" }, /* @__PURE__ */ React15.createElement(Breadcrumbs, { block }), /* @__PURE__ */ React15.createElement(Search, { block })));
824
- };
825
- var Breadcrumbs = ({ block, rootOnly = false }) => {
826
- const { recordMap, mapPageUrl, components } = useNotionContext();
827
- const breadcrumbs = React15.useMemo(() => {
828
- const breadcrumbs2 = getPageBreadcrumbs(recordMap, block.id);
829
- if (rootOnly)
830
- return [breadcrumbs2[0]].filter(Boolean);
831
- return breadcrumbs2;
832
- }, [recordMap, block.id, rootOnly]);
833
- return /* @__PURE__ */ React15.createElement("div", { className: "breadcrumbs", key: "breadcrumbs" }, breadcrumbs.map((breadcrumb, index) => {
834
- if (!breadcrumb)
835
- return null;
836
- const pageLinkProps = {};
837
- const componentMap = {
838
- pageLink: components.PageLink
839
- };
840
- if (breadcrumb.active)
841
- componentMap.pageLink = (props) => /* @__PURE__ */ React15.createElement("div", __spreadValues({}, props));
842
- else
843
- pageLinkProps.href = mapPageUrl(breadcrumb.pageId);
844
- return /* @__PURE__ */ React15.createElement(React15.Fragment, { key: breadcrumb.pageId }, /* @__PURE__ */ React15.createElement(componentMap.pageLink, __spreadValues({ className: cs("breadcrumb", breadcrumb.active && "active") }, pageLinkProps), breadcrumb.icon && /* @__PURE__ */ React15.createElement(PageIcon, { className: "icon", block: breadcrumb.block }), breadcrumb.title && /* @__PURE__ */ React15.createElement("span", { className: "title" }, breadcrumb.title)), index < breadcrumbs.length - 1 && /* @__PURE__ */ React15.createElement("span", { className: "spacer" }, "/"));
845
- }));
846
- };
847
- var Search = ({ block, search, title = "Search" }) => {
848
- const { searchNotion, rootPageId, isShowingSearch, onHideSearch } = useNotionContext();
849
- const onSearchNotion = search || searchNotion;
850
- const [isSearchOpen, setIsSearchOpen] = React15.useState(isShowingSearch);
851
- React15.useEffect(() => {
852
- setIsSearchOpen(isShowingSearch);
853
- }, [isShowingSearch]);
854
- const onOpenSearch = React15.useCallback(() => {
855
- setIsSearchOpen(true);
856
- }, []);
857
- const onCloseSearch = React15.useCallback(() => {
858
- setIsSearchOpen(false);
859
- if (onHideSearch)
860
- onHideSearch();
861
- }, [onHideSearch]);
862
- useHotkeys("cmd+p", (event) => {
863
- onOpenSearch();
864
- event.preventDefault();
865
- event.stopPropagation();
866
- });
867
- useHotkeys("cmd+k", (event) => {
868
- onOpenSearch();
869
- event.preventDefault();
870
- event.stopPropagation();
871
- });
872
- const hasSearch = !!onSearchNotion;
873
- return /* @__PURE__ */ React15.createElement(React15.Fragment, null, hasSearch && /* @__PURE__ */ React15.createElement("div", { role: "button", className: cs("breadcrumb", "button", "notion-search-button"), onClick: onOpenSearch }, /* @__PURE__ */ React15.createElement(SearchIcon, { className: "searchIcon" }), title && /* @__PURE__ */ React15.createElement("span", { className: "title" }, title)), isSearchOpen && hasSearch && /* @__PURE__ */ React15.createElement(
874
- SearchDialog,
875
- {
876
- isOpen: isSearchOpen,
877
- rootBlockId: rootPageId || (block == null ? void 0 : block.id),
878
- onClose: onCloseSearch,
879
- searchNotion: onSearchNotion
880
- }
881
- ));
882
- };
883
-
884
- // src/next.tsx
885
- import * as React16 from "react";
886
- import isEqual from "react-fast-compare";
887
- var wrapNextImage = (NextImage) => {
888
- return React16.memo(function ReactNotionXNextImage(_a) {
889
- var _b = _a, {
890
- src,
891
- alt,
892
- width,
893
- height,
894
- className,
895
- style,
896
- layout
897
- } = _b, rest = __objRest(_b, [
898
- "src",
899
- "alt",
900
- "width",
901
- "height",
902
- "className",
903
- "style",
904
- "layout"
905
- ]);
906
- if (!layout)
907
- layout = width && height ? "intrinsic" : "fill";
908
- return /* @__PURE__ */ React16.createElement(
909
- NextImage,
910
- __spreadValues({
911
- className,
912
- src,
913
- alt,
914
- width: layout === "intrinsic" && width,
915
- height: layout === "intrinsic" && height,
916
- objectFit: style == null ? void 0 : style.objectFit,
917
- objectPosition: style == null ? void 0 : style.objectPosition,
918
- layout
919
- }, rest)
920
- );
921
- }, isEqual);
922
- };
923
- var wrapNextLink = (NextLink) => function ReactNotionXNextLink(_a) {
924
- var _b = _a, { href, as, passHref, prefetch, replace, scroll, shallow, locale } = _b, linkProps = __objRest(_b, ["href", "as", "passHref", "prefetch", "replace", "scroll", "shallow", "locale"]);
925
- return /* @__PURE__ */ React16.createElement(
926
- NextLink,
927
- {
928
- href,
929
- as,
930
- passHref,
931
- prefetch,
932
- replace,
933
- scroll,
934
- shallow,
935
- locale
936
- },
937
- /* @__PURE__ */ React16.createElement("a", __spreadValues({}, linkProps))
938
- );
939
- };
940
-
941
- // src/context.tsx
942
- var DefaultLink = (props) => /* @__PURE__ */ React17.createElement("a", __spreadValues({ target: "_blank", rel: "noopener noreferrer" }, props));
943
- var DefaultLinkMemo = React17.memo(DefaultLink);
944
- var DefaultPageLink = (props) => /* @__PURE__ */ React17.createElement("a", __spreadValues({}, props));
945
- var DefaultPageLinkMemo = React17.memo(DefaultPageLink);
946
- var DefaultEmbed = (props) => /* @__PURE__ */ React17.createElement(AssetWrapper, __spreadValues({}, props));
947
- var DefaultHeader = Header;
948
- var dummyLink = (_a) => {
949
- var _b = _a, { href, rel, target, title } = _b, rest = __objRest(_b, ["href", "rel", "target", "title"]);
950
- return /* @__PURE__ */ React17.createElement("span", __spreadValues({}, rest));
951
- };
952
- var dummyComponent = (name) => () => {
953
- console.warn(`Warning: using empty component "${name}" (you should override this in NotionRenderer.components)`);
954
- return null;
955
- };
956
- var dummyOverrideFn = (_, defaultValueFn) => defaultValueFn();
957
- var defaultComponents = {
958
- Image: null,
959
- // disable custom images by default
960
- Link: DefaultLinkMemo,
961
- PageLink: DefaultPageLinkMemo,
962
- Checkbox,
963
- Callout: void 0,
964
- // use the built-in callout rendering by default
965
- Code: dummyComponent("Code"),
966
- Equation: dummyComponent("Equation"),
967
- Collection: dummyComponent("Collection"),
968
- Property: void 0,
969
- // use the built-in property rendering by default
970
- propertyTextValue: dummyOverrideFn,
971
- propertySelectValue: dummyOverrideFn,
972
- propertyRelationValue: dummyOverrideFn,
973
- propertyFormulaValue: dummyOverrideFn,
974
- propertyTitleValue: dummyOverrideFn,
975
- propertyPersonValue: dummyOverrideFn,
976
- propertyFileValue: dummyOverrideFn,
977
- propertyCheckboxValue: dummyOverrideFn,
978
- propertyUrlValue: dummyOverrideFn,
979
- propertyEmailValue: dummyOverrideFn,
980
- propertyPhoneNumberValue: dummyOverrideFn,
981
- propertyNumberValue: dummyOverrideFn,
982
- propertyLastEditedTimeValue: dummyOverrideFn,
983
- propertyCreatedTimeValue: dummyOverrideFn,
984
- propertyDateValue: dummyOverrideFn,
985
- Pdf: dummyComponent("Pdf"),
986
- Tweet: dummyComponent("Tweet"),
987
- Modal: dummyComponent("Modal"),
988
- Header: DefaultHeader,
989
- Embed: DefaultEmbed
990
- };
991
- var defaultNotionContext = {
992
- recordMap: {
993
- block: {},
994
- collection: {},
995
- collection_view: {},
996
- collection_query: {},
997
- notion_user: {},
998
- signed_urls: {}
999
- },
1000
- components: defaultComponents,
1001
- mapPageUrl: defaultMapPageUrl(),
1002
- mapImageUrl: defaultMapImageUrl,
1003
- searchNotion: null,
1004
- isShowingSearch: false,
1005
- onHideSearch: null,
1006
- fullPage: false,
1007
- darkMode: false,
1008
- previewImages: false,
1009
- forceCustomImages: false,
1010
- showCollectionViewDropdown: true,
1011
- linkTableTitleProperties: true,
1012
- isLinkCollectionToUrlProperty: false,
1013
- showTableOfContents: false,
1014
- minTableOfContentsItems: 3,
1015
- defaultPageIcon: null,
1016
- defaultPageCover: null,
1017
- defaultPageCoverPosition: 0.5,
1018
- zoom: null
1019
- };
1020
- var ctx = React17.createContext(defaultNotionContext);
1021
- var NotionContextProvider = (_a) => {
1022
- var _b = _a, {
1023
- components: themeComponents = {},
1024
- children,
1025
- mapPageUrl,
1026
- mapImageUrl,
1027
- rootPageId
1028
- } = _b, rest = __objRest(_b, [
1029
- "components",
1030
- "children",
1031
- "mapPageUrl",
1032
- "mapImageUrl",
1033
- "rootPageId"
1034
- ]);
1035
- for (const key of Object.keys(rest))
1036
- if (rest[key] === void 0)
1037
- delete rest[key];
1038
- const wrappedThemeComponents = React17.useMemo(
1039
- () => __spreadValues({}, themeComponents),
1040
- [themeComponents]
1041
- );
1042
- if (wrappedThemeComponents.nextImage)
1043
- wrappedThemeComponents.Image = wrapNextImage(themeComponents.nextImage);
1044
- if (wrappedThemeComponents.nextLink)
1045
- wrappedThemeComponents.nextLink = wrapNextLink(themeComponents.nextLink);
1046
- for (const key of Object.keys(wrappedThemeComponents))
1047
- if (!wrappedThemeComponents[key])
1048
- delete wrappedThemeComponents[key];
1049
- const value = React17.useMemo(
1050
- () => __spreadProps(__spreadValues(__spreadValues({}, defaultNotionContext), rest), {
1051
- rootPageId,
1052
- mapPageUrl: mapPageUrl != null ? mapPageUrl : defaultMapPageUrl(rootPageId),
1053
- mapImageUrl: mapImageUrl != null ? mapImageUrl : defaultMapImageUrl,
1054
- components: __spreadValues(__spreadValues({}, defaultComponents), wrappedThemeComponents)
1055
- }),
1056
- [mapImageUrl, mapPageUrl, wrappedThemeComponents, rootPageId, rest]
1057
- );
1058
- return /* @__PURE__ */ React17.createElement(ctx.Provider, { value }, children);
1059
- };
1060
- var NotionContextConsumer = ctx.Consumer;
1061
- var useNotionContext = () => {
1062
- return React17.useContext(ctx);
1063
- };
1064
-
1065
- // src/components/lite-youtube-embed.tsx
1066
- import * as React18 from "react";
1067
- var qs = (params) => {
1068
- return Object.keys(params).map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join("&");
1069
- };
1070
- var LiteYouTubeEmbed = ({
1071
- id,
1072
- defaultPlay = false,
1073
- mute = false,
1074
- lazyImage = false,
1075
- iframeTitle = "YouTube video",
1076
- alt = "Video preview",
1077
- params = {},
1078
- adLinksPreconnect = true,
1079
- style,
1080
- className
1081
- }) => {
1082
- const muteParam = mute || defaultPlay ? "1" : "0";
1083
- const queryString = React18.useMemo(() => qs(__spreadValues({ autoplay: "1", mute: muteParam }, params)), [muteParam, params]);
1084
- const resolution = "hqdefault";
1085
- const posterUrl = `https://i.ytimg.com/vi/${id}/${resolution}.jpg`;
1086
- const ytUrl = "https://www.youtube-nocookie.com";
1087
- const iframeSrc = `${ytUrl}/embed/${id}?${queryString}`;
1088
- const [isPreconnected, setIsPreconnected] = React18.useState(false);
1089
- const [iframeInitialized, setIframeInitialized] = React18.useState(defaultPlay);
1090
- const [isIframeLoaded, setIsIframeLoaded] = React18.useState(false);
1091
- const warmConnections = React18.useCallback(() => {
1092
- if (isPreconnected)
1093
- return;
1094
- setIsPreconnected(true);
1095
- }, [isPreconnected]);
1096
- const onLoadIframe = React18.useCallback(() => {
1097
- if (iframeInitialized)
1098
- return;
1099
- setIframeInitialized(true);
1100
- }, [iframeInitialized]);
1101
- const onIframeLoaded = React18.useCallback(() => {
1102
- setIsIframeLoaded(true);
1103
- }, []);
1104
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("link", { rel: "preload", href: posterUrl, as: "image" }), isPreconnected && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("link", { rel: "preconnect", href: ytUrl }), /* @__PURE__ */ React18.createElement("link", { rel: "preconnect", href: "https://www.google.com" })), isPreconnected && adLinksPreconnect && /* @__PURE__ */ React18.createElement(React18.Fragment, null, /* @__PURE__ */ React18.createElement("link", { rel: "preconnect", href: "https://static.doubleclick.net" }), /* @__PURE__ */ React18.createElement("link", { rel: "preconnect", href: "https://googleads.g.doubleclick.net" })), /* @__PURE__ */ React18.createElement(
1105
- "div",
1106
- {
1107
- onClick: onLoadIframe,
1108
- onPointerOver: warmConnections,
1109
- className: cs(
1110
- "notion-yt-lite",
1111
- isIframeLoaded && "notion-yt-loaded",
1112
- iframeInitialized && "notion-yt-initialized",
1113
- className
1114
- ),
1115
- style
1116
- },
1117
- /* @__PURE__ */ React18.createElement("img", { src: posterUrl, className: "notion-yt-thumbnail", loading: lazyImage ? "lazy" : void 0, alt }),
1118
- /* @__PURE__ */ React18.createElement("div", { className: "notion-yt-playbtn" }),
1119
- iframeInitialized && /* @__PURE__ */ React18.createElement(
1120
- "iframe",
1121
- {
1122
- width: "560",
1123
- height: "315",
1124
- frameBorder: "0",
1125
- allow: "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",
1126
- allowFullScreen: true,
1127
- title: iframeTitle,
1128
- src: iframeSrc,
1129
- onLoad: onIframeLoaded
1130
- }
1131
- )
1132
- ));
1133
- };
1134
-
1135
- // src/components/asset.tsx
1136
- var isServer = typeof window === "undefined";
1137
- var supportedAssetTypes = [
1138
- "video",
1139
- "image",
1140
- "embed",
1141
- "figma",
1142
- "typeform",
1143
- "excalidraw",
1144
- "maps",
1145
- "tweet",
1146
- "pdf",
1147
- "gist",
1148
- "codepen",
1149
- "drive"
1150
- ];
1151
- var Asset = ({ block, zoomable = true, children }) => {
1152
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
1153
- const { recordMap, mapImageUrl, components } = useNotionContext();
1154
- if (!block || !supportedAssetTypes.includes(block.type))
1155
- return null;
1156
- const style = {
1157
- position: "relative",
1158
- display: "flex",
1159
- justifyContent: "center",
1160
- alignSelf: "center",
1161
- width: "100%",
1162
- maxWidth: "100%",
1163
- flexDirection: "column"
1164
- };
1165
- const assetStyle = {};
1166
- if (block.format) {
1167
- const { block_aspect_ratio, block_height, block_width, block_full_width, block_page_width, block_preserve_scale } = block.format;
1168
- if (block_full_width || block_page_width) {
1169
- if (block_full_width)
1170
- style.width = "100vw";
1171
- else
1172
- style.width = "100%";
1173
- if (block.type === "video") {
1174
- if (block_height)
1175
- style.height = block_height;
1176
- else if (block_aspect_ratio)
1177
- style.paddingBottom = `${block_aspect_ratio * 100}%`;
1178
- else if (block_preserve_scale)
1179
- style.objectFit = "contain";
1180
- } else if (block_aspect_ratio && block.type !== "image") {
1181
- style.paddingBottom = `${block_aspect_ratio * 100}%`;
1182
- } else if (block_height) {
1183
- style.height = block_height;
1184
- } else if (block_preserve_scale) {
1185
- if (block.type === "image") {
1186
- style.height = "100%";
1187
- } else {
1188
- style.paddingBottom = "75%";
1189
- style.minHeight = 100;
1190
- }
1191
- }
1192
- } else {
1193
- switch ((_a = block.format) == null ? void 0 : _a.block_alignment) {
1194
- case "center": {
1195
- style.alignSelf = "center";
1196
- break;
1197
- }
1198
- case "left": {
1199
- style.alignSelf = "start";
1200
- break;
1201
- }
1202
- case "right": {
1203
- style.alignSelf = "end";
1204
- break;
1205
- }
1206
- }
1207
- if (block_width)
1208
- style.width = block_width;
1209
- if (block_preserve_scale && block.type !== "image") {
1210
- style.paddingBottom = "50%";
1211
- style.minHeight = 100;
1212
- } else {
1213
- if (block_height && block.type !== "image")
1214
- style.height = block_height;
1215
- }
1216
- }
1217
- if (block.type === "image")
1218
- assetStyle.objectFit = "cover";
1219
- else if (block_preserve_scale)
1220
- assetStyle.objectFit = "contain";
1221
- }
1222
- let source = ((_b = recordMap.signed_urls) == null ? void 0 : _b[block.id]) || ((_e = (_d = (_c = block.properties) == null ? void 0 : _c.source) == null ? void 0 : _d[0]) == null ? void 0 : _e[0]);
1223
- let content = null;
1224
- if (!source)
1225
- return null;
1226
- if (block.type === "tweet") {
1227
- const src = source;
1228
- if (!src)
1229
- return null;
1230
- const id = src.split("?")[0].split("/").pop();
1231
- if (!id)
1232
- return null;
1233
- content = /* @__PURE__ */ React19.createElement(
1234
- "div",
1235
- {
1236
- style: __spreadProps(__spreadValues({}, assetStyle), {
1237
- maxWidth: 420,
1238
- width: "100%",
1239
- marginLeft: "auto",
1240
- marginRight: "auto"
1241
- })
1242
- },
1243
- /* @__PURE__ */ React19.createElement(components.Tweet, { id })
1244
- );
1245
- } else if (block.type === "pdf") {
1246
- style.overflow = "auto";
1247
- style.background = "rgb(226, 226, 226)";
1248
- style.display = "block";
1249
- if (!style.padding)
1250
- style.padding = "8px 16px";
1251
- if (!isServer)
1252
- content = /* @__PURE__ */ React19.createElement(components.Pdf, { file: source });
1253
- } else if (block.type === "embed" || block.type === "video" || block.type === "figma" || block.type === "typeform" || block.type === "gist" || block.type === "maps" || block.type === "excalidraw" || block.type === "codepen" || block.type === "drive") {
1254
- if (block.type === "video" && source && source.indexOf("youtube") < 0 && source.indexOf("youtu.be") < 0 && source.indexOf("vimeo") < 0 && source.indexOf("wistia") < 0 && source.indexOf("loom") < 0 && source.indexOf("videoask") < 0 && source.indexOf("getcloudapp") < 0) {
1255
- style.paddingBottom = void 0;
1256
- content = /* @__PURE__ */ React19.createElement("video", { playsInline: true, controls: true, preload: "metadata", style: assetStyle, src: source, title: block.type });
1257
- } else {
1258
- let src = ((_f = block.format) == null ? void 0 : _f.display_source) || source;
1259
- if (src) {
1260
- const youtubeVideoId = block.type === "video" ? getYoutubeId(src) : null;
1261
- if (youtubeVideoId) {
1262
- content = /* @__PURE__ */ React19.createElement(LiteYouTubeEmbed, { id: youtubeVideoId, style: assetStyle, className: "notion-asset-object-fit" });
1263
- } else if (block.type === "gist") {
1264
- if (!src.endsWith(".pibb"))
1265
- src = `${src}.pibb`;
1266
- assetStyle.width = "100%";
1267
- style.paddingBottom = "50%";
1268
- content = /* @__PURE__ */ React19.createElement(
1269
- "iframe",
1270
- {
1271
- style: assetStyle,
1272
- className: "notion-asset-object-fit",
1273
- src,
1274
- title: "GitHub Gist",
1275
- frameBorder: "0",
1276
- loading: "lazy",
1277
- scrolling: "auto"
1278
- }
1279
- );
1280
- } else {
1281
- content = /* @__PURE__ */ React19.createElement(
1282
- "iframe",
1283
- {
1284
- className: "notion-asset-object-fit",
1285
- style: assetStyle,
1286
- src,
1287
- title: `iframe ${block.type}`,
1288
- frameBorder: "0",
1289
- allowFullScreen: true,
1290
- loading: "lazy",
1291
- scrolling: "auto"
1292
- }
1293
- );
1294
- }
1295
- }
1296
- }
1297
- } else if (block.type === "image") {
1298
- if (source.includes("file.notion.so"))
1299
- source = (_i = (_h = (_g = block.properties) == null ? void 0 : _g.source) == null ? void 0 : _h[0]) == null ? void 0 : _i[0];
1300
- const src = mapImageUrl(source, block);
1301
- const caption = getTextContent((_j = block.properties) == null ? void 0 : _j.caption);
1302
- const alt = caption || "notion image";
1303
- content = /* @__PURE__ */ React19.createElement(LazyImage, { src, alt, zoomable, height: style.height, style: assetStyle });
1304
- }
1305
- return /* @__PURE__ */ React19.createElement(React19.Fragment, null, /* @__PURE__ */ React19.createElement("div", { style }, content, block.type === "image" && children), block.type !== "image" && children);
1306
- };
1307
-
1308
- // src/components/asset-wrapper.tsx
1309
- var urlStyle = { width: "100%" };
1310
- var AssetWrapper = ({ blockId, block }) => {
1311
- var _a, _b, _c, _d, _e, _f;
1312
- const value = block;
1313
- const { components, mapPageUrl, rootDomain, zoom } = useNotionContext();
1314
- let isURL = false;
1315
- if (block.type === "image") {
1316
- const caption = (_c = (_b = (_a = value == null ? void 0 : value.properties) == null ? void 0 : _a.caption) == null ? void 0 : _b[0]) == null ? void 0 : _c[0];
1317
- if (caption) {
1318
- const id = parsePageId2(caption, { uuid: true });
1319
- const isPage = caption.charAt(0) === "/" && id;
1320
- if (isPage || isValidURL(caption))
1321
- isURL = true;
1322
- }
1323
- }
1324
- const figure = /* @__PURE__ */ React20.createElement(
1325
- "figure",
1326
- {
1327
- className: cs(
1328
- "notion-asset-wrapper",
1329
- `notion-asset-wrapper-${block.type}`,
1330
- ((_d = value.format) == null ? void 0 : _d.block_full_width) && "notion-asset-wrapper-full",
1331
- blockId
1332
- )
1333
- },
1334
- /* @__PURE__ */ React20.createElement(Asset, { block: value, zoomable: zoom && !isURL }, ((_e = value == null ? void 0 : value.properties) == null ? void 0 : _e.caption) && !isURL && /* @__PURE__ */ React20.createElement("figcaption", { className: "notion-asset-caption" }, /* @__PURE__ */ React20.createElement(Text, { value: value.properties.caption, block })))
1335
- );
1336
- if (isURL) {
1337
- const caption = (_f = value == null ? void 0 : value.properties) == null ? void 0 : _f.caption[0][0];
1338
- const id = parsePageId2(caption, { uuid: true });
1339
- const isPage = caption.charAt(0) === "/" && id;
1340
- const captionHostname = extractHostname(caption);
1341
- return /* @__PURE__ */ React20.createElement(
1342
- components.PageLink,
1343
- {
1344
- style: urlStyle,
1345
- href: isPage ? mapPageUrl(id) : caption,
1346
- target: captionHostname && captionHostname !== rootDomain && !caption.startsWith("/") ? "blank_" : null
1347
- },
1348
- figure
1349
- );
1350
- }
1351
- return figure;
1352
- };
1353
- function isValidURL(str) {
1354
- const pattern = new RegExp(
1355
- "^(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$",
1356
- "i"
1357
- );
1358
- return !!pattern.test(str);
1359
- }
1360
- function extractHostname(url) {
1361
- try {
1362
- const hostname = new URL(url).hostname;
1363
- return hostname;
1364
- } catch (err) {
1365
- return "";
1366
- }
1367
- }
1368
-
1369
- // src/components/audio.tsx
1370
- import * as React21 from "react";
1371
- var Audio = ({ block, className }) => {
1372
- var _a, _b, _c;
1373
- const { recordMap } = useNotionContext();
1374
- const source = recordMap.signed_urls[block.id] || ((_c = (_b = (_a = block.properties) == null ? void 0 : _a.source) == null ? void 0 : _b[0]) == null ? void 0 : _c[0]);
1375
- return /* @__PURE__ */ React21.createElement("div", { className: cs("notion-audio", className) }, /* @__PURE__ */ React21.createElement("audio", { controls: true, preload: "none", src: source }));
1376
- };
1377
-
1378
- // src/components/file.tsx
1379
- import * as React23 from "react";
1380
-
1381
- // src/icons/file-icon.tsx
1382
- import * as React22 from "react";
1383
- var FileIcon = (props) => {
1384
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
1385
- return /* @__PURE__ */ React22.createElement("svg", __spreadProps(__spreadValues({ className }, rest), { viewBox: "0 0 30 30" }), /* @__PURE__ */ React22.createElement("path", { d: "M22,8v12c0,3.866-3.134,7-7,7s-7-3.134-7-7V8c0-2.762,2.238-5,5-5s5,2.238,5,5v12c0,1.657-1.343,3-3,3s-3-1.343-3-3V8h-2v12c0,2.762,2.238,5,5,5s5-2.238,5-5V8c0-3.866-3.134-7-7-7S6,4.134,6,8v12c0,4.971,4.029,9,9,9s9-4.029,9-9V8H22z" }));
1386
- };
1387
-
1388
- // src/components/file.tsx
1389
- var File = ({ block, className }) => {
1390
- var _a, _b, _c, _d, _e;
1391
- const { components, recordMap } = useNotionContext();
1392
- const source = recordMap.signed_urls[block.id] || ((_c = (_b = (_a = block.properties) == null ? void 0 : _a.source) == null ? void 0 : _b[0]) == null ? void 0 : _c[0]);
1393
- return /* @__PURE__ */ React23.createElement("div", { className: cs("notion-file", className) }, /* @__PURE__ */ React23.createElement(components.Link, { className: "notion-file-link", href: source, target: "_blank", rel: "noopener noreferrer" }, /* @__PURE__ */ React23.createElement(FileIcon, { className: "notion-file-icon" }), /* @__PURE__ */ React23.createElement("div", { className: "notion-file-info" }, /* @__PURE__ */ React23.createElement("div", { className: "notion-file-title" }, /* @__PURE__ */ React23.createElement(Text, { value: ((_d = block.properties) == null ? void 0 : _d.title) || [["File"]], block })), ((_e = block.properties) == null ? void 0 : _e.size) && /* @__PURE__ */ React23.createElement("div", { className: "notion-file-size" }, /* @__PURE__ */ React23.createElement(Text, { value: block.properties.size, block })))));
1394
- };
1395
-
1396
- // src/components/google-drive.tsx
1397
- import * as React24 from "react";
1398
- var GoogleDrive = ({ block, className }) => {
1399
- var _a;
1400
- const { components, mapImageUrl } = useNotionContext();
1401
- const properties = (_a = block.format) == null ? void 0 : _a.drive_properties;
1402
- if (!properties)
1403
- return null;
1404
- let domain;
1405
- try {
1406
- const url = new URL(properties.url);
1407
- domain = url.hostname;
1408
- } catch (err) {
1409
- }
1410
- return /* @__PURE__ */ React24.createElement("div", { className: cs("notion-google-drive", className) }, /* @__PURE__ */ React24.createElement(components.Link, { className: "notion-google-drive-link", href: properties.url, target: "_blank", rel: "noopener noreferrer" }, /* @__PURE__ */ React24.createElement("div", { className: "notion-google-drive-preview" }, /* @__PURE__ */ React24.createElement(
1411
- GracefulImage,
1412
- {
1413
- src: mapImageUrl(properties.thumbnail, block),
1414
- alt: properties.title || "Google Drive Document",
1415
- loading: "lazy"
1416
- }
1417
- )), /* @__PURE__ */ React24.createElement("div", { className: "notion-google-drive-body" }, properties.title && /* @__PURE__ */ React24.createElement("div", { className: "notion-google-drive-body-title" }, properties.title), properties.icon && domain && /* @__PURE__ */ React24.createElement("div", { className: "notion-google-drive-body-source" }, properties.icon && /* @__PURE__ */ React24.createElement(
1418
- "div",
1419
- {
1420
- className: "notion-google-drive-body-source-icon",
1421
- style: {
1422
- backgroundImage: `url(${properties.icon})`
1423
- }
1424
- }
1425
- ), domain && /* @__PURE__ */ React24.createElement("div", { className: "notion-google-drive-body-source-domain" }, domain)))));
1426
- };
1427
-
1428
- // src/components/page-aside.tsx
1429
- var import_lodash2 = __toESM(require_lodash(), 1);
1430
- import * as React25 from "react";
1431
- import { uuidToId } from "@3bases/notion-utils";
1432
- var PageAside = ({ toc, activeSection, setActiveSection, pageAside, hasToc, hasAside, className }) => {
1433
- const throttleMs = 100;
1434
- const actionSectionScrollSpy = React25.useMemo(
1435
- () => (0, import_lodash2.default)(() => {
1436
- const sections = document.getElementsByClassName("notion-h");
1437
- let prevBBox = null;
1438
- let currentSectionId = activeSection;
1439
- for (let i = 0; i < sections.length; ++i) {
1440
- const section = sections[i];
1441
- if (!section || !(section instanceof Element))
1442
- continue;
1443
- if (!currentSectionId)
1444
- currentSectionId = section.getAttribute("data-id");
1445
- const bbox = section.getBoundingClientRect();
1446
- const prevHeight = prevBBox ? bbox.top - prevBBox.bottom : 0;
1447
- const offset = Math.max(150, prevHeight / 4);
1448
- if (bbox.top - offset < 0) {
1449
- currentSectionId = section.getAttribute("data-id");
1450
- prevBBox = bbox;
1451
- continue;
1452
- }
1453
- break;
1454
- }
1455
- setActiveSection(currentSectionId);
1456
- }, throttleMs),
1457
- // eslint-disable-next-line react-hooks/exhaustive-deps
1458
- [
1459
- // explicitly not taking a dependency on activeSection
1460
- setActiveSection
1461
- ]
1462
- );
1463
- React25.useEffect(() => {
1464
- if (!hasToc)
1465
- return;
1466
- window.addEventListener("scroll", actionSectionScrollSpy);
1467
- actionSectionScrollSpy();
1468
- return () => {
1469
- window.removeEventListener("scroll", actionSectionScrollSpy);
1470
- };
1471
- }, [hasToc, actionSectionScrollSpy]);
1472
- if (!hasAside)
1473
- return null;
1474
- return /* @__PURE__ */ React25.createElement("aside", { className: cs("notion-aside", className) }, hasToc && /* @__PURE__ */ React25.createElement("div", { className: "notion-aside-table-of-contents" }, /* @__PURE__ */ React25.createElement("div", { className: "notion-aside-table-of-contents-header" }, "Table of Contents"), /* @__PURE__ */ React25.createElement("nav", { className: "notion-table-of-contents" }, toc.map((tocItem) => {
1475
- const id = uuidToId(tocItem.id);
1476
- return /* @__PURE__ */ React25.createElement(
1477
- "a",
1478
- {
1479
- key: id,
1480
- href: `#${id}`,
1481
- className: cs(
1482
- "notion-table-of-contents-item",
1483
- `notion-table-of-contents-item-indent-level-${tocItem.indentLevel}`,
1484
- activeSection === id && "notion-table-of-contents-active-item"
1485
- )
1486
- },
1487
- /* @__PURE__ */ React25.createElement(
1488
- "span",
1489
- {
1490
- className: "notion-table-of-contents-item-body",
1491
- style: {
1492
- display: "inline-block",
1493
- marginLeft: tocItem.indentLevel * 16
1494
- }
1495
- },
1496
- tocItem.text
1497
- )
1498
- );
1499
- }))), pageAside);
1500
- };
1501
-
1502
- // src/components/sync-pointer-block.tsx
1503
- import * as React26 from "react";
1504
- var SyncPointerBlock = ({ block, level }) => {
1505
- var _a, _b;
1506
- if (!block) {
1507
- if (true)
1508
- console.warn("missing sync pointer block", block.id);
1509
- return null;
1510
- }
1511
- const syncPointerBlock = block;
1512
- const referencePointerId = (_b = (_a = syncPointerBlock == null ? void 0 : syncPointerBlock.format) == null ? void 0 : _a.transclusion_reference_pointer) == null ? void 0 : _b.id;
1513
- if (!referencePointerId)
1514
- return null;
1515
- return /* @__PURE__ */ React26.createElement(NotionBlockRenderer, { key: referencePointerId, level, blockId: referencePointerId });
1516
- };
1517
-
1518
- // src/icons/link-icon.tsx
1519
- import * as React27 from "react";
1520
- var LinkIcon = (props) => {
1521
- const _a = props, { className } = _a, rest = __objRest(_a, ["className"]);
1522
- return /* @__PURE__ */ React27.createElement("svg", __spreadProps(__spreadValues({ className }, rest), { viewBox: "0 0 16 16", width: "16", height: "16" }), /* @__PURE__ */ React27.createElement(
1523
- "path",
1524
- {
1525
- fillRule: "evenodd",
1526
- d: "M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"
1527
- }
1528
- ));
1529
- };
1530
-
1531
- // src/block.tsx
1532
- var tocIndentLevelCache = {};
1533
- var pageCoverStyleCache = {};
1534
- var Block = (props) => {
1535
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q;
1536
- const ctx2 = useNotionContext();
1537
- const {
1538
- components,
1539
- fullPage,
1540
- darkMode,
1541
- recordMap,
1542
- mapPageUrl,
1543
- mapImageUrl,
1544
- showTableOfContents,
1545
- minTableOfContentsItems,
1546
- defaultPageIcon,
1547
- defaultPageCover,
1548
- defaultPageCoverPosition
1549
- } = ctx2;
1550
- const [activeSection, setActiveSection] = React28.useState(null);
1551
- const {
1552
- block,
1553
- children,
1554
- level,
1555
- className,
1556
- bodyClassName,
1557
- header,
1558
- footer,
1559
- pageHeader,
1560
- pageFooter,
1561
- pageTitle,
1562
- pageAside,
1563
- pageCover,
1564
- hideBlockId,
1565
- disableHeader
1566
- } = props;
1567
- if (!block)
1568
- return null;
1569
- if (level === 0 && block.type === "collection_view") {
1570
- ;
1571
- block.type = "collection_view_page";
1572
- }
1573
- const blockId = hideBlockId ? "notion-block" : `notion-block-${uuidToId2(block.id)}`;
1574
- switch (block.type) {
1575
- case "collection_view_page":
1576
- case "page":
1577
- if (level === 0) {
1578
- const {
1579
- page_icon = defaultPageIcon,
1580
- page_cover = defaultPageCover,
1581
- page_cover_position = defaultPageCoverPosition,
1582
- page_full_width,
1583
- page_small_text
1584
- } = block.format || {};
1585
- if (fullPage) {
1586
- const properties = block.type === "page" ? block.properties : {
1587
- title: (_b = (_a = recordMap.collection[getBlockCollectionId(block, recordMap)]) == null ? void 0 : _a.value) == null ? void 0 : _b.name
1588
- };
1589
- const coverPosition = (1 - (page_cover_position || 0.5)) * 100;
1590
- const pageCoverObjectPosition = `center ${coverPosition}%`;
1591
- let pageCoverStyle = pageCoverStyleCache[pageCoverObjectPosition];
1592
- if (!pageCoverStyle)
1593
- pageCoverStyle = pageCoverStyleCache[pageCoverObjectPosition] = {
1594
- objectPosition: pageCoverObjectPosition
1595
- };
1596
- const pageIcon = (_c = getBlockIcon2(block, recordMap)) != null ? _c : defaultPageIcon;
1597
- const isPageIconUrl = pageIcon && isUrl(pageIcon);
1598
- const toc = getPageTableOfContents(block, recordMap);
1599
- const hasToc = showTableOfContents && toc.length >= minTableOfContentsItems;
1600
- const hasAside = (hasToc || pageAside) && !page_full_width;
1601
- const hasPageCover = pageCover || page_cover;
1602
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion", "notion-app", darkMode ? "dark" : "light", blockId, className) }, /* @__PURE__ */ React28.createElement("div", { className: "notion-viewport" }), /* @__PURE__ */ React28.createElement("div", { className: "notion-frame" }, !disableHeader && /* @__PURE__ */ React28.createElement(components.Header, { block }), header, /* @__PURE__ */ React28.createElement("div", { className: "notion-page-scroller" }, hasPageCover && (pageCover ? pageCover : /* @__PURE__ */ React28.createElement("div", { className: "notion-page-cover-wrapper" }, /* @__PURE__ */ React28.createElement(
1603
- LazyImage,
1604
- {
1605
- src: mapImageUrl(page_cover, block),
1606
- alt: getTextContent2(properties == null ? void 0 : properties.title),
1607
- priority: true,
1608
- className: "notion-page-cover",
1609
- style: pageCoverStyle
1610
- }
1611
- ))), /* @__PURE__ */ React28.createElement(
1612
- "main",
1613
- {
1614
- className: cs(
1615
- "notion-page",
1616
- hasPageCover ? "notion-page-has-cover" : "notion-page-no-cover",
1617
- page_icon ? "notion-page-has-icon" : "notion-page-no-icon",
1618
- isPageIconUrl ? "notion-page-has-image-icon" : "notion-page-has-text-icon",
1619
- "notion-full-page",
1620
- page_full_width && "notion-full-width",
1621
- page_small_text && "notion-small-text",
1622
- bodyClassName
1623
- )
1624
- },
1625
- page_icon && /* @__PURE__ */ React28.createElement(PageIcon, { block, defaultIcon: defaultPageIcon, inline: false }),
1626
- pageHeader,
1627
- /* @__PURE__ */ React28.createElement("h1", { className: "notion-title" }, pageTitle != null ? pageTitle : /* @__PURE__ */ React28.createElement(Text, { value: properties == null ? void 0 : properties.title, block })),
1628
- (block.type === "collection_view_page" || block.type === "page" && block.parent_table === "collection") && /* @__PURE__ */ React28.createElement(components.Collection, { block, ctx: ctx2 }),
1629
- block.type !== "collection_view_page" && /* @__PURE__ */ React28.createElement(
1630
- "div",
1631
- {
1632
- className: cs(
1633
- "notion-page-content",
1634
- hasAside && "notion-page-content-has-aside",
1635
- hasToc && "notion-page-content-has-toc"
1636
- )
1637
- },
1638
- /* @__PURE__ */ React28.createElement("article", { className: "notion-page-content-inner" }, children),
1639
- hasAside && /* @__PURE__ */ React28.createElement(
1640
- PageAside,
1641
- {
1642
- toc,
1643
- activeSection,
1644
- setActiveSection,
1645
- hasToc,
1646
- hasAside,
1647
- pageAside
1648
- }
1649
- )
1650
- ),
1651
- pageFooter
1652
- ), footer)));
1653
- } else {
1654
- return /* @__PURE__ */ React28.createElement(
1655
- "main",
1656
- {
1657
- className: cs(
1658
- "notion",
1659
- darkMode ? "dark" : "light",
1660
- "notion-page",
1661
- page_full_width && "notion-full-width",
1662
- page_small_text && "notion-small-text",
1663
- blockId,
1664
- className,
1665
- bodyClassName
1666
- )
1667
- },
1668
- /* @__PURE__ */ React28.createElement("div", { className: "notion-viewport" }),
1669
- pageHeader,
1670
- (block.type === "collection_view_page" || block.type === "page" && block.parent_table === "collection") && /* @__PURE__ */ React28.createElement(components.Collection, { block, ctx: ctx2 }),
1671
- block.type !== "collection_view_page" && children,
1672
- pageFooter
1673
- );
1674
- }
1675
- } else {
1676
- const blockColor = (_d = block.format) == null ? void 0 : _d.block_color;
1677
- return /* @__PURE__ */ React28.createElement(
1678
- components.PageLink,
1679
- {
1680
- className: cs("notion-page-link", blockColor && `notion-${blockColor}`, blockId),
1681
- href: mapPageUrl(block.id)
1682
- },
1683
- /* @__PURE__ */ React28.createElement(PageTitle, { block })
1684
- );
1685
- }
1686
- case "header":
1687
- case "sub_header":
1688
- case "sub_sub_header": {
1689
- if (!block.properties)
1690
- return null;
1691
- const blockColor = (_e = block.format) == null ? void 0 : _e.block_color;
1692
- const id = uuidToId2(block.id);
1693
- const title = getTextContent2(block.properties.title) || `Notion Header ${id}`;
1694
- let indentLevel = tocIndentLevelCache[block.id];
1695
- let indentLevelClass;
1696
- if (indentLevel === void 0) {
1697
- const page = getBlockParentPage2(block, recordMap);
1698
- if (page) {
1699
- const toc = getPageTableOfContents(page, recordMap);
1700
- const tocItem = toc.find((tocItem2) => tocItem2.id === block.id);
1701
- if (tocItem) {
1702
- indentLevel = tocItem.indentLevel;
1703
- tocIndentLevelCache[block.id] = indentLevel;
1704
- }
1705
- }
1706
- }
1707
- if (indentLevel !== void 0)
1708
- indentLevelClass = `notion-h-indent-${indentLevel}`;
1709
- const isH1 = block.type === "header";
1710
- const isH2 = block.type === "sub_header";
1711
- const isH3 = block.type === "sub_sub_header";
1712
- const classNameStr = cs(
1713
- isH1 && "notion-h notion-h1",
1714
- isH2 && "notion-h notion-h2",
1715
- isH3 && "notion-h notion-h3",
1716
- blockColor && `notion-${blockColor}`,
1717
- indentLevelClass,
1718
- blockId
1719
- );
1720
- const innerHeader = /* @__PURE__ */ React28.createElement("span", null, /* @__PURE__ */ React28.createElement("div", { id, className: "notion-header-anchor" }), !((_f = block.format) == null ? void 0 : _f.toggleable) && /* @__PURE__ */ React28.createElement("a", { className: "notion-hash-link", href: `#${id}`, title }, /* @__PURE__ */ React28.createElement(LinkIcon, null)), /* @__PURE__ */ React28.createElement("span", { className: "notion-h-title" }, /* @__PURE__ */ React28.createElement(Text, { value: block.properties.title, block })));
1721
- let headerBlock = null;
1722
- if (isH1)
1723
- headerBlock = /* @__PURE__ */ React28.createElement("h2", { className: classNameStr, "data-id": id }, innerHeader);
1724
- else if (isH2)
1725
- headerBlock = /* @__PURE__ */ React28.createElement("h3", { className: classNameStr, "data-id": id }, innerHeader);
1726
- else
1727
- headerBlock = /* @__PURE__ */ React28.createElement("h4", { className: classNameStr, "data-id": id }, innerHeader);
1728
- if ((_g = block.format) == null ? void 0 : _g.toggleable)
1729
- return /* @__PURE__ */ React28.createElement("details", { className: cs("notion-toggle", blockId) }, /* @__PURE__ */ React28.createElement("summary", null, headerBlock), /* @__PURE__ */ React28.createElement("div", null, children));
1730
- else
1731
- return headerBlock;
1732
- }
1733
- case "divider":
1734
- return /* @__PURE__ */ React28.createElement("hr", { className: cs("notion-hr", blockId) });
1735
- case "text": {
1736
- if (!block.properties && !((_h = block.content) == null ? void 0 : _h.length))
1737
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-blank", blockId) }, "\xA0");
1738
- const blockColor = (_i = block.format) == null ? void 0 : _i.block_color;
1739
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-text", blockColor && `notion-${blockColor}`, blockId) }, ((_j = block.properties) == null ? void 0 : _j.title) && /* @__PURE__ */ React28.createElement(Text, { value: block.properties.title, block }), children && /* @__PURE__ */ React28.createElement("div", { className: "notion-text-children" }, children));
1740
- }
1741
- case "bulleted_list":
1742
- case "numbered_list": {
1743
- const wrapList = (content, start2) => block.type === "bulleted_list" ? /* @__PURE__ */ React28.createElement("ul", { className: cs("notion-list", "notion-list-disc", blockId) }, content) : /* @__PURE__ */ React28.createElement("ol", { start: start2, className: cs("notion-list", "notion-list-numbered", blockId) }, content);
1744
- let output = null;
1745
- if (block.content)
1746
- output = /* @__PURE__ */ React28.createElement(React28.Fragment, null, block.properties && /* @__PURE__ */ React28.createElement("li", null, /* @__PURE__ */ React28.createElement(Text, { value: block.properties.title, block })), wrapList(children));
1747
- else
1748
- output = block.properties ? /* @__PURE__ */ React28.createElement("li", null, /* @__PURE__ */ React28.createElement(Text, { value: block.properties.title, block })) : null;
1749
- const isTopLevel = block.type !== ((_l = (_k = recordMap.block[block.parent_id]) == null ? void 0 : _k.value) == null ? void 0 : _l.type);
1750
- const start = getListNumber(block.id, recordMap.block);
1751
- return isTopLevel ? wrapList(output, start) : output;
1752
- }
1753
- case "embed":
1754
- return /* @__PURE__ */ React28.createElement(components.Embed, { blockId, block });
1755
- case "tweet":
1756
- case "maps":
1757
- case "pdf":
1758
- case "figma":
1759
- case "typeform":
1760
- case "codepen":
1761
- case "excalidraw":
1762
- case "image":
1763
- case "gist":
1764
- case "video":
1765
- return /* @__PURE__ */ React28.createElement(AssetWrapper, { blockId, block });
1766
- case "drive": {
1767
- const properties = (_m = block.format) == null ? void 0 : _m.drive_properties;
1768
- if (!properties) {
1769
- if ((_n = block.format) == null ? void 0 : _n.display_source)
1770
- return /* @__PURE__ */ React28.createElement(AssetWrapper, { blockId, block });
1771
- }
1772
- return /* @__PURE__ */ React28.createElement(GoogleDrive, { block, className: blockId });
1773
- }
1774
- case "audio":
1775
- return /* @__PURE__ */ React28.createElement(Audio, { block, className: blockId });
1776
- case "file":
1777
- return /* @__PURE__ */ React28.createElement(File, { block, className: blockId });
1778
- case "equation":
1779
- return /* @__PURE__ */ React28.createElement(components.Equation, { block, inline: false, className: blockId });
1780
- case "code":
1781
- return /* @__PURE__ */ React28.createElement(components.Code, { block });
1782
- case "column_list":
1783
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-row", blockId) }, children);
1784
- case "column": {
1785
- const spacerWidth = `min(32px, 4vw)`;
1786
- const ratio = ((_o = block.format) == null ? void 0 : _o.column_ratio) || 0.5;
1787
- const parent = (_p = recordMap.block[block.parent_id]) == null ? void 0 : _p.value;
1788
- const columns = ((_q = parent == null ? void 0 : parent.content) == null ? void 0 : _q.length) || Math.max(2, Math.ceil(1 / ratio));
1789
- const width = `calc((100% - (${columns - 1} * ${spacerWidth})) * ${ratio})`;
1790
- const style = { width };
1791
- return /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("div", { className: cs("notion-column", blockId), style }, children), /* @__PURE__ */ React28.createElement("div", { className: "notion-spacer" }));
1792
- }
1793
- case "quote": {
1794
- if (!block.properties)
1795
- return null;
1796
- const blockColor = (_r = block.format) == null ? void 0 : _r.block_color;
1797
- return /* @__PURE__ */ React28.createElement("blockquote", { className: cs("notion-quote", blockColor && `notion-${blockColor}`, blockId) }, /* @__PURE__ */ React28.createElement("div", null, /* @__PURE__ */ React28.createElement(Text, { value: block.properties.title, block })), children);
1798
- }
1799
- case "collection_view":
1800
- return /* @__PURE__ */ React28.createElement(components.Collection, { block, className: blockId, ctx: ctx2 });
1801
- case "callout":
1802
- if (components.Callout)
1803
- return /* @__PURE__ */ React28.createElement(components.Callout, { block, className: blockId });
1804
- else
1805
- return /* @__PURE__ */ React28.createElement(
1806
- "div",
1807
- {
1808
- className: cs("notion-callout", ((_s = block.format) == null ? void 0 : _s.block_color) && `notion-${(_t = block.format) == null ? void 0 : _t.block_color}_co`, blockId)
1809
- },
1810
- /* @__PURE__ */ React28.createElement(PageIcon, { block }),
1811
- /* @__PURE__ */ React28.createElement("div", { className: "notion-callout-text" }, /* @__PURE__ */ React28.createElement(Text, { value: (_u = block.properties) == null ? void 0 : _u.title, block }), children)
1812
- );
1813
- case "bookmark": {
1814
- if (!block.properties)
1815
- return null;
1816
- const link = block.properties.link;
1817
- if (!link || !((_v = link[0]) == null ? void 0 : _v[0]))
1818
- return null;
1819
- let title = getTextContent2(block.properties.title);
1820
- if (!title)
1821
- title = getTextContent2(link);
1822
- if (title) {
1823
- if (title.startsWith("http"))
1824
- try {
1825
- const url = new URL(title);
1826
- title = url.hostname;
1827
- } catch (err) {
1828
- }
1829
- }
1830
- return /* @__PURE__ */ React28.createElement("div", { className: "notion-row" }, /* @__PURE__ */ React28.createElement(
1831
- components.Link,
1832
- {
1833
- target: "_blank",
1834
- rel: "noopener noreferrer",
1835
- className: cs("notion-bookmark", ((_w = block.format) == null ? void 0 : _w.block_color) && `notion-${block.format.block_color}`, blockId),
1836
- href: link[0][0]
1837
- },
1838
- /* @__PURE__ */ React28.createElement("div", null, title && /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-title" }, /* @__PURE__ */ React28.createElement(Text, { value: [[title]], block })), ((_x = block.properties) == null ? void 0 : _x.description) && /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-description" }, /* @__PURE__ */ React28.createElement(Text, { value: (_y = block.properties) == null ? void 0 : _y.description, block })), /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-link" }, ((_z = block.format) == null ? void 0 : _z.bookmark_icon) && /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-link-icon" }, /* @__PURE__ */ React28.createElement(LazyImage, { src: mapImageUrl((_A = block.format) == null ? void 0 : _A.bookmark_icon, block), alt: title })), /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-link-text" }, /* @__PURE__ */ React28.createElement(Text, { value: link, block })))),
1839
- ((_B = block.format) == null ? void 0 : _B.bookmark_cover) && /* @__PURE__ */ React28.createElement("div", { className: "notion-bookmark-image" }, /* @__PURE__ */ React28.createElement(
1840
- LazyImage,
1841
- {
1842
- src: mapImageUrl((_C = block.format) == null ? void 0 : _C.bookmark_cover, block),
1843
- alt: getTextContent2((_D = block.properties) == null ? void 0 : _D.title),
1844
- style: {
1845
- objectFit: "cover"
1846
- }
1847
- }
1848
- ))
1849
- ));
1850
- }
1851
- case "toggle":
1852
- return /* @__PURE__ */ React28.createElement("details", { className: cs("notion-toggle", blockId) }, /* @__PURE__ */ React28.createElement("summary", null, /* @__PURE__ */ React28.createElement(Text, { value: (_E = block.properties) == null ? void 0 : _E.title, block })), /* @__PURE__ */ React28.createElement("div", null, children));
1853
- case "table_of_contents": {
1854
- const page = getBlockParentPage2(block, recordMap);
1855
- if (!page)
1856
- return null;
1857
- const toc = getPageTableOfContents(page, recordMap);
1858
- const blockColor = (_F = block.format) == null ? void 0 : _F.block_color;
1859
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-table-of-contents", blockColor && `notion-${blockColor}`, blockId) }, toc.map((tocItem) => /* @__PURE__ */ React28.createElement("a", { key: tocItem.id, href: `#${uuidToId2(tocItem.id)}`, className: "notion-table-of-contents-item" }, /* @__PURE__ */ React28.createElement(
1860
- "span",
1861
- {
1862
- className: "notion-table-of-contents-item-body",
1863
- style: {
1864
- display: "inline-block",
1865
- marginLeft: tocItem.indentLevel * 24
1866
- }
1867
- },
1868
- tocItem.text
1869
- ))));
1870
- }
1871
- case "to_do": {
1872
- const isChecked = ((_I = (_H = (_G = block.properties) == null ? void 0 : _G.checked) == null ? void 0 : _H[0]) == null ? void 0 : _I[0]) === "Yes";
1873
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-to-do", blockId) }, /* @__PURE__ */ React28.createElement("div", { className: "notion-to-do-item" }, /* @__PURE__ */ React28.createElement(components.Checkbox, { blockId, isChecked }), /* @__PURE__ */ React28.createElement("div", { className: cs("notion-to-do-body", isChecked && `notion-to-do-checked`) }, /* @__PURE__ */ React28.createElement(Text, { value: (_J = block.properties) == null ? void 0 : _J.title, block }))), /* @__PURE__ */ React28.createElement("div", { className: "notion-to-do-children" }, children));
1874
- }
1875
- case "transclusion_container":
1876
- return /* @__PURE__ */ React28.createElement("div", { className: cs("notion-sync-block", blockId) }, children);
1877
- case "transclusion_reference":
1878
- return /* @__PURE__ */ React28.createElement(SyncPointerBlock, __spreadValues({ block, level: level + 1 }, props));
1879
- case "alias": {
1880
- const blockPointerId = (_L = (_K = block == null ? void 0 : block.format) == null ? void 0 : _K.alias_pointer) == null ? void 0 : _L.id;
1881
- const linkedBlock = (_M = recordMap.block[blockPointerId]) == null ? void 0 : _M.value;
1882
- if (!linkedBlock) {
1883
- console.info('"alias" missing block', blockPointerId);
1884
- return null;
1885
- }
1886
- return /* @__PURE__ */ React28.createElement(components.PageLink, { className: cs("notion-page-link", blockPointerId), href: mapPageUrl(blockPointerId) }, /* @__PURE__ */ React28.createElement(PageTitle, { block: linkedBlock }));
1887
- }
1888
- case "table":
1889
- return /* @__PURE__ */ React28.createElement("table", { className: cs("notion-simple-table", blockId) }, /* @__PURE__ */ React28.createElement("tbody", null, children));
1890
- case "table_row": {
1891
- const tableBlock = (_N = recordMap.block[block.parent_id]) == null ? void 0 : _N.value;
1892
- const order = (_O = tableBlock.format) == null ? void 0 : _O.table_block_column_order;
1893
- const formatMap = (_P = tableBlock.format) == null ? void 0 : _P.table_block_column_format;
1894
- const backgroundColor = (_Q = block.format) == null ? void 0 : _Q.block_color;
1895
- if (!tableBlock || !order)
1896
- return null;
1897
- return /* @__PURE__ */ React28.createElement("tr", { className: cs("notion-simple-table-row", backgroundColor && `notion-${backgroundColor}`, blockId) }, order.map((column) => {
1898
- var _a2, _b2, _c2;
1899
- const color = (_a2 = formatMap == null ? void 0 : formatMap[column]) == null ? void 0 : _a2.color;
1900
- return /* @__PURE__ */ React28.createElement(
1901
- "td",
1902
- {
1903
- key: column,
1904
- className: color ? `notion-${color}` : "",
1905
- style: {
1906
- width: ((_b2 = formatMap == null ? void 0 : formatMap[column]) == null ? void 0 : _b2.width) || 120
1907
- }
1908
- },
1909
- /* @__PURE__ */ React28.createElement("div", { className: "notion-simple-table-cell" }, /* @__PURE__ */ React28.createElement(Text, { value: ((_c2 = block.properties) == null ? void 0 : _c2[column]) || [["\u3164"]], block }))
1910
- );
1911
- }));
1912
- }
1913
- case "external_object_instance":
1914
- return /* @__PURE__ */ React28.createElement(EOI, { block, className: blockId });
1915
- default:
1916
- if (true)
1917
- console.info("Unsupported type " + block.type, JSON.stringify(block, null, 2));
1918
- return /* @__PURE__ */ React28.createElement("div", null);
1919
- }
1920
- return null;
1921
- };
1922
-
1923
- // src/renderer.tsx
1924
- var NotionRenderer = (_a) => {
1925
- var _b = _a, {
1926
- components,
1927
- recordMap,
1928
- mapPageUrl,
1929
- mapImageUrl,
1930
- searchNotion,
1931
- isShowingSearch,
1932
- onHideSearch,
1933
- fullPage,
1934
- rootPageId,
1935
- rootDomain,
1936
- darkMode,
1937
- previewImages,
1938
- forceCustomImages,
1939
- showCollectionViewDropdown,
1940
- linkTableTitleProperties,
1941
- isLinkCollectionToUrlProperty,
1942
- isImageZoomable = true,
1943
- showTableOfContents,
1944
- minTableOfContentsItems,
1945
- defaultPageIcon,
1946
- defaultPageCover,
1947
- defaultPageCoverPosition
1948
- } = _b, rest = __objRest(_b, [
1949
- "components",
1950
- "recordMap",
1951
- "mapPageUrl",
1952
- "mapImageUrl",
1953
- "searchNotion",
1954
- "isShowingSearch",
1955
- "onHideSearch",
1956
- "fullPage",
1957
- "rootPageId",
1958
- "rootDomain",
1959
- "darkMode",
1960
- "previewImages",
1961
- "forceCustomImages",
1962
- "showCollectionViewDropdown",
1963
- "linkTableTitleProperties",
1964
- "isLinkCollectionToUrlProperty",
1965
- "isImageZoomable",
1966
- "showTableOfContents",
1967
- "minTableOfContentsItems",
1968
- "defaultPageIcon",
1969
- "defaultPageCover",
1970
- "defaultPageCoverPosition"
1971
- ]);
1972
- const zoom = React29.useMemo(
1973
- () => typeof window !== "undefined" && mediumZoom({
1974
- background: "rgba(0, 0, 0, 0.8)",
1975
- minZoomScale: 2,
1976
- margin: getMediumZoomMargin()
1977
- }),
1978
- []
1979
- );
1980
- return /* @__PURE__ */ React29.createElement(
1981
- NotionContextProvider,
1982
- {
1983
- components,
1984
- recordMap,
1985
- mapPageUrl,
1986
- mapImageUrl,
1987
- searchNotion,
1988
- isShowingSearch,
1989
- onHideSearch,
1990
- fullPage,
1991
- rootPageId,
1992
- rootDomain,
1993
- darkMode,
1994
- previewImages,
1995
- forceCustomImages,
1996
- showCollectionViewDropdown,
1997
- linkTableTitleProperties,
1998
- isLinkCollectionToUrlProperty,
1999
- showTableOfContents,
2000
- minTableOfContentsItems,
2001
- defaultPageIcon,
2002
- defaultPageCover,
2003
- defaultPageCoverPosition,
2004
- zoom: isImageZoomable ? zoom : null
2005
- },
2006
- /* @__PURE__ */ React29.createElement(NotionBlockRenderer, __spreadValues({}, rest))
2007
- );
2008
- };
2009
- var NotionBlockRenderer = (_a) => {
2010
- var _b = _a, { level = 0, blockId } = _b, props = __objRest(_b, ["level", "blockId"]);
2011
- var _a2, _b2;
2012
- const { recordMap } = useNotionContext();
2013
- const id = blockId || Object.keys(recordMap.block)[0];
2014
- const block = (_a2 = recordMap.block[id]) == null ? void 0 : _a2.value;
2015
- if (!block) {
2016
- if (true)
2017
- console.warn("missing block", blockId);
2018
- return null;
2019
- }
2020
- return /* @__PURE__ */ React29.createElement(Block, __spreadValues({ key: id, level, block }, props), (_b2 = block == null ? void 0 : block.content) == null ? void 0 : _b2.map((contentBlockId) => /* @__PURE__ */ React29.createElement(NotionBlockRenderer, __spreadValues({ key: contentBlockId, blockId: contentBlockId, level: level + 1 }, props))));
2021
- };
2022
- function getMediumZoomMargin() {
2023
- const width = window.innerWidth;
2024
- if (width < 500)
2025
- return 8;
2026
- else if (width < 800)
2027
- return 20;
2028
- else if (width < 1280)
2029
- return 30;
2030
- else if (width < 1600)
2031
- return 40;
2032
- else if (width < 1920)
2033
- return 48;
2034
- else
2035
- return 72;
2036
- }
2037
-
2038
- export {
2039
- defaultMapImageUrl,
2040
- defaultMapPageUrl,
2041
- cs,
2042
- getListNumber,
2043
- getHashFragmentValue,
2044
- isBrowser,
2045
- getYoutubeId,
2046
- isUrl,
2047
- formatDate,
2048
- formatNotionDateTime,
2049
- Checkbox,
2050
- LazyImage,
2051
- PageIconImpl,
2052
- PageIcon,
2053
- GracefulImage,
2054
- Text,
2055
- PageTitle,
2056
- Header,
2057
- Breadcrumbs,
2058
- Search,
2059
- dummyLink,
2060
- NotionContextProvider,
2061
- NotionContextConsumer,
2062
- useNotionContext,
2063
- NotionRenderer
2064
- };