@ixo/editor 3.0.0 → 3.1.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.
@@ -30997,7 +30997,7 @@ var MatrixMetadataManager = class {
30997
30997
  this.eventHandler = (event) => {
30998
30998
  if (event.getRoomId() === this.roomId) {
30999
30999
  const eventType = event.getType();
31000
- if (eventType === COVER_IMAGE_EVENT_TYPE || eventType === COVER_ICON_EVENT_TYPE) {
31000
+ if (eventType === COVER_IMAGE_EVENT_TYPE || eventType === COVER_ICON_EVENT_TYPE || eventType === "m.room.name") {
31001
31001
  const metadata = this.getMetadata();
31002
31002
  if (metadata) {
31003
31003
  this.notifySubscribers(metadata);
@@ -31063,6 +31063,17 @@ var MatrixMetadataManager = class {
31063
31063
  )
31064
31064
  );
31065
31065
  }
31066
+ if ("title" in metadata) {
31067
+ promises.push(
31068
+ this.matrixClient.sendStateEvent(
31069
+ this.roomId,
31070
+ "m.room.name",
31071
+ { name: metadata.title || "" },
31072
+ ""
31073
+ // Empty state key
31074
+ )
31075
+ );
31076
+ }
31066
31077
  await Promise.all(promises);
31067
31078
  } catch (error) {
31068
31079
  console.error("Failed to set page metadata:", error);
@@ -31096,10 +31107,13 @@ var MatrixMetadataManager = class {
31096
31107
  );
31097
31108
  const iconContent = iconEvent ? iconEvent.getContent() : null;
31098
31109
  const iconUrl = iconContent?.url || null;
31099
- if (!coverUrl && !iconUrl) {
31110
+ const nameEvent = room.currentState.getStateEvents("m.room.name", "");
31111
+ const roomName = nameEvent ? nameEvent.getContent()?.name || null : null;
31112
+ if (!coverUrl && !iconUrl && !roomName) {
31100
31113
  return null;
31101
31114
  }
31102
31115
  return {
31116
+ title: roomName || void 0,
31103
31117
  cover: coverUrl || void 0,
31104
31118
  icon: iconUrl || void 0,
31105
31119
  coverPosition: coverPos ?? void 0
@@ -31876,7 +31890,7 @@ function useCreateCollaborativeIxoEditor(options) {
31876
31890
  }
31877
31891
 
31878
31892
  // src/mantine/IxoEditor.tsx
31879
- import React299, { useState as useState138, useEffect as useEffect113, useCallback as useCallback111 } from "react";
31893
+ import React299 from "react";
31880
31894
  import { SuggestionMenuController } from "@blocknote/react";
31881
31895
  import { BlockNoteView } from "@blocknote/mantine";
31882
31896
  import { filterSuggestionItems } from "@blocknote/core";
@@ -31933,8 +31947,9 @@ function PanelContent({ theme }) {
31933
31947
  }
31934
31948
 
31935
31949
  // src/mantine/components/CoverImage.tsx
31936
- import React296, { useState as useState135, useRef as useRef29, useEffect as useEffect110, useMemo as useMemo121 } from "react";
31937
- import { Box as Box62, Group as Group108 } from "@mantine/core";
31950
+ import React296, { useState as useState136, useRef as useRef29, useEffect as useEffect110, useMemo as useMemo121 } from "react";
31951
+ import { Box as Box62, Group as Group109 } from "@mantine/core";
31952
+ import { IconMoodSmile, IconPhoto as IconPhoto4, IconSettings as IconSettings22, IconArrowsMove, IconTrash as IconTrash11, IconRefresh as IconRefresh5 } from "@tabler/icons-react";
31938
31953
 
31939
31954
  // src/core/lib/imageTransform.ts
31940
31955
  var CLOUDFLARE_CDN_BASE = "https://www.ixo.earth/cdn-cgi/image";
@@ -32067,33 +32082,53 @@ function transformIconImage(sourceUrl, size = "default", customOptions) {
32067
32082
  }
32068
32083
 
32069
32084
  // src/mantine/components/Base/CoverImageButton.tsx
32070
- import React292, { forwardRef } from "react";
32071
- import { Button as Button55 } from "@mantine/core";
32072
- var CoverImageButton = forwardRef(({ isActive = false, onClick, children, style, ...props }, ref) => /* @__PURE__ */ React292.createElement(
32073
- Button55,
32074
- {
32075
- ref,
32076
- variant: "filled",
32077
- onClick,
32078
- size: "xs",
32079
- style: {
32080
- backgroundColor: isActive ? "rgba(55, 53, 47, 0.9)" : "rgba(255, 255, 255, 0.9)",
32081
- color: isActive ? "white" : "#37352f",
32082
- fontSize: "12px",
32083
- fontWeight: 500,
32084
- padding: "4px 8px",
32085
- height: "auto",
32086
- ...style
32087
- },
32088
- ...props
32089
- },
32090
- children
32091
- ));
32092
- CoverImageButton.displayName = "CoverImageButton";
32085
+ import React292, { forwardRef, useState as useState133 } from "react";
32086
+ import { UnstyledButton as UnstyledButton6, Group as Group106, Text as Text170 } from "@mantine/core";
32087
+ var CoverImageButton = forwardRef(function CoverImageButton2({ isActive = false, onClick, icon: icon2, children, style }, ref) {
32088
+ const [hovered, setHovered] = useState133(false);
32089
+ return /* @__PURE__ */ React292.createElement(
32090
+ UnstyledButton6,
32091
+ {
32092
+ ref,
32093
+ onClick,
32094
+ onMouseEnter: () => setHovered(true),
32095
+ onMouseLeave: () => setHovered(false),
32096
+ style: {
32097
+ padding: "4px 8px",
32098
+ borderRadius: "4px",
32099
+ border: "none",
32100
+ background: isActive || hovered ? "var(--mantine-color-neutralColor-5)" : "transparent",
32101
+ transition: "background 0.15s ease",
32102
+ ...style
32103
+ }
32104
+ },
32105
+ /* @__PURE__ */ React292.createElement(Group106, { gap: 4, wrap: "nowrap" }, icon2 && /* @__PURE__ */ React292.createElement(
32106
+ "span",
32107
+ {
32108
+ style: {
32109
+ display: "flex",
32110
+ alignItems: "center",
32111
+ color: "var(--mantine-color-neutralColor-7)"
32112
+ }
32113
+ },
32114
+ icon2
32115
+ ), /* @__PURE__ */ React292.createElement(
32116
+ Text170,
32117
+ {
32118
+ fz: 12,
32119
+ style: {
32120
+ color: "var(--mantine-color-neutralColor-7) !important",
32121
+ whiteSpace: "nowrap"
32122
+ }
32123
+ },
32124
+ children
32125
+ ))
32126
+ );
32127
+ });
32093
32128
 
32094
32129
  // src/mantine/components/Base/BaseIconPicker.tsx
32095
- import React293, { useState as useState133, useMemo as useMemo119, useEffect as useEffect108 } from "react";
32096
- import { TextInput as TextInput7, Tabs as Tabs4, Box as Box59, Stack as Stack196, UnstyledButton as UnstyledButton6, Text as Text170, Center as Center14, ScrollArea as ScrollArea9, Group as Group106, Popover as Popover6 } from "@mantine/core";
32130
+ import React293, { useState as useState134, useMemo as useMemo119, useEffect as useEffect108 } from "react";
32131
+ import { TextInput as TextInput7, Tabs as Tabs4, Box as Box59, Stack as Stack196, UnstyledButton as UnstyledButton7, Text as Text171, Center as Center14, ScrollArea as ScrollArea9, Group as Group107, Popover as Popover6 } from "@mantine/core";
32097
32132
  import * as TablerIcons from "@tabler/icons-react";
32098
32133
  import { IconSearch as IconSearch7, IconX as IconX13, IconChevronLeft, IconChevronRight as IconChevronRight13 } from "@tabler/icons-react";
32099
32134
 
@@ -32124,10 +32159,10 @@ var localStorageService = {
32124
32159
  // src/mantine/components/Base/BaseIconPicker.tsx
32125
32160
  var iconsKey = "editor_recent_icons";
32126
32161
  var ICONS_PER_PAGE = 500;
32127
- function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children, currentIcon }) {
32128
- const [searchQuery, setSearchQuery] = useState133("");
32129
- const [activeTab, setActiveTab] = useState133("icons");
32130
- const [currentPage, setCurrentPage] = useState133(1);
32162
+ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, onRemove, children, currentIcon }) {
32163
+ const [searchQuery, setSearchQuery] = useState134("");
32164
+ const [activeTab, setActiveTab] = useState134("icons");
32165
+ const [currentPage, setCurrentPage] = useState134(1);
32131
32166
  const allIcons = useMemo119(() => {
32132
32167
  const iconEntries = Object.entries(TablerIcons).filter(([name]) => name.startsWith("Icon") && name !== "IconProps");
32133
32168
  return iconEntries;
@@ -32161,7 +32196,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32161
32196
  };
32162
32197
  const renderIconGrid = (icons) => {
32163
32198
  if (icons.length === 0) {
32164
- return /* @__PURE__ */ React293.createElement(Center14, { py: "xl" }, /* @__PURE__ */ React293.createElement(Text170, { c: "dimmed", size: "sm" }, "No icons found"));
32199
+ return /* @__PURE__ */ React293.createElement(Center14, { py: "xl" }, /* @__PURE__ */ React293.createElement(Text171, { c: "dimmed", size: "sm" }, "No icons found"));
32165
32200
  }
32166
32201
  return /* @__PURE__ */ React293.createElement(
32167
32202
  Box59,
@@ -32176,7 +32211,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32176
32211
  icons.map(([name, IconComponent]) => {
32177
32212
  const isSelected = currentIcon === name.replace("Icon", "").replace(/([A-Z])/g, "-$1").toLowerCase().slice(1);
32178
32213
  return /* @__PURE__ */ React293.createElement(
32179
- UnstyledButton6,
32214
+ UnstyledButton7,
32180
32215
  {
32181
32216
  key: name,
32182
32217
  onClick: () => handleIconClick(name),
@@ -32201,7 +32236,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32201
32236
  }
32202
32237
  }
32203
32238
  },
32204
- /* @__PURE__ */ React293.createElement(IconComponent, { color: "white", size: 24, stroke: 1.5 })
32239
+ /* @__PURE__ */ React293.createElement(IconComponent, { size: 24, stroke: 1.5, style: { color: "var(--mantine-color-neutralColor-8) !important" } })
32205
32240
  );
32206
32241
  })
32207
32242
  );
@@ -32210,12 +32245,32 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32210
32245
  Popover6.Dropdown,
32211
32246
  {
32212
32247
  style: {
32213
- backgroundColor: "#1a1a1a",
32214
- border: "1px solid rgba(255, 255, 255, 0.1)",
32248
+ backgroundColor: "var(--mantine-color-neutralColor-3)",
32249
+ border: "1px solid var(--mantine-color-neutralColor-5)",
32215
32250
  borderRadius: "12px"
32216
32251
  },
32217
32252
  p: 0
32218
32253
  },
32254
+ onRemove && /* @__PURE__ */ React293.createElement(
32255
+ UnstyledButton7,
32256
+ {
32257
+ onClick: () => {
32258
+ onRemove();
32259
+ onClose();
32260
+ },
32261
+ style: {
32262
+ position: "absolute",
32263
+ top: 12,
32264
+ right: 12,
32265
+ zIndex: 10,
32266
+ padding: "4px 8px",
32267
+ borderRadius: "4px",
32268
+ color: "var(--mantine-color-neutralColor-7)",
32269
+ transition: "background 0.15s ease"
32270
+ }
32271
+ },
32272
+ /* @__PURE__ */ React293.createElement(Group107, { gap: 4, wrap: "nowrap" }, /* @__PURE__ */ React293.createElement(IconX13, { size: 14 }), /* @__PURE__ */ React293.createElement(Text171, { fz: 12, style: { color: "var(--mantine-color-neutralColor-7) !important", whiteSpace: "nowrap" } }, "Remove"))
32273
+ ),
32219
32274
  /* @__PURE__ */ React293.createElement(Stack196, { gap: "md", p: "md" }, /* @__PURE__ */ React293.createElement(Tabs4, { value: activeTab, onChange: setActiveTab, variant: "pills" }, /* @__PURE__ */ React293.createElement(Tabs4.List, null, /* @__PURE__ */ React293.createElement(Tabs4.Tab, { value: "icons" }, "Icons"), /* @__PURE__ */ React293.createElement(Tabs4.Tab, { value: "upload" }, "Upload")), /* @__PURE__ */ React293.createElement(Tabs4.Panel, { value: "icons", pt: "md" }, /* @__PURE__ */ React293.createElement(
32220
32275
  TextInput7,
32221
32276
  {
@@ -32224,7 +32279,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32224
32279
  leftSection: /* @__PURE__ */ React293.createElement(IconSearch7, { size: 18 }),
32225
32280
  value: searchQuery,
32226
32281
  onChange: (e) => setSearchQuery(e.currentTarget.value),
32227
- rightSection: searchQuery && /* @__PURE__ */ React293.createElement(UnstyledButton6, { onClick: () => setSearchQuery("") }, /* @__PURE__ */ React293.createElement(IconX13, { size: 18 })),
32282
+ rightSection: searchQuery && /* @__PURE__ */ React293.createElement(UnstyledButton7, { onClick: () => setSearchQuery("") }, /* @__PURE__ */ React293.createElement(IconX13, { size: 18 })),
32228
32283
  style: { flex: 1 },
32229
32284
  styles: {
32230
32285
  input: {
@@ -32234,7 +32289,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32234
32289
  }
32235
32290
  }
32236
32291
  }
32237
- ), !searchQuery && /* @__PURE__ */ React293.createElement(Box59, { mb: "md" }, /* @__PURE__ */ React293.createElement(Text170, { size: "sm", fw: 500, mb: "xs", px: "xs" }, "Recent"), /* @__PURE__ */ React293.createElement(ScrollArea9.Autosize, { scrollbarSize: 0, mah: 60 }, renderIconGrid(recentIcons))), /* @__PURE__ */ React293.createElement(Box59, null, /* @__PURE__ */ React293.createElement(Group106, { justify: "space-between", mb: "xs", px: "xs" }, /* @__PURE__ */ React293.createElement(Text170, { size: "sm", fw: 500 }, searchQuery ? "Results" : "Icons"), totalPages > 1 && /* @__PURE__ */ React293.createElement(Group106, { gap: "xs" }, /* @__PURE__ */ React293.createElement(Text170, { size: "xs", c: "dimmed" }, "Page ", currentPage, " of ", totalPages, " (", filteredIcons.length, " total)"), /* @__PURE__ */ React293.createElement(BaseButton, { size: "xs", onClick: () => setCurrentPage((p) => Math.max(1, p - 1)), disabled: currentPage === 1, leftSection: /* @__PURE__ */ React293.createElement(IconChevronLeft, { size: 14 }) }, "Prev"), /* @__PURE__ */ React293.createElement(
32292
+ ), !searchQuery && /* @__PURE__ */ React293.createElement(Box59, { mb: "md" }, /* @__PURE__ */ React293.createElement(Text171, { size: "sm", fw: 500, mb: "xs", px: "xs" }, "Recent"), /* @__PURE__ */ React293.createElement(ScrollArea9.Autosize, { scrollbarSize: 0, mah: 60 }, renderIconGrid(recentIcons))), /* @__PURE__ */ React293.createElement(Box59, null, /* @__PURE__ */ React293.createElement(Group107, { justify: "space-between", mb: "xs", px: "xs" }, /* @__PURE__ */ React293.createElement(Text171, { size: "sm", fw: 500 }, searchQuery ? "Results" : "Icons"), totalPages > 1 && /* @__PURE__ */ React293.createElement(Group107, { gap: "xs" }, /* @__PURE__ */ React293.createElement(Text171, { size: "xs", c: "dimmed" }, "Page ", currentPage, " of ", totalPages, " (", filteredIcons.length, " total)"), /* @__PURE__ */ React293.createElement(BaseButton, { size: "xs", onClick: () => setCurrentPage((p) => Math.max(1, p - 1)), disabled: currentPage === 1, leftSection: /* @__PURE__ */ React293.createElement(IconChevronLeft, { size: 14 }) }, "Prev"), /* @__PURE__ */ React293.createElement(
32238
32293
  BaseButton,
32239
32294
  {
32240
32295
  size: "xs",
@@ -32243,7 +32298,7 @@ function BaseIconPicker({ opened, onClose, onSelectIcon, onUploadClick, children
32243
32298
  leftSection: /* @__PURE__ */ React293.createElement(IconChevronRight13, { size: 14 })
32244
32299
  },
32245
32300
  "Next"
32246
- ))), /* @__PURE__ */ React293.createElement(ScrollArea9.Autosize, { scrollbarSize: 0, mah: 200 }, renderIconGrid(paginatedIcons)))), /* @__PURE__ */ React293.createElement(Tabs4.Panel, { value: "upload", pt: "md" }, /* @__PURE__ */ React293.createElement(Center14, { py: "xl" }, /* @__PURE__ */ React293.createElement(Stack196, { align: "center", gap: "md" }, /* @__PURE__ */ React293.createElement(Text170, { size: "sm", c: "dimmed", ta: "center" }, "Upload a custom icon image", /* @__PURE__ */ React293.createElement("br", null), "(PNG, JPG, SVG)"), /* @__PURE__ */ React293.createElement(CoverImageButton, { onClick: onUploadClick }, "Choose File"))))))
32301
+ ))), /* @__PURE__ */ React293.createElement(ScrollArea9.Autosize, { scrollbarSize: 0, mah: 200 }, renderIconGrid(paginatedIcons)))), /* @__PURE__ */ React293.createElement(Tabs4.Panel, { value: "upload", pt: "md" }, /* @__PURE__ */ React293.createElement(Center14, { py: "xl" }, /* @__PURE__ */ React293.createElement(Stack196, { align: "center", gap: "md" }, /* @__PURE__ */ React293.createElement(Text171, { size: "sm", c: "dimmed", ta: "center" }, "Upload a custom icon image", /* @__PURE__ */ React293.createElement("br", null), "(PNG, JPG, SVG)"), /* @__PURE__ */ React293.createElement(CoverImageButton, { onClick: onUploadClick }, "Choose File"))))))
32247
32302
  ));
32248
32303
  }
