@questpie/admin 3.2.0 → 3.2.2

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 (86) hide show
  1. package/dist/client/blocks/block-renderer.d.mts +12 -2
  2. package/dist/client/blocks/block-renderer.mjs +357 -49
  3. package/dist/client/components/blocks/block-editor-context.mjs +11 -1
  4. package/dist/client/components/blocks/block-editor-provider.mjs +68 -26
  5. package/dist/client/components/blocks/block-item.mjs +181 -170
  6. package/dist/client/components/blocks/utils/tree-utils.mjs +13 -1
  7. package/dist/client/components/fields/array-field.mjs +177 -118
  8. package/dist/client/components/filter-builder/filter-builder-sheet.mjs +305 -310
  9. package/dist/client/components/filter-builder/filters-tab.mjs +1 -1
  10. package/dist/client/components/history-sidebar.mjs +121 -114
  11. package/dist/client/components/preview/live-preview-mode.mjs +210 -175
  12. package/dist/client/components/preview/preview-pane.mjs +288 -333
  13. package/dist/client/components/primitives/option-label.mjs +44 -0
  14. package/dist/client/components/primitives/select-multi.mjs +408 -383
  15. package/dist/client/components/primitives/select-single.mjs +387 -357
  16. package/dist/client/components/widgets/chart-widget.mjs +168 -143
  17. package/dist/client/contexts/focus-context.d.mts +16 -1
  18. package/dist/client/contexts/focus-context.mjs +90 -38
  19. package/dist/client/hooks/use-brand.mjs +2 -1
  20. package/dist/client/preview/block-scope-context.d.mts +2 -2
  21. package/dist/client/preview/block-scope-context.mjs +10 -20
  22. package/dist/client/preview/index.d.mts +1 -1
  23. package/dist/client/preview/patch.mjs +100 -0
  24. package/dist/client/preview/preview-banner.d.mts +2 -2
  25. package/dist/client/preview/preview-field.d.mts +34 -5
  26. package/dist/client/preview/preview-field.mjs +385 -118
  27. package/dist/client/preview/types.d.mts +82 -3
  28. package/dist/client/preview/types.mjs +85 -6
  29. package/dist/client/preview/use-collection-preview.d.mts +19 -1
  30. package/dist/client/preview/use-collection-preview.mjs +182 -58
  31. package/dist/client/runtime/index.d.mts +2 -2
  32. package/dist/client/runtime/index.mjs +2 -2
  33. package/dist/client/runtime/provider.d.mts +5 -5
  34. package/dist/client/utils/build-field-definitions-from-schema.mjs +8 -3
  35. package/dist/client/views/auth/accept-invite-form.d.mts +2 -2
  36. package/dist/client/views/auth/auth-layout.d.mts +3 -3
  37. package/dist/client/views/auth/login-form.d.mts +2 -2
  38. package/dist/client/views/auth/reset-password-form.d.mts +2 -2
  39. package/dist/client/views/auth/setup-form.d.mts +2 -2
  40. package/dist/client/views/collection/bulk-action-toolbar.mjs +23 -25
  41. package/dist/client/views/collection/cells/primitive-cells.mjs +63 -13
  42. package/dist/client/views/collection/columns/build-columns.mjs +1 -0
  43. package/dist/client/views/collection/form-view.mjs +262 -33
  44. package/dist/client/views/collection/table-view.mjs +16 -11
  45. package/dist/client/views/layout/admin-layout-provider.d.mts +5 -5
  46. package/dist/client/views/layout/admin-layout-provider.mjs +107 -16
  47. package/dist/client/views/pages/accept-invite-page.d.mts +2 -2
  48. package/dist/client/views/pages/dashboard-page.d.mts +2 -2
  49. package/dist/client/views/pages/forgot-password-page.d.mts +2 -2
  50. package/dist/client/views/pages/reset-password-page.d.mts +2 -2
  51. package/dist/client/views/pages/setup-page.d.mts +2 -2
  52. package/dist/client.d.mts +2 -2
  53. package/dist/client.mjs +1 -1
  54. package/dist/index.d.mts +2 -2
  55. package/dist/index.mjs +1 -1
  56. package/dist/server/augmentation/common.d.mts +8 -4
  57. package/dist/server/augmentation/form-layout.d.mts +1 -1
  58. package/dist/server/i18n/messages/cs.mjs +11 -0
  59. package/dist/server/i18n/messages/de.mjs +11 -0
  60. package/dist/server/i18n/messages/en.mjs +11 -0
  61. package/dist/server/i18n/messages/es.mjs +11 -0
  62. package/dist/server/i18n/messages/fr.mjs +11 -0
  63. package/dist/server/i18n/messages/pl.mjs +11 -0
  64. package/dist/server/i18n/messages/pt.mjs +11 -0
  65. package/dist/server/i18n/messages/sk.mjs +11 -0
  66. package/dist/server/modules/admin/block/block-builder.d.mts +7 -10
  67. package/dist/server/modules/admin/block/block-builder.mjs +7 -10
  68. package/dist/server/modules/admin/collections/apikey.d.mts +64 -64
  69. package/dist/server/modules/admin/collections/assets.d.mts +57 -20
  70. package/dist/server/modules/admin/collections/session.d.mts +38 -38
  71. package/dist/server/modules/admin/collections/user.d.mts +100 -34
  72. package/dist/server/modules/admin/collections/user.mjs +4 -4
  73. package/dist/server/modules/admin/collections/verification.d.mts +31 -31
  74. package/dist/server/modules/admin/index.d.mts +3 -3
  75. package/dist/server/modules/admin/routes/admin-config.d.mts +2 -2
  76. package/dist/server/modules/admin/routes/admin-config.mjs +9 -12
  77. package/dist/server/modules/admin/routes/execute-action.d.mts +9 -9
  78. package/dist/server/modules/admin/routes/locales.d.mts +2 -2
  79. package/dist/server/modules/admin/routes/preview.d.mts +11 -11
  80. package/dist/server/modules/admin/routes/reactive.d.mts +9 -9
  81. package/dist/server/modules/admin/routes/translations.d.mts +4 -4
  82. package/dist/server/modules/admin/routes/translations.mjs +1 -1
  83. package/dist/server/modules/admin-preferences/collections/admin-preferences.mjs +4 -6
  84. package/dist/server/modules/admin-preferences/collections/saved-views.d.mts +4 -6
  85. package/dist/server/modules/admin-preferences/collections/saved-views.mjs +4 -6
  86. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import { BlockContent } from "./types.mjs";
