alinea 2.0.0-preview.13 → 2.0.0-preview.14

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 (323) 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 +6 -2
  5. package/dist/adapter/next/context.js +1 -4
  6. package/dist/adapter/next/handler.js +12 -1
  7. package/dist/backend/CommitEntries.d.ts +17 -0
  8. package/dist/backend/CommitEntries.js +39 -0
  9. package/dist/backend/Handler.d.ts +9 -0
  10. package/dist/backend/Handler.js +80 -20
  11. package/dist/backend/api/BasicAuth.js +5 -1
  12. package/dist/backend/api/CreateBackend.js +2 -2
  13. package/dist/backend/api/DatabaseApi.js +18 -5
  14. package/dist/backend/api/GithubApi.d.ts +13 -0
  15. package/dist/backend/api/GithubApi.js +170 -30
  16. package/dist/backend/api/database.js +2 -2
  17. package/dist/backend/util/Syncable.d.ts +6 -0
  18. package/dist/backend/util/Syncable.js +3 -1
  19. package/dist/bundled.d.ts +911 -151
  20. package/dist/chunks/{chunk-5H4D5JQL.js → chunk-2PP7WJUJ.js} +1 -11
  21. package/dist/chunks/{chunk-QHHMKJUO.js → chunk-7DDPSWRY.js} +465 -2
  22. package/dist/chunks/{chunk-HOETF6HN.js → chunk-PMGIIYDD.js} +1 -0
  23. package/dist/chunks/{chunk-3QFSGTGF.js → chunk-SCV3TEXM.js} +1 -1
  24. package/dist/chunks/{chunk-UPY2RUZF.js → chunk-TWBREZWC.js} +30 -0
  25. package/dist/cli/Generate.js +20 -7
  26. package/dist/cli/Mcp.js +1 -1
  27. package/dist/cli/Serve.js +1 -1
  28. package/dist/cli/bin.js +1 -1
  29. package/dist/cli/build/BuildEmitter.d.ts +5 -1
  30. package/dist/cli/build/BuildEmitter.js +8 -3
  31. package/dist/cli/generate/CompileConfig.js +10 -6
  32. package/dist/cli/generate/DevDB.d.ts +4 -1
  33. package/dist/cli/generate/DevDB.js +15 -7
  34. package/dist/cli/generate/GenerateDashboard.js +1 -0
  35. package/dist/cli/generate/MediaLocations.d.ts +18 -0
  36. package/dist/cli/generate/MediaLocations.js +69 -0
  37. package/dist/cli/serve/CreateLocalServer.js +1 -0
  38. package/dist/cli/serve/mcp/DevMcp.js +1 -1
  39. package/dist/cloud/CloudRemote.js +21 -7
  40. package/dist/cms.d.ts +4 -2
  41. package/dist/components/Alert.js +2 -2
  42. package/dist/components/AppShell.js +2 -2
  43. package/dist/components/AsyncList.d.ts +52 -0
  44. package/dist/components/AsyncList.js +69 -0
  45. package/dist/components/Breadcrumbs.js +6 -6
  46. package/dist/components/Button.js +4 -4
  47. package/dist/components/Calendar.js +18 -18
  48. package/dist/components/Checkbox.js +10 -10
  49. package/dist/components/CheckboxGroup.js +2 -2
  50. package/dist/components/Collapsible.js +5 -5
  51. package/dist/components/ColorSwatch.js +2 -2
  52. package/dist/components/ColorSwatchPicker.js +4 -4
  53. package/dist/components/ComboBox.d.ts +27 -9
  54. package/dist/components/ComboBox.js +40 -9
  55. package/dist/components/Command.js +13 -13
  56. package/dist/components/ContentCard.js +28 -28
  57. package/dist/components/ContentGrid.js +11 -11
  58. package/dist/components/DataList.js +1 -1
  59. package/dist/components/DateField.d.ts +4 -0
  60. package/dist/components/DateField.js +2 -2
  61. package/dist/components/DatePicker.js +2 -2
  62. package/dist/components/DateRangePicker.js +2 -2
  63. package/dist/components/Dialog.d.ts +14 -3
  64. package/dist/components/Dialog.js +38 -11
  65. package/dist/components/DropZone.js +6 -6
  66. package/dist/components/DropdownMenu.js +8 -8
  67. package/dist/components/Empty.js +4 -4
  68. package/dist/components/Field.d.ts +1 -1
  69. package/dist/components/Field.js +18 -12
  70. package/dist/components/Form.d.ts +23 -0
  71. package/dist/components/Form.js +64 -0
  72. package/dist/components/Link.d.ts +8 -1
  73. package/dist/components/List.js +27 -27
  74. package/dist/components/MediaPreview.js +5 -5
  75. package/dist/components/MultipleSelect.d.ts +13 -8
  76. package/dist/components/MultipleSelect.js +25 -25
  77. package/dist/components/NavRail.js +7 -7
  78. package/dist/components/NumberField.d.ts +5 -1
  79. package/dist/components/NumberField.js +6 -4
  80. package/dist/components/Page.js +6 -6
  81. package/dist/components/Popover.js +2 -2
  82. package/dist/components/PreviewFrame.js +8 -8
  83. package/dist/components/RadioGroup.js +10 -10
  84. package/dist/components/Resizable.js +1 -1
  85. package/dist/components/SearchField.js +8 -8
  86. package/dist/components/Select.d.ts +13 -10
  87. package/dist/components/Select.js +18 -32
  88. package/dist/components/Sheet.js +6 -6
  89. package/dist/components/Sidebar.js +5 -5
  90. package/dist/components/SortableList.js +12 -12
  91. package/dist/components/Spinner.js +4 -4
  92. package/dist/components/Stack.d.ts +20 -0
  93. package/dist/components/Stack.js +45 -0
  94. package/dist/components/Surface.js +1 -1
  95. package/dist/components/Switch.js +5 -5
  96. package/dist/components/Table.d.ts +11 -1
  97. package/dist/components/Table.js +81 -53
  98. package/dist/components/Tabs.js +6 -6
  99. package/dist/components/TagGroup.js +10 -10
  100. package/dist/components/TextField.d.ts +7 -1
  101. package/dist/components/TextField.js +20 -11
  102. package/dist/components/TimeField.d.ts +6 -1
  103. package/dist/components/TimeField.js +51 -26
  104. package/dist/components/Timestamp.js +1 -1
  105. package/dist/components/ToggleGroup.js +2 -2
  106. package/dist/components/Toolbar.js +3 -3
  107. package/dist/components/Tooltip.js +5 -4
  108. package/dist/components/Tree.js +27 -27
  109. package/dist/components/internal/DateControl.js +11 -11
  110. package/dist/components/internal/FormScope.d.ts +2 -0
  111. package/dist/components/internal/FormScope.js +8 -0
  112. package/dist/components/internal/ListBoxGroup.d.ts +12 -0
  113. package/dist/components/internal/ListBoxGroup.js +46 -0
  114. package/dist/components/internal/ListBoxOption.d.ts +2 -2
  115. package/dist/components/internal/ListBoxOption.js +5 -5
  116. package/dist/components/internal/Locale.js +2 -2
  117. package/dist/components/internal/PopoverSurface.js +5 -4
  118. package/dist/components/internal/SelectionCheckbox.js +5 -5
  119. package/dist/components/internal/Slot.js +1 -1
  120. package/dist/components/internal/ToggleButton.js +4 -4
  121. package/dist/components/internal/Trigger.js +2 -2
  122. package/dist/components/internal/useDragDrop.js +2 -2
  123. package/dist/components/types.d.ts +4 -0
  124. package/dist/components.d.ts +3 -0
  125. package/dist/components.js +3 -0
  126. package/dist/core/Client.js +12 -1
  127. package/dist/core/Config.d.ts +6 -0
  128. package/dist/core/Config.js +12 -0
  129. package/dist/core/DashboardEntry.d.ts +19 -0
  130. package/dist/core/DashboardEntry.js +0 -0
  131. package/dist/core/Document.d.ts +2 -2
  132. package/dist/core/Document.js +10 -3
  133. package/dist/core/EntryFields.d.ts +8 -2
  134. package/dist/core/Field.d.ts +5 -0
  135. package/dist/core/Filter.d.ts +19 -2
  136. package/dist/core/Filter.js +5 -0
  137. package/dist/core/Graph.d.ts +10 -2
  138. package/dist/core/Overview.d.ts +74 -5
  139. package/dist/core/Overview.js +1 -0
  140. package/dist/core/Root.js +1 -1
  141. package/dist/core/Scope.d.ts +5 -0
  142. package/dist/core/Scope.js +22 -5
  143. package/dist/core/Type.d.ts +25 -6
  144. package/dist/core/Type.js +25 -7
  145. package/dist/core/db/LocalStore.d.ts +7 -0
  146. package/dist/core/field/CreateField.d.ts +1 -2
  147. package/dist/core/source/Source.d.ts +2 -0
  148. package/dist/core/source/Source.js +11 -0
  149. package/dist/core/util/Async.d.ts +2 -0
  150. package/dist/core/util/Async.js +12 -1
  151. package/dist/core/util/Checks.js +1 -1
  152. package/dist/core/util/Slugs.js +4 -3
  153. package/dist/dashboard/App.css +13 -11
  154. package/dist/dashboard/App.d.ts +1 -0
  155. package/dist/dashboard/App.js +22 -6
  156. package/dist/dashboard/Href.d.ts +37 -0
  157. package/dist/dashboard/Href.js +46 -0
  158. package/dist/dashboard/app/ActivityStatus.js +34 -12
  159. package/dist/dashboard/app/AuthView.js +2 -2
  160. package/dist/dashboard/app/BlockSettings.d.ts +9 -0
  161. package/dist/dashboard/app/BlockSettings.js +16 -0
  162. package/dist/dashboard/app/BlockSheet.js +3 -3
  163. package/dist/dashboard/app/BlockSheetStoryFrame.js +2 -2
  164. package/dist/dashboard/app/CompactField.js +15 -15
  165. package/dist/dashboard/app/CroppedImage.js +2 -2
  166. package/dist/dashboard/app/DashboardLayout.d.ts +1 -1
  167. package/dist/dashboard/app/DashboardLayout.js +12 -0
  168. package/dist/dashboard/app/EntryActions.d.ts +11 -0
  169. package/dist/dashboard/app/EntryActions.js +30 -0
  170. package/dist/dashboard/app/EntryFields.d.ts +15 -2
  171. package/dist/dashboard/app/EntryFields.js +26 -5
  172. package/dist/dashboard/app/EntryHeader.js +17 -7
  173. package/dist/dashboard/app/EntryReferences.js +2 -2
  174. package/dist/dashboard/app/EntrySidebar.js +25 -23
  175. package/dist/dashboard/app/EntrySidebarPreview.js +2 -2
  176. package/dist/dashboard/app/EntryValidationModal.js +3 -3
  177. package/dist/dashboard/app/Explorer.js +84 -45
  178. package/dist/dashboard/app/ExplorerBatchActions.js +4 -4
  179. package/dist/dashboard/app/ExplorerControls.js +5 -5
  180. package/dist/dashboard/app/ExplorerList.js +2 -2
  181. package/dist/dashboard/app/ExplorerModal.js +3 -3
  182. package/dist/dashboard/app/ExplorerOverviewHeader.d.ts +6 -0
  183. package/dist/dashboard/app/ExplorerOverviewHeader.js +28 -0
  184. package/dist/dashboard/app/ExplorerTable.js +7 -7
  185. package/dist/dashboard/app/ExplorerTabs.d.ts +12 -0
  186. package/dist/dashboard/app/ExplorerTabs.js +42 -0
  187. package/dist/dashboard/app/ImageEditor.js +31 -31
  188. package/dist/dashboard/app/LinkPicker.js +3 -3
  189. package/dist/dashboard/app/LocaleMenu.js +9 -9
  190. package/dist/dashboard/app/MediaPreviewCell.js +5 -5
  191. package/dist/dashboard/app/OverviewCell.js +12 -10
  192. package/dist/dashboard/app/RemoveDialog.js +5 -0
  193. package/dist/dashboard/app/SearchBar.js +4 -4
  194. package/dist/dashboard/app/SettingsTab.d.ts +6 -0
  195. package/dist/dashboard/app/SettingsTab.js +27 -0
  196. package/dist/dashboard/app/SidebarTree.js +19 -19
  197. package/dist/dashboard/app/WorkspaceMenu.js +6 -6
  198. package/dist/dashboard/app/WorkspaceRoots.js +102 -98
  199. package/dist/dashboard/app/editor/FileEditor.js +18 -18
  200. package/dist/dashboard/app/pages/EntryPage.js +42 -39
  201. package/dist/dashboard/app/pages/RootPage.js +3 -3
  202. package/dist/dashboard/app/pages/SplashPage.js +94 -79
  203. package/dist/dashboard/app/pages/UsersPage.js +9 -9
  204. package/dist/dashboard/app/ui/DashboardModal.js +14 -14
  205. package/dist/dashboard/atoms/activity.d.ts +1 -0
  206. package/dist/dashboard/atoms/activity.js +8 -5
  207. package/dist/dashboard/atoms/config.d.ts +2 -0
  208. package/dist/dashboard/atoms/dashboard.d.ts +11 -0
  209. package/dist/dashboard/atoms/dashboard.js +8 -0
  210. package/dist/dashboard/atoms/editor.d.ts +7 -1
  211. package/dist/dashboard/atoms/editor.js +14 -2
  212. package/dist/dashboard/atoms/explorer.d.ts +15 -0
  213. package/dist/dashboard/atoms/explorer.js +43 -14
  214. package/dist/dashboard/atoms/graph.d.ts +5 -0
  215. package/dist/dashboard/atoms/graph.js +26 -1
  216. package/dist/dashboard/atoms/nav.d.ts +16 -10
  217. package/dist/dashboard/atoms/nav.js +96 -36
  218. package/dist/dashboard/atoms/overview.d.ts +26 -4
  219. package/dist/dashboard/atoms/overview.js +41 -12
  220. package/dist/dashboard/atoms/root.js +7 -1
  221. package/dist/dashboard/boot/ActivityEvent.d.ts +1 -1
  222. package/dist/dashboard/boot/Boot.js +6 -0
  223. package/dist/dashboard/boot/DashboardWorker.d.ts +6 -0
  224. package/dist/dashboard/boot/DashboardWorker.js +89 -8
  225. package/dist/dashboard/boot/LoadWorker.js +3 -0
  226. package/dist/dashboard/boot/SyncEvent.d.ts +7 -0
  227. package/dist/dashboard/boot/SyncEvent.js +14 -0
  228. package/dist/dashboard/boot/WorkerDB.d.ts +1 -0
  229. package/dist/dashboard/boot/WorkerDB.js +3 -0
  230. package/dist/dashboard/cms/EntryTable.d.ts +4 -3
  231. package/dist/dashboard/cms/EntryTable.js +2 -2
  232. package/dist/dashboard/cms/ViewProps.d.ts +3 -2
  233. package/dist/dashboard/cms/hooks.d.ts +34 -18
  234. package/dist/dashboard/cms/hooks.js +43 -18
  235. package/dist/dashboard/contexts.d.ts +3 -2
  236. package/dist/dashboard/contexts.js +3 -2
  237. package/dist/dashboard/hook/UseEntryEditor.d.ts +1 -1
  238. package/dist/dashboard/hook/UseEntryEditor.js +7 -3
  239. package/dist/dashboard/icons.d.ts +1 -0
  240. package/dist/dashboard/icons.js +15 -0
  241. package/dist/database/BrowserEntryStore.js +35 -13
  242. package/dist/database/DatabaseTables.js +1 -1
  243. package/dist/database/EntryDatabase.d.ts +10 -1
  244. package/dist/database/EntryDatabase.js +31 -10
  245. package/dist/database/EntryStore.js +1 -11
  246. package/dist/database/entry/EntryTable.d.ts +5 -3
  247. package/dist/database/entry/EntryTable.js +25 -8
  248. package/dist/database/query/Condition.d.ts +4 -1
  249. package/dist/database/query/Condition.js +16 -5
  250. package/dist/database/query/EntryQuery.js +59 -7
  251. package/dist/database/query/Relation.d.ts +13 -1
  252. package/dist/database/query/Relation.js +19 -1
  253. package/dist/database/query/Search.d.ts +7 -1
  254. package/dist/database/query/Search.js +54 -9
  255. package/dist/database/sync/EntrySyncer.d.ts +2 -0
  256. package/dist/database/sync/EntrySyncer.js +4 -2
  257. package/dist/database/sync/Ingest.d.ts +2 -1
  258. package/dist/database/sync/Ingest.js +20 -6
  259. package/dist/field/code/CodeField.view.js +12 -12
  260. package/dist/field/link/EntryLink.d.ts +4 -5
  261. package/dist/field/link/FileLink.d.ts +2 -2
  262. package/dist/field/link/ImageLink.d.ts +2 -5
  263. package/dist/field/link/ImageLink.js +0 -1
  264. package/dist/field/link/LinkField.view.js +18 -15
  265. package/dist/field/list/ListField.view.js +50 -35
  266. package/dist/field/metadata/MetadataField.view.js +14 -14
  267. package/dist/field/richtext/RichTextBlock.js +39 -35
  268. package/dist/field/richtext/RichTextExtensions.js +23 -23
  269. package/dist/field/richtext/RichTextField.view.js +6 -6
  270. package/dist/field/richtext/RichTextInsertMenu.js +5 -5
  271. package/dist/field/richtext/RichTextToolbar.js +26 -1
  272. package/dist/field/richtext/Toolbar.d.ts +9 -1
  273. package/dist/field/richtext/Toolbar.js +12 -2
  274. package/dist/field/select/SelectField.view.js +1 -0
  275. package/dist/index.css +174 -23
  276. package/dist/index.d.ts +1 -0
  277. package/dist/index.js +3 -1
  278. package/dist/next.d.ts +2 -0
  279. package/dist/next.edge.d.ts +2 -0
  280. package/dist/picker/entry/EntryPicker.d.ts +3 -1
  281. package/dist/picker/entry/EntryPicker.js +15 -1
  282. package/dist/preview/react.js +3 -0
  283. package/dist/query.d.ts +26 -14
  284. package/dist/query.js +4 -0
  285. package/dist/types.d.ts +8 -5
  286. package/dist/ui/Stack.d.ts +4 -2
  287. package/docs/ai-setup.md +3 -3
  288. package/docs/cli.md +4 -2
  289. package/docs/components/combo-box.md +105 -16
  290. package/docs/components/date-field.md +1 -1
  291. package/docs/components/dialog.md +51 -0
  292. package/docs/components/form.md +67 -0
  293. package/docs/components/link.md +10 -0
  294. package/docs/components/multiple-select.md +9 -17
  295. package/docs/components/number-field.md +5 -1
  296. package/docs/components/select.md +9 -20
  297. package/docs/components/stack.md +42 -0
  298. package/docs/components/table.md +83 -0
  299. package/docs/components/text-field.md +9 -1
  300. package/docs/components/time-field.md +5 -1
  301. package/docs/components.md +39 -1
  302. package/docs/configuration.md +3 -1
  303. package/docs/custom-fields.md +135 -7
  304. package/docs/deploy/self-host.md +2 -0
  305. package/docs/deploy.md +7 -4
  306. package/docs/fields/image.md +0 -1
  307. package/docs/fields/list.md +19 -0
  308. package/docs/fields/object.md +5 -3
  309. package/docs/fields/rich-text.md +31 -0
  310. package/docs/index.md +8 -6
  311. package/docs/instant-publishing.md +23 -2
  312. package/docs/overviews.md +128 -4
  313. package/docs/query/filtering.md +2 -0
  314. package/docs/query/related.md +58 -9
  315. package/docs/query.md +52 -1
  316. package/docs/quickstart.md +5 -5
  317. package/docs/schema/document.md +2 -0
  318. package/docs/schema/type.md +3 -1
  319. package/docs/upgrading.md +100 -19
  320. package/llms-full.txt +1022 -125
  321. package/package.json +1 -1
  322. package/readme.md +2 -2
  323. package/dist/chunks/{chunk-4ZA6KZHS.js → chunk-6FQ5IMNA.js} +3 -3