32249
32304
 
@@ -32276,7 +32331,7 @@ function PageIcon({ src, iconSize = 64, useCenter = false, style }) {
32276
32331
  ...style
32277
32332
  }
32278
32333
  },
32279
- /* @__PURE__ */ React294.createElement(IconComponent, { size: iconSize, color: "white", stroke: 1.5 })
32334
+ /* @__PURE__ */ React294.createElement(IconComponent, { size: iconSize, stroke: 1.5, style: { color: "var(--mantine-color-neutralColor-8) !important" } })
32280
32335
  );
32281
32336
  }
32282
32337
  return /* @__PURE__ */ React294.createElement(
@@ -32300,13 +32355,13 @@ function PageIcon({ src, iconSize = 64, useCenter = false, style }) {
32300
32355
  import { useDisclosure as useDisclosure7 } from "@mantine/hooks";
32301
32356
 
32302
32357
  // src/mantine/components/FlowSettingsPanel.tsx
32303
- import React295, { useState as useState134, useEffect as useEffect109, useCallback as useCallback109 } from "react";
32304
- import { Stack as Stack197, Group as Group107, Button as Button56, ActionIcon as ActionIcon37, Text as Text171, Box as Box61 } from "@mantine/core";
32358
+ import React295, { useState as useState135, useEffect as useEffect109, useCallback as useCallback109 } from "react";
32359
+ import { Stack as Stack197, Group as Group108, Button as Button55, ActionIcon as ActionIcon37, Text as Text172, Box as Box61 } from "@mantine/core";
32305
32360
  import { IconPlus as IconPlus10, IconTrash as IconTrash10 } from "@tabler/icons-react";
32306
32361
  var SYSTEM_KEYS = /* @__PURE__ */ new Set(["@context", "_type", "schema_version", "doc_id", "title", "createdAt", "createdBy", "flowOwnerDid"]);
32307
32362
  var FlowSettingsPanel = ({ editor }) => {
32308
32363
  const { closePanel } = usePanelStore();
32309
- const [rows, setRows] = useState134([]);
32364
+ const [rows, setRows] = useState135([]);
32310
32365
  const loadSettings = useCallback109(() => {
32311
32366
  const metadata = editor.getFlowMetadata?.();
32312
32367
  if (!metadata) return;
@@ -32367,20 +32422,20 @@ var FlowSettingsPanel = ({ editor }) => {
32367
32422
  },
32368
32423
  [editor]
32369
32424
  );
32370
- const subtitle = /* @__PURE__ */ React295.createElement(Box61, { px: 40, mb: "md" }, /* @__PURE__ */ React295.createElement(Text171, { size: "sm", c: "dimmed" }, "Add key-value settings for this flow. These are available to oracles and action blocks at runtime."));
32371
- return /* @__PURE__ */ React295.createElement(BaseRightPanelLayout, { title: "Flow Settings", onClose: closePanel, isTemplate: true, captionContent: subtitle }, /* @__PURE__ */ React295.createElement(Stack197, { gap: "lg" }, rows.map((row, index) => /* @__PURE__ */ React295.createElement(Stack197, { key: index, gap: "xs" }, /* @__PURE__ */ React295.createElement(Group107, { gap: "xs", align: "center", wrap: "nowrap" }, /* @__PURE__ */ React295.createElement(BaseTextInput, { placeholder: "Key (e.g. protocolDid)", value: row.key, onChange: (e) => handleKeyChange(index, e.currentTarget.value), style: { flex: 1 } }), /* @__PURE__ */ React295.createElement(ActionIcon37, { variant: "subtle", color: "red", onClick: () => handleDelete(index), size: "lg" }, /* @__PURE__ */ React295.createElement(IconTrash10, { size: 16 }))), /* @__PURE__ */ React295.createElement(BaseTextArea, { placeholder: "Value", value: row.value, onChange: (e) => handleValueChange(index, e.currentTarget.value), minRows: 1, maxRows: 8 }))), /* @__PURE__ */ React295.createElement(Button56, { variant: "subtle", leftSection: /* @__PURE__ */ React295.createElement(IconPlus10, { size: 16 }), onClick: handleAdd, size: "sm" }, "Add setting")));
32425
+ const subtitle = /* @__PURE__ */ React295.createElement(Box61, { px: 40, mb: "md" }, /* @__PURE__ */ React295.createElement(Text172, { size: "sm", c: "dimmed" }, "Add key-value settings for this flow. These are available to oracles and action blocks at runtime."));
32426
+ return /* @__PURE__ */ React295.createElement(BaseRightPanelLayout, { title: "Flow Details", onClose: closePanel, isTemplate: true, captionContent: subtitle }, /* @__PURE__ */ React295.createElement(Stack197, { gap: "lg" }, rows.map((row, index) => /* @__PURE__ */ React295.createElement(Stack197, { key: index, gap: "xs" }, /* @__PURE__ */ React295.createElement(Group108, { gap: "xs", align: "center", wrap: "nowrap" }, /* @__PURE__ */ React295.createElement(BaseTextInput, { placeholder: "Key (e.g. protocolDid)", value: row.key, onChange: (e) => handleKeyChange(index, e.currentTarget.value), style: { flex: 1 } }), /* @__PURE__ */ React295.createElement(ActionIcon37, { variant: "subtle", color: "red", onClick: () => handleDelete(index), size: "lg" }, /* @__PURE__ */ React295.createElement(IconTrash10, { size: 16 }))), /* @__PURE__ */ React295.createElement(BaseTextArea, { placeholder: "Value", value: row.value, onChange: (e) => handleValueChange(index, e.currentTarget.value), minRows: 1, maxRows: 8 }))), /* @__PURE__ */ React295.createElement(Button55, { variant: "subtle", leftSection: /* @__PURE__ */ React295.createElement(IconPlus10, { size: 16 }), onClick: handleAdd, size: "sm" }, "Add detail")));
32372
32427
  };
32373
32428
 
32374
32429
  // src/mantine/components/CoverImage.tsx
32375
32430
  function CoverImage({ coverImageUrl, logoUrl }) {
32376
32431
  const { editor, handlers, editable } = useBlocknoteContext();
32377
- const [isHovering, setIsHovering] = useState135(false);
32378
- const [isRepositioning, setIsRepositioning] = useState135(false);
32379
- const [coverPosition, setCoverPosition] = useState135(() => editor?.getPageMetadata?.()?.coverPosition ?? 50);
32432
+ const [isHovering, setIsHovering] = useState136(false);
32433
+ const [isRepositioning, setIsRepositioning] = useState136(false);
32434
+ const [coverPosition, setCoverPosition] = useState136(() => editor?.getPageMetadata?.()?.coverPosition ?? 50);
32380
32435
  const coverFileInputRef = useRef29(null);
32381
32436
  const logoFileInputRef = useRef29(null);
32382
32437
  const [opened, { open, close }] = useDisclosure7(false);
32383
- const [metadata, setMetadata] = useState135(() => editor?.getPageMetadata?.() || null);
32438
+ const [metadata, setMetadata] = useState136(() => editor?.getPageMetadata?.() || null);
32384
32439
  const settingsPanelContent = useMemo121(() => editor ? /* @__PURE__ */ React296.createElement(FlowSettingsPanel, { editor }) : null, [editor]);
32385
32440
  const { open: openSettings } = usePanel("flow-settings-panel", settingsPanelContent);
32386
32441
  useEffect110(() => {
@@ -32477,38 +32532,13 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32477
32532
  style: {
32478
32533
  position: "relative",
32479
32534
  width: "100%",
32480
- minHeight: hasLogo ? "140px" : "48px",
32481
- backgroundColor: "transparent",
32482
- marginBottom: "0"
32535
+ minHeight: hasLogo ? "140px" : editable ? "28px" : "0",
32536
+ backgroundColor: "transparent"
32483
32537
  },
32484
32538
  onMouseEnter: () => editable && setIsHovering(true),
32485
32539
  onMouseLeave: () => editable && setIsHovering(false)
32486
32540
  },
32487
- /* @__PURE__ */ React296.createElement("div", { style: { maxWidth: "900px", margin: "0 auto", position: "relative", height: "100%" } }, /* @__PURE__ */ React296.createElement("input", { ref: coverFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "cover") }), /* @__PURE__ */ React296.createElement("input", { ref: logoFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "logo") }), editable && isHovering && !logoSrc && /* @__PURE__ */ React296.createElement(
32488
- Group108,
32489
- {
32490
- gap: "xs",
32491
- style: {
32492
- position: "absolute",
32493
- top: "12px",
32494
- left: "0",
32495
- zIndex: 10
32496
- }
32497
- },
32498
- /* @__PURE__ */ React296.createElement(
32499
- BaseIconPicker,
32500
- {
32501
- opened,
32502
- onClose: close,
32503
- currentIcon: metadata?.icon ?? "",
32504
- onSelectIcon: (name) => handleSelectLogoIcon(name),
32505
- onUploadClick: () => logoFileInputRef.current?.click()
32506
- },
32507
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: open }, "Add icon")
32508
- ),
32509
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: () => coverFileInputRef.current?.click() }, "Add cover"),
32510
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: openSettings }, "Settings")
32511
- ), logoSrc && /* @__PURE__ */ React296.createElement(
32541
+ /* @__PURE__ */ React296.createElement("div", { style: { maxWidth: "900px", margin: "0 auto", position: "relative", minHeight: "inherit" } }, /* @__PURE__ */ React296.createElement("input", { ref: coverFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "cover") }), /* @__PURE__ */ React296.createElement("input", { ref: logoFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "logo") }), logoSrc && /* @__PURE__ */ React296.createElement(
32512
32542
  Box62,
32513
32543
  {
32514
32544
  style: {
@@ -32516,44 +32546,46 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32516
32546
  insetInlineStart: "0",
32517
32547
  width: "120px",
32518
32548
  height: "120px",
32519
- left: -20,
32520
32549
  marginTop: "16px",
32521
32550
  padding: 12,
32522
32551
  zIndex: 11
32523
32552
  }
32524
32553
  },
32525
32554
  /* @__PURE__ */ React296.createElement(PageIcon, { src: logoSrc, useCenter: true, iconSize: 64 }),
32526
- editable && isHovering && /* @__PURE__ */ React296.createElement(
32527
- "div",
32555
+ editable && /* @__PURE__ */ React296.createElement(
32556
+ BaseIconPicker,
32528
32557
  {
32529
- style: {
32530
- position: "absolute",
32531
- bottom: "-32px",
32532
- left: "50%",
32533
- transform: "translateX(-50%)",
32534
- zIndex: 12,
32535
- display: "flex",
32536
- flexDirection: "row",
32537
- gap: "4px",
32538
- alignItems: "center"
32539
- }
32558
+ opened,
32559
+ onClose: close,
32560
+ currentIcon: metadata?.icon ?? "",
32561
+ onSelectIcon: (name) => handleSelectLogoIcon(name),
32562
+ onUploadClick: () => logoFileInputRef.current?.click(),
32563
+ onRemove: handleRemoveLogo
32540
32564
  },
32541
32565
  /* @__PURE__ */ React296.createElement(
32542
- BaseIconPicker,
32566
+ Box62,
32543
32567
  {
32544
- opened,
32545
- onClose: close,
32546
- currentIcon: metadata?.icon ?? "",
32547
- onSelectIcon: (name) => handleSelectLogoIcon(name),
32548
- onUploadClick: () => logoFileInputRef.current?.click()
32549
- },
32550
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: open }, "Change")
32551
- ),
32552
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: handleRemoveLogo }, "Remove"),
32553
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: () => coverFileInputRef.current?.click() }, "Add cover"),
32554
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: openSettings }, "Settings")
32568
+ onClick: open,
32569
+ style: {
32570
+ position: "absolute",
32571
+ inset: 12,
32572
+ cursor: "pointer",
32573
+ borderRadius: "100%"
32574
+ }
32575
+ }
32576
+ )
32555
32577
  )