2
2
  import * as React from "react";
3
- import * as react_jsx_runtime19 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime17 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/client/blocks/block-renderer.d.ts
6
6
 
@@ -9,6 +9,13 @@ import * as react_jsx_runtime19 from "react/jsx-runtime";
9
9
  * Consumers provide their own renderers mapped by block type.
10
10
  */
11
11
  type BlockRendererFn = (props: any) => React.ReactNode;
12
+ type BlockInsertRequest = {
13
+ position: {
14
+ parentId: string | null;
15
+ index: number;
16
+ };
17
+ referenceBlockId?: string;
18
+ };
12
19
  /**
13
20
  * Props for BlockRenderer component.
14
21
  */
@@ -23,6 +30,8 @@ type BlockRendererProps = {
23
30
  selectedBlockId?: string | null;
24
31
  /** Block click handler (for editor mode) */
25
32
  onBlockClick?: (blockId: string) => void;
33
+ /** Block insert handler (for preview editor mode) */
34
+ onBlockInsert?: (request: BlockInsertRequest) => void;
26
35
  /** Custom class name for the container */
27
36
  className?: string;
28
37
  };
@@ -39,7 +48,8 @@ declare function BlockRenderer({
39
48
  data,
40
49
  selectedBlockId,
41
50
  onBlockClick,
51
+ onBlockInsert,
42
52
  className
43
- }: BlockRendererProps): react_jsx_runtime19.JSX.Element | null;
53
+ }: BlockRendererProps): react_jsx_runtime17.JSX.Element | null;
44
54
  //#endregion
45
55
  export { BlockRenderer, BlockRendererProps };
@@ -1,8 +1,31 @@
1
+ import { cn } from "../lib/utils.mjs";
1
2
  import { BlockScopeProvider } from "../preview/block-scope-context.mjs";
2
3
  import { c } from "react/compiler-runtime";
3
- import { jsx } from "react/jsx-runtime";
4
+ import * as React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
4
6
 
5
7
  //#region src/client/blocks/block-renderer.tsx