@@ -17,12 +17,24 @@ interface ObjectOps<Fields> {
17
17
  interface ArrayOps<Fields> {
18
18
  includes?: Filter<Fields>;
19
19
  }
20
+ declare const related: unique symbol;
21
+ /**
22
+ * A field matched by a query of related entries, eg. `_referenced`. Its
23
+ * condition holds when the query finds an entry.
24
+ */
25
+ export interface Related<Query> {
26
+ [related]: Query;
27
+ }
28
+ /** A query of related entries used as a condition */
29
+ export interface RelationCondition {
30
+ edge: string;
31
+ }
20
32
  type FieldOps<Fields> = {
21
33
  [K in keyof Fields]?: Condition<Fields[K]>;
22
34
  };
23
- export type Condition<Value> = [Value] extends [Primitive] ? Ops<Value> | Value : [Value] extends [Array<any>] ? ArrayOps<Value[0]> : ObjectOps<Value>;
35
+ export type Condition<Value> = [Value] extends [Related<infer Query>] ? Condition<boolean> | Query : [Value] extends [Primitive] ? Ops<Value> | Value : [Value] extends [Array<any>] ? ArrayOps<Value[0]> : ObjectOps<Value>;
24
36
  /** A condition on a field whose type is not known */
25
- export type AnyCondition = Primitive | Ops<unknown> | ArrayOps<unknown> | ObjectOps<unknown>;
37
+ export type AnyCondition = Primitive | Ops<unknown> | ArrayOps<unknown> | ObjectOps<unknown> | RelationCondition;
26
38
  /**
27
39
  * A filter on known fields that also accepts conditions on any other field,
28
40
  * for example the fields of the entry types an entry picker can select
@@ -75,6 +87,11 @@ export type ConditionNode = {
75
87
  } | {
76
88
  op: 'includes';
77
89
  item: ConditionNode;
90
+ }
91
+ /** Holds when the query of related entries finds an entry */
92
+ | {
93
+ op: 'relation';
94
+ query: RelationCondition;
78
95
  };
79
96
  export declare function parseFilter(filter: unknown): FilterNode;
80
97
  export declare function parseCondition(condition: unknown): ConditionNode;
@@ -21,6 +21,8 @@ function parseFilter(filter) {
21
21
  function parseCondition(condition) {
22
22
  if (condition === void 0) return { op: "and", nodes: [] };
23
23
  if (!isRecord(condition)) return { op: "is", value: condition };
24
+ if (typeof condition.edge === "string")
25
+ return { op: "relation", query: { ...condition, edge: condition.edge } };
24
26
  const nodes = Array();
25
27
  for (const [op, value] of Object.entries(condition)) {
26
28
  if (value === void 0) continue;
@@ -121,8 +123,11 @@ function conditionCheck(node) {
121
123
  const check = conditionCheck(node.item);
122
124
  return (value) => Array.isArray(value) && value.some(check);
123
125
  }
126
+ case "relation":
127
+ throw new Error(relationMessage);
124
128
  }
125
129
  }
130
+ var relationMessage = "Relation filters such as `_referenced: Query.referencedBy(...)` only work in queries (graph.find, EntryTable, overview filters), they cannot be checked against loaded entries";
126
131
  function defaultField(input, name) {
127
132
  return isRecord(input) ? input[name] : void 0;
128
133
  }
@@ -46,7 +46,15 @@ export interface EdgeEntry {
46
46
  edge: 'entrySingle';
47
47
  field: HasField & Expr;
48
48
  }
49
- export type Edge = EdgeTranslations | EdgeChildren | EdgeParents | EdgeSiblings | EdgeParent | EdgeNext | EdgePrevious | EdgeEntries | EdgeEntry;
49
+ /**
50
+ * Entries that link to the entry, through any field or through the given
51
+ * link field of their type
52
+ */
53
+ export interface EdgeReferencedBy {
54
+ edge: 'referencedBy';
55
+ field?: HasField & Expr;
56
+ }
57
+ export type Edge = EdgeTranslations | EdgeChildren | EdgeParents | EdgeSiblings | EdgeParent | EdgeNext | EdgePrevious | EdgeEntries | EdgeEntry | EdgeReferencedBy;
50
58
  /** Options that change a query result into a single entry or a count */
51
59
  export interface QueryModifiers {
52
60
  first?: true;
@@ -195,5 +203,5 @@ export declare abstract class Graph {
195
203
  get<Selection extends SelectionGuard = undefined, const Type extends TypeGuard = undefined, Include extends IncludeGuard = undefined>(query: GraphQuery<Selection, Type, Include>): Promise<QueryResult<Selection, Type, Include>>;
196
204
  count<Selection extends SelectionGuard = undefined, const Type extends TypeGuard = undefined, Include extends IncludeGuard = undefined>(query: GraphQuery<Selection, Type, Include>): Promise<number>;
197
205
  }
198
- export declare function querySource(query: unknown): "children" | "entryMultiple" | "entrySingle" | "next" | "parent" | "parents" | "previous" | "siblings" | "translations" | undefined;
206
+ export declare function querySource(query: unknown): "children" | "entryMultiple" | "entrySingle" | "next" | "parent" | "parents" | "previous" | "referencedBy" | "siblings" | "translations" | undefined;
199
207
  export {};
@@ -2,7 +2,7 @@ import type { EntryStatus } from './Entry.js';
2
2
  import type { EntryFilterFields } from './EntryFields.js';
3
3
  import { Expr } from './Expr.js';
4
4
  import type { OpenFilter } from './Filter.js';
5
- import type { EdgeQuery, GraphQuery, InferProjection, Order, Projection } from './Graph.js';
5
+ import type { EdgeQuery, Graph, GraphQuery, InferProjection, Order, Projection } from './Graph.js';
6
6
  import type { Type } from './Type.js';
7
7
  import type { View } from './View.js';
8
8
  /** Horizontal alignment of a column's header and cells */
@@ -12,9 +12,10 @@ export type OverviewColumnPosition = 'start' | 'end';
12
12
  /** A fixed width in pixels or a fraction of the remaining space */
13
13
  export type OverviewColumnWidth = number | `${number}fr`;
14
14
  /**
15
- * A value to sort entries by: an expression such as a field, or a query of a
15
+ * A value to sort entries by: an expression such as a field, a query of a
16
16
  * linked entry that selects a single expression, eg.
17
- * `Product.brand.first({select: Entry.title})`
17
+ * `Product.brand.first({select: Entry.title})`, or a count of related
18
+ * entries, eg. `Query.referencedBy({type: Product, count: true})`
18
19
  */
19
20
  export type OverviewSortValue = Expr<any> | EdgeQuery<Expr<any>>;
20
21
  /** One projection per entry type, keyed by the type names of the schema */
@@ -99,12 +100,39 @@ export interface OverviewFilterOption {
99
100
  /** The condition entries match when the option is picked */
100
101
  filter: OpenFilter<EntryFilterFields>;
101
102
  }
103
+ /** The choices of an overview filter, keyed by a name unique within it */
104
+ export interface OverviewFilterOptions {
105
+ [key: string]: OverviewFilterOption;
106
+ }
107
+ /** What the options of an overview filter can be loaded with */
108
+ export interface OverviewFilterContext {
109
+ /** Query the content, eg. to list an option per entry of a type */
110
+ graph: Graph;
111
+ /** The locale the overview lists, null for unlocalised roots */
112
+ locale: string | null;
113
+ }
102
114
  /** A filter editors can apply in the "Filter and sort" menu of an overview */
103
115
  export interface OverviewFilter {
104
116
  /** The heading of the options in the menu, eg. `File type` */
105
117
  label: string;
106
- /** The choices, keyed by a name that is unique within the filter */
107
- options: Record<string, OverviewFilterOption>;
118
+ /**
119
+ * The choices, keyed by a name that is unique within the filter, or a
120
+ * function that loads them, eg. an option per category:
121
+ *
122
+ * ```ts
123
+ * async options({graph}) {
124
+ * const categories = await graph.find({
125
+ * type: Category,
126
+ * select: {id: Entry.id, title: Entry.title}
127
+ * })
128
+ * return Object.fromEntries(categories.map(category => [category.id, {
129
+ * label: category.title,
130
+ * filter: {category: {has: {_entry: category.id}}}
131
+ * }]))
132
+ * }
133
+ * ```
134
+ */
135
+ options: OverviewFilterOptions | ((context: OverviewFilterContext) => OverviewFilterOptions | Promise<OverviewFilterOptions>);
108
136
  /**
109
137
  * Editors can pick several options, entries then match any of them.
110
138
  * Defaults to false: picking an option replaces the picked one.
@@ -128,6 +156,36 @@ export interface OverviewActionProps {
128
156
  */
129
157
  query: GraphQuery<undefined, Type | Array<Type> | undefined, undefined>;
130
158
  }
159
+ /** A tab above the listed entries, each lists the entries of its filter */
160
+ export interface OverviewTab {
161
+ /** Shown on the tab, eg. `Active` */
162
+ label: string;
163
+ /**
164
+ * The condition entries match when the tab is selected, like the options of
165
+ * a filter. A tab without a filter lists every child.
166
+ */
167
+ filter?: OpenFilter<EntryFilterFields>;
168
+ }
169
+ /** Props of an `overview.header` view */
170
+ export interface OverviewHeaderProps {
171
+ workspace: string;
172
+ root: string;
173
+ /** The entry whose children are listed, null for the root */
174
+ parentId: string | null;
175
+ locale: string | null;
176
+ /** The search terms entered in the overview */
177
+ search: string;
178
+ /**
179
+ * The condition of the selected tab and the applied filters, undefined
180
+ * when none applies
181
+ */
182
+ filter: OpenFilter<EntryFilterFields> | undefined;
183
+ /**
184
+ * A query for the listed entries, without paging. Pass it to
185
+ * `useGraph().find({...query, select})`, eg. to total them.
186
+ */
187
+ query: GraphQuery<undefined, Type | Array<Type> | undefined, undefined>;
188
+ }
131
189
  interface OverviewColumnBase<Value> {
132
190
  /** The column header */
133
191
  header: string;
@@ -212,6 +270,12 @@ export interface OverviewOptions {
212
270
  * applied filter, and the search terms.
213
271
  */
214
272
  filters?: Record<string, OverviewFilter>;
273
+ /**
274
+ * Tabs above the listed children, keyed by a name kept in the url. The
275
+ * first tab is selected by default. Entries match the filter of the
276
+ * selected tab, the applied filters and the search terms.
277
+ */
278
+ tabs?: Record<string, OverviewTab>;
215
279
  /** The default layout, editors can still switch */
216
280
  layout?: 'table' | 'cards';
217
281
  /**
@@ -221,6 +285,11 @@ export interface OverviewOptions {
221
285
  thumbnail?: Expr<any> | Record<string, Expr<any>>;
222
286
  /** Components rendered in the overview toolbar, eg. an export button */
223
287
  actions?: Array<View<OverviewActionProps>>;
288
+ /**
289
+ * A component rendered above the listed children, eg. totals or a chart of
290
+ * the listed entries
291
+ */
292
+ header?: View<OverviewHeaderProps>;
224
293
  }
225
294
  /** Create a column for an overview */
226
295
  export declare function column<const Select extends OverviewColumnSelect | undefined = undefined>(options: OverviewColumnOptions<Select, OverviewColumnValue<Select>>): OverviewColumn<OverviewColumnValue<Select>>;
@@ -13,6 +13,7 @@ var Overview;
13
13
  if (!overview) return [];
14
14
  const views = [
15
15
  ...overview.actions ?? [],
16
+ overview.header,
16
17
  ...values(overview.columns ?? {}).map((column2) => column2.view)
17
18
  ];
18
19
  return views.filter((view) => typeof view === "string");
package/dist/core/Root.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  boolean,
4
4
  object,
5
5
  string
6
- } from "../chunks/chunk-UPY2RUZF.js";
6
+ } from "../chunks/chunk-TWBREZWC.js";
7
7
  import "../chunks/chunk-CQ52GEHY.js";
8
8
 
9
9
  // src/core/Root.ts
@@ -25,6 +25,11 @@ export declare class Scope {
25
25
  fieldOf(field: Field): [type: string, path: string] | undefined;
26
26
  locationOf(entity: Entity): string[] | undefined;
27
27
  nameOf(entity: Entity): string | undefined;
28
+ /**
29
+ * Where a field stores its value in the entry data, eg. `['seo', 'title']`
30
+ * for a field of an object field
31
+ */
32
+ dataPathOf(field: Field): Array<string> | undefined;
28
33
  /** Configured spellings of a locale, matched case-insensitively. */
29
34
  locales(locale: string): Array<string>;
30
35
  stringify(input: any): string;
@@ -41,6 +41,7 @@ var Scope = class {
41
41
  #paths = /* @__PURE__ */ new Map();
42
42
  #locales = /* @__PURE__ */ new Map();
43
43
  #nested = /* @__PURE__ */ new Map();
44
+ #nestedKeys = /* @__PURE__ */ new Map();
44
45
  #shared = /* @__PURE__ */ new Set();
45
46
  constructor(config) {
46
47
  for (const [workspaceName, workspace] of entries(config.workspaces)) {
@@ -67,10 +68,12 @@ var Scope = class {
67
68
  for (const [typeName, type] of entries(config.schema))
68
69
  for (const [fieldName, field] of entries(type))
69
70
  this.#insertNested(field, ["Field", typeName, fieldName]);
71
+ for (const [field, path] of this.#nested)
72
+ this.#nestedKeys.set(path.join("."), field);
70
73
  }
71
74
  // Fields of object fields get a key, eg. Field.Type.object.field, so roles
72
- // can target them. They are kept apart from the other entities: queries
73
- // select top level fields only. A field instance used in more than one
75
+ // can target them and queries can select them. They are kept apart from the
76
+ // other entities, which have a name. A field instance used in more than one
74
77
  // place has no single key, so it can't be targeted.
75
78
  #insertNested(field, path) {
76
79
  if (!hasType(field)) return;
@@ -111,14 +114,27 @@ var Scope = class {
111
114
  nameOf(entity) {
112
115
  return this.#paths.get(entity)?.at(-1);
113
116
  }
117
+ /**
118
+ * Where a field stores its value in the entry data, eg. `['seo', 'title']`
119
+ * for a field of an object field
120
+ */
121
+ dataPathOf(field) {
122
+ if (this.#shared.has(field))
123
+ throw new Error(
124
+ "Field is used in more than one place, select the field containing it"
125
+ );
126
+ const path = this.#paths.get(field) ?? this.#nested.get(field);
127
+ if (path?.[0] !== "Field") return;
128
+ return path.slice(2);
129
+ }
114
130
  /** Configured spellings of a locale, matched case-insensitively. */
115
131
  locales(locale) {
116
132
  return this.#locales.get(locale.toLowerCase()) ?? [locale];
117
133
  }
118
134
  stringify(input) {
119
135
  const result = JSON.stringify(input, (key, value) => {
120
- if (this.#paths.has(value))
121
- return { [ENTITY_KEY]: this.#paths.get(value)?.join(".") };
136
+ const path = this.#paths.get(value) ?? this.#nested.get(value);
137
+ if (path) return { [ENTITY_KEY]: path.join(".") };
122
138
  if (value && typeof value === "object" && hasExpr(value))
123
139
  return { [EXPR_KEY]: getExpr(value) };
124
140
  return value;
@@ -131,7 +147,8 @@ var Scope = class {
131
147
  const props = Object.keys(value);
132
148
  if (props.length === 1) {
133
149
  const [key2] = props;
134
- if (key2 === ENTITY_KEY) return this.#keys.get(value[key2]);
150
+ if (key2 === ENTITY_KEY)
151
+ return this.#keys.get(value[key2]) ?? this.#nestedKeys.get(value[key2]);
135
152
  if (key2 === EXPR_KEY) return new Expr(value[key2]);
136
153
  }
137
154
  }
@@ -1,3 +1,4 @@
1
+ import type { EntryActionProps } from './DashboardEntry.js';
1
2
  import type { ComponentType } from 'react';
2
3
  import type { Config } from './Config.js';
3
4
  import type { EntryStatus } from './Entry.js';
@@ -47,6 +48,8 @@ export declare namespace Type {
47
48
  function references(type: Type, value: Record<string, unknown>, path?: Array<string>, labels?: Array<string>): Array<EntryReferenceTarget>;
48
49
  function fields(type: Type): Record<string, Field>;
49
50
  function sections(type: Type): Section[];
51
+ /** Fields edited in the settings of a block, or a Settings tab of an entry */
52
+ function settings(type: Type): FieldsDefinition | undefined;
50
53
  function isContainer(type: Type): boolean;
51
54
  function field(type: Type, name: string): Field | undefined;
52
55
  function isType(type: any): type is Type;
@@ -65,12 +68,24 @@ export declare namespace Type {
65
68
  export interface FieldsDefinition {
66
69
  [key: string]: Field;
67
70
  }
68
- export interface TypeConfig<Definition> {
71
+ export interface TypeConfig<Definition, Settings = {}> {
69
72
  fields: Definition;
73
+ /**
74
+ * Fields shown in the settings sheet of a block, below its label and
75
+ * anchor. Entries of the type show them in a Settings tab. They are stored
76
+ * and queried like the other fields.
77
+ */
78
+ settings?: Settings;
70
79
  /** Accepts entries of these types as children */
71
80
  contains?: Array<string | Type>;
72
81
  /** How the dashboard lists the children of entries of this type */
73
82
  overview?: OverviewOptions;
83
+ /**
84
+ * Components rendered in the header of the entry editor, next to the
85
+ * publish button, eg. a button that exports or sends the entry. They can
86
+ * read the fields of the entry with the hooks of `alinea/cms`.
87
+ */
88
+ actions?: Array<View<EntryActionProps>>;
74
89
  /**
75
90
  * Order children entries in the sidebar content tree
76
91
  * @deprecated Use `overview.sort`
@@ -88,7 +103,11 @@ export interface TypeConfig<Definition> {
88
103
  collapsed?: boolean;
89
104
  /** An icon (React component) to represent this type in the dashboard */
90
105
  icon?: ComponentType;
91
- /** A React component used to view an entry of this type in the dashboard */
106
+ /**
107
+ * A React component, or a path to one, that replaces the form of entries of
108
+ * this type below the entry header. It edits the fields of the entry with
109
+ * the hooks of `alinea/cms`.
110
+ */
92
111
  view?: View<{
93
112
  type: Type;
94
113
  }>;
@@ -112,17 +131,17 @@ export interface TypeConfig<Definition> {
112
131
  preview?: Preview;
113
132
  }
114
133
  /** Types that only hold children can leave out their fields */
115
- export interface ContainerTypeConfig<Definition> extends Omit<TypeConfig<Definition>, 'fields' | 'contains'> {
134
+ export interface ContainerTypeConfig<Definition, Settings = {}> extends Omit<TypeConfig<Definition, Settings>, 'fields' | 'contains'> {
116
135
  fields?: Definition;
117
136
  /** Accepts entries of these types as children */
118
137
  contains: Array<string | Type>;
119
138
  }
120
- export interface TypeInternal extends TypeConfig<FieldsDefinition> {
139
+ export interface TypeInternal extends TypeConfig<FieldsDefinition, FieldsDefinition> {
121
140
  label: string;
122
141
  allFields: Record<string, Field>;
123
142
  sections: Array<Section>;
124
143
  }
125
144
  /** Create a new type */
126
- export declare function type<Fields extends FieldsDefinition = {}>(label: string, config: TypeConfig<Fields> | ContainerTypeConfig<Fields>): Type<Fields>;
127
- export declare function createType<Fields extends FieldsDefinition = {}>(label: string, { fields: definition, ...config }: TypeConfig<Fields> | ContainerTypeConfig<Fields>): Type<Fields>;
145
+ export declare function type<Fields extends FieldsDefinition = {}, Settings extends FieldsDefinition = {}>(label: string, config: TypeConfig<Fields, Settings> | ContainerTypeConfig<Fields, Settings>): Type<Fields & Settings>;
146
+ export declare function createType<Fields extends FieldsDefinition = {}, Settings extends FieldsDefinition = {}>(label: string, { fields: definition, ...config }: TypeConfig<Fields, Settings> | ContainerTypeConfig<Fields, Settings>): Type<Fields & Settings>;
128
147
  export {};
package/dist/core/Type.js CHANGED
@@ -1,7 +1,9 @@
1
1
  import {
2
+ instance,
2
3
  object,
3
- string
4
- } from "../chunks/chunk-UPY2RUZF.js";
4
+ string,
5
+ union
6
+ } from "../chunks/chunk-TWBREZWC.js";
5
7
  import "../chunks/chunk-CQ52GEHY.js";
6
8
 
7
9
  // src/core/Type.ts
@@ -89,6 +91,11 @@ var Type;
89
91
  return getType(type2).sections;
90
92
  }
91
93
  Type2.sections = sections;
94
+ function settings(type2) {
95
+ const { settings: settings2 } = getType(type2);
96
+ return settings2 && keys(settings2).length > 0 ? settings2 : void 0;
97
+ }
98
+ Type2.settings = settings;
92
99
  function isContainer(type2) {
93
100
  return Boolean(getType(type2).contains);
94
101
  }
@@ -186,7 +193,7 @@ var Type;
186
193
  Type2.defaultView = defaultView;
187
194
  const TypeOptions = object({
188
195
  defaultView: string.optional,
189
- view: string.optional,
196
+ view: union(string, instance(Function)).optional,
190
197
  summaryRow: string.optional,
191
198
  summaryThumb: string.optional
192
199
  });
@@ -203,11 +210,12 @@ var Type;
203
210
  }
204
211
  Type2.validate = validate;
205
212
  function referencedViews(type2) {
206
- const { view, summaryRow, summaryThumb, overview: overview2 } = getType(type2);
213
+ const { view, summaryRow, summaryThumb, overview: overview2, actions } = getType(type2);
207
214
  return [
208
215
  view,
209
216
  summaryRow,
210
217
  summaryThumb,
218
+ ...actions ?? [],
211
219
  ...Overview.referencedViews(overview2),
212
220
  ...viewsOfDefinition(getType(type2).fields)
213
221
  ].filter((v) => typeof v === "string");
@@ -242,9 +250,9 @@ function viewsOfDefinition(definition) {
242
250
  });
243
251
  }
244
252
  function type(label, config) {
245
- const instance = createType(label, config);
246
- Type.validate(instance);
247
- return instance;
253
+ const instance2 = createType(label, config);
254
+ Type.validate(instance2);
255
+ return instance2;
248
256
  }
249
257
  function createType(label, {
250
258
  fields: definition = {},
@@ -273,6 +281,16 @@ function createType(label, {
273
281
  }
274
282
  }
275
283
  addCurrent();
284
+ const taken = new Set(fields.map(([key]) => key));
285
+ for (const [key, value] of entries(config.settings ?? {})) {
286
+ const own = Section.isSection(value) ? entries(Section.fields(value)) : Field.isField(value) ? [[key, value]] : [];
287
+ for (const [name, field] of own) {
288
+ if (taken.has(name))
289
+ throw new Error(`Field "${name}" is defined twice in Type "${label}"`);
290
+ taken.add(name);
291
+ fields.push([name, field]);
292
+ }
293
+ }
276
294
  const allFields = fromEntries(fields);
277
295
  return {
278
296
  ...allFields,
@@ -6,6 +6,13 @@ import type { WriteableGraph } from './WriteableGraph.js';
6
6
  export interface SyncOptions {
7
7
  /** Skip entry validation for a remote whose entries were already validated. */
8
8
  validate?: boolean;
9
+ /** Called as files arrive from the remote, once there are files to fetch. */
10
+ onProgress?(progress: SyncProgress): void;
11
+ }
12
+ /** Files fetched from the remote during a sync. */
13
+ export interface SyncProgress {
14
+ loaded: number;
15
+ total: number;
9
16
  }
10
17
  /**
11
18
  * A locally available entry store: a writeable graph backed by a source that
@@ -1,8 +1,7 @@
1
1
  import type { Field, FieldOptions, WithoutLabel } from '../Field.js';
2
2
  import type { Expand } from '../util/Types.js';
3
3
  import type { View } from '../View.js';
4
- export interface Create<Value, Options = object> extends Field<Value, Value, (value: Value) => void, FieldOptions<Value> & Options> {
5
- }
4
+ export type Create<Value, Options = object> = Field<Value, Value, (value: Value) => void, FieldOptions<Value> & Options>;
6
5
  export type Options<F> = Expand<F extends Field<any, any, any, infer Options> ? WithoutLabel<Options & FieldOptions<any>> : WithoutLabel<FieldOptions<any>>>;
7
6
  export interface CreateConfig<Value, Options> {
8
7
  label: string;
@@ -13,6 +13,8 @@ export interface Source extends RemoteSource {
13
13
  /** Consume remote blobs incrementally instead of materializing one bundle. */
14
14
  applyChangesFrom?(remote: RemoteSource, batch: ChangesBatch, tree: ReadonlyTree): Promise<void>;
15
15
  }
16
+ /** Pin the tree while streaming blobs from the revision already fetched. */
17
+ export declare function sourceAtTree(source: RemoteSource, tree: ReadonlyTree): RemoteSource;
16
18
  export declare function applyChangesFrom(source: Source, remote: RemoteSource, batch: ChangesBatch, tree: ReadonlyTree): Promise<void>;
17
19
  export declare function bundleContents(source: RemoteSource, batch: ChangesBatch): Promise<ChangesBatch>;
18
20
  export declare function diff(source: Source, remote: RemoteSource): Promise<ChangesBatch>;
@@ -3,6 +3,16 @@ import "../../chunks/chunk-CQ52GEHY.js";
3
3
  // src/core/source/Source.ts
4
4
  import { accumulate } from "../util/Async.js";
5
5
  import { hashBlob } from "./GitUtils.js";
6
+ function sourceAtTree(source, tree) {
7
+ return {
8
+ async getTreeIfDifferent(revision) {
9
+ return revision === tree.sha ? void 0 : tree;
10
+ },
11
+ getBlobs(shas, options) {
12
+ return source.getBlobs(shas, options);
13
+ }
14
+ };
15
+ }
6
16
  async function applyChangesFrom(source, remote, batch, tree) {
7
17
  if (source.applyChangesFrom)
8
18
  return source.applyChangesFrom(remote, batch, tree);
@@ -118,6 +128,7 @@ export {
118
128
  applyChangesFrom,
119
129
  bundleContents,
120
130
  diff,
131
+ sourceAtTree,
121
132
  syncWith,
122
133
  transaction
123
134
  };
@@ -8,6 +8,8 @@ export interface MapConcurrentOptions {
8
8
  /** Map concurrently while yielding results as they complete. */
9
9
  export declare function mapConcurrent<T, TResult>(iterable: Iterable<T>, mapper: (item: T, signal?: AbortSignal) => Promise<TResult>, options: MapConcurrentOptions): AsyncGenerator<TResult>;
10
10
  export declare function genEffect<T, TReturn>(gen: AsyncIterable<T, TReturn>, effect: (result: T) => void): AsyncIterable<T>;
11
+ /** Settle like `promise`, or reject when it takes longer than `ms`. */
12
+ export declare function within<T>(promise: Promise<T>, ms: number): Promise<T>;
11
13
  /** Run tasks one after another; a failed task does not block the next one. */
12
14
  export declare class TaskQueue {
13
15
  #private;
@@ -100,6 +100,16 @@ function genEffect(gen, effect) {
100
100
  }
101
101
  };
102
102
  }
103
+ function within(promise, ms) {
104
+ let timer;
105
+ const expired = new Promise((_, reject) => {
106
+ timer = setTimeout(
107
+ () => reject(new Error(`Timed out after ${ms / 1e3}s`)),
108
+ ms
109
+ );
110
+ });
111
+ return Promise.race([promise, expired]).finally(() => clearTimeout(timer));
112
+ }
103
113
  var TaskQueue = class {
104
114
  #tail = Promise.resolve();
105
115
  run(task) {
@@ -119,5 +129,6 @@ export {
119
129
  accumulate,
120
130
  genEffect,
121
131
  mapConcurrent,
122
- toGenerator
132
+ toGenerator,
133
+ within
123
134
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  type
3
- } from "../../chunks/chunk-UPY2RUZF.js";
3
+ } from "../../chunks/chunk-TWBREZWC.js";
4
4
  import "../../chunks/chunk-CQ52GEHY.js";
5
5
 
6
6
  // src/core/util/Checks.ts
@@ -3,15 +3,16 @@ import "../../chunks/chunk-CQ52GEHY.js";
3
3
  // src/core/util/Slugs.ts
4
4
  var strip = /([^\p{L}\p{N}\p{M}\p{Emoji}\p{Emoji_Component}]|\p{P}(?!\u{fe0f}))+/u;
5
5
  var stripGlobal = new RegExp(strip.source, "gu");
6
- var ignore = /['’]/g;
6
+ var ignore = /['’\u00ad]/;
7
+ var ignoreGlobal = new RegExp(ignore.source, "g");
7
8
  var stripAccents = /(\p{Script=Latin})\p{M}+/gu;
8
9
  var separator = "-";
9
10
  var trim = new RegExp(`^${separator}+|${separator}+$`, "g");
10
11
  function isSeparator(char) {
11
- return strip.test(char);
12
+ return !ignore.test(char) && strip.test(char);
12
13
  }
13
14
  function slugify(input) {
14
- return input.normalize("NFKD").replace(stripAccents, "$1").replace(ignore, "").replace(stripGlobal, separator).replace(trim, "").toLowerCase();
15
+ return input.normalize("NFKD").replace(stripAccents, "$1").replace(ignoreGlobal, "").replace(stripGlobal, separator).replace(trim, "").toLowerCase();
15
16
  }
16
17
  export {
17
18
  isSeparator,
@@ -1,6 +1,8 @@
1
1
  /* src/theme.css */
2
- :root {
2
+ :root[data-alinea-theme] {
3
3
  color-scheme: light dark;
4
+ }
5
+ :where([data-alinea-theme]:not([data-alinea-theme] *)) {
4
6
  --alinea-gray-0: #ffffff;
5
7
  --alinea-gray-50: #f9fafb;
6
8
  --alinea-gray-100: #f3f4f7;
@@ -48,7 +50,7 @@
48
50
  --alinea-green-700: #007a55;
49
51
  --alinea-green-800: #006045;
50
52
  }
51
- :root {
53
+ :where([data-alinea-theme]:not([data-alinea-theme] *)) {
52
54
  --alinea-font: "Inter", sans-serif;
53
55
  --alinea-mono-font: "JetBrains Mono", monospace;
54
56
  --alinea-font-size-base: 0.8125rem;
@@ -65,8 +67,8 @@
65
67
  --alinea-warning-fg: var(--alinea-gray-900);
66
68
  --alinea-success: light-dark(var(--alinea-green-600), var(--alinea-green-500));
67
69
  --alinea-ring: var(--alinea-blue-500);
70
+ --alinea-workspace-color: var(--alinea-primary);
68
71
  }
69
- :root,
70
72
  [data-alinea-theme] {
71
73
  --alinea-transition: 0.2s ease-out;
72
74
  --alinea-radius-sm: calc(var(--alinea-radius) / 2);
@@ -107,10 +109,10 @@
107
109
  --alinea-shadow-tooltip: 0 8px 20px rgb(0 0 0 / 10%);
108
110
  --alinea-shadow-modal: 0 2px 13px rgb(0 0 0 / 11%);
109
111
  }
110
- :root[data-theme=light] {
112
+ [data-alinea-theme][data-theme=light] {
111
113
  color-scheme: light;
112
114
  }
113
- :root[data-theme=dark] {
115
+ [data-alinea-theme][data-theme=dark] {
114
116
  color-scheme: dark;
115
117
  }
116
118
 
@@ -273,14 +275,14 @@
273
275
  }
274
276
 
275
277
  /* src/dashboard/global.css */
276
- html,
277
- body,
278
- #root {
278
+ :where(html[data-alinea-theme]),
279
+ :where(html[data-alinea-theme]) body,
280
+ :where(html[data-alinea-theme]) #root {
279
281
  height: 100%;
280
282
  margin: 0;
281
283
  font-family: var(--alinea-font);
282
284
  }
283
- * {
285
+ :where([data-alinea-theme], [data-alinea-theme] *) {
284
286
  box-sizing: border-box;
285
287
  padding: 0;
286
288
  margin: 0;
@@ -292,12 +294,12 @@ body[data-disable-transition=true] {
292
294
  transition: none !important;
293
295
  }
294
296
  }
295
- a {
297
+ :where([data-alinea-theme] a) {
296
298
  color: inherit;
297
299
  font: inherit;
298
300
  text-decoration: none;
299
301
  }
300
- button {
302
+ :where([data-alinea-theme] button) {
301
303
  background: none;
302
304
  border: none;
303
305
  color: inherit;
@@ -17,3 +17,4 @@ export interface AppProps {
17
17
  }
18
18
  export declare const appAtom: import("jotai").Atom<readonly [false, string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | null | undefined] | readonly [true, string | number | bigint | boolean | import("react").JSX.Element | Iterable<ReactNode> | null | undefined]>;
19
19
  export declare function App(props: AppProps): import("react").JSX.Element;
20
+ export declare function AppLoading(): import("react").JSX.Element;