32556
- ))
32578
+ ), editable && (isHovering || opened) && /* @__PURE__ */ React296.createElement(Group109, { gap: 4, style: { position: "absolute", bottom: hasLogo ? -18 : 0, left: 0, zIndex: 10 } }, !logoSrc && /* @__PURE__ */ React296.createElement(
32579
+ BaseIconPicker,
32580
+ {
32581
+ opened,
32582
+ onClose: close,
32583
+ currentIcon: metadata?.icon ?? "",
32584
+ onSelectIcon: (name) => handleSelectLogoIcon(name),
32585
+ onUploadClick: () => logoFileInputRef.current?.click()
32586
+ },
32587
+ /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: open, icon: /* @__PURE__ */ React296.createElement(IconMoodSmile, { size: 14 }) }, "Add icon")
32588
+ ), /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: () => coverFileInputRef.current?.click(), icon: /* @__PURE__ */ React296.createElement(IconPhoto4, { size: 14 }) }, "Add cover"), /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: openSettings, icon: /* @__PURE__ */ React296.createElement(IconSettings22, { size: 14 }) }, "Details")))
32557
32589
  );
32558
32590
  }
32559
32591
  return /* @__PURE__ */ React296.createElement(
@@ -32603,7 +32635,7 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32603
32635
  }
32604
32636
  ),
32605
32637
  editable && isHovering && /* @__PURE__ */ React296.createElement(
32606
- Group108,
32638
+ Group109,
32607
32639
  {
32608
32640
  gap: "xs",
32609
32641
  style: {
@@ -32613,7 +32645,7 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32613
32645
  zIndex: 10
32614
32646
  }
32615
32647
  },
32616
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: () => coverFileInputRef.current?.click() }, "Change cover"),
32648
+ /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: () => coverFileInputRef.current?.click(), icon: /* @__PURE__ */ React296.createElement(IconRefresh5, { size: 14 }) }, "Change cover"),
32617
32649
  /* @__PURE__ */ React296.createElement(
32618
32650
  CoverImageButton,
32619
32651
  {
@@ -32623,12 +32655,12 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32623
32655
  }
32624
32656
  setIsRepositioning(!isRepositioning);
32625
32657
  },
32626
- isActive: isRepositioning
32658
+ isActive: isRepositioning,
32659
+ icon: /* @__PURE__ */ React296.createElement(IconArrowsMove, { size: 14 })
32627
32660
  },
32628
32661
  isRepositioning ? "Done" : "Reposition"
32629
32662
  ),
32630
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: handleRemoveCover }, "Remove"),
32631
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: openSettings }, "Settings")
32663
+ /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: handleRemoveCover, icon: /* @__PURE__ */ React296.createElement(IconTrash11, { size: 14 }) }, "Remove")
32632
32664
  ),
32633
32665
  /* @__PURE__ */ React296.createElement("div", { style: { maxWidth: "900px", margin: "0 auto", position: "absolute", bottom: 0, left: 0, right: 0, height: "70px" } }, /* @__PURE__ */ React296.createElement(
32634
32666
  Box62,
@@ -32642,31 +32674,29 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32642
32674
  zIndex: 11
32643
32675
  }
32644
32676
  },
32645
- logoSrc && /* @__PURE__ */ React296.createElement(PageIcon, { src: logoSrc, useCenter: true, iconSize: 64 }),
32646
- editable && isHovering && /* @__PURE__ */ React296.createElement(React296.Fragment, null, logoSrc ? /* @__PURE__ */ React296.createElement(
32647
- Group108,
32677
+ logoSrc ? /* @__PURE__ */ React296.createElement(React296.Fragment, null, /* @__PURE__ */ React296.createElement(PageIcon, { src: logoSrc, useCenter: true, iconSize: 64 }), editable && /* @__PURE__ */ React296.createElement(
32678
+ BaseIconPicker,
32648
32679
  {
32649
- gap: "xs",
32650
- style: {
32651
- position: "absolute",
32652
- top: "0",
32653
- left: "130px",
32654
- zIndex: 12
32655
- }
32680
+ opened,
32681
+ onClose: close,
32682
+ currentIcon: metadata?.icon ?? "",
32683
+ onSelectIcon: (name) => handleSelectLogoIcon(name),
32684
+ onUploadClick: () => logoFileInputRef.current?.click(),
32685
+ onRemove: handleRemoveLogo
32656
32686
  },
32657
32687
  /* @__PURE__ */ React296.createElement(
32658
- BaseIconPicker,
32688
+ Box62,
32659
32689
  {
32660
- opened,
32661
- onClose: close,
32662
- currentIcon: metadata?.icon ?? "",
32663
- onSelectIcon: (name) => handleSelectLogoIcon(name),
32664
- onUploadClick: () => logoFileInputRef.current?.click()
32665
- },
32666
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: open }, "Change")
32667
- ),
32668
- /* @__PURE__ */ React296.createElement(CoverImageButton, { onClick: handleRemoveLogo }, "Remove")
32669
- ) : /* @__PURE__ */ React296.createElement(
32690
+ onClick: open,
32691
+ style: {
32692
+ position: "absolute",
32693
+ inset: 0,
32694
+ cursor: "pointer",
32695
+ borderRadius: "100%"
32696
+ }
32697
+ }
32698
+ )
32699
+ )) : editable && isHovering && /* @__PURE__ */ React296.createElement(
32670
32700
  BaseIconPicker,
32671
32701
  {
32672
32702
  opened,
@@ -32679,6 +32709,7 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32679
32709
  CoverImageButton,
32680
32710
  {
32681
32711
  onClick: open,
32712
+ icon: /* @__PURE__ */ React296.createElement(IconMoodSmile, { size: 14 }),
32682
32713
  style: {
32683
32714
  position: "absolute",
32684
32715
  top: "50%",
@@ -32689,302 +32720,257 @@ function CoverImage({ coverImageUrl, logoUrl }) {
32689
32720
  },
32690
32721
  "Add icon"
32691
32722
  )
32692
- ))
32723
+ )
32693
32724
  )),
32694
32725
  /* @__PURE__ */ React296.createElement("input", { ref: coverFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "cover") }),
32695
32726
  /* @__PURE__ */ React296.createElement("input", { ref: logoFileInputRef, type: "file", accept: "image/*", style: { display: "none" }, onChange: (e) => handleFileSelect(e, "logo") })
32696
32727
  );
32697
32728
  }
32698
32729
 