8
+ /**
9
+ * BlockRenderer Component
10
+ *
11
+ * Renders a tree of blocks using registered block definitions.
12
+ * Each block type has a renderer component that receives the block's values.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * import { BlockRenderer } from "@questpie/admin/client";
17
+ * import { blocks } from "@/admin/blocks";
18
+ *
19
+ * function PageContent({ page }) {
20
+ * return (
21
+ * <BlockRenderer
22
+ * content={page.content}
23
+ * blocks={blocks}
24
+ * />
25
+ * );
26
+ * }
27
+ * ```
28
+ */
6
29
  const EMPTY_DATA = {};
7
30
  /**
8
31
  * Renders a tree of blocks.
@@ -12,16 +35,16 @@ const EMPTY_DATA = {};
12
35
  * children as the `children` prop.
13
36
  */
14
37
  function BlockRenderer(t0) {
15
- const $ = c(11);
16
- const { content, renderers, data, onBlockClick, className } = t0;
38
+ const $ = c(13);
39
+ const { content, renderers, data, selectedBlockId, onBlockClick, onBlockInsert, className } = t0;
17
40
  const resolvedData = data ?? EMPTY_DATA;
18
41
  let t1;
19
42
  let t2;
20
43
  let t3;
21
- if ($[0] !== className || $[1] !== content || $[2] !== onBlockClick || $[3] !== renderers || $[4] !== resolvedData) {
44
+ if ($[0] !== className || $[1] !== content || $[2] !== onBlockClick || $[3] !== onBlockInsert || $[4] !== renderers || $[5] !== resolvedData || $[6] !== selectedBlockId) {
22
45
  t3 = Symbol.for("react.early_return_sentinel");
23
46
  bb0: {
24
- function renderBlock(node) {
47
+ function renderBlock(node, parentId, index) {
25
48
  const renderFn = renderers[node.type] ?? renderers[kebabToCamelCase(node.type)];
26
49
  if (!renderFn) {
27
50
  if (process.env.NODE_ENV !== "production") console.warn(`[BlockRenderer] No renderer found for block type "${node.type}"`);
@@ -29,42 +52,36 @@ function BlockRenderer(t0) {
29
52
  }
30
53
  const values = content._values[node.id] || {};
31
54
  const blockData = resolvedData[node.id];
32
- const renderedChildren = node.children.length > 0 ? node.children.map(renderBlock) : void 0;
33
- const handleClick = onBlockClick ? (e) => {
34
- e.stopPropagation();
35
- onBlockClick(node.id);
36
- } : void 0;
37
- const BlockComponent = renderFn;
38
- const blockElement = /* @__PURE__ */ jsx(BlockScopeProvider, {
55
+ const isSelected = selectedBlockId === node.id;
56
+ const renderedChildren = node.children.length > 0 ? node.children.map((child, childIndex) => renderBlock(child, node.id, childIndex)) : void 0;
57
+ const blockElement = /* @__PURE__ */ jsx(renderFn, {
58
+ id: node.id,
59
+ type: node.type,
60
+ values,
61
+ data: blockData,
62
+ children: renderedChildren
63
+ });
64
+ const scopedBlockElement = /* @__PURE__ */ jsx(BlockScopeProvider, {
39
65
  blockId: node.id,
40
66
  basePath: "content._values",
41
- children: /* @__PURE__ */ jsx(BlockComponent, {
42
- id: node.id,
43
- type: node.type,
44
- values,
45
- data: blockData,
46
- children: renderedChildren
47
- })
48
- });
49
- if (handleClick) return /* @__PURE__ */ jsx("div", {
50
- "data-block-id": node.id,
51
- "data-block-type": node.type,
52
- onClick: handleClick,
53
- onKeyDown: (e_0) => {
54
- if (e_0.key === "Enter" || e_0.key === " ") {
55
- e_0.preventDefault();
56
- onBlockClick?.(node.id);
57
- }
58
- },
59
- role: "button",
60
- tabIndex: 0,
61
- className: "cursor-pointer",
62
67
  children: blockElement
63
- }, node.id);
68
+ });
69
+ if (onBlockClick) return /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsx(PreviewBlockWrapper, {
70
+ id: node.id,
71
+ isSelected,
72
+ onBlockClick,
73
+ type: node.type,
74
+ children: scopedBlockElement
75
+ }), onBlockInsert && /* @__PURE__ */ jsx(PreviewBlockInsertControl, {
76
+ onBlockInsert,
77
+ parentId,
78
+ referenceBlockId: node.id,
79
+ insertIndex: index + 1
80
+ })] }, node.id);
64
81
  return /* @__PURE__ */ jsx("div", {
65
82
  "data-block-id": node.id,
66
83
  "data-block-type": node.type,
67
- children: blockElement
84
+ children: scopedBlockElement
68
85
  }, node.id);
69
86
  }
70
87
  if (!content?._tree?.length) {
@@ -72,34 +89,325 @@ function BlockRenderer(t0) {
72
89
  break bb0;
73
90
  }
74
91
  t1 = className;
75
- t2 = content._tree.map(renderBlock);
92
+ t2 = content._tree.map((node_0, index_0) => renderBlock(node_0, null, index_0));
76
93
  }
77
94
  $[0] = className;
78
95
  $[1] = content;
79
96
  $[2] = onBlockClick;
80
- $[3] = renderers;
81
- $[4] = resolvedData;
82
- $[5] = t1;
83
- $[6] = t2;
84
- $[7] = t3;
97
+ $[3] = onBlockInsert;
98
+ $[4] = renderers;
99
+ $[5] = resolvedData;
100
+ $[6] = selectedBlockId;
101
+ $[7] = t1;
102
+ $[8] = t2;
103
+ $[9] = t3;
85
104
  } else {
86
- t1 = $[5];
87
- t2 = $[6];
88
- t3 = $[7];
105
+ t1 = $[7];
106
+ t2 = $[8];
107
+ t3 = $[9];
89
108
  }
90
109
  if (t3 !== Symbol.for("react.early_return_sentinel")) return t3;
91
110
  let t4;
92
- if ($[8] !== t1 || $[9] !== t2) {
111
+ if ($[10] !== t1 || $[11] !== t2) {
93
112
  t4 = /* @__PURE__ */ jsx("div", {
94
113
  className: t1,
95
114
  children: t2
96
115
  });
97
- $[8] = t1;
98
- $[9] = t2;
99
- $[10] = t4;
100
- } else t4 = $[10];
116
+ $[10] = t1;
117
+ $[11] = t2;
118
+ $[12] = t4;
119
+ } else t4 = $[12];
101
120
  return t4;
102
121
  }
122
+ function PreviewBlockInsertControl(t0) {
123
+ const $ = c(29);
124
+ const { insertIndex, onBlockInsert, parentId, referenceBlockId } = t0;
125
+ const [isHovered, setIsHovered] = React.useState(false);
126
+ let t1;
127
+ if ($[0] !== insertIndex || $[1] !== onBlockInsert || $[2] !== parentId || $[3] !== referenceBlockId) {
128
+ t1 = (event) => {
129
+ event.preventDefault();
130
+ event.stopPropagation();
131
+ onBlockInsert({
132
+ position: {
133
+ parentId,
134
+ index: insertIndex
135
+ },
136
+ referenceBlockId
137
+ });
138
+ };
139
+ $[0] = insertIndex;
140
+ $[1] = onBlockInsert;
141
+ $[2] = parentId;
142
+ $[3] = referenceBlockId;
143
+ $[4] = t1;
144
+ } else t1 = $[4];
145
+ const handleInsert = t1;
146
+ let t2;
147
+ let t3;
148
+ let t4;
149
+ let t5;
150
+ let t6;
151
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
152
+ t2 = () => setIsHovered(true);
153
+ t3 = () => setIsHovered(false);
154
+ t4 = () => setIsHovered(true);
155
+ t5 = () => setIsHovered(false);
156
+ t6 = {
157
+ alignItems: "center",
158
+ display: "flex",
159
+ height: 24,
160
+ justifyContent: "center",
161
+ marginBlock: -12,
162
+ paddingInline: 18,
163
+ pointerEvents: "auto",
164
+ position: "relative",
165
+ zIndex: 40
166
+ };
167
+ $[5] = t2;
168
+ $[6] = t3;
169
+ $[7] = t4;
170
+ $[8] = t5;
171
+ $[9] = t6;
172
+ } else {
173
+ t2 = $[5];
174
+ t3 = $[6];
175
+ t4 = $[7];
176
+ t5 = $[8];
177
+ t6 = $[9];
178
+ }
179
+ const t7 = isHovered ? .82 : 0;
180
+ const t8 = isHovered ? "translateX(-50%) scaleX(1)" : "translateX(-50%) scaleX(0.58)";
181
+ let t9;
182
+ if ($[10] !== t7 || $[11] !== t8) {
183
+ t9 = /* @__PURE__ */ jsx("span", {
184
+ "aria-hidden": "true",
185
+ style: {
186
+ background: "linear-gradient(90deg, transparent, color-mix(in srgb, var(--ring, var(--highlight, #b700ff)) 34%, transparent), transparent)",
187
+ height: 1,
188
+ left: "50%",
189
+ opacity: t7,
190
+ position: "absolute",
191
+ transform: t8,
192
+ transformOrigin: "center",
193
+ transition: "opacity 140ms ease, transform 140ms ease",
194
+ width: "min(240px, calc(100% - 48px))"
195
+ }
196
+ });
197
+ $[10] = t7;
198
+ $[11] = t8;
199
+ $[12] = t9;
200
+ } else t9 = $[12];
201
+ let t10;
202
+ if ($[13] !== handleInsert) {
203
+ t10 = (event_0) => {
204
+ if (event_0.key === "Enter" || event_0.key === " ") handleInsert(event_0);
205
+ };
206
+ $[13] = handleInsert;
207
+ $[14] = t10;
208
+ } else t10 = $[14];
209
+ const t11 = isHovered ? 1 : .28;
210
+ const t12 = isHovered ? "scale(1)" : "scale(0.92)";
211
+ let t13;
212
+ if ($[15] !== t11 || $[16] !== t12) {
213
+ t13 = {
214
+ alignItems: "center",
215
+ background: "transparent",
216
+ border: 0,
217
+ borderRadius: 999,
218
+ color: "var(--ring, var(--highlight, #b700ff))",
219
+ cursor: "pointer",
220
+ display: "inline-flex",
221
+ height: 32,
222
+ justifyContent: "center",
223
+ lineHeight: 1,
224
+ opacity: t11,
225
+ outline: "none",
226
+ padding: 0,
227
+ pointerEvents: "auto",
228
+ position: "relative",
229
+ transition: "opacity 140ms ease, transform 140ms ease",
230
+ transform: t12,
231
+ width: 40
232
+ };
233
+ $[15] = t11;
234
+ $[16] = t12;
235
+ $[17] = t13;
236
+ } else t13 = $[17];
237
+ const t14 = `1px solid ${isHovered ? "color-mix(in srgb, var(--ring, var(--highlight, #b700ff)) 34%, transparent)" : "color-mix(in srgb, var(--ring, var(--highlight, #b700ff)) 12%, transparent)"}`;
238
+ const t15 = isHovered ? "0 0 0 3px color-mix(in srgb, var(--ring, var(--highlight, #b700ff)) 8%, transparent), 0 5px 14px rgba(0, 0, 0, 0.12)" : "0 2px 8px rgba(0, 0, 0, 0.10)";
239
+ let t16;
240
+ if ($[18] !== t14 || $[19] !== t15) {
241
+ t16 = /* @__PURE__ */ jsx("span", {
242
+ "aria-hidden": "true",
243
+ style: {
244
+ alignItems: "center",
245
+ background: "var(--background, #fff)",
246
+ border: t14,
247
+ borderRadius: 999,
248
+ boxShadow: t15,
249
+ display: "inline-flex",
250
+ fontSize: 13,
251
+ fontWeight: 500,
252
+ height: 24,
253
+ justifyContent: "center",
254
+ transition: "border-color 140ms ease, box-shadow 140ms ease, transform 140ms ease",
255
+ width: 24
256
+ },
257
+ children: "+"
258
+ });
259
+ $[18] = t14;
260
+ $[19] = t15;
261
+ $[20] = t16;
262
+ } else t16 = $[20];
263
+ let t17;
264
+ if ($[21] !== handleInsert || $[22] !== t10 || $[23] !== t13 || $[24] !== t16) {
265
+ t17 = /* @__PURE__ */ jsx("button", {
266
+ type: "button",
267
+ "aria-label": "Add block here",
268
+ onClick: handleInsert,
269
+ onKeyDown: t10,
270
+ style: t13,
271
+ children: t16
272
+ });
273
+ $[21] = handleInsert;
274
+ $[22] = t10;
275
+ $[23] = t13;
276
+ $[24] = t16;
277
+ $[25] = t17;
278
+ } else t17 = $[25];
279
+ let t18;
280
+ if ($[26] !== t17 || $[27] !== t9) {
281
+ t18 = /* @__PURE__ */ jsxs("div", {
282
+ "data-preview-block-insert": "",
283
+ onMouseEnter: t2,
284
+ onMouseLeave: t3,
285
+ onFocus: t4,
286
+ onBlur: t5,
287
+ style: t6,
288
+ children: [t9, t17]
289
+ });
290
+ $[26] = t17;
291
+ $[27] = t9;
292
+ $[28] = t18;
293
+ } else t18 = $[28];
294
+ return t18;
295
+ }
296
+ function PreviewBlockWrapper(t0) {
297
+ const $ = c(25);
298
+ const { children, id, isSelected, onBlockClick, type } = t0;
299
+ const [isHovered, setIsHovered] = React.useState(false);
300
+ const [hasDomFocus, setHasDomFocus] = React.useState(false);
301
+ const t1 = isHovered || hasDomFocus || isSelected ? "var(--ring, var(--highlight, #b700ff))" : "transparent";
302
+ const t2 = isSelected ? "solid" : "dashed";
303
+ const t3 = isSelected ? "0 0 0 4px color-mix(in srgb, var(--ring, var(--highlight, #b700ff)) 18%, transparent)" : void 0;
304
+ let t4;
305
+ if ($[0] !== t1 || $[1] !== t2 || $[2] !== t3) {
306
+ t4 = {
307
+ outlineColor: t1,
308
+ outlineOffset: "4px",
309
+ outlineStyle: t2,
310
+ outlineWidth: "2px",
311
+ boxShadow: t3,
312
+ cursor: "pointer",
313
+ transition: "outline-color 150ms ease, box-shadow 150ms ease"
314
+ };
315
+ $[0] = t1;
316
+ $[1] = t2;
317
+ $[2] = t3;
318
+ $[3] = t4;
319
+ } else t4 = $[3];
320
+ const previewStyle = t4;
321
+ let t5;
322
+ if ($[4] !== id || $[5] !== onBlockClick) {
323
+ t5 = (e) => {
324
+ const target = e.target;
325
+ if (target?.closest("[data-preview-field]")) return;
326
+ const closestBlock = target?.closest("[data-block-id]");
327
+ if (closestBlock && closestBlock !== e.currentTarget) return;
328
+ e.preventDefault();
329
+ e.stopPropagation();
330
+ onBlockClick(id);
331
+ };
332
+ $[4] = id;
333
+ $[5] = onBlockClick;
334
+ $[6] = t5;
335
+ } else t5 = $[6];
336
+ const handleClick = t5;
337
+ let t6;
338
+ if ($[7] !== id || $[8] !== onBlockClick) {
339
+ t6 = (e_0) => {
340
+ const target_0 = e_0.target;
341
+ if (target_0?.closest("[data-preview-field]") || target_0?.closest("[data-block-id]") !== e_0.currentTarget) return;
342
+ if (e_0.key === "Enter" || e_0.key === " ") {
343
+ e_0.preventDefault();
344
+ e_0.stopPropagation();
345
+ onBlockClick(id);
346
+ }
347
+ };
348
+ $[7] = id;
349
+ $[8] = onBlockClick;
350
+ $[9] = t6;
351
+ } else t6 = $[9];
352
+ const handleKeyDown = t6;
353
+ const t7 = isSelected ? "true" : void 0;
354
+ let t10;
355
+ let t11;
356
+ let t8;
357
+ let t9;
358
+ if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
359
+ t8 = () => setIsHovered(true);
360
+ t9 = () => setIsHovered(false);
361
+ t10 = () => setHasDomFocus(true);
362
+ t11 = () => setHasDomFocus(false);
363
+ $[10] = t10;
364
+ $[11] = t11;
365
+ $[12] = t8;
366
+ $[13] = t9;
367
+ } else {
368
+ t10 = $[10];
369
+ t11 = $[11];
370
+ t8 = $[12];
371
+ t9 = $[13];
372
+ }
373
+ const t12 = isSelected && "outline-primary shadow-primary/20 shadow-[0_0_0_4px] outline outline-2 outline-offset-4";
374
+ let t13;
375
+ if ($[14] !== t12) {
376
+ t13 = cn("group/preview-block relative cursor-pointer transition-[outline-color,outline-offset,box-shadow] duration-150", "hover:outline-primary/40 hover:outline hover:outline-2 hover:outline-offset-4 hover:outline-dashed", t12);
377
+ $[14] = t12;
378
+ $[15] = t13;
379
+ } else t13 = $[15];
380
+ let t14;
381
+ if ($[16] !== children || $[17] !== handleClick || $[18] !== handleKeyDown || $[19] !== id || $[20] !== previewStyle || $[21] !== t13 || $[22] !== t7 || $[23] !== type) {
382
+ t14 = /* @__PURE__ */ jsx("div", {
383
+ "data-block-id": id,
384
+ "data-block-type": type,
385
+ "data-preview-block": "",
386
+ "data-preview-block-selected": t7,
387
+ onClick: handleClick,
388
+ onKeyDown: handleKeyDown,
389
+ onMouseEnter: t8,
390
+ onMouseLeave: t9,
391
+ onFocus: t10,
392
+ onBlur: t11,
393
+ role: "button",
394
+ tabIndex: 0,
395
+ style: previewStyle,
396
+ className: t13,
397
+ children
398
+ });
399
+ $[16] = children;
400
+ $[17] = handleClick;
401
+ $[18] = handleKeyDown;
402
+ $[19] = id;
403
+ $[20] = previewStyle;
404
+ $[21] = t13;
405
+ $[22] = t7;
406
+ $[23] = type;
407
+ $[24] = t14;
408
+ } else t14 = $[24];
409
+ return t14;
410
+ }
103
411
  function kebabToCamelCase(value) {
104
412
  return value.replace(/-([a-z])/g, (_, char) => char.toUpperCase());
105
413
  }
