@ixo/editor 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1611 +0,0 @@
1
- import {
2
- getEntity,
3
- useMatrixProvider
4
- } from "./chunk-2UJGZZWQ.mjs";
5
-
6
- // src/shadcn/blocks/list/ListBlock.tsx
7
- import React30 from "react";
8
- import { createReactBlockSpec } from "@blocknote/react";
9
-
10
- // src/shadcn/blocks/list/ListBlockToolbar.tsx
11
- import React28 from "react";
12
-
13
- // src/shadcn/blocks/list/ListSettings.tsx
14
- import React27, { useState as useState4, useEffect as useEffect3 } from "react";
15
-
16
- // src/shadcn/components/SettingsModal/SettingsModal.tsx
17
- import React5, { useState } from "react";
18
-
19
- // src/shadcn/components/ui/button.tsx
20
- import * as React from "react";
21
- import { Slot } from "@radix-ui/react-slot";
22
- import { cva } from "class-variance-authority";
23
-
24
- // src/shadcn/lib/utils.ts
25
- import { clsx } from "clsx";
26
- import { twMerge } from "tailwind-merge";
27
- function cn(...inputs) {
28
- return twMerge(clsx(inputs));
29
- }
30
-
31
- // src/shadcn/components/ui/button.tsx
32
- var buttonVariants = cva(
33
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
34
- {
35
- variants: {
36
- variant: {
37
- default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
38
- destructive: "bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
39
- outline: "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
40
- secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
41
- ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
42
- link: "text-primary underline-offset-4 hover:underline"
43
- },
44
- size: {
45
- default: "h-9 px-4 py-2 has-[>svg]:px-3",
46
- sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
47
- lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
48
- icon: "size-9"
49
- }
50
- },
51
- defaultVariants: {
52
- variant: "default",
53
- size: "default"
54
- }
55
- }
56
- );
57
- function Button({
58
- className,
59
- variant,
60
- size,
61
- asChild = false,
62
- ...props
63
- }) {
64
- const Comp = asChild ? Slot : "button";
65
- return /* @__PURE__ */ React.createElement(
66
- Comp,
67
- {
68
- "data-slot": "button",
69
- className: cn(buttonVariants({ variant, size, className })),
70
- ...props
71
- }
72
- );
73
- }
74
-
75
- // src/shadcn/components/ui/dialog.tsx
76
- import * as React2 from "react";
77
- import * as DialogPrimitive from "@radix-ui/react-dialog";
78
- import { XIcon } from "lucide-react";
79
- function Dialog({ ...props }) {
80
- return /* @__PURE__ */ React2.createElement(DialogPrimitive.Root, { "data-slot": "dialog", ...props });
81
- }
82
- function DialogTrigger({ ...props }) {
83
- return /* @__PURE__ */ React2.createElement(DialogPrimitive.Trigger, { "data-slot": "dialog-trigger", ...props });
84
- }
85
- function DialogPortal({ ...props }) {
86
- return /* @__PURE__ */ React2.createElement(DialogPrimitive.Portal, { "data-slot": "dialog-portal", ...props });
87
- }
88
- function DialogOverlay({
89
- className,
90
- ...props
91
- }) {
92
- return /* @__PURE__ */ React2.createElement(
93
- DialogPrimitive.Overlay,
94
- {
95
- "data-slot": "dialog-overlay",
96
- className: cn(
97
- "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/50",
98
- className
99
- ),
100
- ...props
101
- }
102
- );
103
- }
104
- function DialogContent({
105
- className,
106
- children,
107
- showCloseButton = true,
108
- ...props
109
- }) {
110
- return /* @__PURE__ */ React2.createElement(DialogPortal, { "data-slot": "dialog-portal" }, /* @__PURE__ */ React2.createElement(DialogOverlay, null), /* @__PURE__ */ React2.createElement(
111
- DialogPrimitive.Content,
112
- {
113
- "data-slot": "dialog-content",
114
- className: cn(
115
- "bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg",
116
- className
117
- ),
118
- ...props
119
- },
120
- children,
121
- showCloseButton && /* @__PURE__ */ React2.createElement(
122
- DialogPrimitive.Close,
123
- {
124
- "data-slot": "dialog-close",
125
- className: "ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
126
- },
127
- /* @__PURE__ */ React2.createElement(XIcon, null),
128
- /* @__PURE__ */ React2.createElement("span", { className: "sr-only" }, "Close")
129
- )
130
- ));
131
- }
132
-
133
- // src/shadcn/components/PenIcon.tsx
134
- import React3 from "react";
135
- function PenIcon({ size = 16, className = "", color = "secondary" }) {
136
- const colors = {
137
- primary: "#2F2F2F",
138
- secondary: "#9B9B9B",
139
- accent: "#1976D2"
140
- };
141
- return /* @__PURE__ */ React3.createElement(
142
- "svg",
143
- {
144
- xmlns: "http://www.w3.org/2000/svg",
145
- width: size,
146
- height: size,
147
- viewBox: "0 0 24 24",
148
- fill: "none",
149
- stroke: colors[color],
150
- strokeWidth: "1.5",
151
- strokeLinecap: "round",
152
- strokeLinejoin: "round",
153
- className: `transition-colors duration-200 hover:stroke-[#1976D2] ${className}`,
154
- style: {
155
- cursor: "pointer"
156
- }
157
- },
158
- /* @__PURE__ */ React3.createElement("path", { d: "M13 21h8" }),
159
- /* @__PURE__ */ React3.createElement("path", { d: "m15 5 4 4" }),
160
- /* @__PURE__ */ React3.createElement("path", { d: "M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z" })
161
- );
162
- }
163
-
164
- // src/shadcn/components/SettingsModal/SettingsNavigation.tsx
165
- import React4 from "react";
166
- import { CheckIcon } from "lucide-react";
167
- function SettingsNavigation({
168
- activeTab,
169
- onTabChange,
170
- onAddToPage,
171
- navigationItems,
172
- loading = false
173
- }) {
174
- return /* @__PURE__ */ React4.createElement("div", { className: "w-56 border-r bg-muted/50 p-6 flex flex-col" }, /* @__PURE__ */ React4.createElement("nav", { className: "space-y-2 flex-1" }, navigationItems.map((item) => /* @__PURE__ */ React4.createElement(
175
- "button",
176
- {
177
- key: item.id,
178
- onClick: () => !loading && onTabChange(item.id),
179
- disabled: loading,
180
- className: `w-full text-left px-3 py-2 rounded-md text-sm font-medium transition-colors ${activeTab === item.id ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted"} ${loading ? "opacity-50 cursor-not-allowed" : ""}`
181
- },
182
- item.label,
183
- loading && item.id !== activeTab && /* @__PURE__ */ React4.createElement("div", { className: "inline-block ml-2 animate-spin rounded-full h-3 w-3 border-b border-current opacity-50" })
184
- ))), /* @__PURE__ */ React4.createElement("div", { className: "mt-auto pt-4" }, /* @__PURE__ */ React4.createElement(
185
- Button,
186
- {
187
- onClick: onAddToPage,
188
- disabled: loading,
189
- className: "w-full bg-black hover:bg-black/90 text-white rounded-md justify-start px-3 py-2 disabled:opacity-50 disabled:cursor-not-allowed"
190
- },
191
- /* @__PURE__ */ React4.createElement(CheckIcon, { className: "mr-2 h-4 w-4" }),
192
- "Add to page"
193
- )));
194
- }
195
-
196
- // src/shadcn/components/SettingsModal/SettingsModal.tsx
197
- function SettingsModal({
198
- tabs,
199
- onAddToPage,
200
- loading = false,
201
- open,
202
- onOpenChange
203
- }) {
204
- const [activeTab, setActiveTab] = useState(tabs[0]?.id || "general");
205
- const navigationItems = tabs.map((tab) => ({
206
- id: tab.id,
207
- label: tab.label
208
- }));
209
- const activeTabContent = tabs.find((tab) => tab.id === activeTab)?.content;
210
- return /* @__PURE__ */ React5.createElement(Dialog, { open, onOpenChange }, /* @__PURE__ */ React5.createElement(DialogTrigger, { asChild: true }, /* @__PURE__ */ React5.createElement(Button, { variant: "secondary", className: "font-semibold" }, /* @__PURE__ */ React5.createElement(PenIcon, null), " Edit")), /* @__PURE__ */ React5.createElement(DialogContent, { className: "max-w-4xl h-[600px] p-0 rounded-2xl" }, /* @__PURE__ */ React5.createElement("div", { className: "flex h-full overflow-hidden" }, /* @__PURE__ */ React5.createElement(
211
- SettingsNavigation,
212
- {
213
- activeTab,
214
- onTabChange: setActiveTab,
215
- onAddToPage,
216
- navigationItems,
217
- loading
218
- }
219
- ), /* @__PURE__ */ React5.createElement("div", { className: "flex-1 p-6 overflow-y-auto" }, activeTabContent))));
220
- }
221
-
222
- // src/shadcn/blocks/list/ListGeneralTab.tsx
223
- import React11, { useState as useState2, useEffect } from "react";
224
-
225
- // src/shadcn/components/ui/input.tsx
226
- import * as React6 from "react";
227
- function Input({ className, type, ...props }) {
228
- return /* @__PURE__ */ React6.createElement(
229
- "input",
230
- {
231
- type,
232
- "data-slot": "input",
233
- className: cn(
234
- "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
235
- "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
236
- "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
237
- className
238
- ),
239
- ...props
240
- }
241
- );
242
- }
243
-
244
- // src/shadcn/components/ui/label.tsx
245
- import * as React7 from "react";
246
- import * as LabelPrimitive from "@radix-ui/react-label";
247
- function Label({ className, ...props }) {
248
- return /* @__PURE__ */ React7.createElement(
249
- LabelPrimitive.Root,
250
- {
251
- "data-slot": "label",
252
- className: cn(
253
- "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
254
- className
255
- ),
256
- ...props
257
- }
258
- );
259
- }
260
-
261
- // src/shadcn/components/ui/tabs.tsx
262
- import * as React8 from "react";
263
- import * as TabsPrimitive from "@radix-ui/react-tabs";
264
- function Tabs({ className, ...props }) {
265
- return /* @__PURE__ */ React8.createElement(
266
- TabsPrimitive.Root,
267
- {
268
- "data-slot": "tabs",
269
- className: cn("flex flex-col gap-2", className),
270
- ...props
271
- }
272
- );
273
- }
274
- function TabsList({ className, ...props }) {
275
- return /* @__PURE__ */ React8.createElement(
276
- TabsPrimitive.List,
277
- {
278
- "data-slot": "tabs-list",
279
- className: cn(
280
- "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
281
- className
282
- ),
283
- ...props
284
- }
285
- );
286
- }
287
- function TabsTrigger({ className, ...props }) {
288
- return /* @__PURE__ */ React8.createElement(
289
- TabsPrimitive.Trigger,
290
- {
291
- "data-slot": "tabs-trigger",
292
- className: cn(
293
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
294
- className
295
- ),
296
- ...props
297
- }
298
- );
299
- }
300
- function TabsContent({ className, ...props }) {
301
- return /* @__PURE__ */ React8.createElement(
302
- TabsPrimitive.Content,
303
- {
304
- "data-slot": "tabs-content",
305
- className: cn("flex-1 outline-none", className),
306
- ...props
307
- }
308
- );
309
- }
310
-
311
- // src/shadcn/blocks/list/ListGeneralTab.tsx
312
- import { CheckIcon as CheckIcon2 } from "lucide-react";
313
-
314
- // src/shadcn/components/SettingsModal/DomainPreview.tsx
315
- import React10 from "react";
316
-
317
- // src/shadcn/components/ui/card.tsx
318
- import * as React9 from "react";
319
- var Card = React9.forwardRef(
320
- ({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement(
321
- "div",
322
- {
323
- ref,
324
- className: cn("rounded-lg border bg-card text-card-foreground shadow-sm", className),
325
- ...props
326
- }
327
- )
328
- );
329
- Card.displayName = "Card";
330
- var CardHeader = React9.forwardRef(
331
- ({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement("div", { ref, className: cn("flex flex-col space-y-1.5 p-6", className), ...props })
332
- );
333
- CardHeader.displayName = "CardHeader";
334
- var CardTitle = React9.forwardRef(
335
- ({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement(
336
- "h3",
337
- {
338
- ref,
339
- className: cn("text-2xl font-semibold leading-none tracking-tight", className),
340
- ...props
341
- }
342
- )
343
- );
344
- CardTitle.displayName = "CardTitle";
345
- var CardDescription = React9.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement("p", { ref, className: cn("text-sm text-muted-foreground", className), ...props }));
346
- CardDescription.displayName = "CardDescription";
347
- var CardContent = React9.forwardRef(
348
- ({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement("div", { ref, className: cn("p-6 pt-0", className), ...props })
349
- );
350
- CardContent.displayName = "CardContent";
351
- var CardFooter = React9.forwardRef(
352
- ({ className, ...props }, ref) => /* @__PURE__ */ React9.createElement("div", { ref, className: cn("flex items-center p-6 pt-0", className), ...props })
353
- );
354
- CardFooter.displayName = "CardFooter";
355
-
356
- // src/shadcn/components/SettingsModal/DomainPreview.tsx
357
- function DomainPreview({ domainProfile }) {
358
- if (!domainProfile) {
359
- return null;
360
- }
361
- return /* @__PURE__ */ React10.createElement(Card, { className: "border-0 shadow-sm rounded-xl" }, /* @__PURE__ */ React10.createElement(CardContent, { className: "p-4" }, /* @__PURE__ */ React10.createElement("div", { className: "flex items-start space-x-4" }, /* @__PURE__ */ React10.createElement("div", { className: "w-16 h-16 bg-muted rounded-lg flex items-center justify-center shrink-0" }, /* @__PURE__ */ React10.createElement(
362
- "img",
363
- {
364
- src: domainProfile.image ?? "https://studio.ixo.earth/domain-profile-default.jpg",
365
- alt: domainProfile.name,
366
- className: "w-full h-full object-cover rounded-lg border-2 border-gray-200"
367
- }
368
- )), /* @__PURE__ */ React10.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ React10.createElement("h3", { className: "font-semibold text-lg" }, domainProfile.name), /* @__PURE__ */ React10.createElement("p", { className: "text-muted-foreground text-sm" }, domainProfile.description)))));
369
- }
370
-
371
- // src/shadcn/blocks/list/ListGeneralTab.tsx
372
- function ListGeneralTab({
373
- block: _block,
374
- editor: _editor,
375
- domainValue,
376
- onDomainChange,
377
- domainProfile
378
- }) {
379
- const [domainType, setDomainType] = useState2("this-domain");
380
- const [isValidDomain, setIsValidDomain] = useState2(true);
381
- const [isLoading, setIsLoading] = useState2(false);
382
- const [customDomainValue, setCustomDomainValue] = useState2("");
383
- const thisDomainValue = "did:ixo:entity:example123";
384
- useEffect(() => {
385
- if (domainValue) {
386
- if (domainValue === thisDomainValue) {
387
- setDomainType("this-domain");
388
- setIsValidDomain(true);
389
- } else {
390
- setDomainType("custom-domain");
391
- setCustomDomainValue(domainValue);
392
- setIsValidDomain(true);
393
- }
394
- } else {
395
- setDomainType("this-domain");
396
- setCustomDomainValue("");
397
- setIsValidDomain(true);
398
- }
399
- }, [domainValue, thisDomainValue]);
400
- const handleCustomDomainChange = async (did) => {
401
- setCustomDomainValue(did);
402
- if (!did) {
403
- setIsValidDomain(false);
404
- return;
405
- }
406
- const isValid = did.startsWith("did:") && did.length > 10;
407
- if (isValid) {
408
- setIsLoading(true);
409
- try {
410
- await new Promise((resolve) => setTimeout(resolve, 1e3));
411
- setIsValidDomain(true);
412
- onDomainChange(did);
413
- } catch (error) {
414
- setIsValidDomain(false);
415
- } finally {
416
- setIsLoading(false);
417
- }
418
- } else {
419
- setIsValidDomain(false);
420
- }
421
- };
422
- const handleTabChange = (value) => {
423
- setDomainType(value);
424
- if (value === "this-domain") {
425
- setIsValidDomain(true);
426
- onDomainChange(thisDomainValue);
427
- } else {
428
- setIsValidDomain(false);
429
- onDomainChange("");
430
- }
431
- };
432
- return /* @__PURE__ */ React11.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React11.createElement("div", null, /* @__PURE__ */ React11.createElement("h2", { className: "text-2xl font-semibold" }, "List"), /* @__PURE__ */ React11.createElement("p", { className: "text-muted-foreground mt-1" }, "Add a domain list to your page")), /* @__PURE__ */ React11.createElement(Tabs, { defaultValue: "this-domain", value: domainType, onValueChange: handleTabChange }, /* @__PURE__ */ React11.createElement(TabsList, { className: "px-1" }, /* @__PURE__ */ React11.createElement(TabsTrigger, { value: "this-domain" }, "This domain"), /* @__PURE__ */ React11.createElement(TabsTrigger, { value: "custom-domain" }, "Custom domain")), /* @__PURE__ */ React11.createElement(TabsContent, { value: "this-domain", className: "space-y-4" }, /* @__PURE__ */ React11.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React11.createElement(Label, { htmlFor: "this-domain-input" }, "Domain"), /* @__PURE__ */ React11.createElement("div", { className: "relative" }, /* @__PURE__ */ React11.createElement(
433
- Input,
434
- {
435
- id: "this-domain-input",
436
- value: thisDomainValue,
437
- disabled: true,
438
- className: "pr-10",
439
- placeholder: "Enter domain DID"
440
- }
441
- ), isValidDomain && /* @__PURE__ */ React11.createElement(CheckIcon2, { className: "absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-green-500" }))), /* @__PURE__ */ React11.createElement(DomainPreview, { key: thisDomainValue, domainProfile })), /* @__PURE__ */ React11.createElement(TabsContent, { value: "custom-domain", className: "space-y-4" }, /* @__PURE__ */ React11.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React11.createElement(Label, { htmlFor: "custom-domain-input" }, "Domain"), /* @__PURE__ */ React11.createElement("div", { className: "relative" }, /* @__PURE__ */ React11.createElement(
442
- Input,
443
- {
444
- id: "custom-domain-input",
445
- value: customDomainValue,
446
- onChange: (e) => handleCustomDomainChange(e.target.value),
447
- className: "pr-10",
448
- placeholder: "Enter domain DID",
449
- disabled: isLoading
450
- }
451
- ), isLoading ? /* @__PURE__ */ React11.createElement("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2" }, /* @__PURE__ */ React11.createElement("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-gray-900" })) : isValidDomain && customDomainValue && /* @__PURE__ */ React11.createElement(CheckIcon2, { className: "absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-green-500" }))), isValidDomain && customDomainValue && !isLoading && /* @__PURE__ */ React11.createElement(DomainPreview, { key: customDomainValue, domainProfile }))));
452
- }
453
-
454
- // src/shadcn/blocks/list/ListPreviewTab.tsx
455
- import React23, { useState as useState3, useEffect as useEffect2 } from "react";
456
-
457
- // src/shadcn/blocks/list/ListItem.tsx
458
- import React22 from "react";
459
-
460
- // src/core/lib/getMediaTypeIcon.tsx
461
- import React21 from "react";
462
-
463
- // src/shadcn/components/icons/DocumentIcon.tsx
464
- import React12 from "react";
465
- function DocumentIcon({
466
- size = 16,
467
- className = "",
468
- color = "secondary"
469
- }) {
470
- const colors = {
471
- primary: "#2F2F2F",
472
- secondary: "#9B9B9B",
473
- accent: "#1976D2"
474
- };
475
- return /* @__PURE__ */ React12.createElement(
476
- "svg",
477
- {
478
- xmlns: "http://www.w3.org/2000/svg",
479
- width: size,
480
- height: size,
481
- viewBox: "0 0 24 24",
482
- fill: "none",
483
- stroke: colors[color],
484
- strokeWidth: "1.5",
485
- strokeLinecap: "round",
486
- strokeLinejoin: "round",
487
- className: `transition-colors duration-200 ${className}`
488
- },
489
- /* @__PURE__ */ React12.createElement("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
490
- /* @__PURE__ */ React12.createElement("polyline", { points: "14,2 14,8 20,8" }),
491
- /* @__PURE__ */ React12.createElement("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
492
- /* @__PURE__ */ React12.createElement("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
493
- /* @__PURE__ */ React12.createElement("polyline", { points: "10,9 9,9 8,9" })
494
- );
495
- }
496
-
497
- // src/shadcn/components/icons/ImageIcon.tsx
498
- import React13 from "react";
499
- function ImageIcon({
500
- size = 16,
501
- className = "",
502
- color = "secondary"
503
- }) {
504
- const colors = {
505
- primary: "#2F2F2F",
506
- secondary: "#9B9B9B",
507
- accent: "#1976D2"
508
- };
509
- return /* @__PURE__ */ React13.createElement(
510
- "svg",
511
- {
512
- xmlns: "http://www.w3.org/2000/svg",
513
- width: size,
514
- height: size,
515
- viewBox: "0 0 24 24",
516
- fill: "none",
517
- stroke: colors[color],
518
- strokeWidth: "1.5",
519
- strokeLinecap: "round",
520
- strokeLinejoin: "round",
521
- className: `transition-colors duration-200 ${className}`
522
- },
523
- /* @__PURE__ */ React13.createElement("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
524
- /* @__PURE__ */ React13.createElement("circle", { cx: "9", cy: "9", r: "2" }),
525
- /* @__PURE__ */ React13.createElement("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
526
- );
527
- }
528
-
529
- // src/shadcn/components/icons/VideoIcon.tsx
530
- import React14 from "react";
531
- function VideoIcon({
532
- size = 16,
533
- className = "",
534
- color = "secondary"
535
- }) {
536
- const colors = {
537
- primary: "#2F2F2F",
538
- secondary: "#9B9B9B",
539
- accent: "#1976D2"
540
- };
541
- return /* @__PURE__ */ React14.createElement(
542
- "svg",
543
- {
544
- xmlns: "http://www.w3.org/2000/svg",
545
- width: size,
546
- height: size,
547
- viewBox: "0 0 24 24",
548
- fill: "none",
549
- stroke: colors[color],
550
- strokeWidth: "1.5",
551
- strokeLinecap: "round",
552
- strokeLinejoin: "round",
553
- className: `transition-colors duration-200 ${className}`
554
- },
555
- /* @__PURE__ */ React14.createElement("path", { d: "m22 8-6 4 6 4V8Z" }),
556
- /* @__PURE__ */ React14.createElement("rect", { width: "14", height: "12", x: "2", y: "6", rx: "2", ry: "2" })
557
- );
558
- }
559
-
560
- // src/shadcn/components/icons/AudioIcon.tsx
561
- import React15 from "react";
562
- function AudioIcon({
563
- size = 16,
564
- className = "",
565
- color = "secondary"
566
- }) {
567
- const colors = {
568
- primary: "#2F2F2F",
569
- secondary: "#9B9B9B",
570
- accent: "#1976D2"
571
- };
572
- return /* @__PURE__ */ React15.createElement(
573
- "svg",
574
- {
575
- xmlns: "http://www.w3.org/2000/svg",
576
- width: size,
577
- height: size,
578
- viewBox: "0 0 24 24",
579
- fill: "none",
580
- stroke: colors[color],
581
- strokeWidth: "1.5",
582
- strokeLinecap: "round",
583
- strokeLinejoin: "round",
584
- className: `transition-colors duration-200 ${className}`
585
- },
586
- /* @__PURE__ */ React15.createElement("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
587
- /* @__PURE__ */ React15.createElement("path", { d: "m19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07" })
588
- );
589
- }
590
-
591
- // src/shadcn/components/icons/PdfIcon.tsx
592
- import React16 from "react";
593
- function PdfIcon({ size = 16, className = "", color = "secondary" }) {
594
- const colors = {
595
- primary: "#2F2F2F",
596
- secondary: "#9B9B9B",
597
- accent: "#1976D2"
598
- };
599
- return /* @__PURE__ */ React16.createElement(
600
- "svg",
601
- {
602
- xmlns: "http://www.w3.org/2000/svg",
603
- width: size,
604
- height: size,
605
- viewBox: "0 0 24 24",
606
- fill: "none",
607
- stroke: colors[color],
608
- strokeWidth: "1.5",
609
- strokeLinecap: "round",
610
- strokeLinejoin: "round",
611
- className: `transition-colors duration-200 ${className}`
612
- },
613
- /* @__PURE__ */ React16.createElement("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
614
- /* @__PURE__ */ React16.createElement("polyline", { points: "14,2 14,8 20,8" }),
615
- /* @__PURE__ */ React16.createElement("path", { d: "M10 12h4" }),
616
- /* @__PURE__ */ React16.createElement("path", { d: "M10 16h2" }),
617
- /* @__PURE__ */ React16.createElement("path", { d: "M8 12v4" })
618
- );
619
- }
620
-
621
- // src/shadcn/components/icons/JsonIcon.tsx
622
- import React17 from "react";
623
- function JsonIcon({
624
- size = 16,
625
- className = "",
626
- color = "secondary"
627
- }) {
628
- const colors = {
629
- primary: "#2F2F2F",
630
- secondary: "#9B9B9B",
631
- accent: "#1976D2"
632
- };
633
- return /* @__PURE__ */ React17.createElement(
634
- "svg",
635
- {
636
- xmlns: "http://www.w3.org/2000/svg",
637
- width: size,
638
- height: size,
639
- viewBox: "0 0 24 24",
640
- fill: "none",
641
- stroke: colors[color],
642
- strokeWidth: "1.5",
643
- strokeLinecap: "round",
644
- strokeLinejoin: "round",
645
- className: `transition-colors duration-200 ${className}`
646
- },
647
- /* @__PURE__ */ React17.createElement("path", { d: "M5 12s2.545-5 7-5c4.454 0 7 5 7 5s-2.546 5-7 5c-4.455 0-7-5-7-5z" }),
648
- /* @__PURE__ */ React17.createElement("path", { d: "M12 13a1 1 0 1 0 0-2 1 1 0 0 0 0 2z" }),
649
- /* @__PURE__ */ React17.createElement("path", { d: "M21 17v2a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2" }),
650
- /* @__PURE__ */ React17.createElement("path", { d: "M21 7V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v2" })
651
- );
652
- }
653
-
654
- // src/shadcn/components/icons/XmlIcon.tsx
655
- import React18 from "react";
656
- function XmlIcon({ size = 16, className = "", color = "secondary" }) {
657
- const colors = {
658
- primary: "#2F2F2F",
659
- secondary: "#9B9B9B",
660
- accent: "#1976D2"
661
- };
662
- return /* @__PURE__ */ React18.createElement(
663
- "svg",
664
- {
665
- xmlns: "http://www.w3.org/2000/svg",
666
- width: size,
667
- height: size,
668
- viewBox: "0 0 24 24",
669
- fill: "none",
670
- stroke: colors[color],
671
- strokeWidth: "1.5",
672
- strokeLinecap: "round",
673
- strokeLinejoin: "round",
674
- className: `transition-colors duration-200 ${className}`
675
- },
676
- /* @__PURE__ */ React18.createElement("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
677
- /* @__PURE__ */ React18.createElement("polyline", { points: "14,2 14,8 20,8" }),
678
- /* @__PURE__ */ React18.createElement("path", { d: "m9 13 2 2-2 2" }),
679
- /* @__PURE__ */ React18.createElement("path", { d: "m15 13-2 2 2 2" })
680
- );
681
- }
682
-
683
- // src/shadcn/components/icons/ArchiveIcon.tsx
684
- import React19 from "react";
685
- function ArchiveIcon({
686
- size = 16,
687
- className = "",
688
- color = "secondary"
689
- }) {
690
- const colors = {
691
- primary: "#2F2F2F",
692
- secondary: "#9B9B9B",
693
- accent: "#1976D2"
694
- };
695
- return /* @__PURE__ */ React19.createElement(
696
- "svg",
697
- {
698
- xmlns: "http://www.w3.org/2000/svg",
699
- width: size,
700
- height: size,
701
- viewBox: "0 0 24 24",
702
- fill: "none",
703
- stroke: colors[color],
704
- strokeWidth: "1.5",
705
- strokeLinecap: "round",
706
- strokeLinejoin: "round",
707
- className: `transition-colors duration-200 ${className}`
708
- },
709
- /* @__PURE__ */ React19.createElement("rect", { width: "20", height: "5", x: "2", y: "3", rx: "1" }),
710
- /* @__PURE__ */ React19.createElement("path", { d: "M4 8v11a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8" }),
711
- /* @__PURE__ */ React19.createElement("path", { d: "M10 12h4" })
712
- );
713
- }
714
-
715
- // src/shadcn/components/icons/DefaultIcon.tsx
716
- import React20 from "react";
717
- function DefaultIcon({
718
- size = 16,
719
- className = "",
720
- color = "secondary"
721
- }) {
722
- const colors = {
723
- primary: "#2F2F2F",
724
- secondary: "#9B9B9B",
725
- accent: "#1976D2"
726
- };
727
- return /* @__PURE__ */ React20.createElement(
728
- "svg",
729
- {
730
- xmlns: "http://www.w3.org/2000/svg",
731
- width: size,
732
- height: size,
733
- viewBox: "0 0 24 24",
734
- fill: "none",
735
- stroke: colors[color],
736
- strokeWidth: "1.5",
737
- strokeLinecap: "round",
738
- strokeLinejoin: "round",
739
- className: `transition-colors duration-200 ${className}`
740
- },
741
- /* @__PURE__ */ React20.createElement("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
742
- /* @__PURE__ */ React20.createElement("polyline", { points: "14,2 14,8 20,8" })
743
- );
744
- }
745
-
746
- // src/core/lib/getMediaTypeIcon.tsx
747
- function getMediaTypeIcon(mediaType, props = {}) {
748
- const normalizedType = mediaType?.toLowerCase() || "";
749
- if (normalizedType.startsWith("image/")) {
750
- return /* @__PURE__ */ React21.createElement(ImageIcon, { ...props });
751
- }
752
- if (normalizedType.startsWith("video/")) {
753
- return /* @__PURE__ */ React21.createElement(VideoIcon, { ...props });
754
- }
755
- if (normalizedType.startsWith("audio/")) {
756
- return /* @__PURE__ */ React21.createElement(AudioIcon, { ...props });
757
- }
758
- if (normalizedType.includes("pdf") || normalizedType === "application/pdf") {
759
- return /* @__PURE__ */ React21.createElement(PdfIcon, { ...props });
760
- }
761
- if (normalizedType.includes("json") || normalizedType === "application/json" || normalizedType === "text/json") {
762
- return /* @__PURE__ */ React21.createElement(JsonIcon, { ...props });
763
- }
764
- if (normalizedType.includes("xml") || normalizedType === "application/xml" || normalizedType === "text/xml" || normalizedType === "application/rss+xml" || normalizedType === "application/atom+xml") {
765
- return /* @__PURE__ */ React21.createElement(XmlIcon, { ...props });
766
- }
767
- if (normalizedType.includes("zip") || normalizedType.includes("rar") || normalizedType.includes("tar") || normalizedType.includes("gzip") || normalizedType.includes("7z") || normalizedType === "application/x-compressed" || normalizedType === "application/x-zip-compressed" || normalizedType === "multipart/x-zip") {
768
- return /* @__PURE__ */ React21.createElement(ArchiveIcon, { ...props });
769
- }
770
- if (normalizedType.startsWith("text/") || normalizedType.includes("document") || normalizedType.includes("word") || normalizedType.includes("excel") || normalizedType.includes("powerpoint") || normalizedType.includes("spreadsheet") || normalizedType.includes("presentation")) {
771
- return /* @__PURE__ */ React21.createElement(DocumentIcon, { ...props });
772
- }
773
- return /* @__PURE__ */ React21.createElement(DefaultIcon, { ...props });
774
- }
775
-
776
- // src/shadcn/blocks/list/ListItem.tsx
777
- function ListItem({ item, index = 0 }) {
778
- const title = typeof item === "string" ? item : item.description || item.title || item.name || `Item ${index + 1}`;
779
- const mediaType = typeof item === "object" ? item.mediaType || "" : "";
780
- return /* @__PURE__ */ React22.createElement("div", { className: "group w-full bg-white rounded-lg p-4 border border-gray-100 hover:bg-gray-50 transition-colors duration-150 ease-in-out cursor-pointer" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center justify-between space-x-4" }, /* @__PURE__ */ React22.createElement("div", { className: "flex items-center space-x-3 flex-1 min-w-0" }, /* @__PURE__ */ React22.createElement("div", { className: "flex-shrink-0 w-8 h-8 bg-gray-100 rounded-md flex items-center justify-center" }, getMediaTypeIcon(mediaType, {
781
- size: 16,
782
- className: "text-gray-500",
783
- color: "secondary"
784
- })), /* @__PURE__ */ React22.createElement("span", { className: "font-semibold text-gray-800 truncate flex-1" }, title))));
785
- }
786
-
787
- // src/shadcn/blocks/list/ListPreviewTab.tsx
788
- function ListPreviewTab({ block, domain }) {
789
- const [items, setItems] = useState3([]);
790
- const showResources = block.props.showLinkedResources;
791
- useEffect2(() => {
792
- if (showResources) {
793
- setItems(domain.linkedResource);
794
- }
795
- }, []);
796
- return /* @__PURE__ */ React23.createElement("div", { className: "flex flex-col gap-4 mt-[30px]" }, items.map((item) => /* @__PURE__ */ React23.createElement(ListItem, { item })));
797
- }
798
-
799
- // src/shadcn/components/SwitchOption.tsx
800
- import * as React25 from "react";
801
-
802
- // src/shadcn/components/ui/switch.tsx
803
- import * as React24 from "react";
804
- import * as SwitchPrimitive from "@radix-ui/react-switch";
805
- function Switch({ className, ...props }) {
806
- return /* @__PURE__ */ React24.createElement(
807
- SwitchPrimitive.Root,
808
- {
809
- "data-slot": "switch",
810
- className: cn(
811
- "peer data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 inline-flex h-[1.15rem] w-8 shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50",
812
- className
813
- ),
814
- ...props
815
- },
816
- /* @__PURE__ */ React24.createElement(
817
- SwitchPrimitive.Thumb,
818
- {
819
- "data-slot": "switch-thumb",
820
- className: cn(
821
- "bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0"
822
- )
823
- }
824
- )
825
- );
826
- }
827
-
828
- // src/shadcn/components/SwitchOption.tsx
829
- function SwitchOption({ label, description, checked, onChange }) {
830
- return /* @__PURE__ */ React25.createElement("div", { className: "flex w-full max-w-md items-start justify-between gap-4 py-2" }, /* @__PURE__ */ React25.createElement("div", { className: "flex flex-col" }, /* @__PURE__ */ React25.createElement("span", { className: "text-sm font-medium leading-none" }, label), /* @__PURE__ */ React25.createElement("span", { className: "mt-1 text-sm text-muted-foreground" }, description)), /* @__PURE__ */ React25.createElement(Switch, { id: label, "aria-label": label, checked, onCheckedChange: onChange }));
831
- }
832
-
833
- // src/shadcn/blocks/list/ListSettingsTab.tsx
834
- import React26, { useMemo } from "react";
835
- function ListSettingsTab({ block, editor, domain }) {
836
- const linkedResources = {
837
- count: domain?.linkedResource?.length ?? 0
838
- };
839
- const isCollection = useMemo(() => {
840
- return domain?.type === "asset/collection";
841
- }, [domain]);
842
- return /* @__PURE__ */ React26.createElement("div", null, /* @__PURE__ */ React26.createElement(
843
- SwitchOption,
844
- {
845
- label: `Linked Resources ${linkedResources.count}`,
846
- description: "Resources linked to this list",
847
- checked: block.props.showLinkedResources,
848
- onChange: (checked) => {
849
- editor.updateBlock(block.id, {
850
- props: {
851
- showLinkedResources: checked
852
- }
853
- });
854
- }
855
- }
856
- ), isCollection && /* @__PURE__ */ React26.createElement(
857
- SwitchOption,
858
- {
859
- label: "Display assets in collection",
860
- description: "Display assets in collection",
861
- checked: block.props.showAssetsInCollection,
862
- onChange: (checked) => {
863
- editor.updateBlock(block.id, {
864
- props: {
865
- showAssetsInCollection: checked
866
- }
867
- });
868
- }
869
- }
870
- ));
871
- }
872
-
873
- // src/shadcn/blocks/list/ListSettings.tsx
874
- function ListSettings({ block, editor, setList }) {
875
- const [domainValue, setDomainValue] = useState4(block.props.did);
876
- const [loading, setLoading] = useState4(false);
877
- const [domainProfile, setDomainProfile] = useState4(null);
878
- const [modalOpen, setModalOpen] = useState4(false);
879
- const [domain, setDomain] = useState4(null);
880
- useEffect3(() => {
881
- if (!domainValue) {
882
- setDomainProfile(null);
883
- return;
884
- }
885
- setLoading(true);
886
- setDomainProfile(null);
887
- const fetchEntity = async () => {
888
- try {
889
- const entity = await getEntity(domainValue);
890
- setDomain(entity);
891
- const profileResource = entity.settings.Profile;
892
- if (profileResource?.serviceEndpoint) {
893
- const fetchedProfile = await fetch(profileResource.serviceEndpoint).then(
894
- (res) => res.json()
895
- );
896
- setDomainProfile(fetchedProfile);
897
- } else {
898
- setDomainProfile(null);
899
- }
900
- setLoading(false);
901
- } catch (err) {
902
- setDomainProfile(null);
903
- setLoading(false);
904
- }
905
- };
906
- fetchEntity();
907
- }, [domainValue]);
908
- const handleDidChange = (did) => {
909
- setDomainValue(did);
910
- };
911
- const handleAddToPage = () => {
912
- editor.updateBlock(block.id, {
913
- props: {
914
- did: domainValue
915
- }
916
- });
917
- console.log("Adding to page with DID:", domainValue);
918
- if (block.props.showLinkedResources && domain?.linkedResource) {
919
- setList(domain.linkedResource);
920
- }
921
- setModalOpen(false);
922
- };
923
- return /* @__PURE__ */ React27.createElement(
924
- SettingsModal,
925
- {
926
- onAddToPage: handleAddToPage,
927
- loading,
928
- open: modalOpen,
929
- onOpenChange: setModalOpen,
930
- tabs: [
931
- {
932
- id: "general",
933
- label: "General",
934
- content: /* @__PURE__ */ React27.createElement(
935
- ListGeneralTab,
936
- {
937
- block,
938
- editor,
939
- domainValue,
940
- onDomainChange: handleDidChange,
941
- domainProfile
942
- }
943
- )
944
- },
945
- {
946
- id: "settings",
947
- label: "Settings",
948
- content: /* @__PURE__ */ React27.createElement(ListSettingsTab, { block, editor, domain })
949
- },
950
- {
951
- id: "preview",
952
- label: "Preview",
953
- content: /* @__PURE__ */ React27.createElement(ListPreviewTab, { block, domain })
954
- }
955
- ]
956
- }
957
- );
958
- }
959
-
960
- // src/shadcn/blocks/list/ListBlockToolbar.tsx
961
- function ListBlockToolbar({ block, editor, setList }) {
962
- return /* @__PURE__ */ React28.createElement("div", { className: "flex justify-between items-center mb-3 pb-2 border-b border-gray-100 dark:border-gray-700" }, /* @__PURE__ */ React28.createElement(
963
- Input,
964
- {
965
- value: block.props.title,
966
- placeholder: "New list",
967
- className: "font-semibold flex-1 border-0 bg-transparent px-2 py-1 focus-visible:ring-0 focus-visible:ring-offset-0 hover:bg-gray-50 dark:hover:bg-gray-700 focus:bg-gray-50 dark:focus:bg-gray-700 notion-list-title-input",
968
- style: {
969
- color: "#2F2F2F",
970
- fontFamily: "Inter, Helvetica, Arial, sans-serif",
971
- fontSize: "14px",
972
- fontWeight: 600
973
- },
974
- onChange: (e) => {
975
- editor.updateBlock(block, {
976
- props: {
977
- ...block.props,
978
- title: e.target.value
979
- }
980
- });
981
- }
982
- }
983
- ), /* @__PURE__ */ React28.createElement(ListSettings, { block, editor, setList }));
984
- }
985
-
986
- // src/shadcn/blocks/list/useList.tsx
987
- import { useState as useState5 } from "react";
988
- function useList() {
989
- const [list, setList] = useState5([]);
990
- return {
991
- list,
992
- setList
993
- };
994
- }
995
-
996
- // src/shadcn/blocks/list/ListContainer.tsx
997
- import React29 from "react";
998
- function ListContainer({ children }) {
999
- return /* @__PURE__ */ React29.createElement("div", { className: "flex flex-col gap-2" }, children);
1000
- }
1001
-
1002
- // src/shadcn/blocks/list/ListBlock.tsx
1003
- var ListBlockContent = ({ block, editor }) => {
1004
- const { list, setList } = useList();
1005
- return /* @__PURE__ */ React30.createElement(
1006
- "div",
1007
- {
1008
- style: {
1009
- width: "100%",
1010
- borderRadius: "6px",
1011
- padding: "16px",
1012
- backgroundColor: "#FFFFFF",
1013
- fontFamily: "Inter, Helvetica, Arial, sans-serif"
1014
- }
1015
- },
1016
- /* @__PURE__ */ React30.createElement(ListBlockToolbar, { block, editor, setList }),
1017
- /* @__PURE__ */ React30.createElement("div", { style: { minHeight: "40px" } }, /* @__PURE__ */ React30.createElement(ListContainer, null, list?.map((item, index) => /* @__PURE__ */ React30.createElement(ListItem, { key: index, item, index }))))
1018
- );
1019
- };
1020
- var ListBlock = createReactBlockSpec(
1021
- {
1022
- type: "list",
1023
- propSchema: {
1024
- title: {
1025
- default: ""
1026
- },
1027
- did: {
1028
- default: ""
1029
- },
1030
- fragmentIdentifier: {
1031
- default: ""
1032
- },
1033
- listItemType: {
1034
- default: "keyvalue"
1035
- },
1036
- showLinkedResources: {
1037
- default: false
1038
- },
1039
- showAssetsInCollection: {
1040
- default: false
1041
- }
1042
- },
1043
- content: "none"
1044
- },
1045
- {
1046
- render: ListBlockContent
1047
- }
1048
- );
1049
-
1050
- // src/shadcn/blocks/overview/OverviewBlock.tsx
1051
- import React36 from "react";
1052
- import { createReactBlockSpec as createReactBlockSpec2 } from "@blocknote/react";
1053
-
1054
- // src/shadcn/blocks/overview/OverviewBlockToolbar.tsx
1055
- import React35 from "react";
1056
-
1057
- // src/shadcn/components/GlobeIcon.tsx
1058
- import React31 from "react";
1059
- function GlobeIcon({
1060
- size = 16,
1061
- className = "",
1062
- color = "secondary"
1063
- }) {
1064
- const colors = {
1065
- primary: "#2F2F2F",
1066
- secondary: "#9B9B9B",
1067
- accent: "#1976D2"
1068
- };
1069
- return /* @__PURE__ */ React31.createElement(
1070
- "svg",
1071
- {
1072
- xmlns: "http://www.w3.org/2000/svg",
1073
- width: size,
1074
- height: size,
1075
- viewBox: "0 0 24 24",
1076
- fill: "none",
1077
- stroke: colors[color],
1078
- strokeWidth: "1.5",
1079
- strokeLinecap: "round",
1080
- strokeLinejoin: "round",
1081
- className: `transition-colors duration-200 hover:stroke-[#1976D2] ${className}`,
1082
- style: {
1083
- cursor: "pointer"
1084
- }
1085
- },
1086
- /* @__PURE__ */ React31.createElement("circle", { cx: "12", cy: "12", r: "10" }),
1087
- /* @__PURE__ */ React31.createElement("path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20" }),
1088
- /* @__PURE__ */ React31.createElement("path", { d: "M2 12h20" })
1089
- );
1090
- }
1091
-
1092
- // src/shadcn/blocks/overview/OverviewSettings.tsx
1093
- import React34, { useState as useState7, useEffect as useEffect5 } from "react";
1094
-
1095
- // src/shadcn/blocks/overview/OverviewGeneralTab.tsx
1096
- import React32, { useState as useState6, useEffect as useEffect4 } from "react";
1097
- import { CheckIcon as CheckIcon3 } from "lucide-react";
1098
- function OverviewGeneralTab({
1099
- block: _block,
1100
- editor: _editor,
1101
- domainValue,
1102
- onDomainChange,
1103
- domainProfile
1104
- }) {
1105
- const [domainType, setDomainType] = useState6("this-domain");
1106
- const [isValidDomain, setIsValidDomain] = useState6(true);
1107
- const [isLoading, setIsLoading] = useState6(false);
1108
- const [customDomainValue, setCustomDomainValue] = useState6("");
1109
- const thisDomainValue = "did:ixo:entity:example123";
1110
- useEffect4(() => {
1111
- if (domainValue) {
1112
- if (domainValue === thisDomainValue) {
1113
- setDomainType("this-domain");
1114
- setIsValidDomain(true);
1115
- } else {
1116
- setDomainType("custom-domain");
1117
- setCustomDomainValue(domainValue);
1118
- setIsValidDomain(true);
1119
- }
1120
- } else {
1121
- setDomainType("this-domain");
1122
- setCustomDomainValue("");
1123
- setIsValidDomain(true);
1124
- }
1125
- }, [domainValue, thisDomainValue]);
1126
- const handleCustomDomainChange = async (did) => {
1127
- setCustomDomainValue(did);
1128
- if (!did) {
1129
- setIsValidDomain(false);
1130
- return;
1131
- }
1132
- const isValid = did.startsWith("did:") && did.length > 10;
1133
- if (isValid) {
1134
- setIsLoading(true);
1135
- try {
1136
- await new Promise((resolve) => setTimeout(resolve, 1e3));
1137
- setIsValidDomain(true);
1138
- onDomainChange(did);
1139
- } catch (error) {
1140
- setIsValidDomain(false);
1141
- } finally {
1142
- setIsLoading(false);
1143
- }
1144
- } else {
1145
- setIsValidDomain(false);
1146
- }
1147
- };
1148
- const handleTabChange = (value) => {
1149
- setDomainType(value);
1150
- if (value === "this-domain") {
1151
- setIsValidDomain(true);
1152
- onDomainChange(thisDomainValue);
1153
- } else {
1154
- setIsValidDomain(false);
1155
- onDomainChange("");
1156
- }
1157
- };
1158
- return /* @__PURE__ */ React32.createElement("div", { className: "space-y-6" }, /* @__PURE__ */ React32.createElement("div", null, /* @__PURE__ */ React32.createElement("h2", { className: "text-2xl font-semibold" }, "Overview"), /* @__PURE__ */ React32.createElement("p", { className: "text-muted-foreground mt-1" }, "Add a domain overview to your page")), /* @__PURE__ */ React32.createElement(Tabs, { defaultValue: "this-domain", value: domainType, onValueChange: handleTabChange }, /* @__PURE__ */ React32.createElement(TabsList, { className: "px-1" }, /* @__PURE__ */ React32.createElement(TabsTrigger, { value: "this-domain" }, "This domain"), /* @__PURE__ */ React32.createElement(TabsTrigger, { value: "custom-domain" }, "Custom domain")), /* @__PURE__ */ React32.createElement(TabsContent, { value: "this-domain", className: "space-y-4" }, /* @__PURE__ */ React32.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React32.createElement(Label, { htmlFor: "this-domain-input" }, "Domain"), /* @__PURE__ */ React32.createElement("div", { className: "relative" }, /* @__PURE__ */ React32.createElement(
1159
- Input,
1160
- {
1161
- id: "this-domain-input",
1162
- value: thisDomainValue,
1163
- disabled: true,
1164
- className: "pr-10",
1165
- placeholder: "Enter domain DID"
1166
- }
1167
- ), isValidDomain && /* @__PURE__ */ React32.createElement(CheckIcon3, { className: "absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-green-500" }))), /* @__PURE__ */ React32.createElement(DomainPreview, { domainProfile })), /* @__PURE__ */ React32.createElement(TabsContent, { value: "custom-domain", className: "space-y-4" }, /* @__PURE__ */ React32.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React32.createElement(Label, { htmlFor: "custom-domain-input" }, "Domain"), /* @__PURE__ */ React32.createElement("div", { className: "relative" }, /* @__PURE__ */ React32.createElement(
1168
- Input,
1169
- {
1170
- id: "custom-domain-input",
1171
- value: customDomainValue,
1172
- onChange: (e) => handleCustomDomainChange(e.target.value),
1173
- className: "pr-10",
1174
- placeholder: "Enter domain DID",
1175
- disabled: isLoading
1176
- }
1177
- ), isLoading ? /* @__PURE__ */ React32.createElement("div", { className: "absolute right-3 top-1/2 transform -translate-y-1/2" }, /* @__PURE__ */ React32.createElement("div", { className: "animate-spin rounded-full h-4 w-4 border-b-2 border-gray-900" })) : isValidDomain && customDomainValue && /* @__PURE__ */ React32.createElement(CheckIcon3, { className: "absolute right-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-green-500" }))), isValidDomain && customDomainValue && !isLoading && /* @__PURE__ */ React32.createElement(DomainPreview, { domainProfile }))));
1178
- }
1179
-
1180
- // src/shadcn/blocks/overview/OverviewPreviewTab.tsx
1181
- import React33 from "react";
1182
- import { BlockNoteView } from "@blocknote/shadcn";
1183
- import { useCreateBlockNote } from "@blocknote/react";
1184
- function OverviewPreviewTab({
1185
- blocks,
1186
- loading = false,
1187
- error = null
1188
- }) {
1189
- const editor = useCreateBlockNote({
1190
- ...blocks ? { initialContent: blocks } : {}
1191
- });
1192
- console.log({ blocks });
1193
- if (loading) {
1194
- return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center p-8" }, /* @__PURE__ */ React33.createElement("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900" }));
1195
- }
1196
- if (error) {
1197
- return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center p-8 text-red-500" }, /* @__PURE__ */ React33.createElement("p", null, "Error loading preview: ", error));
1198
- }
1199
- if (blocks === null) {
1200
- return /* @__PURE__ */ React33.createElement("div", { className: "flex items-center justify-center p-8 text-gray-500" }, /* @__PURE__ */ React33.createElement("p", null, "No content available"));
1201
- }
1202
- return /* @__PURE__ */ React33.createElement(BlockNoteView, { editor, editable: false });
1203
- }
1204
-
1205
- // src/shadcn/blocks/overview/OverviewSettings.tsx
1206
- function OverviewSettings({ block, editor }) {
1207
- const [domainValue, setDomainValue] = useState7(block.props.did);
1208
- const [pageBlocks, setPageBlocks] = useState7(block.props.blocks || null);
1209
- const [loading, setLoading] = useState7(false);
1210
- const [error, setError] = useState7(null);
1211
- const [domainProfile, setDomainProfile] = useState7(null);
1212
- const [modalOpen, setModalOpen] = useState7(false);
1213
- useEffect5(() => {
1214
- if (!domainValue) {
1215
- setPageBlocks(block.props.blocks || null);
1216
- return;
1217
- }
1218
- setLoading(true);
1219
- setError(null);
1220
- const fetchPageBlocks = async () => {
1221
- try {
1222
- const entity = await getEntity(domainValue);
1223
- const overviewResource = entity.settings.Page;
1224
- const profileResource = entity.settings.Profile;
1225
- if (overviewResource?.serviceEndpoint) {
1226
- const fetchedPageBlocks = await fetch(overviewResource.serviceEndpoint).then(
1227
- (res) => res.json()
1228
- );
1229
- console.log({ fetchedPageBlocks });
1230
- setPageBlocks(fetchedPageBlocks.blocks || block.props.blocks || null);
1231
- } else {
1232
- setPageBlocks(block.props.blocks || null);
1233
- }
1234
- if (profileResource?.serviceEndpoint) {
1235
- const fetchedProfile = await fetch(profileResource.serviceEndpoint).then(
1236
- (res) => res.json()
1237
- );
1238
- setDomainProfile(fetchedProfile);
1239
- }
1240
- setLoading(false);
1241
- } catch (err) {
1242
- setError(err instanceof Error ? err.message : "Failed to fetch page blocks");
1243
- setPageBlocks(block.props.blocks || null);
1244
- setLoading(false);
1245
- }
1246
- };
1247
- fetchPageBlocks();
1248
- }, [domainValue, block.props.blocks]);
1249
- const handleDidChange = (did) => {
1250
- setDomainValue(did);
1251
- };
1252
- const handleAddToPage = () => {
1253
- editor.updateBlock(block.id, {
1254
- props: {
1255
- did: domainValue
1256
- },
1257
- children: pageBlocks
1258
- });
1259
- console.log("Adding to page with DID:", domainValue);
1260
- setModalOpen(false);
1261
- };
1262
- return /* @__PURE__ */ React34.createElement(
1263
- SettingsModal,
1264
- {
1265
- onAddToPage: handleAddToPage,
1266
- loading,
1267
- open: modalOpen,
1268
- onOpenChange: setModalOpen,
1269
- tabs: [
1270
- {
1271
- id: "general",
1272
- label: "General",
1273
- content: /* @__PURE__ */ React34.createElement(
1274
- OverviewGeneralTab,
1275
- {
1276
- block,
1277
- editor,
1278
- domainValue,
1279
- onDomainChange: handleDidChange,
1280
- domainProfile
1281
- }
1282
- )
1283
- },
1284
- {
1285
- id: "preview",
1286
- label: "Preview",
1287
- content: /* @__PURE__ */ React34.createElement(OverviewPreviewTab, { blocks: pageBlocks ?? null, loading, error })
1288
- }
1289
- ]
1290
- }
1291
- );
1292
- }
1293
-
1294
- // src/shadcn/blocks/overview/OverviewBlockToolbar.tsx
1295
- function OverviewBlockToolbar({ block, editor }) {
1296
- return /* @__PURE__ */ React35.createElement("div", { className: "flex justify-between items-center mb-3 pb-2 border-b border-gray-100 dark:border-gray-700" }, /* @__PURE__ */ React35.createElement("div", { className: "flex gap-2 items-center font-semibold" }, /* @__PURE__ */ React35.createElement(GlobeIcon, { size: 16 }), " Overview"), /* @__PURE__ */ React35.createElement(OverviewSettings, { block, editor }));
1297
- }
1298
-
1299
- // src/shadcn/blocks/overview/OverviewBlock.tsx
1300
- var OverviewBlockContent = ({ block, editor, contentRef }) => {
1301
- return /* @__PURE__ */ React36.createElement(
1302
- "div",
1303
- {
1304
- style: {
1305
- width: "100%",
1306
- backgroundColor: "#FFFFFF",
1307
- borderRadius: "8px"
1308
- }
1309
- },
1310
- /* @__PURE__ */ React36.createElement(OverviewBlockToolbar, { block, editor }),
1311
- /* @__PURE__ */ React36.createElement("div", { ref: contentRef })
1312
- );
1313
- };
1314
- var OverviewBlock = createReactBlockSpec2(
1315
- {
1316
- type: "overview",
1317
- propSchema: {
1318
- did: { default: "" }
1319
- },
1320
- content: "inline"
1321
- // <– KEY: makes this block host nested editable content
1322
- },
1323
- {
1324
- render: OverviewBlockContent
1325
- }
1326
- );
1327
-
1328
- // src/shadcn/blocks/index.ts
1329
- var blockSpecs = {
1330
- list: ListBlock,
1331
- overview: OverviewBlock
1332
- };
1333
- var getExtraSlashMenuItems = (editor) => [
1334
- {
1335
- title: "List",
1336
- onItemClick: () => {
1337
- editor.insertBlocks(
1338
- [
1339
- {
1340
- type: "list",
1341
- props: {
1342
- title: "",
1343
- did: "",
1344
- fragmentIdentifier: ""
1345
- }
1346
- }
1347
- ],
1348
- editor.getTextCursorPosition().block,
1349
- "after"
1350
- );
1351
- },
1352
- aliases: ["list", "data", "dynamic"],
1353
- group: "Domains",
1354
- subtext: "Create a dynamic list from DID data"
1355
- },
1356
- {
1357
- title: "Overview",
1358
- onItemClick: () => {
1359
- editor.insertBlocks(
1360
- [
1361
- {
1362
- type: "overview",
1363
- props: {
1364
- did: ""
1365
- }
1366
- }
1367
- ],
1368
- editor.getTextCursorPosition().block,
1369
- "after"
1370
- );
1371
- },
1372
- aliases: ["overview", "overview-block", "data-overview"],
1373
- group: "Domains",
1374
- subtext: "Create an overview from DID data"
1375
- }
1376
- ];
1377
-
1378
- // src/shadcn/hooks/useCreateIxoEditor.ts
1379
- import { useCreateBlockNote as useCreateBlockNote2 } from "@blocknote/react";
1380
- import {
1381
- BlockNoteSchema,
1382
- defaultBlockSpecs,
1383
- defaultInlineContentSpecs,
1384
- defaultStyleSpecs
1385
- } from "@blocknote/core";
1386
- function useCreateIxoEditor(options) {
1387
- const {
1388
- theme = "light",
1389
- uploadFile,
1390
- initialContent,
1391
- editable = true,
1392
- sideMenu = true,
1393
- slashMenu = true,
1394
- formattingToolbar = true,
1395
- linkToolbar = true,
1396
- filePanel = true,
1397
- tableHandles = true
1398
- } = options || {};
1399
- const defaultUploadFile = uploadFile || (async (file) => {
1400
- return new Promise((resolve, reject) => {
1401
- const reader = new FileReader();
1402
- reader.onloadend = () => {
1403
- const dataUrl = reader.result;
1404
- resolve(dataUrl);
1405
- };
1406
- reader.onerror = reject;
1407
- reader.readAsDataURL(file);
1408
- });
1409
- });
1410
- const schema = BlockNoteSchema.create({
1411
- blockSpecs: {
1412
- ...defaultBlockSpecs,
1413
- ...blockSpecs
1414
- },
1415
- inlineContentSpecs: {
1416
- ...defaultInlineContentSpecs
1417
- },
1418
- styleSpecs: {
1419
- ...defaultStyleSpecs
1420
- }
1421
- });
1422
- const editor = useCreateBlockNote2({
1423
- schema,
1424
- initialContent,
1425
- uploadFile: defaultUploadFile
1426
- });
1427
- if (editor) {
1428
- editor._ixoConfig = {
1429
- theme,
1430
- editable,
1431
- sideMenu,
1432
- slashMenu,
1433
- formattingToolbar,
1434
- linkToolbar,
1435
- filePanel,
1436
- tableHandles
1437
- };
1438
- }
1439
- return editor;
1440
- }
1441
-
1442
- // src/shadcn/hooks/useCollaborativeIxoEditor.ts
1443
- import { useCreateBlockNote as useCreateBlockNote3 } from "@blocknote/react";
1444
- import {
1445
- BlockNoteSchema as BlockNoteSchema2,
1446
- defaultBlockSpecs as defaultBlockSpecs2,
1447
- defaultInlineContentSpecs as defaultInlineContentSpecs2,
1448
- defaultStyleSpecs as defaultStyleSpecs2
1449
- } from "@blocknote/core";
1450
- import * as Y from "yjs";
1451
- import { useMemo as useMemo2 } from "react";
1452
- function useCreateCollaborativeIxoEditor(options) {
1453
- const yDoc = useMemo2(() => new Y.Doc(), []);
1454
- const {
1455
- theme = "light",
1456
- uploadFile,
1457
- initialContent,
1458
- editable = true,
1459
- sideMenu = true,
1460
- slashMenu = true,
1461
- formattingToolbar = true,
1462
- linkToolbar = true,
1463
- filePanel = true,
1464
- tableHandles = true,
1465
- user,
1466
- matrixClient
1467
- } = options || {};
1468
- const memoizedUser = useMemo2(
1469
- () => ({
1470
- id: user?.id || "",
1471
- name: user?.name || "",
1472
- color: user?.color || "",
1473
- accessToken: user?.accessToken || ""
1474
- }),
1475
- [user?.id, user?.name, user?.color, user?.accessToken]
1476
- );
1477
- const { matrixProvider, connectionStatus } = useMatrixProvider({
1478
- yDoc,
1479
- matrixClient,
1480
- roomId: options.roomId
1481
- });
1482
- const defaultUploadFile = useMemo2(
1483
- () => uploadFile || (async (file) => {
1484
- return new Promise((resolve, reject) => {
1485
- const reader = new FileReader();
1486
- reader.onloadend = () => {
1487
- const dataUrl = reader.result;
1488
- resolve(dataUrl);
1489
- };
1490
- reader.onerror = reject;
1491
- reader.readAsDataURL(file);
1492
- });
1493
- }),
1494
- [uploadFile]
1495
- );
1496
- const schema = useMemo2(
1497
- () => BlockNoteSchema2.create({
1498
- blockSpecs: {
1499
- ...defaultBlockSpecs2,
1500
- ...blockSpecs
1501
- },
1502
- inlineContentSpecs: {
1503
- ...defaultInlineContentSpecs2
1504
- },
1505
- styleSpecs: {
1506
- ...defaultStyleSpecs2
1507
- }
1508
- }),
1509
- []
1510
- );
1511
- const collaborationConfig = useMemo2(
1512
- () => ({
1513
- provider: matrixProvider,
1514
- fragment: yDoc.getXmlFragment("document"),
1515
- user: {
1516
- name: memoizedUser.name,
1517
- color: memoizedUser.color
1518
- }
1519
- }),
1520
- [matrixProvider, yDoc, memoizedUser.name, memoizedUser.color]
1521
- );
1522
- const ixoConfig = useMemo2(
1523
- () => ({
1524
- theme,
1525
- editable,
1526
- sideMenu,
1527
- slashMenu,
1528
- formattingToolbar,
1529
- linkToolbar,
1530
- filePanel,
1531
- tableHandles
1532
- }),
1533
- [theme, editable, sideMenu, slashMenu, formattingToolbar, linkToolbar, filePanel, tableHandles]
1534
- );
1535
- const editor = useCreateBlockNote3({
1536
- schema,
1537
- initialContent,
1538
- uploadFile: defaultUploadFile,
1539
- collaboration: collaborationConfig
1540
- });
1541
- if (editor) {
1542
- editor._ixoConfig = ixoConfig;
1543
- }
1544
- return { editor, connectionStatus };
1545
- }
1546
-
1547
- // src/shadcn/IxoEditor.tsx
1548
- import React37 from "react";
1549
- import { getDefaultReactSlashMenuItems, SuggestionMenuController } from "@blocknote/react";
1550
- import { BlockNoteView as BlockNoteView2 } from "@blocknote/shadcn";
1551
- import { filterSuggestionItems } from "@blocknote/core";
1552
- function IxoEditor({
1553
- editor,
1554
- className = "",
1555
- onChange,
1556
- onSelectionChange,
1557
- children
1558
- }) {
1559
- if (!editor) {
1560
- return null;
1561
- }
1562
- const config = editor._ixoConfig || {
1563
- theme: "light",
1564
- editable: true,
1565
- sideMenu: true,
1566
- slashMenu: true,
1567
- formattingToolbar: true,
1568
- linkToolbar: true,
1569
- filePanel: true,
1570
- tableHandles: true
1571
- };
1572
- return /* @__PURE__ */ React37.createElement("div", { className: `ixo-editor ixo-editor--theme-${config.theme} ${className}` }, /* @__PURE__ */ React37.createElement(
1573
- BlockNoteView2,
1574
- {
1575
- editor,
1576
- editable: config.editable,
1577
- sideMenu: config.sideMenu,
1578
- slashMenu: false,
1579
- formattingToolbar: config.formattingToolbar,
1580
- linkToolbar: config.linkToolbar,
1581
- filePanel: config.filePanel,
1582
- tableHandles: config.tableHandles,
1583
- theme: config.theme,
1584
- onChange,
1585
- onSelectionChange
1586
- },
1587
- config.slashMenu && /* @__PURE__ */ React37.createElement(
1588
- SuggestionMenuController,
1589
- {
1590
- triggerCharacter: "/",
1591
- getItems: async (query) => {
1592
- const defaultItems = getDefaultReactSlashMenuItems(editor);
1593
- const customItems = getExtraSlashMenuItems(editor);
1594
- return filterSuggestionItems([...defaultItems, ...customItems], query);
1595
- }
1596
- }
1597
- ),
1598
- children
1599
- ));
1600
- }
1601
-
1602
- export {
1603
- ListBlock,
1604
- OverviewBlock,
1605
- blockSpecs,
1606
- getExtraSlashMenuItems,
1607
- useCreateIxoEditor,
1608
- useCreateCollaborativeIxoEditor,
1609
- IxoEditor
1610
- };
1611
- //# sourceMappingURL=chunk-GSKWOGSU.mjs.map