32699
- // src/mantine/components/PageHeader.tsx
32700
- import React297, { useState as useState136, useRef as useRef30, useEffect as useEffect111 } from "react";
32701
- function PageHeader({
32702
- title = "New page",
32703
- icon: icon2,
32704
- isPrivate = true,
32705
- onPrivacyChange,
32706
- lastEdited,
32707
- onShare,
32708
- onFavorite,
32709
- isFavorited = false,
32710
- menuItems = []
32711
- }) {
32712
- const [isMenuOpen, setIsMenuOpen] = useState136(false);
32713
- const [isPrivacyOpen, setIsPrivacyOpen] = useState136(false);
32714
- const menuRef = useRef30(null);
32715
- const privacyRef = useRef30(null);
32730
+ // src/mantine/components/PageTitle.tsx
32731
+ import React297, { useState as useState137, useEffect as useEffect111, useRef as useRef30, useCallback as useCallback110 } from "react";
32732
+ import { Box as Box63 } from "@mantine/core";
32733
+ var DEFAULT_TITLE = "New page";
32734
+ function isUserTitle(name) {
32735
+ if (!name) return "";
32736
+ if (name.startsWith("#") || name.startsWith("!")) return "";
32737
+ if (name === DEFAULT_TITLE) return "";
32738
+ return name;
32739
+ }
32740
+ function cleanEmptyEditable(el) {
32741
+ const text = el.textContent?.trim() || "";
32742
+ if (!text) {
32743
+ el.innerHTML = "";
32744
+ }
32745
+ }
32746
+ function PageTitle({ editor, editable }) {
32747
+ const [title, setTitle] = useState137("");
32748
+ const [hasIcon, setHasIcon] = useState137(false);
32749
+ const titleRef = useRef30(null);
32750
+ const isComposing = useRef30(false);
32716
32751
  useEffect111(() => {
32717
- function handleClickOutside(event) {
32718
- if (menuRef.current && !menuRef.current.contains(event.target)) {
32719
- setIsMenuOpen(false);
32752
+ if (!editor?._metadataManager) return;
32753
+ const metadata = editor._metadataManager.getMetadata();
32754
+ const initial = isUserTitle(metadata?.title);
32755
+ if (initial) {
32756
+ setTitle(initial);
32757
+ }
32758
+ setHasIcon(!!metadata?.icon);
32759
+ const unsubscribe = editor._metadataManager.subscribe((newMetadata) => {
32760
+ if (newMetadata.title !== void 0) {
32761
+ const resolved = isUserTitle(newMetadata.title);
32762
+ setTitle(resolved);
32763
+ if (titleRef.current && titleRef.current.textContent !== resolved) {
32764
+ titleRef.current.textContent = resolved;
32765
+ }
32720
32766
  }
32721
- if (privacyRef.current && !privacyRef.current.contains(event.target)) {
32722
- setIsPrivacyOpen(false);
32767
+ setHasIcon(!!newMetadata.icon);
32768
+ });
32769
+ return unsubscribe;
32770
+ }, [editor]);
32771
+ useEffect111(() => {
32772
+ if (titleRef.current && title && !titleRef.current.textContent) {
32773
+ titleRef.current.textContent = title;
32774
+ }
32775
+ }, [title]);
32776
+ const saveTitle = useCallback110(
32777
+ async (newTitle) => {
32778
+ const trimmed = newTitle.trim();
32779
+ const toSave = trimmed || DEFAULT_TITLE;
32780
+ setTitle(trimmed);
32781
+ try {
32782
+ await editor.setPageMetadata?.({ title: toSave });
32783
+ } catch {
32784
+ const current = editor.getPageMetadata?.();
32785
+ if (current?.title !== void 0) {
32786
+ setTitle(isUserTitle(current.title));
32787
+ }
32723
32788
  }
32789
+ },
32790
+ [editor]
32791
+ );
32792
+ const handleInput = useCallback110(() => {
32793
+ if (titleRef.current) {
32794
+ cleanEmptyEditable(titleRef.current);
32795
+ setTitle(titleRef.current.textContent || "");
32724
32796
  }
32725
- if (isMenuOpen || isPrivacyOpen) {
32726
- document.addEventListener("mousedown", handleClickOutside);
32797
+ }, []);
32798
+ const handleBlur = useCallback110(() => {
32799
+ if (titleRef.current) {
32800
+ cleanEmptyEditable(titleRef.current);
32801
+ saveTitle(titleRef.current.textContent || "");
32727
32802
  }
32803
+ }, [saveTitle]);
32804
+ const handleKeyDown = useCallback110(
32805
+ (e) => {
32806
+ if (isComposing.current) return;
32807
+ if (e.key === "Enter" || e.key === "ArrowDown") {
32808
+ e.preventDefault();
32809
+ saveTitle(titleRef.current?.textContent || "");
32810
+ editor.focus?.();
32811
+ }
32812
+ },
32813
+ [editor, saveTitle]
32814
+ );
32815
+ useEffect111(() => {
32816
+ const handleEditorKeyDown = (e) => {
32817
+ if (e.key !== "ArrowUp" || !titleRef.current) return;
32818
+ try {
32819
+ const pos = editor.getTextCursorPosition?.();
32820
+ if (pos && !pos.prevBlock) {
32821
+ e.preventDefault();
32822
+ titleRef.current.focus();
32823
+ const sel = window.getSelection();
32824
+ if (sel && titleRef.current.childNodes.length > 0) {
32825
+ sel.selectAllChildren(titleRef.current);
32826
+ sel.collapseToEnd();
32827
+ }
32828
+ }
32829
+ } catch {
32830
+ }
32831
+ };
32832
+ const container = titleRef.current?.closest(".ixo-editor");
32833
+ container?.addEventListener("keydown", handleEditorKeyDown, true);
32728
32834
  return () => {
32729
- document.removeEventListener("mousedown", handleClickOutside);
32835
+ container?.removeEventListener("keydown", handleEditorKeyDown, true);
32730
32836
  };
32731
- }, [isMenuOpen, isPrivacyOpen]);
32732
- const handleMenuItemClick = (item) => {
32733
- if (!item.disabled) {
32734
- item.onClick();
32735
- setIsMenuOpen(false);
32736
- }
32737
- };
32738
- return /* @__PURE__ */ React297.createElement("div", { style: styles.container }, /* @__PURE__ */ React297.createElement("div", { style: styles.leftSection }, /* @__PURE__ */ React297.createElement("span", { style: styles.icon }, icon2 || "\u{1F4C4}"), /* @__PURE__ */ React297.createElement("span", { style: styles.title }, title), /* @__PURE__ */ React297.createElement("div", { style: styles.privacyContainer, ref: privacyRef }, /* @__PURE__ */ React297.createElement("button", { style: styles.privacyBadge, onClick: () => onPrivacyChange && setIsPrivacyOpen(!isPrivacyOpen) }, /* @__PURE__ */ React297.createElement("span", { style: styles.lockIcon }, isPrivate ? "\u{1F512}" : "\u{1F310}"), /* @__PURE__ */ React297.createElement("span", null, isPrivate ? "Private" : "Public"), onPrivacyChange && /* @__PURE__ */ React297.createElement("span", { style: styles.chevron }, "\u25BE")), isPrivacyOpen && onPrivacyChange && /* @__PURE__ */ React297.createElement("div", { style: styles.dropdown }, /* @__PURE__ */ React297.createElement(
32739
- "button",
32837
+ }, [editor]);
32838
+ const handlePaste = useCallback110((e) => {
32839
+ e.preventDefault();
32840
+ const text = e.clipboardData.getData("text/plain").replace(/\n/g, " ");
32841
+ document.execCommand("insertText", false, text);
32842
+ }, []);
32843
+ return /* @__PURE__ */ React297.createElement(Box63, { maw: 900, mx: "auto", w: "100%" }, /* @__PURE__ */ React297.createElement(
32844
+ Box63,
32740
32845
  {
32846
+ ref: titleRef,
32847
+ component: "div",
32848
+ contentEditable: editable !== false,
32849
+ suppressContentEditableWarning: true,
32850
+ role: "textbox",
32851
+ "aria-label": "Page title",
32852
+ "data-placeholder": "New page",
32853
+ fz: 40,
32854
+ fw: 700,
32855
+ lh: 1.2,
32856
+ mih: "1em",
32857
+ pt: hasIcon ? 24 : 0,
32858
+ pb: 24,
32859
+ px: 0,
32741
32860
  style: {
32742
- ...styles.menuItem,
32743
- ...isPrivate ? styles.menuItemActive : {}
32744
- },
32745
- onClick: () => {
32746
- onPrivacyChange(true);
32747
- setIsPrivacyOpen(false);
32861
+ color: "var(--mantine-color-neutralColor-8) !important",
32862
+ caretColor: "var(--mantine-color-neutralColor-8) !important",
32863
+ outline: "none",
32864
+ border: "none",
32865
+ wordBreak: "break-word",
32866
+ whiteSpace: "pre-wrap",
32867
+ cursor: editable === false ? "default" : void 0
32868
+ },
32869
+ onInput: handleInput,
32870
+ onBlur: handleBlur,
32871
+ onKeyDown: handleKeyDown,
32872
+ onPaste: handlePaste,
32873
+ onCompositionStart: () => {
32874
+ isComposing.current = true;
32875
+ },
32876
+ onCompositionEnd: () => {
32877
+ isComposing.current = false;
32878
+ },
32879
+ spellCheck: false
32880
+ }
32881
+ ));
32882
+ }
32883
+ if (typeof document !== "undefined") {
32884
+ const styleId = "ixo-page-title-styles";
32885
+ if (!document.getElementById(styleId)) {
32886
+ const style = document.createElement("style");
32887
+ style.id = styleId;
32888
+ style.textContent = `
32889
+ [data-placeholder]:empty::before {
32890
+ content: attr(data-placeholder);
32891
+ color: var(--mantine-color-neutralColor-7) !important;
32892
+ pointer-events: none;
32748
32893
  }
32749
- },
32750
- /* @__PURE__ */ React297.createElement("span", { style: styles.menuItemIcon }, "\u{1F512}"),
32751
- /* @__PURE__ */ React297.createElement("span", null, "Private")
32752
- ), /* @__PURE__ */ React297.createElement(
32753
- "button",
32754
- {
32755
- style: {
32756
- ...styles.menuItem,
32757
- ...!isPrivate ? styles.menuItemActive : {}
32758
- },
32759
- onClick: () => {
32760
- onPrivacyChange(false);
32761
- setIsPrivacyOpen(false);
32762
- }
32763
- },
32764
- /* @__PURE__ */ React297.createElement("span", { style: styles.menuItemIcon }, "\u{1F310}"),
32765
- /* @__PURE__ */ React297.createElement("span", null, "Public")
32766
- )))), /* @__PURE__ */ React297.createElement("div", { style: styles.rightSection }, lastEdited && /* @__PURE__ */ React297.createElement("span", { style: styles.editedText }, lastEdited), onShare && /* @__PURE__ */ React297.createElement("button", { style: styles.shareButton, onClick: onShare }, "Share"), onFavorite && /* @__PURE__ */ React297.createElement("button", { style: styles.iconButton, onClick: onFavorite }, isFavorited ? "\u2605" : "\u2606"), menuItems.length > 0 && /* @__PURE__ */ React297.createElement("div", { style: styles.menuContainer, ref: menuRef }, /* @__PURE__ */ React297.createElement("button", { style: styles.menuButton, onClick: () => setIsMenuOpen(!isMenuOpen), "aria-label": "Menu" }, /* @__PURE__ */ React297.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor" }, /* @__PURE__ */ React297.createElement("circle", { cx: "3", cy: "8", r: "1.5" }), /* @__PURE__ */ React297.createElement("circle", { cx: "8", cy: "8", r: "1.5" }), /* @__PURE__ */ React297.createElement("circle", { cx: "13", cy: "8", r: "1.5" }))), isMenuOpen && /* @__PURE__ */ React297.createElement("div", { style: styles.dropdown }, menuItems.map((item, index) => /* @__PURE__ */ React297.createElement(React297.Fragment, { key: index }, item.divider && index > 0 && /* @__PURE__ */ React297.createElement("div", { style: styles.divider }), /* @__PURE__ */ React297.createElement(
32767
- "button",
32768
- {
32769
- style: {
32770
- ...styles.menuItem,
32771
- ...item.disabled ? styles.menuItemDisabled : {}
32772
- },
32773
- onClick: () => handleMenuItemClick(item),
32774
- disabled: item.disabled
32775
- },
32776
- item.icon && /* @__PURE__ */ React297.createElement("span", { style: styles.menuItemIcon }, item.icon),
32777
- /* @__PURE__ */ React297.createElement("span", null, item.label)
32778
- )))))));
32779
- }
32780
- var styles = {
32781
- container: {
32782
- display: "flex",
32783
- alignItems: "center",
32784
- justifyContent: "space-between",
32785
- padding: "8px 12px",
32786
- borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
32787
- backgroundColor: "transparent",
32788
- fontSize: "14px",
32789
- minHeight: "44px",
32790
- color: "rgba(255, 255, 255, 0.9)"
32791
- },
32792
- leftSection: {
32793
- display: "flex",
32794
- alignItems: "center",
32795
- gap: "8px"
32796
- },
32797
- icon: {
32798
- fontSize: "16px"
32799
- },
32800
- title: {
32801
- fontWeight: 500,
32802
- color: "rgba(255, 255, 255, 0.9)"
32803
- },
32804
- privacyContainer: {
32805
- position: "relative"
32806
- },
32807
- privacyBadge: {
32808
- display: "flex",
32809
- alignItems: "center",
32810
- gap: "4px",
32811
- padding: "2px 6px",
32812
- border: "none",
32813
- backgroundColor: "transparent",
32814
- color: "rgba(255, 255, 255, 0.5)",
32815
- fontSize: "12px",
32816
- cursor: "pointer",
32817
- borderRadius: "3px"
32818
- },
32819
- lockIcon: {
32820
- fontSize: "12px"
32821
- },
32822
- chevron: {
32823
- fontSize: "10px",
32824
- marginLeft: "2px"
32825
- },
32826
- rightSection: {
32827
- display: "flex",
32828
- alignItems: "center",
32829
- gap: "8px"
32830
- },
32831
- editedText: {
32832
- color: "rgba(255, 255, 255, 0.4)",
32833
- fontSize: "12px"
32834
- },
32835
- shareButton: {
32836
- padding: "4px 10px",
32837
- border: "none",
32838
- backgroundColor: "transparent",
32839
- color: "rgba(255, 255, 255, 0.9)",
32840
- fontSize: "14px",
32841
- cursor: "pointer",
32842
- borderRadius: "3px",
32843
- fontWeight: 500
32844
- },
32845
- iconButton: {
32846
- padding: "4px 8px",
32847
- border: "none",
32848
- backgroundColor: "transparent",
32849
- color: "rgba(255, 255, 255, 0.5)",
32850
- fontSize: "16px",
32851
- cursor: "pointer",
32852
- borderRadius: "3px"
32853
- },
32854
- menuContainer: {
32855
- position: "relative"
32856
- },
32857
- menuButton: {
32858
- display: "flex",
32859
- alignItems: "center",
32860
- justifyContent: "center",
32861
- padding: "4px 8px",
32862
- border: "none",
32863
- backgroundColor: "transparent",
32864
- color: "rgba(255, 255, 255, 0.5)",
32865
- cursor: "pointer",
32866
- borderRadius: "3px"
32867
- },
32868
- dropdown: {
32869
- position: "absolute",
32870
- top: "100%",
32871
- right: 0,
32872
- marginTop: "4px",
32873
- minWidth: "180px",
32874
- backgroundColor: "rgb(37, 37, 37)",
32875
- borderRadius: "6px",
32876
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.4)",
32877
- border: "1px solid rgba(255, 255, 255, 0.1)",
32878
- padding: "4px 0",
32879
- zIndex: 1e3
32880
- },
32881
- menuItem: {
32882
- display: "flex",
32883
- alignItems: "center",
32884
- gap: "8px",
32885
- width: "100%",
32886
- padding: "8px 12px",
32887
- border: "none",
32888
- backgroundColor: "transparent",
32889
- color: "rgba(255, 255, 255, 0.9)",
32890
- fontSize: "14px",
32891
- cursor: "pointer",
32892
- textAlign: "left"
32893
- },
32894
- menuItemDisabled: {
32895
- color: "rgba(255, 255, 255, 0.3)",
32896
- cursor: "not-allowed"
32897
- },
32898
- menuItemActive: {
32899
- backgroundColor: "rgba(255, 255, 255, 0.08)"
32900
- },
32901
- menuItemIcon: {
32902
- display: "flex",
32903
- alignItems: "center",
32904
- fontSize: "16px"
32905
- },
32906
- divider: {
32907
- height: "1px",
32908
- backgroundColor: "rgba(255, 255, 255, 0.1)",
32909
- margin: "4px 0"
32910
- }
32911
- };
32912
-
32913
- // src/mantine/components/ExternalDropZone.tsx
32914
- import React298, { useCallback as useCallback110, useEffect as useEffect112, useRef as useRef31, useState as useState137 } from "react";
32915
- import { Box as Box63 } from "@mantine/core";
32916
- var SCROLL_ZONE_SIZE = 80;
32917
- var SCROLL_SPEED = 12;
32918
- var ExternalDropZone = ({
32919
- editor,
32920
- onDrop,
32921
- acceptedType = "application/x-artifact",
32922
- dropIndicator,
32923
- isPlacementMode = false,
32924
- onPlacementCancel,
32925
- children
32926
- }) => {
32927
- const containerRef = useRef31(null);
32928
- const [isValidDrag, setIsValidDrag] = useState137(false);
32929
- const [isHoveringInPlacementMode, setIsHoveringInPlacementMode] = useState137(false);
32930
- const [indicatorStyle, setIndicatorStyle] = useState137({});
32931
- const dropPositionRef = useRef31(null);
32932
- const scrollAnimationRef = useRef31(null);
32933
- const scrollDirectionRef = useRef31(null);
32934
- const scrollContainerRef = useRef31(null);
32935
- const getBlockElements = useCallback110(() => {
32936
- if (!containerRef.current) return [];
32937
- const blocks = containerRef.current.querySelectorAll('[data-node-type="blockContainer"]');
32938
- return Array.from(blocks);
32939
- }, []);
32940
- const getScrollContainer = useCallback110(() => {
32941
- if (scrollContainerRef.current) return scrollContainerRef.current;
32942
- let element = containerRef.current;
32943
- while (element) {
32944
- const style = getComputedStyle(element);
32945
- const overflowY = style.overflowY;
32946
- if (overflowY === "auto" || overflowY === "scroll") {
32947
- scrollContainerRef.current = element;
32948
- return element;
32949
- }
32950
- element = element.parentElement;
32951
- }
32952
- scrollContainerRef.current = window;
32953
- return window;
32954
- }, []);
32955
- const performScroll = useCallback110(() => {
32956
- const container = getScrollContainer();
32957
- const direction = scrollDirectionRef.current;
32958
- if (!direction) {
32959
- scrollAnimationRef.current = null;
32960
- return;
32961
- }
32962
- const scrollAmount = direction === "up" ? -SCROLL_SPEED : SCROLL_SPEED;
32963
- if (container === window) {
32964
- window.scrollBy(0, scrollAmount);
32965
- } else {
32966
- container.scrollBy(0, scrollAmount);
32967
- }
32968
- scrollAnimationRef.current = requestAnimationFrame(performScroll);
32969
- }, [getScrollContainer]);
32970
- const startAutoScroll = useCallback110(
32971
- (direction) => {
32972
- if (scrollDirectionRef.current === direction) return;
32973
- scrollDirectionRef.current = direction;
32974
- if (!scrollAnimationRef.current) {
32975
- scrollAnimationRef.current = requestAnimationFrame(performScroll);
32894
+ `;
32895
+ document.head.appendChild(style);
32896
+ }
32897
+ }
32898
+
32899
+ // src/mantine/components/ExternalDropZone.tsx
32900
+ import React298, { useCallback as useCallback111, useEffect as useEffect112, useRef as useRef31, useState as useState138 } from "react";
32901
+ import { Box as Box64 } from "@mantine/core";
32902
+ var SCROLL_ZONE_SIZE = 80;
32903
+ var SCROLL_SPEED = 12;
32904
+ var ExternalDropZone = ({
32905
+ editor,
32906
+ onDrop,
32907
+ acceptedType = "application/x-artifact",
32908
+ dropIndicator,
32909
+ isPlacementMode = false,
32910
+ onPlacementCancel,
32911
+ children
32912
+ }) => {
32913
+ const containerRef = useRef31(null);
32914
+ const [isValidDrag, setIsValidDrag] = useState138(false);
32915
+ const [isHoveringInPlacementMode, setIsHoveringInPlacementMode] = useState138(false);
32916
+ const [indicatorStyle, setIndicatorStyle] = useState138({});
32917
+ const dropPositionRef = useRef31(null);
32918
+ const scrollAnimationRef = useRef31(null);
32919
+ const scrollDirectionRef = useRef31(null);
32920
+ const scrollContainerRef = useRef31(null);
32921
+ const getBlockElements = useCallback111(() => {
32922
+ if (!containerRef.current) return [];
32923
+ const blocks = containerRef.current.querySelectorAll('[data-node-type="blockContainer"]');
32924
+ return Array.from(blocks);
32925
+ }, []);
32926
+ const getScrollContainer = useCallback111(() => {
32927
+ if (scrollContainerRef.current) return scrollContainerRef.current;
32928
+ let element = containerRef.current;
32929
+ while (element) {
32930
+ const style = getComputedStyle(element);
32931
+ const overflowY = style.overflowY;
32932
+ if (overflowY === "auto" || overflowY === "scroll") {
32933
+ scrollContainerRef.current = element;
32934
+ return element;
32935
+ }
32936
+ element = element.parentElement;
32937
+ }
32938
+ scrollContainerRef.current = window;
32939
+ return window;
32940
+ }, []);
32941
+ const performScroll = useCallback111(() => {
32942
+ const container = getScrollContainer();
32943
+ const direction = scrollDirectionRef.current;
32944
+ if (!direction) {
32945
+ scrollAnimationRef.current = null;
32946
+ return;
32947
+ }
32948
+ const scrollAmount = direction === "up" ? -SCROLL_SPEED : SCROLL_SPEED;
32949
+ if (container === window) {
32950
+ window.scrollBy(0, scrollAmount);
32951
+ } else {
32952
+ container.scrollBy(0, scrollAmount);
32953
+ }
32954
+ scrollAnimationRef.current = requestAnimationFrame(performScroll);
32955
+ }, [getScrollContainer]);
32956
+ const startAutoScroll = useCallback111(
32957
+ (direction) => {
32958
+ if (scrollDirectionRef.current === direction) return;
32959
+ scrollDirectionRef.current = direction;
32960
+ if (!scrollAnimationRef.current) {
32961
+ scrollAnimationRef.current = requestAnimationFrame(performScroll);
32976
32962
  }
32977
32963
  },
32978
32964
  [performScroll]
32979
32965
  );
32980
- const stopAutoScroll = useCallback110(() => {
32966
+ const stopAutoScroll = useCallback111(() => {
32981
32967
  scrollDirectionRef.current = null;
32982
32968
  if (scrollAnimationRef.current) {
32983
32969
  cancelAnimationFrame(scrollAnimationRef.current);
32984
32970
  scrollAnimationRef.current = null;
32985
32971
  }
32986
32972
  }, []);
32987
- const checkAutoScroll = useCallback110(
32973
+ const checkAutoScroll = useCallback111(
32988
32974
  (clientY) => {
32989
32975
  const container = getScrollContainer();
32990
32976
  let containerTop;
@@ -33007,7 +32993,7 @@ var ExternalDropZone = ({
33007
32993
  },
33008
32994
  [getScrollContainer, startAutoScroll, stopAutoScroll]
33009
32995
  );
33010
- const findDropPosition = useCallback110(
32996
+ const findDropPosition = useCallback111(
33011
32997
  (clientY) => {
33012
32998
  const blocks = getBlockElements();
33013
32999
  if (blocks.length === 0 || !editor?.document) return null;
@@ -33040,7 +33026,7 @@ var ExternalDropZone = ({
33040
33026
  },
33041
33027
  [getBlockElements, editor]
33042
33028
  );
33043
- const handleDragOver = useCallback110(
33029
+ const handleDragOver = useCallback111(
33044
33030
  (e) => {
33045
33031
  if (!e.dataTransfer.types.includes(acceptedType)) return;
33046
33032
  e.preventDefault();
@@ -33063,7 +33049,7 @@ var ExternalDropZone = ({
33063
33049
  },
33064
33050
  [acceptedType, findDropPosition, checkAutoScroll]
33065
33051
  );
33066
- const handleDragLeave = useCallback110(
33052
+ const handleDragLeave = useCallback111(
33067
33053
  (e) => {
33068
33054
  if (containerRef.current && !containerRef.current.contains(e.relatedTarget)) {
33069
33055
  setIsValidDrag(false);
@@ -33073,7 +33059,7 @@ var ExternalDropZone = ({
33073
33059
  },
33074
33060
  [stopAutoScroll]
33075
33061
  );
33076
- const handleDrop = useCallback110(
33062
+ const handleDrop = useCallback111(
33077
33063
  (e) => {
33078
33064
  e.preventDefault();
33079
33065
  e.stopPropagation();
@@ -33096,7 +33082,7 @@ var ExternalDropZone = ({
33096
33082
  window.addEventListener("dragend", handleGlobalDragEnd);
33097
33083
  return () => window.removeEventListener("dragend", handleGlobalDragEnd);
33098
33084
  }, [stopAutoScroll]);
33099
- const handleOverlayMouseMove = useCallback110(
33085
+ const handleOverlayMouseMove = useCallback111(
33100
33086
  (e) => {
33101
33087
  setIsHoveringInPlacementMode(true);
33102
33088
  checkAutoScroll(e.clientY);
@@ -33115,12 +33101,12 @@ var ExternalDropZone = ({
33115
33101
  },
33116
33102
  [findDropPosition, checkAutoScroll]
33117
33103
  );
33118
- const handleOverlayMouseLeave = useCallback110(() => {
33104
+ const handleOverlayMouseLeave = useCallback111(() => {
33119
33105
  setIsHoveringInPlacementMode(false);
33120
33106
  dropPositionRef.current = null;
33121
33107
  stopAutoScroll();
33122
33108
  }, [stopAutoScroll]);
33123
- const handleOverlayClick = useCallback110(
33109
+ const handleOverlayClick = useCallback111(
33124
33110
  (e) => {
33125
33111
  e.preventDefault();
33126
33112
  e.stopPropagation();
@@ -33134,7 +33120,7 @@ var ExternalDropZone = ({
33134
33120
  },
33135
33121
  [onDrop, stopAutoScroll]
33136
33122
  );
33137
- const handleOverlayWheel = useCallback110(
33123
+ const handleOverlayWheel = useCallback111(
33138
33124
  (e) => {
33139
33125
  const container = getScrollContainer();
33140
33126
  if (container === window) {
@@ -33197,7 +33183,7 @@ var ExternalDropZone = ({
33197
33183
  }) : dropIndicator;
33198
33184
  const shouldShowIndicator = isValidDrag || isPlacementMode && isHoveringInPlacementMode;
33199
33185
  return /* @__PURE__ */ React298.createElement(
33200
- Box63,
33186
+ Box64,
33201
33187
  {
33202
33188
  ref: containerRef,
33203
33189
  style: {
@@ -33213,7 +33199,7 @@ var ExternalDropZone = ({
33213
33199
  },
33214
33200
  children,
33215
33201
  isPlacementMode && /* @__PURE__ */ React298.createElement(
33216
- Box63,
33202
+ Box64,
33217
33203
  {
33218
33204
  style: {
33219
33205
  position: "absolute",
@@ -33232,7 +33218,7 @@ var ExternalDropZone = ({
33232
33218
  onWheel: handleOverlayWheel
33233
33219
  }
33234
33220
  ),
33235
- shouldShowIndicator && indicatorWithPosition && /* @__PURE__ */ React298.createElement(Box63, { style: { ...indicatorStyle, background: "none", border: "none", boxShadow: "none" } }, indicatorWithPosition)
33221
+ shouldShowIndicator && indicatorWithPosition && /* @__PURE__ */ React298.createElement(Box64, { style: { ...indicatorStyle, background: "none", border: "none", boxShadow: "none" } }, indicatorWithPosition)
33236
33222
  );
33237
33223
  };
33238
33224
 
@@ -33248,8 +33234,6 @@ function IxoEditorContent({
33248
33234
  children,
33249
33235
  coverImageUrl,
33250
33236
  logoUrl,
33251
- selfNav = false,
33252
- pageHeaderProps,
33253
33237
  onExternalDrop,
33254
33238
  externalDropType,
33255
33239
  dropIndicator,
@@ -33258,44 +33242,6 @@ function IxoEditorContent({
33258
33242
  }) {
33259
33243
  const { activePanel } = usePanelStore();
33260
33244
  const isPanelOpen = activePanel !== null;
33261
- const [isRoomPrivate, setIsRoomPrivate] = useState138(pageHeaderProps?.isPrivate ?? true);
33262
- useEffect113(() => {
33263
- const matrixClient = editor.getMatrixClient?.();
33264
- const roomId = editor.getRoomId?.();
33265
- if (!matrixClient || !roomId) return;
33266
- try {
33267
- const room = matrixClient.getRoom(roomId);
33268
- if (room) {
33269
- const joinRules = room.currentState.getStateEvents("m.room.join_rules", "");
33270
- if (joinRules) {
33271
- const rule = joinRules.getContent?.()?.join_rule;
33272
- setIsRoomPrivate(rule !== "public");
33273
- }
33274
- }
33275
- } catch {
33276
- }
33277
- }, [editor]);
33278
- const handlePrivacyChange = useCallback111(
33279
- async (makePrivate) => {
33280
- const matrixClient = editor.getMatrixClient?.();
33281
- const roomId = editor.getRoomId?.();
33282
- if (!matrixClient || !roomId) return;
33283
- try {
33284
- await matrixClient.sendStateEvent(
33285
- roomId,
33286
- "m.room.join_rules",
33287
- {
33288
- join_rule: makePrivate ? "invite" : "public"
33289
- },
33290
- ""
33291
- );
33292
- setIsRoomPrivate(makePrivate);
33293
- } catch (err) {
33294
- console.error("Failed to update room privacy:", err);
33295
- }
33296
- },
33297
- [editor]
33298
- );
33299
33245
  const editorContent = /* @__PURE__ */ React299.createElement(
33300
33246
  BlockNoteView,
33301
33247
  {
@@ -33338,8 +33284,8 @@ function IxoEditorContent({
33338
33284
  transition: "width 0.2s ease"
33339
33285
  }
33340
33286
  },
33341
- selfNav && /* @__PURE__ */ React299.createElement(PageHeader, { ...pageHeaderProps, isPrivate: isRoomPrivate, onPrivacyChange: handlePrivacyChange }),
33342
33287
  /* @__PURE__ */ React299.createElement(CoverImage, { coverImageUrl, logoUrl }),
33288
+ /* @__PURE__ */ React299.createElement(PageTitle, { editor, editable: isEditable }),
33343
33289
  (onExternalDrop || isPlacementMode) && isEditable ? /* @__PURE__ */ React299.createElement(
33344
33290
  ExternalDropZone,
33345
33291
  {
@@ -33368,8 +33314,6 @@ function IxoEditor({
33368
33314
  isPanelVisible,
33369
33315
  coverImageUrl,
33370
33316
  logoUrl,
33371
- selfNav = false,
33372
- pageHeaderProps,
33373
33317
  visualizationRenderer,
33374
33318
  getDynamicListData,
33375
33319
  dynamicListPanelRenderer,
@@ -33423,8 +33367,6 @@ function IxoEditor({
33423
33367
  onSelectionChange,
33424
33368
  coverImageUrl,
33425
33369
  logoUrl,
33426
- selfNav,
33427
- pageHeaderProps,
33428
33370
  onExternalDrop,
33429
33371
  externalDropType,
33430
33372
  dropIndicator,
@@ -33493,16 +33435,230 @@ function DebugButton({ editor }) {
33493
33435
  );
33494
33436
  }
33495
33437
 
33438
+ // src/mantine/components/PageHeader.tsx
33439
+ import React301, { useState as useState139, useRef as useRef32, useEffect as useEffect113 } from "react";
33440
+ function PageHeader({
33441
+ title = "New page",
33442
+ icon: icon2,
33443
+ isPrivate = true,
33444
+ onPrivacyChange,
33445
+ lastEdited,
33446
+ onShare,
33447
+ onFavorite,
33448
+ isFavorited = false,
33449
+ menuItems = []
33450
+ }) {
33451
+ const [isMenuOpen, setIsMenuOpen] = useState139(false);
33452
+ const [isPrivacyOpen, setIsPrivacyOpen] = useState139(false);
33453
+ const menuRef = useRef32(null);
33454
+ const privacyRef = useRef32(null);
33455
+ useEffect113(() => {
33456
+ function handleClickOutside(event) {
33457
+ if (menuRef.current && !menuRef.current.contains(event.target)) {
33458
+ setIsMenuOpen(false);
33459
+ }
33460
+ if (privacyRef.current && !privacyRef.current.contains(event.target)) {
33461
+ setIsPrivacyOpen(false);
33462
+ }
33463
+ }
33464
+ if (isMenuOpen || isPrivacyOpen) {
33465
+ document.addEventListener("mousedown", handleClickOutside);
33466
+ }
33467
+ return () => {
33468
+ document.removeEventListener("mousedown", handleClickOutside);
33469
+ };
33470
+ }, [isMenuOpen, isPrivacyOpen]);
33471
+ const handleMenuItemClick = (item) => {
33472
+ if (!item.disabled) {
33473
+ item.onClick();
33474
+ setIsMenuOpen(false);
33475
+ }
33476
+ };
33477
+ return /* @__PURE__ */ React301.createElement("div", { style: styles.container }, /* @__PURE__ */ React301.createElement("div", { style: styles.leftSection }, /* @__PURE__ */ React301.createElement("span", { style: styles.icon }, icon2 || "\u{1F4C4}"), /* @__PURE__ */ React301.createElement("span", { style: styles.title }, title), /* @__PURE__ */ React301.createElement("div", { style: styles.privacyContainer, ref: privacyRef }, /* @__PURE__ */ React301.createElement("button", { style: styles.privacyBadge, onClick: () => onPrivacyChange && setIsPrivacyOpen(!isPrivacyOpen) }, /* @__PURE__ */ React301.createElement("span", { style: styles.lockIcon }, isPrivate ? "\u{1F512}" : "\u{1F310}"), /* @__PURE__ */ React301.createElement("span", null, isPrivate ? "Private" : "Public"), onPrivacyChange && /* @__PURE__ */ React301.createElement("span", { style: styles.chevron }, "\u25BE")), isPrivacyOpen && onPrivacyChange && /* @__PURE__ */ React301.createElement("div", { style: styles.dropdown }, /* @__PURE__ */ React301.createElement(
33478
+ "button",
33479
+ {
33480
+ style: {
33481
+ ...styles.menuItem,
33482
+ ...isPrivate ? styles.menuItemActive : {}
33483
+ },
33484
+ onClick: () => {
33485
+ onPrivacyChange(true);
33486
+ setIsPrivacyOpen(false);
33487
+ }
33488
+ },
33489
+ /* @__PURE__ */ React301.createElement("span", { style: styles.menuItemIcon }, "\u{1F512}"),
33490
+ /* @__PURE__ */ React301.createElement("span", null, "Private")
33491
+ ), /* @__PURE__ */ React301.createElement(
33492
+ "button",
33493
+ {
33494
+ style: {
33495
+ ...styles.menuItem,
33496
+ ...!isPrivate ? styles.menuItemActive : {}
33497
+ },
33498
+ onClick: () => {
33499
+ onPrivacyChange(false);
33500
+ setIsPrivacyOpen(false);
33501
+ }
33502
+ },
33503
+ /* @__PURE__ */ React301.createElement("span", { style: styles.menuItemIcon }, "\u{1F310}"),
33504
+ /* @__PURE__ */ React301.createElement("span", null, "Public")
33505
+ )))), /* @__PURE__ */ React301.createElement("div", { style: styles.rightSection }, lastEdited && /* @__PURE__ */ React301.createElement("span", { style: styles.editedText }, lastEdited), onShare && /* @__PURE__ */ React301.createElement("button", { style: styles.shareButton, onClick: onShare }, "Share"), onFavorite && /* @__PURE__ */ React301.createElement("button", { style: styles.iconButton, onClick: onFavorite }, isFavorited ? "\u2605" : "\u2606"), menuItems.length > 0 && /* @__PURE__ */ React301.createElement("div", { style: styles.menuContainer, ref: menuRef }, /* @__PURE__ */ React301.createElement("button", { style: styles.menuButton, onClick: () => setIsMenuOpen(!isMenuOpen), "aria-label": "Menu" }, /* @__PURE__ */ React301.createElement("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "currentColor" }, /* @__PURE__ */ React301.createElement("circle", { cx: "3", cy: "8", r: "1.5" }), /* @__PURE__ */ React301.createElement("circle", { cx: "8", cy: "8", r: "1.5" }), /* @__PURE__ */ React301.createElement("circle", { cx: "13", cy: "8", r: "1.5" }))), isMenuOpen && /* @__PURE__ */ React301.createElement("div", { style: styles.dropdown }, menuItems.map((item, index) => /* @__PURE__ */ React301.createElement(React301.Fragment, { key: index }, item.divider && index > 0 && /* @__PURE__ */ React301.createElement("div", { style: styles.divider }), /* @__PURE__ */ React301.createElement(
33506
+ "button",
33507
+ {
33508
+ style: {
33509
+ ...styles.menuItem,
33510
+ ...item.disabled ? styles.menuItemDisabled : {}
33511
+ },
33512
+ onClick: () => handleMenuItemClick(item),
33513
+ disabled: item.disabled
33514
+ },
33515
+ item.icon && /* @__PURE__ */ React301.createElement("span", { style: styles.menuItemIcon }, item.icon),
33516
+ /* @__PURE__ */ React301.createElement("span", null, item.label)
33517
+ )))))));
33518
+ }
33519
+ var styles = {
33520
+ container: {
33521
+ display: "flex",
33522
+ alignItems: "center",
33523
+ justifyContent: "space-between",
33524
+ padding: "8px 12px",
33525
+ borderBottom: "1px solid rgba(255, 255, 255, 0.1)",
33526
+ backgroundColor: "transparent",
33527
+ fontSize: "14px",
33528
+ minHeight: "44px",
33529
+ color: "rgba(255, 255, 255, 0.9)"
33530
+ },
33531
+ leftSection: {
33532
+ display: "flex",
33533
+ alignItems: "center",
33534
+ gap: "8px"
33535
+ },
33536
+ icon: {
33537
+ fontSize: "16px"
33538
+ },
33539
+ title: {
33540
+ fontWeight: 500,
33541
+ color: "rgba(255, 255, 255, 0.9)"
33542
+ },
33543
+ privacyContainer: {
33544
+ position: "relative"
33545
+ },
33546
+ privacyBadge: {
33547
+ display: "flex",
33548
+ alignItems: "center",
33549
+ gap: "4px",
33550
+ padding: "2px 6px",
33551
+ border: "none",
33552
+ backgroundColor: "transparent",
33553
+ color: "rgba(255, 255, 255, 0.5)",
33554
+ fontSize: "12px",
33555
+ cursor: "pointer",
33556
+ borderRadius: "3px"
33557
+ },
33558
+ lockIcon: {
33559
+ fontSize: "12px"
33560
+ },
33561
+ chevron: {
33562
+ fontSize: "10px",
33563
+ marginLeft: "2px"
33564
+ },
33565
+ rightSection: {
33566
+ display: "flex",
33567
+ alignItems: "center",
33568
+ gap: "8px"
33569
+ },
33570
+ editedText: {
33571
+ color: "rgba(255, 255, 255, 0.4)",
33572
+ fontSize: "12px"
33573
+ },
33574
+ shareButton: {
33575
+ padding: "4px 10px",
33576
+ border: "none",
33577
+ backgroundColor: "transparent",
33578
+ color: "rgba(255, 255, 255, 0.9)",
33579
+ fontSize: "14px",
33580
+ cursor: "pointer",
33581
+ borderRadius: "3px",
33582
+ fontWeight: 500
33583
+ },
33584
+ iconButton: {
33585
+ padding: "4px 8px",
33586
+ border: "none",
33587
+ backgroundColor: "transparent",
33588
+ color: "rgba(255, 255, 255, 0.5)",
33589
+ fontSize: "16px",
33590
+ cursor: "pointer",
33591
+ borderRadius: "3px"
33592
+ },
33593
+ menuContainer: {
33594
+ position: "relative"
33595
+ },
33596
+ menuButton: {
33597
+ display: "flex",
33598
+ alignItems: "center",
33599
+ justifyContent: "center",
33600
+ padding: "4px 8px",
33601
+ border: "none",
33602
+ backgroundColor: "transparent",
33603
+ color: "rgba(255, 255, 255, 0.5)",
33604
+ cursor: "pointer",
33605
+ borderRadius: "3px"
33606
+ },
33607
+ dropdown: {
33608
+ position: "absolute",
33609
+ top: "100%",
33610
+ right: 0,
33611
+ marginTop: "4px",
33612
+ minWidth: "180px",
33613
+ backgroundColor: "rgb(37, 37, 37)",
33614
+ borderRadius: "6px",
33615
+ boxShadow: "0 4px 12px rgba(0, 0, 0, 0.4)",
33616
+ border: "1px solid rgba(255, 255, 255, 0.1)",
33617
+ padding: "4px 0",
33618
+ zIndex: 1e3
33619
+ },
33620
+ menuItem: {
33621
+ display: "flex",
33622
+ alignItems: "center",
33623
+ gap: "8px",
33624
+ width: "100%",
33625
+ padding: "8px 12px",
33626
+ border: "none",
33627
+ backgroundColor: "transparent",
33628
+ color: "rgba(255, 255, 255, 0.9)",
33629
+ fontSize: "14px",
33630
+ cursor: "pointer",
33631
+ textAlign: "left"
33632
+ },
33633
+ menuItemDisabled: {
33634
+ color: "rgba(255, 255, 255, 0.3)",
33635
+ cursor: "not-allowed"
33636
+ },
33637
+ menuItemActive: {
33638
+ backgroundColor: "rgba(255, 255, 255, 0.08)"
33639
+ },
33640
+ menuItemIcon: {
33641
+ display: "flex",
33642
+ alignItems: "center",
33643
+ fontSize: "16px"
33644
+ },
33645
+ divider: {
33646
+ height: "1px",
33647
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
33648
+ margin: "4px 0"
33649
+ }
33650
+ };
33651
+
33496
33652
  // src/mantine/components/EntitySigningSetup.tsx
33497
- import React301, { useState as useState139 } from "react";
33498
- import { Modal as Modal3, Stack as Stack198, Text as Text172, TextInput as TextInput8, Button as Button57, Alert as Alert54, Group as Group109 } from "@mantine/core";
33653
+ import React302, { useState as useState140 } from "react";
33654
+ import { Modal as Modal3, Stack as Stack198, Text as Text173, TextInput as TextInput8, Button as Button56, Alert as Alert54, Group as Group110 } from "@mantine/core";
33499
33655
  import { IconAlertCircle as IconAlertCircle20, IconCheck as IconCheck23, IconKey as IconKey2 } from "@tabler/icons-react";
33500
33656
  var EntitySigningSetup = ({ opened, onClose, entityDid, entityName, onSetup }) => {
33501
- const [pin, setPin] = useState139("");
33502
- const [confirmPin, setConfirmPin] = useState139("");
33503
- const [loading, setLoading] = useState139(false);
33504
- const [error, setError] = useState139(null);
33505
- const [success, setSuccess] = useState139(false);
33657
+ const [pin, setPin] = useState140("");
33658
+ const [confirmPin, setConfirmPin] = useState140("");
33659
+ const [loading, setLoading] = useState140(false);
33660
+ const [error, setError] = useState140(null);
33661
+ const [success, setSuccess] = useState140(false);
33506
33662
  const handleSetup = async () => {
33507
33663
  if (pin.length < 4) {
33508
33664
  setError("PIN must be at least 4 characters");
@@ -33542,15 +33698,15 @@ var EntitySigningSetup = ({ opened, onClose, entityDid, entityName, onSetup }) =
33542
33698
  setSuccess(false);
33543
33699
  }
33544
33700
  };
33545
- return /* @__PURE__ */ React301.createElement(
33701
+ return /* @__PURE__ */ React302.createElement(
33546
33702
  Modal3,
33547
33703
  {
33548
33704
  opened,
33549
33705
  onClose: handleClose,
33550
- title: /* @__PURE__ */ React301.createElement(Group109, { gap: "xs" }, /* @__PURE__ */ React301.createElement(IconKey2, { size: 20 }), /* @__PURE__ */ React301.createElement(Text172, { fw: 600 }, "Entity Signing Setup")),
33706
+ title: /* @__PURE__ */ React302.createElement(Group110, { gap: "xs" }, /* @__PURE__ */ React302.createElement(IconKey2, { size: 20 }), /* @__PURE__ */ React302.createElement(Text173, { fw: 600 }, "Entity Signing Setup")),
33551
33707
  size: "md"
33552
33708
  },
33553
- /* @__PURE__ */ React301.createElement(Stack198, { gap: "md" }, success ? /* @__PURE__ */ React301.createElement(Alert54, { color: "green", icon: /* @__PURE__ */ React301.createElement(IconCheck23, { size: 16 }) }, "Entity signing key set up successfully!") : /* @__PURE__ */ React301.createElement(React301.Fragment, null, /* @__PURE__ */ React301.createElement(Text172, { size: "sm", c: "dimmed" }, "Flow authorization requires a signing key for", " ", /* @__PURE__ */ React301.createElement(Text172, { span: true, fw: 500 }, entityName || entityDid), "."), /* @__PURE__ */ React301.createElement(Alert54, { color: "blue", variant: "light" }, /* @__PURE__ */ React301.createElement(Text172, { size: "sm" }, "This is a ", /* @__PURE__ */ React301.createElement("strong", null, "one-time setup"), " that allows flows to grant permissions without requiring wallet signatures for each delegation.")), /* @__PURE__ */ React301.createElement(Stack198, { gap: "xs" }, /* @__PURE__ */ React301.createElement(Text172, { size: "sm", fw: 500 }, "What happens:"), /* @__PURE__ */ React301.createElement(Text172, { size: "sm", c: "dimmed" }, "1. A new signing key is generated"), /* @__PURE__ */ React301.createElement(Text172, { size: "sm", c: "dimmed" }, "2. Key is registered on the entity's DID document (requires wallet)"), /* @__PURE__ */ React301.createElement(Text172, { size: "sm", c: "dimmed" }, "3. Key is stored encrypted in the entity's Matrix room")), /* @__PURE__ */ React301.createElement(
33709
+ /* @__PURE__ */ React302.createElement(Stack198, { gap: "md" }, success ? /* @__PURE__ */ React302.createElement(Alert54, { color: "green", icon: /* @__PURE__ */ React302.createElement(IconCheck23, { size: 16 }) }, "Entity signing key set up successfully!") : /* @__PURE__ */ React302.createElement(React302.Fragment, null, /* @__PURE__ */ React302.createElement(Text173, { size: "sm", c: "dimmed" }, "Flow authorization requires a signing key for", " ", /* @__PURE__ */ React302.createElement(Text173, { span: true, fw: 500 }, entityName || entityDid), "."), /* @__PURE__ */ React302.createElement(Alert54, { color: "blue", variant: "light" }, /* @__PURE__ */ React302.createElement(Text173, { size: "sm" }, "This is a ", /* @__PURE__ */ React302.createElement("strong", null, "one-time setup"), " that allows flows to grant permissions without requiring wallet signatures for each delegation.")), /* @__PURE__ */ React302.createElement(Stack198, { gap: "xs" }, /* @__PURE__ */ React302.createElement(Text173, { size: "sm", fw: 500 }, "What happens:"), /* @__PURE__ */ React302.createElement(Text173, { size: "sm", c: "dimmed" }, "1. A new signing key is generated"), /* @__PURE__ */ React302.createElement(Text173, { size: "sm", c: "dimmed" }, "2. Key is registered on the entity's DID document (requires wallet)"), /* @__PURE__ */ React302.createElement(Text173, { size: "sm", c: "dimmed" }, "3. Key is stored encrypted in the entity's Matrix room")), /* @__PURE__ */ React302.createElement(
33554
33710
  TextInput8,
33555
33711
  {
33556
33712
  label: "Enter PIN to encrypt signing key",
@@ -33561,18 +33717,18 @@ var EntitySigningSetup = ({ opened, onClose, entityDid, entityName, onSetup }) =
33561
33717
  onChange: (e) => setPin(e.currentTarget.value),
33562
33718
  disabled: loading
33563
33719
  }
33564
- ), /* @__PURE__ */ React301.createElement(TextInput8, { label: "Confirm PIN", type: "password", placeholder: "Confirm PIN", value: confirmPin, onChange: (e) => setConfirmPin(e.currentTarget.value), disabled: loading }), error && /* @__PURE__ */ React301.createElement(Alert54, { color: "red", icon: /* @__PURE__ */ React301.createElement(IconAlertCircle20, { size: 16 }) }, error), /* @__PURE__ */ React301.createElement(Group109, { justify: "flex-end", mt: "md" }, /* @__PURE__ */ React301.createElement(Button57, { variant: "subtle", onClick: handleClose, disabled: loading }, "Cancel"), /* @__PURE__ */ React301.createElement(Button57, { onClick: handleSetup, loading, leftSection: /* @__PURE__ */ React301.createElement(IconKey2, { size: 16 }) }, "Setup Entity Signing"))))
33720
+ ), /* @__PURE__ */ React302.createElement(TextInput8, { label: "Confirm PIN", type: "password", placeholder: "Confirm PIN", value: confirmPin, onChange: (e) => setConfirmPin(e.currentTarget.value), disabled: loading }), error && /* @__PURE__ */ React302.createElement(Alert54, { color: "red", icon: /* @__PURE__ */ React302.createElement(IconAlertCircle20, { size: 16 }) }, error), /* @__PURE__ */ React302.createElement(Group110, { justify: "flex-end", mt: "md" }, /* @__PURE__ */ React302.createElement(Button56, { variant: "subtle", onClick: handleClose, disabled: loading }, "Cancel"), /* @__PURE__ */ React302.createElement(Button56, { onClick: handleSetup, loading, leftSection: /* @__PURE__ */ React302.createElement(IconKey2, { size: 16 }) }, "Setup Entity Signing"))))
33565
33721
  );
33566
33722
  };
33567
33723
 
33568
33724
  // src/mantine/components/FlowPermissionsPanel.tsx
33569
- import React302, { useState as useState140, useEffect as useEffect114, useMemo as useMemo122 } from "react";
33570
- import { Stack as Stack199, Text as Text173, Paper as Paper18, Group as Group110, Badge as Badge45, Button as Button58, ActionIcon as ActionIcon38, Loader as Loader54, Alert as Alert55, Divider as Divider29 } from "@mantine/core";
33571
- import { IconPlus as IconPlus11, IconTrash as IconTrash11, IconShieldCheck as IconShieldCheck16, IconUser as IconUser14, IconRobot as IconRobot4, IconBuilding as IconBuilding2 } from "@tabler/icons-react";
33725
+ import React303, { useState as useState141, useEffect as useEffect114, useMemo as useMemo122 } from "react";
33726
+ import { Stack as Stack199, Text as Text174, Paper as Paper18, Group as Group111, Badge as Badge45, Button as Button57, ActionIcon as ActionIcon38, Loader as Loader54, Alert as Alert55, Divider as Divider29 } from "@mantine/core";
33727
+ import { IconPlus as IconPlus11, IconTrash as IconTrash12, IconShieldCheck as IconShieldCheck16, IconUser as IconUser14, IconRobot as IconRobot4, IconBuilding as IconBuilding2 } from "@tabler/icons-react";
33572
33728
  var FlowPermissionsPanel = ({ editor, entityDid, entityName, onGrantPermission, onRevokePermission, getUserDisplayName }) => {
33573
- const [delegations, setDelegations] = useState140([]);
33574
- const [loading, setLoading] = useState140(true);
33575
- const [revoking, setRevoking] = useState140(null);
33729
+ const [delegations, setDelegations] = useState141([]);
33730
+ const [loading, setLoading] = useState141(true);
33731
+ const [revoking, setRevoking] = useState141(null);
33576
33732
  const rootDelegation = useMemo122(() => {
33577
33733
  if (editor.getUcanService) {
33578
33734
  return editor.getUcanService()?.getRootDelegation() || null;
@@ -33621,11 +33777,11 @@ var FlowPermissionsPanel = ({ editor, entityDid, entityName, onGrantPermission,
33621
33777
  const getIcon2 = (type) => {
33622
33778
  switch (type) {
33623
33779
  case "oracle":
33624
- return /* @__PURE__ */ React302.createElement(IconRobot4, { size: 16 });
33780
+ return /* @__PURE__ */ React303.createElement(IconRobot4, { size: 16 });
33625
33781
  case "entity":
33626
- return /* @__PURE__ */ React302.createElement(IconBuilding2, { size: 16 });
33782
+ return /* @__PURE__ */ React303.createElement(IconBuilding2, { size: 16 });
33627
33783
  default:
33628
- return /* @__PURE__ */ React302.createElement(IconUser14, { size: 16 });
33784
+ return /* @__PURE__ */ React303.createElement(IconUser14, { size: 16 });
33629
33785
  }
33630
33786
  };
33631
33787
  const formatCapabilities = (caps) => {
@@ -33644,31 +33800,31 @@ var FlowPermissionsPanel = ({ editor, entityDid, entityName, onGrantPermission,
33644
33800
  if (date < /* @__PURE__ */ new Date()) return "Expired";
33645
33801
  return date.toLocaleDateString();
33646
33802
  };
33647
- return /* @__PURE__ */ React302.createElement(Stack199, { gap: "md" }, /* @__PURE__ */ React302.createElement(Stack199, { gap: "xs" }, /* @__PURE__ */ React302.createElement(Text173, { fw: 600, size: "sm" }, "Root Authority"), /* @__PURE__ */ React302.createElement(Paper18, { p: "sm", withBorder: true }, /* @__PURE__ */ React302.createElement(Group110, { gap: "xs" }, /* @__PURE__ */ React302.createElement(IconShieldCheck16, { size: 20, color: "var(--mantine-color-green-6)" }), /* @__PURE__ */ React302.createElement(Stack199, { gap: 2, style: { flex: 1 } }, /* @__PURE__ */ React302.createElement(Text173, { size: "sm", fw: 500 }, entityName || entityDid), /* @__PURE__ */ React302.createElement(Text173, { size: "xs", c: "dimmed" }, rootDelegation ? `Granted: ${new Date(rootDelegation.createdAt).toLocaleDateString()}` : "Root capability not set up")), /* @__PURE__ */ React302.createElement(Badge45, { color: "green", variant: "light" }, "Entity")))), /* @__PURE__ */ React302.createElement(Divider29, { label: "Delegated Permissions", labelPosition: "center" }), loading ? /* @__PURE__ */ React302.createElement(Group110, { justify: "center", py: "xl" }, /* @__PURE__ */ React302.createElement(Loader54, { size: "sm" })) : delegations.length === 0 ? /* @__PURE__ */ React302.createElement(Alert55, { color: "gray", variant: "light" }, /* @__PURE__ */ React302.createElement(Text173, { size: "sm" }, "No permissions have been granted yet.")) : /* @__PURE__ */ React302.createElement(Stack199, { gap: "xs" }, delegations.map(({ delegation, displayName, type }) => /* @__PURE__ */ React302.createElement(Paper18, { key: delegation.cid, p: "sm", withBorder: true }, /* @__PURE__ */ React302.createElement(Group110, { justify: "space-between" }, /* @__PURE__ */ React302.createElement(Group110, { gap: "xs" }, getIcon2(type), /* @__PURE__ */ React302.createElement(Stack199, { gap: 2 }, /* @__PURE__ */ React302.createElement(Text173, { size: "sm", fw: 500 }, displayName), /* @__PURE__ */ React302.createElement(Text173, { size: "xs", c: "dimmed" }, formatCapabilities(delegation.capabilities)), /* @__PURE__ */ React302.createElement(Group110, { gap: "xs" }, /* @__PURE__ */ React302.createElement(Text173, { size: "xs", c: "dimmed" }, "Expires: ", formatExpiration(delegation.expiration)), /* @__PURE__ */ React302.createElement(Text173, { size: "xs", c: "dimmed" }, "\u2022"), /* @__PURE__ */ React302.createElement(Text173, { size: "xs", c: "dimmed" }, "Granted by: ", delegation.issuerDid === entityDid ? "Entity" : delegation.issuerDid.slice(-8))))), /* @__PURE__ */ React302.createElement(ActionIcon38, { color: "red", variant: "subtle", onClick: () => handleRevoke(delegation.cid), loading: revoking === delegation.cid, disabled: !!revoking }, /* @__PURE__ */ React302.createElement(IconTrash11, { size: 16 })))))), /* @__PURE__ */ React302.createElement(Button58, { leftSection: /* @__PURE__ */ React302.createElement(IconPlus11, { size: 16 }), variant: "light", onClick: onGrantPermission }, "Grant Permission"));
33803
+ return /* @__PURE__ */ React303.createElement(Stack199, { gap: "md" }, /* @__PURE__ */ React303.createElement(Stack199, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Text174, { fw: 600, size: "sm" }, "Root Authority"), /* @__PURE__ */ React303.createElement(Paper18, { p: "sm", withBorder: true }, /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, /* @__PURE__ */ React303.createElement(IconShieldCheck16, { size: 20, color: "var(--mantine-color-green-6)" }), /* @__PURE__ */ React303.createElement(Stack199, { gap: 2, style: { flex: 1 } }, /* @__PURE__ */ React303.createElement(Text174, { size: "sm", fw: 500 }, entityName || entityDid), /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed" }, rootDelegation ? `Granted: ${new Date(rootDelegation.createdAt).toLocaleDateString()}` : "Root capability not set up")), /* @__PURE__ */ React303.createElement(Badge45, { color: "green", variant: "light" }, "Entity")))), /* @__PURE__ */ React303.createElement(Divider29, { label: "Delegated Permissions", labelPosition: "center" }), loading ? /* @__PURE__ */ React303.createElement(Group111, { justify: "center", py: "xl" }, /* @__PURE__ */ React303.createElement(Loader54, { size: "sm" })) : delegations.length === 0 ? /* @__PURE__ */ React303.createElement(Alert55, { color: "gray", variant: "light" }, /* @__PURE__ */ React303.createElement(Text174, { size: "sm" }, "No permissions have been granted yet.")) : /* @__PURE__ */ React303.createElement(Stack199, { gap: "xs" }, delegations.map(({ delegation, displayName, type }) => /* @__PURE__ */ React303.createElement(Paper18, { key: delegation.cid, p: "sm", withBorder: true }, /* @__PURE__ */ React303.createElement(Group111, { justify: "space-between" }, /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, getIcon2(type), /* @__PURE__ */ React303.createElement(Stack199, { gap: 2 }, /* @__PURE__ */ React303.createElement(Text174, { size: "sm", fw: 500 }, displayName), /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed" }, formatCapabilities(delegation.capabilities)), /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed" }, "Expires: ", formatExpiration(delegation.expiration)), /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed" }, "\u2022"), /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed" }, "Granted by: ", delegation.issuerDid === entityDid ? "Entity" : delegation.issuerDid.slice(-8))))), /* @__PURE__ */ React303.createElement(ActionIcon38, { color: "red", variant: "subtle", onClick: () => handleRevoke(delegation.cid), loading: revoking === delegation.cid, disabled: !!revoking }, /* @__PURE__ */ React303.createElement(IconTrash12, { size: 16 })))))), /* @__PURE__ */ React303.createElement(Button57, { leftSection: /* @__PURE__ */ React303.createElement(IconPlus11, { size: 16 }), variant: "light", onClick: onGrantPermission }, "Grant Permission"));
33648
33804
  };
33649
33805
 
33650
33806
  // src/mantine/components/GrantPermissionModal.tsx
33651
- import React303, { useState as useState141, useCallback as useCallback112 } from "react";
33652
- import { Modal as Modal4, Stack as Stack200, Text as Text174, TextInput as TextInput9, Button as Button59, Group as Group111, Radio as Radio5, Checkbox as Checkbox13, Alert as Alert56, Paper as Paper19, Loader as Loader55, Badge as Badge46, ActionIcon as ActionIcon39, Divider as Divider30, NumberInput as NumberInput3 } from "@mantine/core";
33807
+ import React304, { useState as useState142, useCallback as useCallback112 } from "react";
33808
+ import { Modal as Modal4, Stack as Stack200, Text as Text175, TextInput as TextInput9, Button as Button58, Group as Group112, Radio as Radio5, Checkbox as Checkbox13, Alert as Alert56, Paper as Paper19, Loader as Loader55, Badge as Badge46, ActionIcon as ActionIcon39, Divider as Divider30, NumberInput as NumberInput3 } from "@mantine/core";
33653
33809
  import { IconSearch as IconSearch8, IconUser as IconUser15, IconRobot as IconRobot5, IconX as IconX14, IconShieldPlus as IconShieldPlus4 } from "@tabler/icons-react";
33654
33810
  var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, searchUsers, getOracles, onGrant }) => {
33655
33811
  const singleBlockMode = !!targetBlockId || blocks.length === 1;
33656
33812
  const fixedBlockId = targetBlockId || (blocks.length === 1 ? blocks[0].id : null);
33657
33813
  const fixedBlock = fixedBlockId ? blocks.find((b) => b.id === fixedBlockId) || blocks[0] : null;
33658
- const [recipientType, setRecipientType] = useState141("user");
33659
- const [searchQuery, setSearchQuery] = useState141("");
33660
- const [searchResults, setSearchResults] = useState141([]);
33661
- const [searching, setSearching] = useState141(false);
33662
- const [selectedRecipient, setSelectedRecipient] = useState141(null);
33663
- const [manualDid, setManualDid] = useState141("");
33664
- const [scopeType, setScopeType] = useState141("full");
33665
- const [selectedBlocks, setSelectedBlocks] = useState141([]);
33666
- const [expirationEnabled, setExpirationEnabled] = useState141(false);
33667
- const [expirationDays, setExpirationDays] = useState141(30);
33668
- const [canDelegate, setCanDelegate] = useState141(false);
33669
- const [pin, setPin] = useState141("");
33670
- const [loading, setLoading] = useState141(false);
33671
- const [error, setError] = useState141(null);
33814
+ const [recipientType, setRecipientType] = useState142("user");
33815
+ const [searchQuery, setSearchQuery] = useState142("");
33816
+ const [searchResults, setSearchResults] = useState142([]);
33817
+ const [searching, setSearching] = useState142(false);
33818
+ const [selectedRecipient, setSelectedRecipient] = useState142(null);
33819
+ const [manualDid, setManualDid] = useState142("");
33820
+ const [scopeType, setScopeType] = useState142("full");
33821
+ const [selectedBlocks, setSelectedBlocks] = useState142([]);
33822
+ const [expirationEnabled, setExpirationEnabled] = useState142(false);
33823
+ const [expirationDays, setExpirationDays] = useState142(30);
33824
+ const [canDelegate, setCanDelegate] = useState142(false);
33825
+ const [pin, setPin] = useState142("");
33826
+ const [loading, setLoading] = useState142(false);
33827
+ const [error, setError] = useState142(null);
33672
33828
  const handleSearch = useCallback112(async () => {
33673
33829
  if (searchQuery.length < 2) return;
33674
33830
  setSearching(true);
@@ -33756,15 +33912,15 @@ var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, s
33756
33912
  resetForm();
33757
33913
  }
33758
33914
  };
33759
- return /* @__PURE__ */ React303.createElement(
33915
+ return /* @__PURE__ */ React304.createElement(
33760
33916
  Modal4,
33761
33917
  {
33762
33918
  opened,
33763
33919
  onClose: handleClose,
33764
- title: /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, /* @__PURE__ */ React303.createElement(IconShieldPlus4, { size: 20 }), /* @__PURE__ */ React303.createElement(Text174, { fw: 600 }, "Grant Permission")),
33920
+ title: /* @__PURE__ */ React304.createElement(Group112, { gap: "xs" }, /* @__PURE__ */ React304.createElement(IconShieldPlus4, { size: 20 }), /* @__PURE__ */ React304.createElement(Text175, { fw: 600 }, "Grant Permission")),
33765
33921
  size: "lg"
33766
33922
  },
33767
- /* @__PURE__ */ React303.createElement(Stack200, { gap: "md" }, /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Text174, { size: "sm", fw: 500 }, "Recipient Type"), /* @__PURE__ */ React303.createElement(
33923
+ /* @__PURE__ */ React304.createElement(Stack200, { gap: "md" }, /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React304.createElement(Text175, { size: "sm", fw: 500 }, "Recipient Type"), /* @__PURE__ */ React304.createElement(
33768
33924
  Radio5.Group,
33769
33925
  {
33770
33926
  value: recipientType,
@@ -33774,23 +33930,23 @@ var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, s
33774
33930
  setSearchResults([]);
33775
33931
  }
33776
33932
  },
33777
- /* @__PURE__ */ React303.createElement(Group111, null, /* @__PURE__ */ React303.createElement(Radio5, { value: "user", label: "User" }), /* @__PURE__ */ React303.createElement(Radio5, { value: "oracle", label: "Oracle" }), /* @__PURE__ */ React303.createElement(Radio5, { value: "manual", label: "Enter DID" }))
33778
- )), recipientType !== "manual" ? /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React303.createElement(
33933
+ /* @__PURE__ */ React304.createElement(Group112, null, /* @__PURE__ */ React304.createElement(Radio5, { value: "user", label: "User" }), /* @__PURE__ */ React304.createElement(Radio5, { value: "oracle", label: "Oracle" }), /* @__PURE__ */ React304.createElement(Radio5, { value: "manual", label: "Enter DID" }))
33934
+ )), recipientType !== "manual" ? /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React304.createElement(
33779
33935
  TextInput9,
33780
33936
  {
33781
33937
  placeholder: recipientType === "oracle" ? "Search oracles..." : "Search users...",
33782
- leftSection: /* @__PURE__ */ React303.createElement(IconSearch8, { size: 16 }),
33783
- rightSection: searching ? /* @__PURE__ */ React303.createElement(Loader55, { size: 14 }) : null,
33938
+ leftSection: /* @__PURE__ */ React304.createElement(IconSearch8, { size: 16 }),
33939
+ rightSection: searching ? /* @__PURE__ */ React304.createElement(Loader55, { size: 14 }) : null,
33784
33940
  value: searchQuery,
33785
33941
  onChange: (e) => setSearchQuery(e.currentTarget.value),
33786
33942
  onKeyDown: (e) => e.key === "Enter" && handleSearch()
33787
33943
  }
33788
- ), selectedRecipient ? /* @__PURE__ */ React303.createElement(Paper19, { p: "sm", withBorder: true }, /* @__PURE__ */ React303.createElement(Group111, { justify: "space-between" }, /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, recipientType === "oracle" ? /* @__PURE__ */ React303.createElement(IconRobot5, { size: 16 }) : /* @__PURE__ */ React303.createElement(IconUser15, { size: 16 }), /* @__PURE__ */ React303.createElement(Text174, { size: "sm" }, selectedRecipient.displayName), /* @__PURE__ */ React303.createElement(Badge46, { size: "xs", variant: "light" }, selectedRecipient.did.slice(-12))), /* @__PURE__ */ React303.createElement(ActionIcon39, { size: "sm", variant: "subtle", onClick: () => setSelectedRecipient(null) }, /* @__PURE__ */ React303.createElement(IconX14, { size: 14 })))) : searchResults.length > 0 ? /* @__PURE__ */ React303.createElement(Paper19, { p: "xs", withBorder: true, style: { maxHeight: 150, overflow: "auto" } }, /* @__PURE__ */ React303.createElement(Stack200, { gap: 4 }, searchResults.map((result) => /* @__PURE__ */ React303.createElement(Button59, { key: result.did, variant: "subtle", size: "sm", justify: "flex-start", onClick: () => setSelectedRecipient(result) }, result.displayName)))) : null) : /* @__PURE__ */ React303.createElement(TextInput9, { label: "Recipient DID", placeholder: "did:ixo:...", value: manualDid, onChange: (e) => setManualDid(e.currentTarget.value) }), /* @__PURE__ */ React303.createElement(Divider30, null), /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Text174, { size: "sm", fw: 500 }, "Permission Scope"), singleBlockMode && fixedBlock ? (
33944
+ ), selectedRecipient ? /* @__PURE__ */ React304.createElement(Paper19, { p: "sm", withBorder: true }, /* @__PURE__ */ React304.createElement(Group112, { justify: "space-between" }, /* @__PURE__ */ React304.createElement(Group112, { gap: "xs" }, recipientType === "oracle" ? /* @__PURE__ */ React304.createElement(IconRobot5, { size: 16 }) : /* @__PURE__ */ React304.createElement(IconUser15, { size: 16 }), /* @__PURE__ */ React304.createElement(Text175, { size: "sm" }, selectedRecipient.displayName), /* @__PURE__ */ React304.createElement(Badge46, { size: "xs", variant: "light" }, selectedRecipient.did.slice(-12))), /* @__PURE__ */ React304.createElement(ActionIcon39, { size: "sm", variant: "subtle", onClick: () => setSelectedRecipient(null) }, /* @__PURE__ */ React304.createElement(IconX14, { size: 14 })))) : searchResults.length > 0 ? /* @__PURE__ */ React304.createElement(Paper19, { p: "xs", withBorder: true, style: { maxHeight: 150, overflow: "auto" } }, /* @__PURE__ */ React304.createElement(Stack200, { gap: 4 }, searchResults.map((result) => /* @__PURE__ */ React304.createElement(Button58, { key: result.did, variant: "subtle", size: "sm", justify: "flex-start", onClick: () => setSelectedRecipient(result) }, result.displayName)))) : null) : /* @__PURE__ */ React304.createElement(TextInput9, { label: "Recipient DID", placeholder: "did:ixo:...", value: manualDid, onChange: (e) => setManualDid(e.currentTarget.value) }), /* @__PURE__ */ React304.createElement(Divider30, null), /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React304.createElement(Text175, { size: "sm", fw: 500 }, "Permission Scope"), singleBlockMode && fixedBlock ? (
33789
33945
  // Single block mode: show fixed block info
33790
- /* @__PURE__ */ React303.createElement(Paper19, { p: "sm", withBorder: true }, /* @__PURE__ */ React303.createElement(Group111, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Badge46, { variant: "light", color: "blue" }, fixedBlock.type), /* @__PURE__ */ React303.createElement(Text174, { size: "sm" }, fixedBlock.name || `Block ${fixedBlock.id.slice(-8)}`)), /* @__PURE__ */ React303.createElement(Text174, { size: "xs", c: "dimmed", mt: "xs" }, "Permission will be granted to execute this specific block."))
33946
+ /* @__PURE__ */ React304.createElement(Paper19, { p: "sm", withBorder: true }, /* @__PURE__ */ React304.createElement(Group112, { gap: "xs" }, /* @__PURE__ */ React304.createElement(Badge46, { variant: "light", color: "blue" }, fixedBlock.type), /* @__PURE__ */ React304.createElement(Text175, { size: "sm" }, fixedBlock.name || `Block ${fixedBlock.id.slice(-8)}`)), /* @__PURE__ */ React304.createElement(Text175, { size: "xs", c: "dimmed", mt: "xs" }, "Permission will be granted to execute this specific block."))
33791
33947
  ) : (
33792
33948
  // Multi-block mode: show scope selection
33793
- /* @__PURE__ */ React303.createElement(React303.Fragment, null, /* @__PURE__ */ React303.createElement(Radio5.Group, { value: scopeType, onChange: (v) => setScopeType(v) }, /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Radio5, { value: "full", label: "Full flow access (can execute any block)" }), /* @__PURE__ */ React303.createElement(Radio5, { value: "blocks", label: "Specific blocks only" }))), scopeType === "blocks" && /* @__PURE__ */ React303.createElement(Paper19, { p: "sm", withBorder: true, style: { maxHeight: 150, overflow: "auto" } }, /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, blocks.map((block) => /* @__PURE__ */ React303.createElement(
33949
+ /* @__PURE__ */ React304.createElement(React304.Fragment, null, /* @__PURE__ */ React304.createElement(Radio5.Group, { value: scopeType, onChange: (v) => setScopeType(v) }, /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React304.createElement(Radio5, { value: "full", label: "Full flow access (can execute any block)" }), /* @__PURE__ */ React304.createElement(Radio5, { value: "blocks", label: "Specific blocks only" }))), scopeType === "blocks" && /* @__PURE__ */ React304.createElement(Paper19, { p: "sm", withBorder: true, style: { maxHeight: 150, overflow: "auto" } }, /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, blocks.map((block) => /* @__PURE__ */ React304.createElement(
33794
33950
  Checkbox13,
33795
33951
  {
33796
33952
  key: block.id,
@@ -33805,7 +33961,7 @@ var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, s
33805
33961
  }
33806
33962
  }
33807
33963
  )))))
33808
- )), /* @__PURE__ */ React303.createElement(Divider30, null), /* @__PURE__ */ React303.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React303.createElement(Checkbox13, { label: "Set expiration", checked: expirationEnabled, onChange: (e) => setExpirationEnabled(e.currentTarget.checked) }), expirationEnabled && /* @__PURE__ */ React303.createElement(NumberInput3, { label: "Expires in (days)", placeholder: "30", value: expirationDays, onChange: setExpirationDays, min: 1, max: 365 })), /* @__PURE__ */ React303.createElement(
33964
+ )), /* @__PURE__ */ React304.createElement(Divider30, null), /* @__PURE__ */ React304.createElement(Stack200, { gap: "xs" }, /* @__PURE__ */ React304.createElement(Checkbox13, { label: "Set expiration", checked: expirationEnabled, onChange: (e) => setExpirationEnabled(e.currentTarget.checked) }), expirationEnabled && /* @__PURE__ */ React304.createElement(NumberInput3, { label: "Expires in (days)", placeholder: "30", value: expirationDays, onChange: setExpirationDays, min: 1, max: 365 })), /* @__PURE__ */ React304.createElement(
33809
33965
  Checkbox13,
33810
33966
  {
33811
33967
  label: "Recipient can grant permissions to others",
@@ -33813,7 +33969,7 @@ var GrantPermissionModal = ({ opened, onClose, flowUri, blocks, targetBlockId, s
33813
33969
  checked: canDelegate,
33814
33970
  onChange: (e) => setCanDelegate(e.currentTarget.checked)
33815
33971
  }
33816
- ), /* @__PURE__ */ React303.createElement(Divider30, null), /* @__PURE__ */ React303.createElement(TextInput9, { label: "Enter your PIN to sign this delegation", type: "password", placeholder: "PIN", value: pin, onChange: (e) => setPin(e.currentTarget.value) }), error && /* @__PURE__ */ React303.createElement(Alert56, { color: "red" }, error), /* @__PURE__ */ React303.createElement(Group111, { justify: "flex-end" }, /* @__PURE__ */ React303.createElement(Button59, { variant: "subtle", onClick: handleClose, disabled: loading }, "Cancel"), /* @__PURE__ */ React303.createElement(Button59, { onClick: handleGrant, loading }, "Grant Permission")))
33972
+ ), /* @__PURE__ */ React304.createElement(Divider30, null), /* @__PURE__ */ React304.createElement(TextInput9, { label: "Enter your PIN to sign this delegation", type: "password", placeholder: "PIN", value: pin, onChange: (e) => setPin(e.currentTarget.value) }), error && /* @__PURE__ */ React304.createElement(Alert56, { color: "red" }, error), /* @__PURE__ */ React304.createElement(Group112, { justify: "flex-end" }, /* @__PURE__ */ React304.createElement(Button58, { variant: "subtle", onClick: handleClose, disabled: loading }, "Cancel"), /* @__PURE__ */ React304.createElement(Button58, { onClick: handleGrant, loading }, "Grant Permission")))
33817
33973
  );
33818
33974
  };
33819
33975
 
@@ -33905,10 +34061,11 @@ export {
33905
34061
  useCreateCollaborativeIxoEditor,
33906
34062
  BaseIconPicker,
33907
34063
  CoverImage,
33908
- PageHeader,
34064
+ PageTitle,
33909
34065
  ExternalDropZone,
33910
34066
  IxoEditor,
33911
34067
  DebugButton,
34068
+ PageHeader,
33912
34069
  EvaluationTab,
33913
34070
  EntitySigningSetup,
33914
34071
  FlowPermissionsPanel,
@@ -33926,4 +34083,4 @@ export {
33926
34083
  getExtraSlashMenuItems,
33927
34084
  useCreateIxoEditor
33928
34085
  };
33929
- //# sourceMappingURL=chunk-UWTEHXWI.mjs.map
34086
+ //# sourceMappingURL=chunk-FM2G22RS.mjs.map