@@ -87,6 +87,16 @@ function useBlockLibraryOpen() {
87
87
  function _temp7(state) {
88
88
  return state.isLibraryOpen;
89
89
  }
90
+ function useIsBlockSelected(blockId) {
91
+ const $ = c(2);
92
+ let t0;
93
+ if ($[0] !== blockId) {
94
+ t0 = (state) => state.selectedBlockId === blockId;
95
+ $[0] = blockId;
96
+ $[1] = t0;
97
+ } else t0 = $[1];
98
+ return useBlockEditorStore(t0);
99
+ }
90
100
  /**
91
101
  * Hook to check if a block is expanded.
92
102
  */
@@ -122,4 +132,4 @@ function useBlockDefinition(blockType) {
122
132
  }
123
133
 
124
134
  //#endregion
125
- export { BlockEditorContextProvider, useAllowedBlockTypes, useBlockDefinition, useBlockEditorActions, useBlockInsertPosition, useBlockLibraryOpen, useBlockRegistry, useBlockSchema, useBlockTree, useBlockValues, useIsBlockExpanded };
135
+ export { BlockEditorContextProvider, useAllowedBlockTypes, useBlockDefinition, useBlockEditorActions, useBlockInsertPosition, useBlockLibraryOpen, useBlockRegistry, useBlockSchema, useBlockTree, useBlockValues, useIsBlockExpanded, useIsBlockSelected };
@@ -1,7 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  import { BlockEditorContextProvider } from "./block-editor-context.mjs";
4
- import { duplicateBlockInTree, getAllBlockIds, getDefaultValues, insertBlockInTree, removeBlockFromTree, reorderBlockInTree } from "./utils/tree-utils.mjs";
4
+ import { duplicateBlockInTree, getAllBlockIds, getBlockPathIds, getDefaultValues, insertBlockInTree, removeBlockFromTree, reorderBlockInTree } from "./utils/tree-utils.mjs";
5
+ import { useFocusOptional } from "../../contexts/focus-context.mjs";
5
6
  import { c } from "react/compiler-runtime";
6
7
  import * as React from "react";
7
8
  import { createStore } from "zustand";
@@ -14,10 +15,11 @@ import { jsx } from "react/jsx-runtime";
14
15
  * Provides selector-driven state and actions for the block editor.
15
16
  */
16
17
  function BlockEditorProvider(t0) {
17
- const $ = c(18);
18
+ const $ = c(22);
18
19
  const { value, onChange, blocks, allowedBlocks, locale: t1, children } = t0;
19
20
  const locale = t1 === void 0 ? "en" : t1;
20
21
  const onChangeRef = React.useRef(onChange);
22
+ const previewFocusState = useFocusOptional()?.state;
21
23
  let t2;
22
24
  let t3;
23
25
  if ($[0] !== onChange) {
@@ -186,49 +188,89 @@ function BlockEditorProvider(t0) {
186
188
  const [store] = React.useState(t4);
187
189
  let t5;
188
190
  let t6;
189
- if ($[8] !== allowedBlocks || $[9] !== blocks || $[10] !== locale || $[11] !== store || $[12] !== value) {
191
+ if ($[8] !== previewFocusState || $[9] !== store) {
190
192
  t5 = () => {
193
+ if (previewFocusState?.type !== "block" && previewFocusState?.type !== "block-insert") return;
191
194
  const state_4 = store.getState();
195
+ const targetBlockId = previewFocusState.type === "block" ? previewFocusState.blockId : previewFocusState.referenceBlockId ?? previewFocusState.position.parentId;
196
+ let expandedBlockIds = state_4.expandedBlockIds;
197
+ if (targetBlockId) {
198
+ const blockPath = getBlockPathIds(state_4.content._tree, targetBlockId);
199
+ if (!blockPath) return;
200
+ expandedBlockIds = new Set(state_4.expandedBlockIds);
201
+ for (const blockId of blockPath) expandedBlockIds.add(blockId);
202
+ }
203
+ if (previewFocusState.type === "block-insert") {
204
+ store.setState({
205
+ selectedBlockId: targetBlockId,
206
+ isLibraryOpen: true,
207
+ insertPosition: previewFocusState.position,
208
+ expandedBlockIds
209
+ });
210
+ return;
211
+ }
212
+ store.setState({
213
+ selectedBlockId: previewFocusState.blockId,
214
+ isLibraryOpen: false,
215
+ insertPosition: null,
216
+ expandedBlockIds
217
+ });
218
+ };
219
+ t6 = [previewFocusState, store];
220
+ $[8] = previewFocusState;
221
+ $[9] = store;
222
+ $[10] = t5;
223
+ $[11] = t6;
224
+ } else {
225
+ t5 = $[10];
226
+ t6 = $[11];
227
+ }
228
+ React.useEffect(t5, t6);
229
+ let t7;
230
+ let t8;
231
+ if ($[12] !== allowedBlocks || $[13] !== blocks || $[14] !== locale || $[15] !== store || $[16] !== value) {
232
+ t7 = () => {
233
+ const state_5 = store.getState();
192
234
  let nextAllowedBlocks;
193
235
  if (allowedBlocks != null) nextAllowedBlocks = allowedBlocks;
194
236
  else nextAllowedBlocks = null;
195
237
  const patch = {};
196
- if (state_4.content !== value) patch.content = value;
197
- if (state_4.blocks !== blocks) patch.blocks = blocks;
198
- if (state_4.allowedBlocks !== nextAllowedBlocks) patch.allowedBlocks = nextAllowedBlocks;
199
- if (state_4.locale !== locale) patch.locale = locale;
238
+ if (state_5.content !== value) patch.content = value;
239
+ if (state_5.blocks !== blocks) patch.blocks = blocks;
240
+ if (state_5.allowedBlocks !== nextAllowedBlocks) patch.allowedBlocks = nextAllowedBlocks;
241
+ if (state_5.locale !== locale) patch.locale = locale;
200
242
  if (Object.keys(patch).length > 0) store.setState(patch);
201
243
  };
202
- t6 = [
244
+ t8 = [
203
245
  value,
204
246
  blocks,
205
247
  allowedBlocks,
206
248
  locale,
207
249
  store
208
250
  ];
209
- $[8] = allowedBlocks;
210
- $[9] = blocks;
211
- $[10] = locale;
212
- $[11] = store;
213
- $[12] = value;
214
- $[13] = t5;
215
- $[14] = t6;
251
+ $[12] = allowedBlocks;
252
+ $[13] = blocks;
253
+ $[14] = locale;
254
+ $[15] = store;
255
+ $[16] = value;
256
+ $[17] = t7;
257
+ $[18] = t8;
216
258
  } else {
217
- t5 = $[13];
218
- t6 = $[14];
259
+ t7 = $[17];
260
+ t8 = $[18];
219
261
  }
220
- React.useEffect(t5, t6);
221
- let t7;
222
- if ($[15] !== children || $[16] !== store) {
223
- t7 = /* @__PURE__ */ jsx(BlockEditorContextProvider, {
262
+ React.useEffect(t7, t8);
263
+ let t9;
264
+ if ($[19] !== children || $[20] !== store) {
265
+ t9 = /* @__PURE__ */ jsx(BlockEditorContextProvider, {
224
266
  value: store,
225
267
  children
226
268
  });
227
- $[15] = children;
228
- $[16] = store;
229
- $[17] = t7;
230
- } else t7 = $[17];
231
- return t7;
269
+ $[19] = children;
270
+ $[20] = store;
271
+ $[21] = t9;
272
+ } else t9 = $[21];
273
+ return t9;
232
274
  }
233
275
 
234
276
  //#endregion