alinea 2.0.0-preview.12 → 2.0.0-preview.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (264) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/.mcp/later/dev.json +1 -1
  3. package/dist/.mcp/online/dev.json +1 -1
  4. package/dist/adapter/next/cms.js +16 -8
  5. package/dist/adapter/next/dashboardUrl.d.ts +6 -0
  6. package/dist/adapter/next/dashboardUrl.js +13 -0
  7. package/dist/adapter/next/syncCheck.d.ts +15 -2
  8. package/dist/adapter/next/syncCheck.js +26 -9
  9. package/dist/backend/Handler.js +5 -1
  10. package/dist/backend/api/BlobStore.d.ts +21 -0
  11. package/dist/backend/api/BlobStore.js +63 -0
  12. package/dist/backend/api/CreateBackend.js +10 -8
  13. package/dist/backend/api/DatabaseApi.d.ts +4 -1
  14. package/dist/backend/api/DatabaseApi.js +88 -4
  15. package/dist/backend/api/GithubApi.js +47 -24
  16. package/dist/backend/api/database.js +6 -6
  17. package/dist/bundled.d.ts +676 -280
  18. package/dist/chunks/{bun-sqlite-5SHXN3AT.js → bun-sqlite-RI6BYU5S.js} +3 -3
  19. package/dist/chunks/{chunk-OHGAVV4G.js → chunk-3QFSGTGF.js} +2 -3
  20. package/dist/chunks/{chunk-QJGGYF6E.js → chunk-4ZA6KZHS.js} +5 -5
  21. package/dist/chunks/{chunk-ASYKC6IE.js → chunk-5H4D5JQL.js} +1 -1
  22. package/dist/chunks/{chunk-ETWOY4AL.js → chunk-A2I6MCCS.js} +1 -1
  23. package/dist/chunks/{chunk-W5AXN7GH.js → chunk-CYVOGRSD.js} +1 -2
  24. package/dist/chunks/{chunk-TIJTT5ZI.js → chunk-G43W7AME.js} +1 -0
  25. package/dist/chunks/{chunk-RE523BQ7.js → chunk-HOETF6HN.js} +5829 -5830
  26. package/dist/chunks/{chunk-AIU6CMVT.js → chunk-PTYZMV5G.js} +1 -1
  27. package/dist/chunks/{chunk-JOF663EG.js → chunk-QHHMKJUO.js} +1 -1
  28. package/dist/chunks/{chunk-66YZ47TY.js → chunk-RAR44T5O.js} +1 -1
  29. package/dist/chunks/{chunk-QSN6RH6X.js → chunk-VA6NC3MI.js} +1 -1
  30. package/dist/chunks/{node-sqlite-XVNTNMCY.js → node-sqlite-C7VJ2NSN.js} +3 -3
  31. package/dist/cli/Mcp.js +1 -1
  32. package/dist/cli/Serve.js +1 -1
  33. package/dist/cli/bin.js +2 -3
  34. package/dist/cli/serve/mcp/DevMcp.js +1 -1
  35. package/dist/cli/serve/mcp/McpTools.js +29 -1
  36. package/dist/cloud/CloudRemote.js +1 -1
  37. package/dist/components/Alert.js +2 -2
  38. package/dist/components/AppShell.js +2 -2
  39. package/dist/components/Badge.d.ts +3 -1
  40. package/dist/components/Badge.js +5 -3
  41. package/dist/components/Breadcrumbs.js +7 -7
  42. package/dist/components/Button.d.ts +6 -1
  43. package/dist/components/Button.js +16 -7
  44. package/dist/components/Calendar.js +20 -20
  45. package/dist/components/Checkbox.js +7 -7
  46. package/dist/components/CheckboxGroup.js +4 -4
  47. package/dist/components/Code.js +2 -2
  48. package/dist/components/Collapsible.js +3 -3
  49. package/dist/components/ColorSwatch.js +2 -2
  50. package/dist/components/ColorSwatchPicker.js +2 -2
  51. package/dist/components/ComboBox.js +7 -7
  52. package/dist/components/Command.js +14 -13
  53. package/dist/components/ContentCard.d.ts +3 -1
  54. package/dist/components/ContentCard.js +46 -24
  55. package/dist/components/ContentGrid.js +17 -17
  56. package/dist/components/DataList.js +2 -2
  57. package/dist/components/DateField.js +2 -2
  58. package/dist/components/DatePicker.js +2 -2
  59. package/dist/components/DateRangePicker.js +2 -2
  60. package/dist/components/Dialog.js +7 -7
  61. package/dist/components/DropZone.js +6 -6
  62. package/dist/components/DropdownMenu.js +9 -9
  63. package/dist/components/Empty.js +5 -5
  64. package/dist/components/Field.js +8 -8
  65. package/dist/components/List.js +27 -27
  66. package/dist/components/MediaPreview.js +5 -5
  67. package/dist/components/MultipleSelect.js +22 -22
  68. package/dist/components/NavRail.js +4 -4
  69. package/dist/components/NumberField.js +4 -4
  70. package/dist/components/Page.js +3 -3
  71. package/dist/components/Popover.js +2 -2
  72. package/dist/components/PreviewFrame.js +9 -9
  73. package/dist/components/RadioGroup.js +9 -9
  74. package/dist/components/Resizable.js +4 -4
  75. package/dist/components/SearchField.d.ts +6 -1
  76. package/dist/components/SearchField.js +5 -3
  77. package/dist/components/Select.js +13 -13
  78. package/dist/components/Sheet.d.ts +50 -0
  79. package/dist/components/Sheet.js +202 -0
  80. package/dist/components/Sidebar.js +4 -4
  81. package/dist/components/SortableList.d.ts +34 -30
  82. package/dist/components/SortableList.js +161 -264
  83. package/dist/components/Spinner.js +2 -2
  84. package/dist/components/Surface.js +2 -2
  85. package/dist/components/Switch.js +8 -8
  86. package/dist/components/Table.d.ts +3 -1
  87. package/dist/components/Table.js +57 -46
  88. package/dist/components/Tabs.js +5 -5
  89. package/dist/components/TagGroup.js +8 -8
  90. package/dist/components/TextField.js +10 -10
  91. package/dist/components/TimeField.js +6 -6
  92. package/dist/components/Timestamp.js +1 -1
  93. package/dist/components/ToggleGroup.js +2 -2
  94. package/dist/components/Toolbar.js +2 -2
  95. package/dist/components/Tooltip.js +5 -5
  96. package/dist/components/Tree.js +24 -24
  97. package/dist/components/internal/DateControl.js +12 -12
  98. package/dist/components/internal/ListBoxOption.js +6 -6
  99. package/dist/components/internal/Locale.js +2 -2
  100. package/dist/components/internal/PopoverSurface.js +4 -4
  101. package/dist/components/internal/SelectionCheckbox.js +5 -5
  102. package/dist/components/internal/Slot.js +1 -1
  103. package/dist/components/internal/ToggleButton.js +3 -3
  104. package/dist/components/internal/Trigger.js +2 -2
  105. package/dist/components/internal/sortableDrag.d.ts +19 -0
  106. package/dist/components/internal/sortableDrag.js +175 -0
  107. package/dist/components/internal/useDragDrop.js +2 -2
  108. package/dist/components.d.ts +1 -0
  109. package/dist/components.js +1 -0
  110. package/dist/core/Config.d.ts +6 -1
  111. package/dist/core/Document.d.ts +9 -1
  112. package/dist/core/Document.js +31 -6
  113. package/dist/core/Overview.d.ts +2 -4
  114. package/dist/core/TextDoc.d.ts +4 -0
  115. package/dist/core/Validation.d.ts +0 -1
  116. package/dist/core/Validation.js +0 -6
  117. package/dist/core/field/RichTextField.js +23 -4
  118. package/dist/core/media/MediaTypes.js +1 -1
  119. package/dist/core/source/GithubSource.d.ts +4 -0
  120. package/dist/core/source/GithubSource.js +127 -25
  121. package/dist/core/source/GithubUsage.d.ts +21 -0
  122. package/dist/core/source/GithubUsage.js +47 -0
  123. package/dist/dashboard/App.d.ts +2 -2
  124. package/dist/dashboard/App.js +5 -3
  125. package/dist/dashboard/ViewKeys.d.ts +1 -0
  126. package/dist/dashboard/ViewKeys.js +1 -0
  127. package/dist/dashboard/app/ActivityStatus.js +7 -7
  128. package/dist/dashboard/app/AuthView.js +5 -5
  129. package/dist/dashboard/app/BlockSheet.d.ts +50 -0
  130. package/dist/dashboard/app/BlockSheet.js +207 -0
  131. package/dist/dashboard/app/BlockSheetStoryFrame.d.ts +6 -0
  132. package/dist/dashboard/app/BlockSheetStoryFrame.js +29 -0
  133. package/dist/dashboard/app/CompactField.js +16 -16
  134. package/dist/dashboard/app/DashboardLayout.js +3 -1
  135. package/dist/dashboard/app/EntryFields.js +2 -2
  136. package/dist/dashboard/app/EntryHeader.js +33 -34
  137. package/dist/dashboard/app/EntryReferences.js +7 -7
  138. package/dist/dashboard/app/EntrySidebar.js +15 -15
  139. package/dist/dashboard/app/EntrySidebarPreview.js +3 -3
  140. package/dist/dashboard/app/EntryStatusIcon.d.ts +23 -0
  141. package/dist/dashboard/app/EntryStatusIcon.js +58 -0
  142. package/dist/dashboard/app/EntryValidationModal.d.ts +6 -5
  143. package/dist/dashboard/app/EntryValidationModal.js +20 -20
  144. package/dist/dashboard/app/Explorer.d.ts +3 -1
  145. package/dist/dashboard/app/Explorer.js +48 -44
  146. package/dist/dashboard/app/ExplorerBatchActions.d.ts +3 -1
  147. package/dist/dashboard/app/ExplorerBatchActions.js +68 -43
  148. package/dist/dashboard/app/ExplorerCards.js +7 -1
  149. package/dist/dashboard/app/ExplorerControls.js +6 -6
  150. package/dist/dashboard/app/ExplorerList.js +5 -5
  151. package/dist/dashboard/app/ExplorerModal.js +2 -2
  152. package/dist/dashboard/app/ExplorerTable.js +11 -8
  153. package/dist/dashboard/app/ImageEditor.js +28 -28
  154. package/dist/dashboard/app/ImagePicker.js +3 -13
  155. package/dist/dashboard/app/LinkPicker.js +28 -26
  156. package/dist/dashboard/app/LocaleMenu.js +4 -4
  157. package/dist/dashboard/app/MediaPreviewCell.js +1 -1
  158. package/dist/dashboard/app/MoveConfirmDialog.d.ts +5 -0
  159. package/dist/dashboard/app/MoveConfirmDialog.js +79 -0
  160. package/dist/dashboard/app/OverviewCell.js +8 -13
  161. package/dist/dashboard/app/PendingUploadsView.js +3 -3
  162. package/dist/dashboard/app/ReadOnlyBadge.d.ts +1 -1
  163. package/dist/dashboard/app/RemoveDialog.d.ts +17 -0
  164. package/dist/dashboard/app/{DeleteDialog.js → RemoveDialog.js} +67 -27
  165. package/dist/dashboard/app/RemoveRedirect.d.ts +7 -0
  166. package/dist/dashboard/app/RemoveRedirect.js +123 -0
  167. package/dist/dashboard/app/SearchBar.d.ts +9 -0
  168. package/dist/dashboard/app/SearchBar.js +31 -0
  169. package/dist/dashboard/app/SidebarTree.js +27 -72
  170. package/dist/dashboard/app/WorkspaceMenu.js +7 -7
  171. package/dist/dashboard/app/WorkspaceRoots.js +12 -12
  172. package/dist/dashboard/app/editor/FileEditor.js +14 -14
  173. package/dist/dashboard/app/modals/CreateEntry.js +3 -3
  174. package/dist/dashboard/app/pages/EntryPage.d.ts +2 -1
  175. package/dist/dashboard/app/pages/EntryPage.js +34 -15
  176. package/dist/dashboard/app/pages/SplashPage.js +37 -37
  177. package/dist/dashboard/app/pages/UsersPage.js +12 -12
  178. package/dist/dashboard/app/ui/DashboardModal.js +15 -14
  179. package/dist/dashboard/atoms/dashboard.js +1 -1
  180. package/dist/dashboard/atoms/entry.js +1 -14
  181. package/dist/dashboard/atoms/entryTable.js +1 -0
  182. package/dist/dashboard/atoms/explorer.d.ts +4 -0
  183. package/dist/dashboard/atoms/explorer.js +19 -7
  184. package/dist/dashboard/atoms/graph.js +1 -1
  185. package/dist/dashboard/atoms/link.js +5 -2
  186. package/dist/dashboard/atoms/move.d.ts +5 -0
  187. package/dist/dashboard/atoms/move.js +29 -3
  188. package/dist/dashboard/atoms/moveConfirmation.d.ts +34 -0
  189. package/dist/dashboard/atoms/moveConfirmation.js +95 -0
  190. package/dist/dashboard/atoms/nav.d.ts +9 -5
  191. package/dist/dashboard/atoms/nav.js +120 -45
  192. package/dist/dashboard/atoms/overview.d.ts +6 -5
  193. package/dist/dashboard/atoms/overview.js +2 -16
  194. package/dist/dashboard/atoms/remove.d.ts +112 -0
  195. package/dist/dashboard/atoms/remove.js +268 -0
  196. package/dist/dashboard/atoms/root.d.ts +2 -2
  197. package/dist/dashboard/atoms/root.js +41 -26
  198. package/dist/dashboard/atoms/user.js +1 -1
  199. package/dist/dashboard/atoms/utils.js +1 -1
  200. package/dist/dashboard/boot/Boot.js +25 -17
  201. package/dist/dashboard/boot/DashboardWorker.d.ts +1 -0
  202. package/dist/dashboard/boot/DashboardWorker.js +10 -46
  203. package/dist/dashboard/boot/LoadWorker.js +17 -10
  204. package/dist/dashboard/cms/EntryTable.js +8 -5
  205. package/dist/database/BrowserEntryStore.d.ts +12 -62
  206. package/dist/database/BrowserEntryStore.js +97 -196
  207. package/dist/database/DatabaseTables.js +2 -2
  208. package/dist/database/EntryDatabase.js +21 -1
  209. package/dist/database/EntryTransaction.js +0 -35
  210. package/dist/database/EntryUrlAliases.d.ts +4 -0
  211. package/dist/database/EntryUrlAliases.js +16 -10
  212. package/dist/database/driver/RuntimeDatabase.js +3 -3
  213. package/dist/database/driver/WasmDatabase.d.ts +5 -18
  214. package/dist/database/driver/WasmDatabase.js +15 -16
  215. package/dist/database/entry/EntryTable.js +2 -2
  216. package/dist/database/query/EntryQuery.js +1 -1
  217. package/dist/database/query/Relation.js +1 -1
  218. package/dist/database/query/Search.js +2 -2
  219. package/dist/field/code/CodeField.view.js +16 -16
  220. package/dist/field/link/EntryLink.d.ts +4 -4
  221. package/dist/field/link/FileLink.d.ts +4 -4
  222. package/dist/field/link/ImageLink.d.ts +4 -4
  223. package/dist/field/link/Link.d.ts +1 -1
  224. package/dist/field/link/LinkField.d.ts +5 -0
  225. package/dist/field/link/LinkField.view.js +244 -370
  226. package/dist/field/link/UrlLink.d.ts +4 -4
  227. package/dist/field/list/ListField.d.ts +2 -0
  228. package/dist/field/list/ListField.view.d.ts +15 -0
  229. package/dist/field/list/ListField.view.js +343 -301
  230. package/dist/field/metadata/MetadataField.d.ts +17 -7
  231. package/dist/field/metadata/MetadataField.js +14 -3
  232. package/dist/field/metadata/MetadataField.view.d.ts +1 -0
  233. package/dist/field/metadata/MetadataField.view.js +25 -21
  234. package/dist/field/richtext/RichTextBlock.d.ts +3 -1
  235. package/dist/field/richtext/RichTextBlock.js +177 -74
  236. package/dist/field/richtext/RichTextBlockHost.js +1 -1
  237. package/dist/field/richtext/RichTextExtensions.js +31 -31
  238. package/dist/field/richtext/RichTextField.view.js +14 -8
  239. package/dist/field/richtext/RichTextInsertMenu.js +43 -27
  240. package/dist/field/views.js +2 -0
  241. package/dist/index.css +490 -309
  242. package/dist/picker/url/UrlPicker.js +1 -0
  243. package/docs/components/badge.md +1 -0
  244. package/docs/components/button.md +1 -0
  245. package/docs/components/content-card.md +1 -0
  246. package/docs/components/search-field.md +1 -0
  247. package/docs/components/sortable-list.md +5 -20
  248. package/docs/components/table.md +1 -0
  249. package/docs/configuration.md +1 -1
  250. package/docs/deploy/self-host.md +1 -1
  251. package/docs/deploy.md +5 -4
  252. package/docs/fields.md +1 -1
  253. package/docs/index.md +1 -1
  254. package/docs/instant-publishing.md +7 -22
  255. package/docs/overviews.md +3 -4
  256. package/docs/upgrading.md +3 -2
  257. package/llms-full.txt +31 -55
  258. package/package.json +2 -3
  259. package/dist/core/db/EntryValidationError.d.ts +0 -13
  260. package/dist/core/db/EntryValidationError.js +0 -23
  261. package/dist/dashboard/app/DeleteDialog.d.ts +0 -11
  262. package/dist/dashboard/atoms/delete.d.ts +0 -68
  263. package/dist/dashboard/atoms/delete.js +0 -143
  264. package/dist/chunks/{chunk-MOWR65LM.js → chunk-PYDOMKJZ.js} +71 -71
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  unwrap
3
- } from "../../chunks/chunk-TIJTT5ZI.js";
3
+ } from "../../chunks/chunk-G43W7AME.js";
4
4
  import {
5
5
  useAtomValueRaw,
6
6
  useAtomValueRawSync,
@@ -23,25 +23,31 @@ import {
23
23
  Icon,
24
24
  SortableList,
25
25
  SortableListItemTitle,
26
+ SortableListItemTrigger,
27
+ SortableListItemInsert,
28
+ SortableListItemSettings,
26
29
  SortableListAdd,
27
- SortableListDragPreview,
28
30
  ListError,
29
31
  ListLabel,
30
32
  SortableListItem,
31
33
  SortableListItemActions,
32
34
  SortableListItemContent,
33
35
  SortableListItemDescription,
34
- SortableListHandle,
35
36
  SortableListItemToggle,
36
37
  SortableListItemFooter,
37
38
  SortableListItemHeader,
38
- SortableListItemSettings,
39
39
  Popover,
40
40
  PopoverAnchor,
41
41
  PopoverContent,
42
- PopoverTrigger,
43
42
  Select,
44
43
  SelectItem,
44
+ SheetBody,
45
+ SheetClose,
46
+ SheetContent,
47
+ SheetFooter,
48
+ SheetHeader,
49
+ SheetSection,
50
+ SheetTitle,
45
51
  TextField
46
52
  } from "alinea/components";
47
53
  import { Config } from "alinea/core/Config";
@@ -51,6 +57,10 @@ import { Reference } from "alinea/core/Reference";
51
57
  import { Root } from "alinea/core/Root";
52
58
  import { Type } from "alinea/core/Type";
53
59
  import { Badge } from "alinea/components";
60
+ import {
61
+ BlockSheet,
62
+ useBlockSheet
63
+ } from "alinea/dashboard/app/BlockSheet";
54
64
  import { CompactRecordFields } from "alinea/dashboard/app/CompactField";
55
65
  import { NodeEditor } from "alinea/dashboard/app/NodeEditor";
56
66
  import { configAtom, graphAtom } from "alinea/dashboard/atoms/core";
@@ -77,9 +87,9 @@ import {
77
87
  IcRoundAttachFile,
78
88
  IcRoundAdd,
79
89
  IcRoundClose,
90
+ IcRoundDelete,
80
91
  IcRoundEdit,
81
92
  IcRoundLink,
82
- IcRoundMoreHoriz,
83
93
  IcRoundOpenInNew,
84
94
  IcRoundPanorama
85
95
  } from "alinea/dashboard/icons";
@@ -87,67 +97,33 @@ import { useId, useMemo, useRef, useState } from "react";
87
97
 
88
98
  // src/field/link/LinkField.module.css
89
99
  var LinkField_default = {
90
- "LinkFieldView-inputHeader": "alinea-LinkFieldView-inputHeader",
91
- "LinkFieldViewInputHeader": "alinea-LinkFieldView-inputHeader",
92
- "LinkFieldView-skeleton": "alinea-LinkFieldView-skeleton",
93
- "LinkFieldViewSkeleton": "alinea-LinkFieldView-skeleton",
100
+ "LinkFieldView-previewImagePlaceholder": "alinea-LinkFieldView-previewImagePlaceholder",
101
+ "LinkFieldViewPreviewImagePlaceholder": "alinea-LinkFieldView-previewImagePlaceholder",
102
+ "LinkFieldView-previewImage": "alinea-LinkFieldView-previewImage",
103
+ "LinkFieldViewPreviewImage": "alinea-LinkFieldView-previewImage",
104
+ "LinkFieldView-anchorOption-label": "alinea-LinkFieldView-anchorOption-label",
105
+ "LinkFieldViewAnchorOptionLabel": "alinea-LinkFieldView-anchorOption-label",
94
106
  "LinkFieldView-metaLabel": "alinea-LinkFieldView-metaLabel",
95
107
  "LinkFieldViewMetaLabel": "alinea-LinkFieldView-metaLabel",
96
108
  "LinkFieldView-anchorOption-location": "alinea-LinkFieldView-anchorOption-location",
97
109
  "LinkFieldViewAnchorOptionLocation": "alinea-LinkFieldView-anchorOption-location",
98
- "is-wide": "alinea-is-wide",
99
- "isWide": "alinea-is-wide",
100
- "LinkFieldView-settingsSeparator": "alinea-LinkFieldView-settingsSeparator",
101
- "LinkFieldViewSettingsSeparator": "alinea-LinkFieldView-settingsSeparator",
102
- "LinkFieldView-label": "alinea-LinkFieldView-label",
103
- "LinkFieldViewLabel": "alinea-LinkFieldView-label",
104
- "is-missing": "alinea-is-missing",
105
- "isMissing": "alinea-is-missing",
106
- "LinkFieldView-image": "alinea-LinkFieldView-image",
107
- "LinkFieldViewImage": "alinea-LinkFieldView-image",
108
- "LinkFieldView-rowAction": "alinea-LinkFieldView-rowAction",
109
- "LinkFieldViewRowAction": "alinea-LinkFieldView-rowAction",
110
- "LinkFieldView-labelText": "alinea-LinkFieldView-labelText",
111
- "LinkFieldViewLabelText": "alinea-LinkFieldView-labelText",
112
- "LinkFieldView-meta": "alinea-LinkFieldView-meta",
113
- "LinkFieldViewMeta": "alinea-LinkFieldView-meta",
114
- "LinkFieldView-icon": "alinea-LinkFieldView-icon",
115
- "LinkFieldViewIcon": "alinea-LinkFieldView-icon",
116
- "LinkFieldView-type": "alinea-LinkFieldView-type",
117
- "LinkFieldViewType": "alinea-LinkFieldView-type",
118
- "is-loading": "alinea-is-loading",
119
- "isLoading": "alinea-is-loading",
120
- "LinkFieldView-previewImagePlaceholder": "alinea-LinkFieldView-previewImagePlaceholder",
121
- "LinkFieldViewPreviewImagePlaceholder": "alinea-LinkFieldView-previewImagePlaceholder",
122
110
  "LinkFieldView-skeleton-pulse": "alinea-LinkFieldView-skeleton-pulse",
123
111
  "LinkFieldViewSkeletonPulse": "alinea-LinkFieldView-skeleton-pulse",
112
+ "LinkFieldView-type": "alinea-LinkFieldView-type",
113
+ "LinkFieldViewType": "alinea-LinkFieldView-type",
124
114
  "LinkFieldView-anchorOption": "alinea-LinkFieldView-anchorOption",
125
115
  "LinkFieldViewAnchorOption": "alinea-LinkFieldView-anchorOption",
116
+ "LinkFieldView-icon": "alinea-LinkFieldView-icon",
117
+ "LinkFieldViewIcon": "alinea-LinkFieldView-icon",
126
118
  "LinkFieldView-create": "alinea-LinkFieldView-create",
127
119
  "LinkFieldViewCreate": "alinea-LinkFieldView-create",
128
120
  "LinkFieldView-createButton": "alinea-LinkFieldView-createButton",
129
- "LinkFieldViewCreateButton": "alinea-LinkFieldView-createButton",
130
- "LinkFieldView-imagePlaceholder": "alinea-LinkFieldView-imagePlaceholder",
131
- "LinkFieldViewImagePlaceholder": "alinea-LinkFieldView-imagePlaceholder",
132
- "LinkFieldView-anchorOption-label": "alinea-LinkFieldView-anchorOption-label",
133
- "LinkFieldViewAnchorOptionLabel": "alinea-LinkFieldView-anchorOption-label",
134
- "LinkFieldView-previewImage": "alinea-LinkFieldView-previewImage",
135
- "LinkFieldViewPreviewImage": "alinea-LinkFieldView-previewImage",
136
- "LinkFieldView-title": "alinea-LinkFieldView-title",
137
- "LinkFieldViewTitle": "alinea-LinkFieldView-title"
121
+ "LinkFieldViewCreateButton": "alinea-LinkFieldView-createButton"
138
122
  };
139
123
 
140
124
  // src/field/link/LinkField.view.tsx
141
125
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
142
126
  var styles = dist_default(LinkField_default);
143
- var LINK_FIELD_ROW_DRAG_TYPE = "application/x-alinea-link-field-row";
144
- function LinkRowText({ node }) {
145
- const type = useAtomValueRaw(node.field("_type"));
146
- if (type === "entry" || type === "image" || type === "file")
147
- return /* @__PURE__ */ jsx(EntryRowLayer, { node, textOnly: true });
148
- if (type === "url") return /* @__PURE__ */ jsx(UrlRow, { node, textOnly: true });
149
- return null;
150
- }
151
127
  function isPickerType(type) {
152
128
  return type === "entry" || type === "url" || type === "file" || type === "image";
153
129
  }
@@ -162,156 +138,11 @@ function getPickerType(type) {
162
138
  function getEntryPickerType(type) {
163
139
  return type === "url" ? "entry" : type;
164
140
  }
165
- function EntryRowLayer({ hasFields, node, textOnly }) {
166
- const entryId = useAtomValueRaw(node.field("_entry"));
167
- const locale = useAtomValueRaw(node.field("_locale"));
168
- const type = useAtomValueRaw(node.field("_type"));
169
- if (!entryId) return null;
170
- return /* @__PURE__ */ jsx(
171
- EntryRow,
172
- {
173
- entryId,
174
- locale,
175
- hasFields,
176
- image: type === "image",
177
- textOnly
178
- }
179
- );
180
- }
181
- function EntryRow({
182
- entryId,
183
- locale,
184
- hasFields,
185
- image,
186
- textOnly
187
- }) {
188
- const state = useLinkEntryState(entryId, locale);
189
- if (state.state === "hasData" && state.data)
190
- return /* @__PURE__ */ jsx(
191
- LoadedEntryRow,
192
- {
193
- entry: state.data,
194
- hasFields,
195
- image,
196
- textOnly
197
- }
198
- );
199
- if (state.state !== "loading")
200
- return /* @__PURE__ */ jsx(
201
- MissingEntryRow,
202
- {
203
- entryId,
204
- hasFields,
205
- image,
206
- textOnly
207
- }
208
- );
209
- return /* @__PURE__ */ jsx(
210
- EntryLoadingRow,
211
- {
212
- hasFields,
213
- image,
214
- pending: true,
215
- textOnly
216
- }
217
- );
218
- }
219
141
  function useLinkEntryState(entryId, locale) {
220
142
  const scope = useOptionalEntryAtoms();
221
143
  const linkLocale = locale ?? scope?.localeData.requestedLocale ?? void 0;
222
144
  return useAtomValueRawSync(linkEntryAtoms(entryId, linkLocale));
223
145
  }
224
- function MissingEntryRow({
225
- entryId,
226
- hasFields,
227
- image,
228
- textOnly
229
- }) {
230
- return /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.label({ missing: true }), children: [
231
- image && !textOnly && /* @__PURE__ */ jsx(
232
- "span",
233
- {
234
- className: styles.LinkFieldView.imagePlaceholder(),
235
- "data-has-fields": hasFields ? "true" : void 0,
236
- "aria-hidden": "true"
237
- }
238
- ),
239
- /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.labelText(), children: [
240
- /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.title(), children: "Missing entry" }),
241
- !textOnly && /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.meta(), children: entryId })
242
- ] })
243
- ] });
244
- }
245
- function EntryLoadingRow({
246
- hasFields,
247
- image,
248
- pending,
249
- textOnly
250
- }) {
251
- return /* @__PURE__ */ jsxs(
252
- "span",
253
- {
254
- className: styles.LinkFieldView.label({ loading: true }),
255
- "aria-busy": pending || void 0,
256
- children: [
257
- image && !textOnly && /* @__PURE__ */ jsx(
258
- "span",
259
- {
260
- className: styles.LinkFieldView.imagePlaceholder(),
261
- "data-has-fields": hasFields ? "true" : void 0,
262
- "aria-hidden": "true"
263
- }
264
- ),
265
- /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.labelText(), children: [
266
- /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.skeleton({ wide: true }) }),
267
- /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.skeleton() })
268
- ] })
269
- ]
270
- }
271
- );
272
- }
273
- function LoadedEntryRow({
274
- entry,
275
- hasFields,
276
- image,
277
- textOnly
278
- }) {
279
- return /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.label(), children: [
280
- image && !textOnly && /* @__PURE__ */ jsx(EntryRowImage, { entry, hasFields }),
281
- /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.labelText(), children: [
282
- /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.title(), children: entry.title }),
283
- entry.parents.length > 0 ? /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.meta(), children: /* @__PURE__ */ jsx(EntryParents, { parents: entry.parents }) }) : null
284
- ] })
285
- ] });
286
- }
287
- function EntryRowImage({ entry, hasFields }) {
288
- if (entry.preview) {
289
- return /* @__PURE__ */ jsx(
290
- "img",
291
- {
292
- alt: "",
293
- className: styles.LinkFieldView.image(),
294
- "data-has-fields": hasFields ? "true" : void 0,
295
- src: entry.preview
296
- }
297
- );
298
- }
299
- return null;
300
- }
301
- function UrlRow({ node, textOnly }) {
302
- const title = useAtomValueRaw(node.field("_title"));
303
- const url = useAtomValueRaw(node.field("_url"));
304
- return /* @__PURE__ */ jsxs("span", { className: styles.LinkFieldView.label(), children: [
305
- /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.title(), children: textOnly ? title || url : title || url }),
306
- !textOnly && title && url && /* @__PURE__ */ jsx("span", { className: styles.LinkFieldView.meta(), children: url })
307
- ] });
308
- }
309
- function EntryParents({ parents }) {
310
- return /* @__PURE__ */ jsx(Fragment, { children: parents.map((parent, index) => /* @__PURE__ */ jsxs("span", { children: [
311
- parent.title,
312
- index < parents.length - 1 ? " / " : ""
313
- ] }, parent.id)) });
314
- }
315
146
  function getLinkIcon(type) {
316
147
  if (type === "url") return IcRoundOpenInNew;
317
148
  if (type === "file") return IcRoundAttachFile;
@@ -740,6 +571,7 @@ function LinkRowActions({
740
571
  {
741
572
  "aria-label": "Replace link",
742
573
  variant: "ghost",
574
+ size: "sm",
743
575
  icon: IcRoundEdit,
744
576
  disabled: isDisabled,
745
577
  onClick: () => {
@@ -770,6 +602,7 @@ function LinkLabelField({ isDisabled, node, value }) {
770
602
  ResolvedLinkLabelField,
771
603
  {
772
604
  customLabel,
605
+ fallbackLabel: "_title" in value ? value._title : void 0,
773
606
  isDisabled,
774
607
  onChange: setCustomLabel
775
608
  }
@@ -849,60 +682,46 @@ function EntryAnchorFieldInner({
849
682
  );
850
683
  }
851
684
  function LinkMetaLabel({ className, node, value }) {
685
+ return /* @__PURE__ */ jsx(LinkLabel, { node, value, children: (label) => label && /* @__PURE__ */ jsx(SortableListItemDescription, { className, children: label }) });
686
+ }
687
+ function LinkLabel({ node, value, children }) {
852
688
  const customLabel = useAtomValueRaw(node.field("_label"));
853
- if ("_entry" in value) {
689
+ if ("_entry" in value)
854
690
  return /* @__PURE__ */ jsx(
855
- EntryLinkMetaLabel,
691
+ EntryLinkLabel,
856
692
  {
857
- className,
858
693
  customLabel,
859
694
  entryId: value._entry,
860
- locale: value._locale
695
+ locale: value._locale,
696
+ children
861
697
  }
862
698
  );
863
- }
864
- return /* @__PURE__ */ jsx(
865
- ResolvedLinkMetaLabel,
866
- {
867
- className,
868
- label: customLabel || linkFallbackLabel(value)
869
- }
870
- );
699
+ return children(trimmed(customLabel || linkFallbackLabel(value)));
871
700
  }
872
701
  function linkFallbackLabel(value) {
873
702
  if ("_title" in value && value._title) return value._title;
874
703
  if ("_url" in value && value._url) return value._url;
875
704
  return void 0;
876
705
  }
877
- function EntryLinkMetaLabel({
878
- className,
706
+ function trimmed(label) {
707
+ return label?.trim() || void 0;
708
+ }
709
+ function EntryLinkLabel({
879
710
  customLabel,
880
711
  entryId,
881
- locale
712
+ locale,
713
+ children
882
714
  }) {
883
715
  const state = useLinkEntryState(entryId, locale);
884
- if (state.state !== "hasData" || !state.data) {
885
- return /* @__PURE__ */ jsx(ResolvedLinkMetaLabel, { className, label: customLabel });
886
- }
887
- return /* @__PURE__ */ jsx(
888
- ResolvedLinkMetaLabel,
889
- {
890
- className,
891
- label: customLabel ?? state.data.title
892
- }
893
- );
894
- }
895
- function ResolvedLinkMetaLabel({ className, label }) {
896
- const value = label?.trim();
897
- if (!value) return null;
898
- return /* @__PURE__ */ jsx(SortableListItemDescription, { className, children: value });
716
+ const title = state.state === "hasData" ? state.data?.title : void 0;
717
+ return children(trimmed(customLabel ?? title));
899
718
  }
900
719
  function LinkTypeBadge({ picker, type, value, ...props }) {
901
720
  const fallbackIcon = getLinkIcon(type);
902
721
  const fallbackLabel = picker?.label ?? type;
903
722
  if (type === "image") return null;
904
723
  if (type === "file") {
905
- return /* @__PURE__ */ jsx(Badge, { ...props, icon: IcRoundAttachFile, size: "sm", children: "File" });
724
+ return /* @__PURE__ */ jsx(Badge, { ...props, icon: IcRoundAttachFile, size: "sm", color: "primary", children: "File" });
906
725
  }
907
726
  if ("_entry" in value) {
908
727
  return /* @__PURE__ */ jsx(
@@ -916,7 +735,7 @@ function LinkTypeBadge({ picker, type, value, ...props }) {
916
735
  }
917
736
  );
918
737
  }
919
- return /* @__PURE__ */ jsx(Badge, { ...props, icon: fallbackIcon, size: "sm", children: fallbackLabel });
738
+ return /* @__PURE__ */ jsx(Badge, { ...props, icon: fallbackIcon, size: "sm", color: "primary", children: fallbackLabel });
920
739
  }
921
740
  function EntryLinkImagePreview({ entryId }) {
922
741
  const state = useLinkEntryState(entryId);
@@ -943,7 +762,7 @@ function EntryLinkTypeBadge({
943
762
  const entry = state.state === "hasData" ? state.data : void 0;
944
763
  const type = entry ? config.schema[entry.type] : void 0;
945
764
  if (!type) {
946
- return /* @__PURE__ */ jsx(Badge, { ...props, icon: fallbackIcon, size: "sm", children: fallbackLabel });
765
+ return /* @__PURE__ */ jsx(Badge, { ...props, icon: fallbackIcon, size: "sm", color: "primary", children: fallbackLabel });
947
766
  }
948
767
  return /* @__PURE__ */ jsx(
949
768
  Badge,
@@ -954,6 +773,7 @@ function EntryLinkTypeBadge({
954
773
  ),
955
774
  icon: getType(type).icon || IcRoundLink,
956
775
  size: "sm",
776
+ color: "primary",
957
777
  children: Type.label(type)
958
778
  }
959
779
  );
@@ -985,7 +805,6 @@ function ResolvedLinkLabelField({
985
805
  return /* @__PURE__ */ jsx(
986
806
  TextField,
987
807
  {
988
- autoFocus: true,
989
808
  disabled: isDisabled,
990
809
  label: "Label",
991
810
  onValueChange: onChange,
@@ -993,17 +812,6 @@ function ResolvedLinkLabelField({
993
812
  }
994
813
  );
995
814
  }
996
- function LinkSettingsButton() {
997
- return /* @__PURE__ */ jsx(
998
- PopoverTrigger,
999
- {
1000
- variant: "ghost",
1001
- "aria-label": "Link settings",
1002
- icon: IcRoundMoreHoriz,
1003
- size: "icon-sm"
1004
- }
1005
- );
1006
- }
1007
815
  function LinkRowReferenceActions({
1008
816
  closeActions,
1009
817
  type,
@@ -1030,6 +838,7 @@ function UrlLinkRowAction({ closeActions, url }) {
1030
838
  {
1031
839
  "aria-label": "Open link",
1032
840
  variant: "ghost",
841
+ size: "sm",
1033
842
  icon: IcRoundOpenInNew,
1034
843
  disabled: !href,
1035
844
  onClick: () => {
@@ -1060,6 +869,7 @@ function EntryLinkRowActions({
1060
869
  {
1061
870
  "aria-label": "Open link",
1062
871
  variant: "ghost",
872
+ size: "sm",
1063
873
  icon: IcRoundOpenInNew,
1064
874
  disabled: true,
1065
875
  children: "Open link"
@@ -1075,6 +885,7 @@ function EntryLinkRowActions({
1075
885
  {
1076
886
  "aria-label": "Open link",
1077
887
  variant: "ghost",
888
+ size: "sm",
1078
889
  icon: IcRoundOpenInNew,
1079
890
  onClick: () => {
1080
891
  window.open(href, "_blank", "noopener,noreferrer");
@@ -1084,37 +895,20 @@ function EntryLinkRowActions({
1084
895
  }
1085
896
  );
1086
897
  }
1087
- function useLinkRowSettings() {
1088
- const rowRef = useRef(null);
1089
- const [open, setOpen] = useState(false);
1090
- const [anchoredToRow, setAnchoredToRow] = useState(false);
1091
- return {
1092
- rowRef,
1093
- open,
1094
- anchoredToRow,
1095
- openFromRow() {
1096
- setAnchoredToRow(true);
1097
- setOpen(true);
1098
- },
1099
- onOpenChange(open2) {
1100
- if (open2) setAnchoredToRow(false);
1101
- setOpen(open2);
1102
- },
1103
- close() {
1104
- setOpen(false);
1105
- }
1106
- };
1107
- }
1108
- function LinkRowButton({ children, settings }) {
898
+ function LinkRowButton({ children, sheet, onEdit, onOpen }) {
1109
899
  const descriptionId = useId();
900
+ function toggleSheet() {
901
+ if (!sheet.open) onOpen?.();
902
+ sheet.toggle();
903
+ }
1110
904
  return /* @__PURE__ */ jsxs(
1111
- Button,
905
+ SortableListItemTrigger,
1112
906
  {
1113
- ref: settings.rowRef,
907
+ ...sheet.triggerProps,
1114
908
  "aria-describedby": descriptionId,
1115
- variant: "ghost",
1116
- className: styles.LinkFieldView.rowAction(),
1117
- onClick: settings.openFromRow,
909
+ "aria-expanded": sheet.available ? sheet.open : void 0,
910
+ more: sheet.available,
911
+ onClick: sheet.available ? toggleSheet : onEdit,
1118
912
  children: [
1119
913
  children,
1120
914
  /* @__PURE__ */ jsx("span", { id: descriptionId, hidden: true, children: "Edit link" })
@@ -1122,53 +916,59 @@ function LinkRowButton({ children, settings }) {
1122
916
  }
1123
917
  );
1124
918
  }
1125
- function LinkRowSettings({
919
+ function LinkSheet({
1126
920
  node,
1127
921
  onEdit,
922
+ onRemove,
1128
923
  picker,
1129
924
  readOnly,
1130
- settings,
925
+ sheet,
1131
926
  type,
1132
927
  value
1133
928
  }) {
1134
- return /* @__PURE__ */ jsxs(Popover, { open: settings.open, onOpenChange: settings.onOpenChange, children: [
1135
- /* @__PURE__ */ jsx(LinkSettingsButton, {}),
1136
- settings.anchoredToRow && /* @__PURE__ */ jsx(PopoverAnchor, { virtualRef: settings.rowRef }),
1137
- /* @__PURE__ */ jsxs(
1138
- PopoverContent,
929
+ const close = () => sheet.setOpen(false);
930
+ return /* @__PURE__ */ jsx(BlockSheet, { id: value[Reference.id], children: /* @__PURE__ */ jsxs(SheetContent, { onClose: close, children: [
931
+ /* @__PURE__ */ jsxs(SheetHeader, { children: [
932
+ /* @__PURE__ */ jsx(LinkTypeBadge, { picker, type, value }),
933
+ /* @__PURE__ */ jsx(SheetTitle, { children: /* @__PURE__ */ jsx(LinkLabel, { node, value, children: (label) => label ?? "Link" }) }),
934
+ /* @__PURE__ */ jsx(SheetClose, { "aria-label": "Close link settings" })
935
+ ] }),
936
+ /* @__PURE__ */ jsx(SheetBody, { children: /* @__PURE__ */ jsxs(SheetSection, { children: [
937
+ /* @__PURE__ */ jsx(LinkLabelField, { isDisabled: readOnly, node, value }),
938
+ /* @__PURE__ */ jsx(EntryAnchorField, { isDisabled: readOnly, node, value }),
939
+ /* @__PURE__ */ jsx(
940
+ EntryLinkSuffixField,
941
+ {
942
+ isDisabled: readOnly,
943
+ node,
944
+ value
945
+ }
946
+ )
947
+ ] }) }),
948
+ /* @__PURE__ */ jsx(SheetFooter, { children: /* @__PURE__ */ jsx(
949
+ LinkRowActions,
1139
950
  {
1140
- "aria-label": "Link settings",
1141
- side: "bottom",
1142
- align: settings.anchoredToRow ? "start" : "end",
1143
- children: [
1144
- /* @__PURE__ */ jsx(SortableListItemSettings, { variant: "actions", children: /* @__PURE__ */ jsx(
1145
- LinkRowActions,
1146
- {
1147
- closeActions: settings.close,
1148
- isDisabled: readOnly,
1149
- onEdit,
1150
- picker,
1151
- type,
1152
- value
1153
- }
1154
- ) }),
1155
- /* @__PURE__ */ jsx("hr", { className: styles.LinkFieldView.settingsSeparator() }),
1156
- /* @__PURE__ */ jsxs(SortableListItemSettings, { children: [
1157
- /* @__PURE__ */ jsx(LinkLabelField, { isDisabled: readOnly, node, value }),
1158
- /* @__PURE__ */ jsx(EntryAnchorField, { isDisabled: readOnly, node, value }),
1159
- /* @__PURE__ */ jsx(
1160
- EntryLinkSuffixField,
1161
- {
1162
- isDisabled: readOnly,
1163
- node,
1164
- value
1165
- }
1166
- )
1167
- ] })
1168
- ]
951
+ closeActions: close,
952
+ isDisabled: readOnly,
953
+ onEdit,
954
+ picker,
955
+ type,
956
+ value
1169
957
  }
1170
- )
1171
- ] });
958
+ ) }),
959
+ /* @__PURE__ */ jsx(SheetFooter, { children: /* @__PURE__ */ jsx(
960
+ Button,
961
+ {
962
+ variant: "ghost",
963
+ size: "sm",
964
+ color: "destructive",
965
+ icon: IcRoundDelete,
966
+ disabled: readOnly,
967
+ onClick: onRemove,
968
+ children: "Remove"
969
+ }
970
+ ) })
971
+ ] }) });
1172
972
  }
1173
973
  function SingleLinkRow({ field, node, value }) {
1174
974
  const [, setValue] = useField(field);
@@ -1177,7 +977,7 @@ function SingleLinkRow({ field, node, value }) {
1177
977
  const picker = options.pickers[type];
1178
978
  const hasFields = Boolean(picker?.fields);
1179
979
  const imagePreviewEntryId = type === "image" && "_entry" in value ? value._entry : void 0;
1180
- const settings = useLinkRowSettings();
980
+ const sheet = useBlockSheet(value[Reference.id]);
1181
981
  const [editOpen, setEditOpen] = useState(false);
1182
982
  function removeLink() {
1183
983
  setValue(void 0);
@@ -1204,35 +1004,35 @@ function SingleLinkRow({ field, node, value }) {
1204
1004
  /* @__PURE__ */ jsx(EntryAnchorBadge, { node, value })
1205
1005
  ] });
1206
1006
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1207
- /* @__PURE__ */ jsxs(SortableListItem, { "aria-label": "Link item 1", children: [
1208
- /* @__PURE__ */ jsxs(SortableListItemHeader, { className: styles.LinkFieldView.inputHeader(), children: [
1209
- /* @__PURE__ */ jsx(SortableListItemTitle, { children: options.readOnly ? rowContent : /* @__PURE__ */ jsx(LinkRowButton, { settings, children: rowContent }) }),
1210
- !options.readOnly && /* @__PURE__ */ jsxs(SortableListItemActions, { children: [
1211
- /* @__PURE__ */ jsx(
1212
- LinkRowSettings,
1213
- {
1214
- node,
1215
- onEdit: () => setEditOpen(true),
1216
- picker,
1217
- settings,
1218
- type,
1219
- value
1220
- }
1221
- ),
1222
- /* @__PURE__ */ jsx(
1223
- Button,
1224
- {
1225
- variant: "ghost",
1226
- "aria-label": "Remove link",
1227
- icon: IcRoundClose,
1228
- onClick: removeLink,
1229
- size: "icon-sm"
1230
- }
1231
- )
1232
- ] })
1007
+ /* @__PURE__ */ jsxs(SortableListItem, { "aria-label": "Link item 1", current: sheet.open, children: [
1008
+ /* @__PURE__ */ jsxs(SortableListItemHeader, { children: [
1009
+ /* @__PURE__ */ jsx(SortableListItemTitle, { children: options.readOnly ? rowContent : /* @__PURE__ */ jsx(LinkRowButton, { sheet, onEdit: () => setEditOpen(true), children: rowContent }) }),
1010
+ !options.readOnly && /* @__PURE__ */ jsx(SortableListItemActions, { children: /* @__PURE__ */ jsx(
1011
+ Button,
1012
+ {
1013
+ variant: "ghost",
1014
+ "aria-label": "Remove link",
1015
+ icon: IcRoundClose,
1016
+ onClick: removeLink,
1017
+ size: "icon-sm"
1018
+ }
1019
+ ) })
1233
1020
  ] }),
1234
1021
  hasFields && /* @__PURE__ */ jsx(SortableListItemContent, { children: /* @__PURE__ */ jsx(LinkRowEditor, { node, picker }) })
1235
1022
  ] }),
1023
+ /* @__PURE__ */ jsx(
1024
+ LinkSheet,
1025
+ {
1026
+ node,
1027
+ onEdit: () => setEditOpen(true),
1028
+ onRemove: removeLink,
1029
+ picker,
1030
+ readOnly: options.readOnly,
1031
+ sheet,
1032
+ type,
1033
+ value
1034
+ }
1035
+ ),
1236
1036
  picker && /* @__PURE__ */ jsx(
1237
1037
  LinkPickerDialog,
1238
1038
  {
@@ -1254,18 +1054,19 @@ function MultipleLinkRow({
1254
1054
  onToggleRow,
1255
1055
  value
1256
1056
  }) {
1257
- const [, setValue] = useField(field);
1057
+ const [links, setValue] = useField(field);
1258
1058
  const options = useFieldOptions(field);
1059
+ const canCreate = !options.max || (links?.length ?? 0) < options.max;
1259
1060
  const type = getPickerType(value[Reference.type]);
1260
1061
  const picker = options.pickers[type];
1261
1062
  const hasFields = Boolean(picker?.fields);
1262
1063
  const imagePreviewEntryId = type === "image" && "_entry" in value ? value._entry : void 0;
1263
1064
  const itemId = value[Reference.id];
1264
1065
  const readOnly = Boolean(options.readOnly);
1265
- const settings = useLinkRowSettings();
1066
+ const sheet = useBlockSheet(value[Reference.id]);
1266
1067
  const [editOpen, setEditOpen] = useState(false);
1267
1068
  function removeLink() {
1268
- setValue((links) => links.filter((_, currentIndex) => currentIndex !== index));
1069
+ setValue((links2) => links2.filter((_, currentIndex) => currentIndex !== index));
1269
1070
  }
1270
1071
  const rowContent = /* @__PURE__ */ jsxs(Fragment, { children: [
1271
1072
  imagePreviewEntryId && /* @__PURE__ */ jsx(EntryLinkImagePreview, { entryId: imagePreviewEntryId }),
@@ -1285,17 +1086,18 @@ function MultipleLinkRow({
1285
1086
  SortableListItem,
1286
1087
  {
1287
1088
  "aria-label": `Link item ${index + 1}`,
1288
- dragPreview: /* @__PURE__ */ jsx(
1289
- SortableListDragPreview,
1290
- {
1291
- icon: getLinkIcon(type),
1292
- label: /* @__PURE__ */ jsx(LinkRowText, { node })
1293
- }
1294
- ),
1295
1089
  id: itemId,
1090
+ current: sheet.open,
1296
1091
  children: [
1092
+ !readOnly && canCreate && /* @__PURE__ */ jsx(
1093
+ LinkInsertGap,
1094
+ {
1095
+ field,
1096
+ index,
1097
+ label: `Insert link before link item ${index + 1}`
1098
+ }
1099
+ ),
1297
1100
  /* @__PURE__ */ jsxs(SortableListItemHeader, { children: [
1298
- !readOnly && /* @__PURE__ */ jsx(SortableListHandle, { "aria-label": `Drag link item ${index + 1}` }),
1299
1101
  /* @__PURE__ */ jsxs(SortableListItemTitle, { children: [
1300
1102
  hasFields && /* @__PURE__ */ jsx(
1301
1103
  SortableListItemToggle,
@@ -1305,33 +1107,29 @@ function MultipleLinkRow({
1305
1107
  onClick: () => onToggleRow(itemId)
1306
1108
  }
1307
1109
  ),
1308
- readOnly ? rowContent : /* @__PURE__ */ jsx(LinkRowButton, { settings, children: rowContent })
1309
- ] }),
1310
- /* @__PURE__ */ jsxs(SortableListItemActions, { children: [
1311
- /* @__PURE__ */ jsx(
1312
- LinkRowSettings,
1110
+ readOnly ? rowContent : /* @__PURE__ */ jsx(
1111
+ LinkRowButton,
1313
1112
  {
1314
- node,
1113
+ sheet,
1315
1114
  onEdit: () => setEditOpen(true),
1316
- picker,
1317
- readOnly,
1318
- settings,
1319
- type,
1320
- value
1321
- }
1322
- ),
1323
- /* @__PURE__ */ jsx(
1324
- Button,
1325
- {
1326
- variant: "ghost",
1327
- "aria-label": "Remove link",
1328
- icon: IcRoundClose,
1329
- disabled: readOnly,
1330
- onClick: removeLink,
1331
- size: "icon-sm"
1115
+ onOpen: () => {
1116
+ if (hasFields && !expanded) onToggleRow(itemId);
1117
+ },
1118
+ children: rowContent
1332
1119
  }
1333
1120
  )
1334
- ] })
1121
+ ] }),
1122
+ /* @__PURE__ */ jsx(SortableListItemActions, { children: /* @__PURE__ */ jsx(
1123
+ Button,
1124
+ {
1125
+ variant: "ghost",
1126
+ "aria-label": "Remove link",
1127
+ icon: IcRoundClose,
1128
+ disabled: readOnly,
1129
+ onClick: removeLink,
1130
+ size: "icon-sm"
1131
+ }
1132
+ ) })
1335
1133
  ] }),
1336
1134
  expanded && hasFields && /* @__PURE__ */ jsx(SortableListItemContent, { children: /* @__PURE__ */ jsx(LinkRowEditor, { node, picker }) }),
1337
1135
  !expanded && picker?.fields && /* @__PURE__ */ jsx(SortableListItemFooter, { children: /* @__PURE__ */ jsx(
@@ -1345,6 +1143,19 @@ function MultipleLinkRow({
1345
1143
  ]
1346
1144
  }
1347
1145
  ),
1146
+ /* @__PURE__ */ jsx(
1147
+ LinkSheet,
1148
+ {
1149
+ node,
1150
+ onEdit: () => setEditOpen(true),
1151
+ onRemove: removeLink,
1152
+ picker,
1153
+ readOnly,
1154
+ sheet,
1155
+ type,
1156
+ value
1157
+ }
1158
+ ),
1348
1159
  picker && /* @__PURE__ */ jsx(
1349
1160
  LinkPickerDialog,
1350
1161
  {
@@ -1352,7 +1163,7 @@ function MultipleLinkRow({
1352
1163
  onOpenChange: setEditOpen,
1353
1164
  onPick: (link) => {
1354
1165
  setValue(
1355
- (links) => links.map(
1166
+ (links2) => links2.map(
1356
1167
  (current, currentIndex) => currentIndex === index ? link : current
1357
1168
  )
1358
1169
  );
@@ -1364,6 +1175,70 @@ function MultipleLinkRow({
1364
1175
  )
1365
1176
  ] });
1366
1177
  }
1178
+ function LinkInsertGap({ field, index, label }) {
1179
+ const options = useFieldOptions(field);
1180
+ const [, setValue] = useField(field);
1181
+ const ref = useRef(null);
1182
+ const [menuOpen, setMenuOpen] = useState(false);
1183
+ const [picking, setPicking] = useState(null);
1184
+ const types = Object.keys(options.pickers);
1185
+ const picker = picking ? options.pickers[picking] : void 0;
1186
+ function pick(type) {
1187
+ setMenuOpen(false);
1188
+ setPicking(type);
1189
+ }
1190
+ function insert(picked) {
1191
+ setValue((links) => {
1192
+ const current = links ?? [];
1193
+ const linked = new Set(
1194
+ current.flatMap((row) => "_entry" in row ? [row._entry] : [])
1195
+ );
1196
+ const rows = options.allowDuplicates ? picked : picked.filter((row) => !("_entry" in row) || !linked.has(row._entry));
1197
+ return [...current.slice(0, index), ...rows, ...current.slice(index)];
1198
+ });
1199
+ }
1200
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1201
+ /* @__PURE__ */ jsx(
1202
+ SortableListItemInsert,
1203
+ {
1204
+ ref,
1205
+ "aria-label": label,
1206
+ "aria-haspopup": "dialog",
1207
+ "aria-expanded": menuOpen || picking !== null,
1208
+ onClick: () => {
1209
+ if (types.length === 1) pick(types[0]);
1210
+ else setMenuOpen(true);
1211
+ }
1212
+ }
1213
+ ),
1214
+ types.length > 1 && /* @__PURE__ */ jsxs(Popover, { open: menuOpen, onOpenChange: setMenuOpen, children: [
1215
+ /* @__PURE__ */ jsx(PopoverAnchor, { virtualRef: ref }),
1216
+ /* @__PURE__ */ jsx(PopoverContent, { "aria-label": label, side: "bottom", align: "start", children: /* @__PURE__ */ jsx(SortableListItemSettings, { variant: "actions", children: types.map((type) => /* @__PURE__ */ jsx(
1217
+ Button,
1218
+ {
1219
+ variant: "ghost",
1220
+ icon: options.isEntryField ? IcRoundAdd : getLinkIcon(type),
1221
+ onClick: () => pick(type),
1222
+ children: options.isEntryField ? options.label : options.pickers[type].label
1223
+ },
1224
+ type
1225
+ )) }) })
1226
+ ] }),
1227
+ picking && picker && /* @__PURE__ */ jsx(
1228
+ LinkPickerDialog,
1229
+ {
1230
+ isOpen: true,
1231
+ onOpenChange: (open) => {
1232
+ if (!open) setPicking(null);
1233
+ },
1234
+ onPick: (link) => insert([link]),
1235
+ onPickMany: insert,
1236
+ picker,
1237
+ type: picking
1238
+ }
1239
+ )
1240
+ ] });
1241
+ }
1367
1242
  function SingleLinkFieldView({ field }) {
1368
1243
  const [value] = useField(field);
1369
1244
  const options = useFieldOptions(field);
@@ -1383,7 +1258,7 @@ function SingleLinkFieldView({ field }) {
1383
1258
  value: selectedValue
1384
1259
  }
1385
1260
  ),
1386
- isEmpty && !readOnly && /* @__PURE__ */ jsx(SortableListAdd, { className: styles.LinkFieldView.inputHeader(), children: /* @__PURE__ */ jsx(SingleLinkCreateActions, { field }) })
1261
+ isEmpty && !readOnly && /* @__PURE__ */ jsx(SortableListAdd, { children: /* @__PURE__ */ jsx(SingleLinkCreateActions, { field }) })
1387
1262
  ] });
1388
1263
  return /* @__PURE__ */ jsx(
1389
1264
  Field,
@@ -1454,7 +1329,6 @@ function MultipleLinksFieldView({ field }) {
1454
1329
  SortableList,
1455
1330
  {
1456
1331
  "aria-label": options.label || "Links",
1457
- dragType: LINK_FIELD_ROW_DRAG_TYPE,
1458
1332
  onReorder: readOnly ? void 0 : moveRow,
1459
1333
  children: [
1460
1334
  nodes.map((node, index) => {