rimecms 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/adapter-sqlite/generate-schema/templates.server.d.ts +9 -9
  2. package/dist/adapter-sqlite/generate-schema/templates.server.js +9 -9
  3. package/dist/adapter-sqlite/paths.server.js +24 -15
  4. package/dist/adapter-sqlite/rows.server.d.ts +1 -1
  5. package/dist/core/adapter.d.ts +8 -4
  6. package/dist/core/boot.server.d.ts +2 -2
  7. package/dist/core/config/context.server.d.ts +2 -2
  8. package/dist/core/dev/codegen/routes/common.server.d.ts +2 -0
  9. package/dist/core/dev/codegen/routes/common.server.js +7 -3
  10. package/dist/core/dev/codegen/routes/util.server.d.ts +2 -1
  11. package/dist/core/dev/codegen/routes/util.server.js +4 -1
  12. package/dist/core/dev/config-memo.server.js +4 -0
  13. package/dist/core/i18n/en/fields.d.ts +1 -1
  14. package/dist/core/i18n/en/fields.js +1 -1
  15. package/dist/core/i18n/fr/fields.d.ts +1 -1
  16. package/dist/core/i18n/fr/fields.js +1 -1
  17. package/dist/core/prototype/collection/operations/duplicate.js +1 -1
  18. package/dist/core/prototype/collection/thumbnail/hooks/set-document-thumbnail.server.js +1 -1
  19. package/dist/core/prototype/shared/title/hooks/set-document-title.server.js +1 -1
  20. package/dist/core/prototype/shared/url/addresses.server.d.ts +10 -0
  21. package/dist/core/prototype/shared/url/addresses.server.js +17 -17
  22. package/dist/core/prototype/shared/url/hooks/detach-paths.server.d.ts +3 -2
  23. package/dist/core/prototype/shared/url/hooks/detach-paths.server.js +9 -8
  24. package/dist/core/prototype/shared/url/hooks/sync-paths.server.d.ts +3 -2
  25. package/dist/core/prototype/shared/url/hooks/sync-paths.server.js +5 -4
  26. package/dist/fields/blocks/component/AddBlockButton.svelte +1 -1
  27. package/dist/fields/blocks/component/Block.svelte +4 -5
  28. package/dist/fields/blocks/component/Blocks.svelte +17 -13
  29. package/dist/fields/blocks/component/focus/BlocksFocus.svelte +53 -65
  30. package/dist/fields/blocks/component/focus/DefaultRender.svelte +108 -0
  31. package/dist/fields/blocks/component/focus/{RenderPlaceholder.svelte.d.ts → DefaultRender.svelte.d.ts} +3 -3
  32. package/dist/fields/blocks/component/focus/Inspector.svelte +160 -0
  33. package/dist/fields/blocks/component/focus/Inspector.svelte.d.ts +7 -0
  34. package/dist/fields/blocks/component/focus/Layers.svelte +16 -3
  35. package/dist/fields/blocks/component/focus/LayersList.svelte +28 -11
  36. package/dist/fields/blocks/component/focus/LayersList.svelte.d.ts +2 -0
  37. package/dist/fields/blocks/component/focus/Palette.svelte +3 -3
  38. package/dist/fields/blocks/component/focus/Renders.svelte +66 -15
  39. package/dist/fields/blocks/component/focus/Renders.svelte.d.ts +5 -1
  40. package/dist/fields/blocks/component/focus/StagePlaceholder.svelte +1 -4
  41. package/dist/fields/blocks/component/focus/focus.svelte.d.ts +26 -12
  42. package/dist/fields/blocks/component/focus/focus.svelte.js +114 -57
  43. package/dist/fields/blocks/component/picker/BlockTile.svelte +3 -5
  44. package/dist/fields/combobox/component/ComboBox.svelte +1 -1
  45. package/dist/fields/combobox/component/combobox.css +1 -1
  46. package/dist/fields/date/component/Date.svelte +1 -1
  47. package/dist/fields/group/component/Group.svelte +4 -4
  48. package/dist/fields/link/component/Link.svelte +1 -1
  49. package/dist/fields/link/component/RessourceInput.svelte +2 -2
  50. package/dist/fields/link/index.d.ts +1 -1
  51. package/dist/fields/number/component/Number.svelte +1 -1
  52. package/dist/fields/relation/component/Cell.svelte +3 -1
  53. package/dist/fields/relation/component/RelationInline.svelte +51 -20
  54. package/dist/fields/relation/component/default/Default.svelte +3 -3
  55. package/dist/fields/relation/component/upload/Browse.svelte +2 -2
  56. package/dist/fields/relation/component/upload/Upload.svelte +2 -2
  57. package/dist/fields/relation/index.d.ts +1 -41
  58. package/dist/fields/relation/index.js +0 -67
  59. package/dist/fields/relation/util.d.ts +69 -0
  60. package/dist/fields/relation/util.js +103 -0
  61. package/dist/fields/rich-text/client.d.ts +2 -5
  62. package/dist/fields/rich-text/client.js +1 -3
  63. package/dist/fields/rich-text/component/Cell.svelte +1 -1
  64. package/dist/fields/rich-text/component/bubble-menu/bubble-menu.css +1 -1
  65. package/dist/fields/rich-text/component/bubble-menu/node-selector/node-selector.css +1 -1
  66. package/dist/fields/rich-text/core/features/link/component/link-selector.svelte +2 -2
  67. package/dist/fields/rich-text/core/features/resource/resource-extension.js +3 -3
  68. package/dist/fields/rich-text/core/features/resource/resource.svelte +2 -2
  69. package/dist/fields/rich-text/core/features/upload/upload-extension.js +3 -4
  70. package/dist/fields/rich-text/core/features/upload/upload.svelte +2 -2
  71. package/dist/fields/rich-text/index.d.ts +0 -17
  72. package/dist/fields/rich-text/index.js +0 -44
  73. package/dist/fields/rich-text/json.d.ts +18 -0
  74. package/dist/fields/rich-text/json.js +44 -0
  75. package/dist/fields/select/component/Select.svelte +2 -2
  76. package/dist/fields/text/component/TextInline.svelte +113 -0
  77. package/dist/fields/text/component/TextInline.svelte.d.ts +14 -0
  78. package/dist/fields/textarea/component/TextArea.svelte +1 -1
  79. package/dist/fields/tree/component/TreeBlock.svelte +4 -4
  80. package/dist/index.d.ts +2 -9
  81. package/dist/index.js +3 -8
  82. package/dist/{panel/components/sections/live → live}/Consumer.svelte +2 -2
  83. package/dist/{panel/components/sections/live → live}/Consumer.svelte.d.ts +1 -1
  84. package/dist/{panel/components/sections/live → live}/LiveEdit.svelte +2 -2
  85. package/dist/{panel/components/sections/live → live}/Provider.svelte +1 -1
  86. package/dist/{panel/context/live.svelte.d.ts → live/context.svelte.d.ts} +1 -1
  87. package/dist/{panel/context/live.svelte.js → live/context.svelte.js} +3 -3
  88. package/dist/panel/components/fields/Error.svelte +1 -1
  89. package/dist/panel/components/fields/FieldsPreview.svelte +1 -1
  90. package/dist/panel/components/fields/FieldsPreviewTrigger.svelte +1 -1
  91. package/dist/panel/components/fields/Hint.svelte +1 -1
  92. package/dist/panel/components/fields/setting.css +6 -6
  93. package/dist/panel/components/sections/auth/AuthForm.svelte +2 -2
  94. package/dist/panel/components/sections/collection/Avatar.svelte +1 -1
  95. package/dist/panel/components/sections/collection/bulk-upload/FileDrop.svelte +1 -1
  96. package/dist/panel/components/sections/collection/bulk-upload/PageDrop.svelte +3 -3
  97. package/dist/panel/components/sections/collection/bulk-upload/UploadProgress.svelte +1 -1
  98. package/dist/panel/components/sections/collection/folder/Folder.svelte +1 -1
  99. package/dist/panel/components/sections/collection/folder/FolderWithActions.svelte +2 -2
  100. package/dist/panel/components/sections/collection/grid/grid-item/GridItem.svelte +1 -1
  101. package/dist/panel/components/sections/collection/header/DisplayMode.svelte +1 -2
  102. package/dist/panel/components/sections/collection/list/CollectionList.svelte +2 -2
  103. package/dist/panel/components/sections/collection/list/header/Header.svelte +1 -1
  104. package/dist/panel/components/sections/collection/list/row/Row.svelte +1 -1
  105. package/dist/panel/components/sections/collection/tree/CollectionTree.svelte +1 -1
  106. package/dist/panel/components/sections/collection/tree/CollectionTreeNode.svelte +1 -1
  107. package/dist/panel/components/sections/collection/upload-thumb-cell/UploadThumbCell.svelte +1 -1
  108. package/dist/panel/components/sections/commands/CommandButton.svelte +1 -1
  109. package/dist/panel/components/sections/document/AuthAPIKeyDialog.svelte +1 -1
  110. package/dist/panel/components/sections/document/AuthFooter.svelte +2 -2
  111. package/dist/panel/components/sections/document/AutoSaveBanner.svelte +2 -2
  112. package/dist/panel/components/sections/document/ButtonStatus.svelte +1 -1
  113. package/dist/panel/components/sections/document/ChangeSlugDialog.svelte +1 -1
  114. package/dist/panel/components/sections/document/DocumentChildren.svelte +2 -2
  115. package/dist/panel/components/sections/document/upload-header/UploadHeader.svelte +2 -2
  116. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte +1 -1
  117. package/dist/panel/components/sections/document/upload-header/drop-zone/DropZone.svelte.d.ts +1 -1
  118. package/dist/panel/components/sections/live/LiveFloatingUI.svelte +2 -2
  119. package/dist/panel/components/ui/breadcrumb/BreadCrumb.svelte +1 -1
  120. package/dist/panel/components/ui/button/button.svelte +3 -4
  121. package/dist/panel/components/ui/calendar/calendar.svelte.d.ts +1 -1
  122. package/dist/panel/components/ui/card/card.svelte +2 -2
  123. package/dist/panel/components/ui/card-document/card-document.svelte +2 -2
  124. package/dist/panel/components/ui/card-resource/card-resource.svelte +2 -2
  125. package/dist/panel/components/ui/checkbox/checkbox.svelte.d.ts +1 -1
  126. package/dist/panel/components/ui/command/command-input.svelte +1 -1
  127. package/dist/panel/components/ui/context-menu/context-menu.css +1 -1
  128. package/dist/panel/components/ui/dialog/dialog-content.css +1 -1
  129. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +1 -1
  130. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +1 -1
  131. package/dist/panel/components/ui/dropdown-menu/dropdown-menu-content.css +1 -1
  132. package/dist/panel/components/ui/input/input.svelte +1 -1
  133. package/dist/panel/components/ui/nav/Nav.svelte +2 -3
  134. package/dist/panel/components/ui/nav/NavGroup.svelte +1 -1
  135. package/dist/panel/components/ui/nav/NavItemButton.svelte +1 -1
  136. package/dist/panel/components/ui/nav/UserButton.svelte +1 -1
  137. package/dist/panel/components/ui/page-header/PageHeader.svelte +1 -1
  138. package/dist/panel/components/ui/popover/popover-content.css +1 -1
  139. package/dist/panel/components/ui/radio-row-group/radio-row-group.css +0 -1
  140. package/dist/panel/components/ui/sheet/sheet.css +1 -1
  141. package/dist/panel/components/ui/sonner/sonner.css +1 -1
  142. package/dist/panel/components/ui/switch/switch.css +0 -2
  143. package/dist/panel/components/ui/switch/switch.svelte.d.ts +1 -1
  144. package/dist/panel/components/ui/tabs/tabs.css +2 -1
  145. package/dist/panel/components/ui/tag/tag.svelte +1 -1
  146. package/dist/panel/components/ui/tree/tree-rows.css +3 -3
  147. package/dist/panel/context/collection.svelte.d.ts +2 -2
  148. package/dist/panel/context/config.svelte.d.ts +2 -2
  149. package/dist/panel/context/documentForm.svelte.js +1 -1
  150. package/dist/panel/index.d.ts +3 -5
  151. package/dist/panel/index.js +4 -6
  152. package/dist/panel/pages/auth/forgot-password/ForgotPassword.svelte +1 -1
  153. package/dist/panel/pages/dashboard/Dashboard.svelte +1 -1
  154. package/dist/panel/pages/dashboard/DashboardCard.svelte +2 -2
  155. package/dist/panel/pages/dashboard/DashboardCollection.svelte +1 -1
  156. package/dist/panel/pages/dashboard/DashboardRow.svelte +1 -1
  157. package/dist/panel/public.d.ts +4 -0
  158. package/dist/panel/public.js +6 -0
  159. package/dist/panel/style/index.css +13 -37
  160. package/dist/panel/style/mixins/index.css +1 -1
  161. package/dist/panel/style/palette.css +3 -3
  162. package/dist/panel/style/scheme.css +10 -34
  163. package/dist/public.d.ts +13 -0
  164. package/dist/public.js +12 -0
  165. package/package.json +12 -6
  166. package/dist/fields/blocks/component/focus/RenderPlaceholder.svelte +0 -77
  167. package/dist/fields/blocks/component/focus/Stage.svelte +0 -190
  168. package/dist/fields/blocks/component/focus/Stage.svelte.d.ts +0 -8
  169. package/dist/fields/relation/client.d.ts +0 -28
  170. package/dist/fields/relation/client.js +0 -37
  171. /package/dist/{panel/util → fields/relation}/populate.d.ts +0 -0
  172. /package/dist/{panel/util → fields/relation}/populate.js +0 -0
  173. /package/dist/{panel/components/sections/live → live}/LiveEdit.svelte.d.ts +0 -0
  174. /package/dist/{panel/components/sections/live → live}/Provider.svelte.d.ts +0 -0
@@ -8,8 +8,9 @@
8
8
  import { getBlocksFocusContext } from './focus.svelte.js';
9
9
  import LayersList from './LayersList.svelte';
10
10
 
11
- type Props = { form: DocumentFormContext; list: string; depth: number };
12
- const { form, list, depth }: Props = $props();
11
+ /** `label` names the list above it, for a block that holds several. */
12
+ type Props = { form: DocumentFormContext; list: string; depth: number; label?: string };
13
+ const { form, list, depth, label }: Props = $props();
13
14
 
14
15
  const focus = getBlocksFocusContext()!;
15
16
  const rows = $derived(focus.rowsOf(list, depth));
@@ -59,6 +60,9 @@
59
60
  }
60
61
  </script>
61
62
 
63
+ {#if label}
64
+ <span class="rz-layers__child-label" style:--rz-layers-depth={depth}>{label}</span>
65
+ {/if}
62
66
  <ul
63
67
  class="rz-layers__list"
64
68
  data-list={list}
@@ -103,8 +107,8 @@
103
107
  {#if hasError(row.path)}
104
108
  <span class="rz-layers__error" aria-label="error"></span>
105
109
  {/if}
106
- {#if focus.hasRenders && !focus.locked && focus.isSelected(row.path)}
107
- <!-- Beside the renders, the fields are a tab away: this opens it. -->
110
+ {#if !focus.locked && focus.isSelected(row.path)}
111
+ <!-- The fields are a tab away: this opens it. -->
108
112
  <button
109
113
  type="button"
110
114
  class="rz-layers__edit"
@@ -123,12 +127,12 @@
123
127
  {#if row.children.length && !folded}
124
128
  {#each row.children as child (child.builder.name)}
125
129
  <div class="rz-layers__child">
126
- {#if row.children.length > 1}
127
- <span class="rz-layers__child-label" style:--rz-layers-depth={depth + 1}>
128
- {child.label}
129
- </span>
130
- {/if}
131
- <LayersList {form} list={child.list} depth={depth + 1} />
130
+ <LayersList
131
+ {form}
132
+ list={child.list}
133
+ depth={depth + 1}
134
+ label={row.children.length > 1 ? child.label : undefined}
135
+ />
132
136
  </div>
133
137
  {/each}
134
138
  {/if}
@@ -136,7 +140,7 @@
136
140
  {/each}
137
141
  </ul>
138
142
 
139
- <style>/* A level: its fill, a hairline, its shadow. raised, float. */
143
+ <style>/* A level: its fill, a hairline, and its shadow when it has one. raised has none, float does. */
140
144
 
141
145
  /* A well: an input, a track, a dropzone. Its edge shows on hover. */
142
146
 
@@ -301,4 +305,17 @@
301
305
  :global(.rz-layers__item.sortable-ghost > .rz-layers__row) {
302
306
  opacity: 0.4;
303
307
  }
308
+
309
+ /* A type dragged in from the palette: a row of the layers, its name alone. */
310
+ :global(.rz-layers__list > .rz-palette__item.rz-block-tile) {
311
+ height: var(--rz-size-7);
312
+ padding: 0 0 0 var(--rz-layers-start);
313
+ border-radius: var(--rz-radius-sm);
314
+ justify-content: center;
315
+ }
316
+ :global(
317
+ .rz-layers__list > .rz-palette__item :is(.rz-block-tile__frame, .rz-block-tile__description)
318
+ ) {
319
+ display: none;
320
+ }
304
321
  </style>
@@ -1,9 +1,11 @@
1
1
  import type { DocumentFormContext } from '../../../../panel/context/documentForm.svelte.js';
2
2
  import LayersList from './LayersList.svelte';
3
+ /** `label` names the list above it, for a block that holds several. */
3
4
  type Props = {
4
5
  form: DocumentFormContext;
5
6
  list: string;
6
7
  depth: number;
8
+ label?: string;
7
9
  };
8
10
  declare const LayersList: import("svelte").Component<Props, {}, "">;
9
11
  type LayersList = ReturnType<typeof LayersList>;
@@ -14,8 +14,8 @@
14
14
  const { form, heading = true }: Props = $props();
15
15
 
16
16
  const focus = getBlocksFocusContext()!;
17
- /** The block types of the list the next insert goes to: the current block's, else the open one. */
18
- const list = $derived(focus.current?.list ?? focus.path ?? '');
17
+ /** The block types of the list the next insert goes to. */
18
+ const list = $derived(focus.insertList() ?? '');
19
19
  const types = $derived(list ? (form.blocks.builder(list)?.get.blocks ?? []) : []);
20
20
 
21
21
  /** Past this many types, a search sits above them. */
@@ -85,7 +85,7 @@
85
85
  </div>
86
86
  </div>
87
87
 
88
- <style>/* A level: its fill, a hairline, its shadow. raised, float. */
88
+ <style>/* A level: its fill, a hairline, and its shadow when it has one. raised has none, float does. */
89
89
 
90
90
  /* A well: an input, a track, a dropzone. Its edge shows on hover. */
91
91
 
@@ -3,18 +3,23 @@
3
3
  import type { DocumentFormContext } from '../../../../panel/context/documentForm.svelte.js';
4
4
  import { shiftListPath } from '../../../../panel/context/blocks-ops.js';
5
5
  import { useSortable } from '../../../../panel/util/Sortable.js';
6
- import { ArrowDown, ArrowUp, CopyPlus, Trash2 } from '@lucide/svelte';
6
+ import { ArrowDown, ArrowUp, CopyPlus, Focus, Trash2 } from '@lucide/svelte';
7
7
  import type Sortable from 'sortablejs';
8
+ import DefaultRender from './DefaultRender.svelte';
8
9
  import { getBlocksFocusContext } from './focus.svelte.js';
9
- import RenderPlaceholder from './RenderPlaceholder.svelte';
10
10
  import Renders from './Renders.svelte';
11
11
 
12
- /** `onRemove` asks first when the block holds blocks of its own. */
13
- type Props = { form: DocumentFormContext; list: string; onRemove: () => void };
14
- const { form, list, onRemove }: Props = $props();
12
+ /**
13
+ * `only` narrows the list to the block at that index, focus on one block: it does not move
14
+ * then, its own lists do. `onRemove` asks first when the block holds blocks of its own.
15
+ */
16
+ type Props = { form: DocumentFormContext; list: string; only?: number; onRemove: () => void };
17
+ const { form, list, only, onRemove }: Props = $props();
15
18
 
16
19
  const focus = getBlocksFocusContext()!;
17
- const rows = $derived(focus.rowsOf(list));
20
+ const rows = $derived(
21
+ only === undefined ? focus.rowsOf(list) : focus.rowsOf(list).filter((row) => row.index === only)
22
+ );
18
23
 
19
24
  /**
20
25
  * A click selects the block, shows its fields, and stops there; a link inside a render does not
@@ -46,8 +51,10 @@
46
51
 
47
52
  /**
48
53
  * The stage is in the same group as the layers: a block drags from one to the other, a type
49
- * drags in from the palette, and a nested list is a target like any other.
54
+ * drags in from the palette, and a nested list is a target like any other. The stage mounts a
55
+ * list anew when focus moves, so `only` is read once.
50
56
  */
57
+ // svelte-ignore state_referenced_locally
51
58
  const { sortable } = useSortable({
52
59
  group: {
53
60
  name: 'rz-blocks-layers',
@@ -61,7 +68,7 @@
61
68
  animation: 150,
62
69
  fallbackOnBody: true,
63
70
  swapThreshold: 0.65,
64
- disabled: focus.locked,
71
+ disabled: focus.locked || only !== undefined,
65
72
  /** A type dropped from the palette: a new block at the drop index. */
66
73
  onAdd: (event: Sortable.SortableEvent) => {
67
74
  if (!event.from.classList.contains('rz-palette__list')) return;
@@ -90,7 +97,7 @@
90
97
 
91
98
  <!--
92
99
  One list of blocks, one wrapper per block. A block's nested lists are the `nested` snippet its
93
- render puts where they go; a block without a render is a placeholder card with them below.
100
+ render puts where they go; a block without a render is a row with them under it.
94
101
  -->
95
102
  <div class="rz-renders" data-list={list} data-empty={rows.length ? undefined : ''} use:sortableList>
96
103
  {#each rows as row (row.block.id)}
@@ -98,12 +105,15 @@
98
105
  {@const Render = config?.render}
99
106
  {#snippet nested(name?: string)}
100
107
  {#each row.children.filter((child) => !name || child.builder.name === name) as child (child.builder.name)}
108
+ <!-- All of them at once, and more than one: each under its name. -->
109
+ {#if !name && row.children.length > 1}
110
+ <p class="rz-renders__list-label">{child.label}</p>
111
+ {/if}
101
112
  <Renders {form} list={child.list} {onRemove} />
102
113
  {/each}
103
114
  {/snippet}
104
115
  <div
105
116
  class="rz-renders__item"
106
- data-placeholder={config?.render ? null : ''}
107
117
  data-path={row.path}
108
118
  data-type={row.block.type}
109
119
  data-selected={focus.isSelected(row.path) ? '' : undefined}
@@ -117,7 +127,7 @@
117
127
  }
118
128
  }}
119
129
  >
120
- {#if controlled(row.path)}
130
+ {#if controlled(row.path) && !focus.isNarrowedBlock(row.path)}
121
131
  <!-- Above it: move, duplicate, remove. A click on the block already opens its fields. -->
122
132
  <div class="rz-renders__toolbar">
123
133
  <button
@@ -139,6 +149,17 @@
139
149
  <ArrowDown size={14} />
140
150
  </button>
141
151
  <span class="rz-renders__toolbar-separator" aria-hidden="true"></span>
152
+ {#if row.children.length && focus.path !== row.path}
153
+ <!-- The stage narrowed to this block and what it holds. -->
154
+ <button
155
+ type="button"
156
+ title={t__('fields.focus_block')}
157
+ aria-label={t__('fields.focus_block')}
158
+ onclick={(event) => control(event, () => focus.open(row.path))}
159
+ >
160
+ <Focus size={14} />
161
+ </button>
162
+ {/if}
142
163
  <button
143
164
  type="button"
144
165
  title={t__('common.duplicate')}
@@ -167,21 +188,21 @@
167
188
  children={nested}
168
189
  />
169
190
  {#snippet failed(error)}
170
- <RenderPlaceholder {row} {error} children={nested} />
191
+ <DefaultRender {row} {error} children={nested} />
171
192
  {/snippet}
172
193
  </svelte:boundary>
173
194
  {:else}
174
- <RenderPlaceholder {row} children={nested} />
195
+ <DefaultRender {row} children={nested} />
175
196
  {/if}
176
197
  </div>
177
198
  {:else}
178
199
  {#if list === focus.path}
179
- <p class="rz-renders__empty">{t__('fields.no_blocks_yet_render')}</p>
200
+ <p class="rz-renders__empty">{t__('fields.no_blocks_yet')}</p>
180
201
  {/if}
181
202
  {/each}
182
203
  </div>
183
204
 
184
- <style>/* A level: its fill, a hairline, its shadow. raised, float. */
205
+ <style>/* A level: its fill, a hairline, and its shadow when it has one. raised has none, float does. */
185
206
 
186
207
  /* A well: an input, a track, a dropzone. Its edge shows on hover. */
187
208
 
@@ -236,6 +257,36 @@
236
257
  opacity: 0.4;
237
258
  }
238
259
 
260
+ /* A type dragged in from the palette: the row the block will be, not the palette's tile. */
261
+ :global(.rz-renders > .rz-palette__item.rz-block-tile) {
262
+ flex-direction: row;
263
+ align-items: center;
264
+ gap: var(--rz-size-2);
265
+ height: calc(11 * var(--rz-unit));
266
+ padding: 0 var(--rz-size-3);
267
+ border-radius: var(--rz-radius-md);
268
+ color: var(--rz-fg);
269
+ }
270
+ :global(.rz-renders > .rz-palette__item .rz-block-tile__frame) {
271
+ width: var(--rz-size-6);
272
+ flex-shrink: 0;
273
+ aspect-ratio: 1;
274
+ border-radius: var(--rz-radius-sm);
275
+ }
276
+ :global(.rz-renders > .rz-palette__item .rz-block-tile__title) {
277
+ padding-inline: 0;
278
+ }
279
+ :global(.rz-renders > .rz-palette__item .rz-block-tile__description) {
280
+ display: none;
281
+ }
282
+
283
+ /* The name of a nested list, when a block holds several. */
284
+ .rz-renders__list-label {
285
+ margin-bottom: calc(-1.5 * var(--rz-unit));
286
+ font-size: var(--rz-text-xs);
287
+ color: var(--rz-fg-subtle);
288
+ }
289
+
239
290
  /*
240
291
  * The selected block's bar: dark, on its top edge at the right, half over the gap above, so it
241
292
  * covers little of the block before.
@@ -1,9 +1,13 @@
1
1
  import type { DocumentFormContext } from '../../../../panel/context/documentForm.svelte.js';
2
2
  import Renders from './Renders.svelte';
3
- /** `onRemove` asks first when the block holds blocks of its own. */
3
+ /**
4
+ * `only` narrows the list to the block at that index, focus on one block: it does not move
5
+ * then, its own lists do. `onRemove` asks first when the block holds blocks of its own.
6
+ */
4
7
  type Props = {
5
8
  form: DocumentFormContext;
6
9
  list: string;
10
+ only?: number;
7
11
  onRemove: () => void;
8
12
  };
9
13
  declare const Renders: import("svelte").Component<Props, {}, "">;
@@ -22,7 +22,7 @@
22
22
  {before}<Kbd keys="/" />{after}
23
23
  </button>
24
24
 
25
- <style>/* A level: its fill, a hairline, its shadow. raised, float. */
25
+ <style>/* A level: its fill, a hairline, and its shadow when it has one. raised has none, float does. */
26
26
 
27
27
  /* A well: an input, a track, a dropzone. Its edge shows on hover. */
28
28
 
@@ -62,8 +62,5 @@
62
62
  font-size: var(--rz-text-sm);
63
63
  vertical-align: text-bottom;
64
64
  }
65
- :global(.rz-kbd__key) {
66
- background-color: var(--rz-bg-raised);
67
- }
68
65
  }
69
66
  </style>
@@ -2,7 +2,10 @@ import type { GenericBlock } from '../../../../core/prototype/types.js';
2
2
  import type { BlocksBuilder, BlocksFieldBlock } from '../../index.js';
3
3
  import { type BlockAt } from '../../../../panel/context/blocks-ops.js';
4
4
  import type { DocumentFormContext } from '../../../../panel/context/documentForm.svelte.js';
5
- /** The query parameter that names the list focus is open on: `?focus=layout.sections`. */
5
+ /**
6
+ * The query parameter that names what focus is open on: a list, `?focus=layout.sections`, or one
7
+ * block and what it holds, `?focus=layout.sections.1`.
8
+ */
6
9
  export declare const FOCUS_PARAM = "focus";
7
10
  export type SidebarTab = 'layers' | 'inspector' | 'add';
8
11
  /** One step of the way down to the open list: a blocks field, or the block an index names. */
@@ -33,12 +36,13 @@ export type LayerRow = {
33
36
  * rows are folded. The document form is the only state it writes to; a page reload with
34
37
  * `?focus=` in the address reopens it.
35
38
  *
36
- * The selection drives the stage: a block, or nothing, which is the root node of the layers and
37
- * shows the whole list.
39
+ * The stage shows the open list, or the one block the path ends on and the lists it holds. The
40
+ * selection is a block, or nothing, which is the root node of the layers.
38
41
  *
39
- * A focus opened from the field rides in `page.state`, so Escape, the close button and the back
40
- * button all do the same thing. One opened by the address has no history entry of its own: the
41
- * router is not ready for one while the page mounts, and closing it rewrites the address instead.
42
+ * A focus opened from the field rides in `page.state`, one history entry per `open`, so Escape
43
+ * and the back button go up the same levels. One opened by the address has no history entry of
44
+ * its own: the router is not ready for one while the page mounts, and going up rewrites the
45
+ * address instead.
42
46
  */
43
47
  export declare function setBlocksFocusContext(form: DocumentFormContext): {
44
48
  readonly path: string | null;
@@ -53,18 +57,23 @@ export declare function setBlocksFocusContext(form: DocumentFormContext): {
53
57
  picking: boolean;
54
58
  /** Opens the picker of types to add; the one picked goes after the selection. */
55
59
  pick(): void;
56
- /** The open list's block set has at least one render: the stage is the stack of renders. */
57
- readonly hasRenders: boolean;
60
+ /** The block the stage is narrowed to, when the path ends on one. */
61
+ readonly narrowedRow: LayerRow | null;
58
62
  /** Nothing selected: the root node, and the whole list on the stage. */
59
63
  readonly rootSelected: boolean;
60
64
  rootLabel: () => string;
61
65
  selectRoot: () => void;
62
66
  breadcrumb: () => Crumb[];
63
67
  isSelected: (rowPath: string) => boolean;
68
+ isNarrowedBlock: (rowPath: string) => boolean;
69
+ insertList: () => string | null;
64
70
  isCollapsed: (rowPath: string) => boolean;
65
- open: (list: string, selected?: string) => void;
71
+ open: (target: string, selected?: string) => void;
66
72
  close: () => void;
73
+ up: () => void;
67
74
  rowsOf: (list: string, depth?: number) => LayerRow[];
75
+ rootRows: () => LayerRow[];
76
+ homeList: () => string | null;
68
77
  allRows: () => LayerRow[];
69
78
  visibleRows: () => LayerRow[];
70
79
  moveTargets: () => {
@@ -103,18 +112,23 @@ export declare const getBlocksFocusContext: () => {
103
112
  picking: boolean;
104
113
  /** Opens the picker of types to add; the one picked goes after the selection. */
105
114
  pick(): void;
106
- /** The open list's block set has at least one render: the stage is the stack of renders. */
107
- readonly hasRenders: boolean;
115
+ /** The block the stage is narrowed to, when the path ends on one. */
116
+ readonly narrowedRow: LayerRow | null;
108
117
  /** Nothing selected: the root node, and the whole list on the stage. */
109
118
  readonly rootSelected: boolean;
110
119
  rootLabel: () => string;
111
120
  selectRoot: () => void;
112
121
  breadcrumb: () => Crumb[];
113
122
  isSelected: (rowPath: string) => boolean;
123
+ isNarrowedBlock: (rowPath: string) => boolean;
124
+ insertList: () => string | null;
114
125
  isCollapsed: (rowPath: string) => boolean;
115
- open: (list: string, selected?: string) => void;
126
+ open: (target: string, selected?: string) => void;
116
127
  close: () => void;
128
+ up: () => void;
117
129
  rowsOf: (list: string, depth?: number) => LayerRow[];
130
+ rootRows: () => LayerRow[];
131
+ homeList: () => string | null;
118
132
  allRows: () => LayerRow[];
119
133
  visibleRows: () => LayerRow[];
120
134
  moveTargets: () => {