camox 0.12.1 → 0.14.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.
@@ -10,7 +10,7 @@ import { LexicalComposer } from "@lexical/react/LexicalComposer";
10
10
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
11
11
  import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
12
12
  import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
13
- import { COMMAND_PRIORITY_LOW, KEY_ESCAPE_COMMAND } from "lexical";
13
+ import { COMMAND_PRIORITY_LOW, INSERT_LINE_BREAK_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND } from "lexical";
14
14
 
15
15
  //#region src/core/components/lexical/InlineLexicalEditor.tsx
16
16
  function ExternalStateSync(t0) {
@@ -89,6 +89,28 @@ function EscapeHandler() {
89
89
  React.useEffect(t0, t1);
90
90
  return null;
91
91
  }
92
+ function EnterAsLineBreakHandler() {
93
+ const $ = c(3);
94
+ const [editor] = useLexicalComposerContext();
95
+ let t0;
96
+ let t1;
97
+ if ($[0] !== editor) {
98
+ t0 = () => editor.registerCommand(KEY_ENTER_COMMAND, (event) => {
99
+ event?.preventDefault();
100
+ editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
101
+ return true;
102
+ }, COMMAND_PRIORITY_LOW);
103
+ t1 = [editor];
104
+ $[0] = editor;
105
+ $[1] = t0;
106
+ $[2] = t1;
107
+ } else {
108
+ t0 = $[1];
109
+ t1 = $[2];
110
+ }
111
+ React.useEffect(t0, t1);
112
+ return null;
113
+ }
92
114
  function FocusBlurHandler(t0) {
93
115
  const $ = c(5);
94
116
  const { onFocus, onBlur } = t0;
@@ -157,6 +179,7 @@ function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, o
157
179
  /* @__PURE__ */ jsx(OnChangePlugin, { onChange: handleChange }),
158
180
  /* @__PURE__ */ jsx(ExternalStateSync, { externalState }),
159
181
  /* @__PURE__ */ jsx(EscapeHandler, {}),
182
+ /* @__PURE__ */ jsx(EnterAsLineBreakHandler, {}),
160
183
  /* @__PURE__ */ jsx(FocusBlurHandler, {
161
184
  onFocus: handleFocus,
162
185
  onBlur: handleBlur
@@ -8,9 +8,32 @@ import { LexicalComposer } from "@lexical/react/LexicalComposer";
8
8
  import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
9
9
  import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
10
10
  import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
11
+ import { COMMAND_PRIORITY_LOW, INSERT_LINE_BREAK_COMMAND, KEY_ENTER_COMMAND } from "lexical";
11
12
  import { ContentEditable } from "@lexical/react/LexicalContentEditable";
12
13
 
13
14
  //#region src/core/components/lexical/SidebarLexicalEditor.tsx
15
+ function EnterAsLineBreakHandler() {
16
+ const $ = c(3);
17
+ const [editor] = useLexicalComposerContext();
18
+ let t0;
19
+ let t1;
20
+ if ($[0] !== editor) {
21
+ t0 = () => editor.registerCommand(KEY_ENTER_COMMAND, (event) => {
22
+ event?.preventDefault();
23
+ editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
24
+ return true;
25
+ }, COMMAND_PRIORITY_LOW);
26
+ t1 = [editor];
27
+ $[0] = editor;
28
+ $[1] = t0;
29
+ $[2] = t1;
30
+ } else {
31
+ t0 = $[1];
32
+ t1 = $[2];
33
+ }
34
+ React.useEffect(t0, t1);
35
+ return null;
36
+ }
14
37
  function ExternalStateSync(t0) {
15
38
  const $ = c(5);
16
39
  const { value, isSyncingRef } = t0;
@@ -82,7 +105,8 @@ function SidebarLexicalEditor({ id, value, onChange, onFocus, onBlur }) {
82
105
  /* @__PURE__ */ jsx(ExternalStateSync, {
83
106
  value,
84
107
  isSyncingRef
85
- })
108
+ }),
109
+ /* @__PURE__ */ jsx(EnterAsLineBreakHandler, {})
86
110
  ]
87
111
  });
88
112
  }
@@ -271,8 +271,10 @@ declare function createApp({
271
271
  name: string;
272
272
  children: (item: any, index: number) => React.ReactNode;
273
273
  }) => React.ReactNode;
274
+ useSetting: (name: string) => unknown;
274
275
  }, index: number) => React.ReactNode;
275
276
  }) => React.ReactNode;
277
+ useSetting: <F extends string>(name: F) => never;
276
278
  }, index: number) => React.ReactNode;
277
279
  }) => _$react_jsx_runtime0.JSX.Element;
278
280
  useSetting: <K extends string>(name: K) => unknown;
@@ -593,8 +595,10 @@ declare function createApp({
593
595
  name: string;
594
596
  children: (item: any, index: number) => React.ReactNode;
595
597
  }) => React.ReactNode;
598
+ useSetting: (name: string) => unknown;
596
599
  }, index: number) => React.ReactNode;
597
600
  }) => React.ReactNode;
601
+ useSetting: <F extends string>(name: F) => never;
598
602
  }, index: number) => React.ReactNode;
599
603
  }) => _$react_jsx_runtime0.JSX.Element;
600
604
  useSetting: <K extends string>(name: K) => unknown;
@@ -1,4 +1,4 @@
1
- import { EmbedURL, FileValue, ImageValue, LinkValue, ToMarkdownBuilder, Type } from "./lib/contentType.js";
1
+ import { EmbedURL, FileValue, ImageValue, ItemSettingsBrand, LinkValue, ToMarkdownBuilder, Type } from "./lib/contentType.js";
2
2
  import * as _$_sinclair_typebox0 from "@sinclair/typebox";
3
3
  import { Static, TSchema, Type as Type$1 } from "@sinclair/typebox";
4
4
  import * as React from "react";
@@ -61,13 +61,16 @@ interface CreateBlockOptions<TSchemaShape extends Record<string, TSchema> = Reco
61
61
  /**
62
62
  * Builder for rendering block content as markdown.
63
63
  * `c` is a proxy typed on `content` keys — `c.title`, `c.description`, etc.
64
- * Each returned entry becomes a paragraph (joined with `\n\n`).
65
- * Lines where all referenced fields resolve to empty are omitted at render time.
64
+ * `s` is a proxy typed on `settings` keys — call a boolean setting with a line
65
+ * (`s.showCta(c.cta)`) or an enum with a value (`s.variant("banner", [...])`)
66
+ * to wrap lines in a conditional. Each returned entry becomes a paragraph
67
+ * (joined with `\n\n`). Lines where all referenced fields resolve to empty
68
+ * (or whose condition is false) are omitted at render time.
66
69
  *
67
70
  * @example
68
- * toMarkdown: (c) => [`# ${c.title}`, c.description, c.illustration, c.cta]
71
+ * toMarkdown: (c, s) => [`# ${c.title}`, c.description, s.showCta(c.cta)]
69
72
  */
70
- toMarkdown: ToMarkdownBuilder<TSchemaShape>;
73
+ toMarkdown: ToMarkdownBuilder<TSchemaShape, TSettingsShape>;
71
74
  }
72
75
  interface BlockData<TContent> {
73
76
  _id: number;
@@ -90,6 +93,7 @@ interface PeekItem {
90
93
  parentItemId: number | null;
91
94
  fieldName: string;
92
95
  content: unknown;
96
+ settings: Record<string, unknown> | null;
93
97
  summary: string;
94
98
  position: string;
95
99
  createdAt: number;
@@ -100,6 +104,7 @@ interface RepeatableItemSeed {
100
104
  parentTempId: string | null;
101
105
  fieldName: string;
102
106
  content: Record<string, unknown>;
107
+ settings?: Record<string, unknown>;
103
108
  position: string;
104
109
  }
105
110
  declare function createBlock<TSchemaShape extends Record<string, TSchema>, TSettingsShape extends Record<string, TSchema> = Record<string, never>, TLayoutOnly extends boolean = false>(options: CreateBlockOptions<TSchemaShape, TSettingsShape, TLayoutOnly>): {
@@ -1055,8 +1060,30 @@ declare function createBlock<TSchemaShape extends Record<string, TSchema>, TSett
1055
1060
  name: string;
1056
1061
  children: (item: any, index: number) => React.ReactNode;
1057
1062
  }) => React.ReactNode;
1063
+ useSetting: (name: string) => unknown;
1058
1064
  }, index: number) => React.ReactNode;
1059
1065
  }) => React.ReactNode;
1066
+ useSetting: <F extends keyof (TSchemaShape[K] extends {
1067
+ readonly [ItemSettingsBrand]?: infer S;
1068
+ } ? S extends Record<string, TSchema> ? _$_sinclair_typebox0.Evaluate<Readonly<Partial<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1069
+ params: unknown[] & [];
1070
+ })["static"] }, { [K_7 in keyof S]: S[K_7] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_7] extends _$_sinclair_typebox0.TOptional<S[K_7]> ? K_7 : never : never }[keyof S]>>> & Readonly<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1071
+ params: unknown[] & [];
1072
+ })["static"] }, { [K_8 in keyof S]: S[K_8] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_8] extends _$_sinclair_typebox0.TOptional<S[K_8]> ? never : K_8 : never }[keyof S]>> & Partial<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1073
+ params: unknown[] & [];
1074
+ })["static"] }, { [K_9 in keyof S]: S[K_9] extends _$_sinclair_typebox0.TOptional<TSchema> ? S[K_9] extends _$_sinclair_typebox0.TReadonly<S[K_9]> ? never : K_9 : never }[keyof S]>> & Required<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1075
+ params: unknown[] & [];
1076
+ })["static"] }, Exclude<keyof S, { [K_7 in keyof S]: S[K_7] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_7] extends _$_sinclair_typebox0.TOptional<S[K_7]> ? K_7 : never : never }[keyof S] | { [K_8 in keyof S]: S[K_8] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_8] extends _$_sinclair_typebox0.TOptional<S[K_8]> ? never : K_8 : never }[keyof S] | { [K_9 in keyof S]: S[K_9] extends _$_sinclair_typebox0.TOptional<TSchema> ? S[K_9] extends _$_sinclair_typebox0.TReadonly<S[K_9]> ? never : K_9 : never }[keyof S]>>>> : Record<string, never> : Record<string, never>)>(name: F) => (TSchemaShape[K] extends {
1077
+ readonly [ItemSettingsBrand]?: infer S;
1078
+ } ? S extends Record<string, TSchema> ? _$_sinclair_typebox0.Evaluate<Readonly<Partial<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1079
+ params: unknown[] & [];
1080
+ })["static"] }, { [K_7 in keyof S]: S[K_7] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_7] extends _$_sinclair_typebox0.TOptional<S[K_7]> ? K_7 : never : never }[keyof S]>>> & Readonly<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1081
+ params: unknown[] & [];
1082
+ })["static"] }, { [K_8 in keyof S]: S[K_8] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_8] extends _$_sinclair_typebox0.TOptional<S[K_8]> ? never : K_8 : never }[keyof S]>> & Partial<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1083
+ params: unknown[] & [];
1084
+ })["static"] }, { [K_9 in keyof S]: S[K_9] extends _$_sinclair_typebox0.TOptional<TSchema> ? S[K_9] extends _$_sinclair_typebox0.TReadonly<S[K_9]> ? never : K_9 : never }[keyof S]>> & Required<Pick<{ [K_6 in keyof S]: (S[K_6] & {
1085
+ params: unknown[] & [];
1086
+ })["static"] }, Exclude<keyof S, { [K_7 in keyof S]: S[K_7] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_7] extends _$_sinclair_typebox0.TOptional<S[K_7]> ? K_7 : never : never }[keyof S] | { [K_8 in keyof S]: S[K_8] extends _$_sinclair_typebox0.TReadonly<TSchema> ? S[K_8] extends _$_sinclair_typebox0.TOptional<S[K_8]> ? never : K_8 : never }[keyof S] | { [K_9 in keyof S]: S[K_9] extends _$_sinclair_typebox0.TOptional<TSchema> ? S[K_9] extends _$_sinclair_typebox0.TReadonly<S[K_9]> ? never : K_9 : never }[keyof S]>>>> : Record<string, never> : Record<string, never>)[F];
1060
1087
  }, index: number) => React.ReactNode;
1061
1088
  }) => _$react_jsx_runtime0.JSX.Element;
1062
1089
  useSetting: <K extends keyof (TSettingsShape extends Record<string, never> ? Record<string, never> : _$_sinclair_typebox0.Evaluate<Readonly<Partial<Pick<{ [K_1 in keyof TSettingsShape]: (TSettingsShape[K_1] & {
@@ -67,6 +67,7 @@ function buildInitialSeeds(properties, parentTempId, content, allSeeds, counter)
67
67
  if (propSchema.type === "array" && propSchema.items?.properties) continue;
68
68
  if ("default" in propSchema) itemContent[propName] = propSchema.default;
69
69
  }
70
+ const itemSettingsDefaults = fieldSchema.defaultItemSettings;
70
71
  const markers = [];
71
72
  let prevPosition = null;
72
73
  for (let i = 0; i < defaultCount; i++) {
@@ -78,6 +79,7 @@ function buildInitialSeeds(properties, parentTempId, content, allSeeds, counter)
78
79
  parentTempId,
79
80
  fieldName,
80
81
  content: { ...itemContent },
82
+ settings: itemSettingsDefaults ? { ...itemSettingsDefaults } : void 0,
81
83
  position
82
84
  });
83
85
  markers.push({ _itemId: tempId });
@@ -102,6 +104,7 @@ function buildPeekItems(properties, blockId, parentItemId, content, allItems, co
102
104
  if (propSchema.type === "array" && propSchema.items?.properties) continue;
103
105
  if ("default" in propSchema) itemContent[propName] = propSchema.default;
104
106
  }
107
+ const itemSettingsDefaults = fieldSchema.defaultItemSettings;
105
108
  const markers = [];
106
109
  let prevPosition = null;
107
110
  for (let i = 0; i < defaultCount; i++) {
@@ -114,6 +117,7 @@ function buildPeekItems(properties, blockId, parentItemId, content, allItems, co
114
117
  parentItemId,
115
118
  fieldName,
116
119
  content: { ...itemContent },
120
+ settings: itemSettingsDefaults ? { ...itemSettingsDefaults } : null,
117
121
  summary: "",
118
122
  position,
119
123
  createdAt: 0,
@@ -139,7 +143,7 @@ function createBlock(options) {
139
143
  description: options.description,
140
144
  properties: typeboxSchema.properties,
141
145
  required: Object.keys(options.content),
142
- toMarkdown: resolveToMarkdown(options.toMarkdown)
146
+ toMarkdown: resolveToMarkdown(options.toMarkdown, options.settings, "block")
143
147
  };
144
148
  const settingsTypeboxSchema = options.settings ? Type$1.Object(options.settings) : null;
145
149
  const settingsSchema = settingsTypeboxSchema ? {
@@ -157,12 +161,14 @@ function createBlock(options) {
157
161
  contentDefaultsForStorage[key] = prop.default;
158
162
  }
159
163
  const repeatableItemDefaults = {};
164
+ const repeatableItemSettingsDefaults = {};
160
165
  for (const [key, prop] of Object.entries(typeboxSchema.properties)) {
161
166
  const p = prop;
162
167
  if (p.type === "array" && p.items?.properties) {
163
168
  const itemDefaults = {};
164
169
  for (const [itemKey, itemProp] of Object.entries(p.items.properties)) if (itemProp && typeof itemProp === "object" && "default" in itemProp) itemDefaults[itemKey] = itemProp.default;
165
170
  if (Object.keys(itemDefaults).length > 0) repeatableItemDefaults[key] = itemDefaults;
171
+ if (p.defaultItemSettings && typeof p.defaultItemSettings === "object") repeatableItemSettingsDefaults[key] = p.defaultItemSettings;
166
172
  }
167
173
  }
168
174
  const settingsDefaults = {};
@@ -968,92 +974,141 @@ function createBlock(options) {
968
974
  return t3;
969
975
  };
970
976
  const Repeater = (t0) => {
971
- const $ = c(10);
977
+ const $ = c(28);
972
978
  const { name, children } = t0;
973
979
  const blockContext = React.use(Context);
974
980
  if (!blockContext) throw new Error("Repeater must be used within a Block Component");
975
981
  const { blockId, content, mode } = blockContext;
976
982
  const parentRepeaterContext = React.use(RepeaterItemContext);
977
983
  const fieldName = String(name);
978
- const itemComponents = {
979
- Field,
980
- Link,
981
- Embed,
982
- Image,
983
- File,
984
- Repeater
985
- };
984
+ const ItemField = Field;
985
+ const ItemLink = Link;
986
+ const ItemEmbed = Embed;
987
+ const ItemImage = Image;
988
+ const ItemFile = File;
989
+ const ItemRepeater = Repeater;
986
990
  const source = parentRepeaterContext ? parentRepeaterContext.itemContent[name] : content[name];
987
991
  const { itemsMap } = useNormalizedData();
988
- let arrayValue = source ?? [];
989
- if (!Array.isArray(arrayValue)) throw new Error(`Field "${String(name)}" is not an array`);
992
+ let T0;
990
993
  let t1;
991
- if ($[0] !== itemsMap) {
992
- t1 = (item) => {
993
- if (isItemMarker(item)) return itemsMap.get(item._itemId) ?? null;
994
- return item;
995
- };
996
- $[0] = itemsMap;
997
- $[1] = t1;
998
- } else t1 = $[1];
999
- arrayValue = arrayValue.map(t1).filter(Boolean);
1000
- if (arrayValue.length === 0) {
1001
- const fieldSchema = parentRepeaterContext ? typeboxSchema.properties[parentRepeaterContext.arrayFieldName]?.items?.properties?.[fieldName] : typeboxSchema.properties[fieldName];
1002
- const ait = fieldSchema?.arrayItemType;
1003
- if (ait === "Image" || ait === "File") {
1004
- const defaultCount = fieldSchema.defaultItems ?? 0;
1005
- const itemProps = fieldSchema.items?.properties;
1006
- if (defaultCount > 0 && itemProps) {
1007
- let t2;
1008
- if ($[2] !== defaultCount || $[3] !== itemProps) {
1009
- const itemContent = {};
1010
- for (const [propName, propSchema] of Object.entries(itemProps)) if (propSchema && typeof propSchema === "object" && "default" in propSchema) itemContent[propName] = propSchema.default;
1011
- t2 = Array.from({ length: defaultCount }, () => ({ ...itemContent }));
1012
- $[2] = defaultCount;
1013
- $[3] = itemProps;
1014
- $[4] = t2;
1015
- } else t2 = $[4];
1016
- arrayValue = t2;
994
+ let t2;
995
+ let t3;
996
+ if ($[0] !== blockId || $[1] !== children || $[2] !== fieldName || $[3] !== itemsMap || $[4] !== mode || $[5] !== name || $[6] !== parentRepeaterContext || $[7] !== source) {
997
+ let arrayValue = source ?? [];
998
+ if (!Array.isArray(arrayValue)) throw new Error(`Field "${String(name)}" is not an array`);
999
+ let t4;
1000
+ if ($[12] !== itemsMap) {
1001
+ t4 = (item) => {
1002
+ if (isItemMarker(item)) return itemsMap.get(item._itemId) ?? null;
1003
+ return item;
1004
+ };
1005
+ $[12] = itemsMap;
1006
+ $[13] = t4;
1007
+ } else t4 = $[13];
1008
+ arrayValue = arrayValue.map(t4).filter(Boolean);
1009
+ if (arrayValue.length === 0) {
1010
+ const fieldSchema = parentRepeaterContext ? typeboxSchema.properties[parentRepeaterContext.arrayFieldName]?.items?.properties?.[fieldName] : typeboxSchema.properties[fieldName];
1011
+ const ait = fieldSchema?.arrayItemType;
1012
+ if (ait === "Image" || ait === "File") {
1013
+ const defaultCount = fieldSchema.defaultItems ?? 0;
1014
+ const itemProps = fieldSchema.items?.properties;
1015
+ if (defaultCount > 0 && itemProps) {
1016
+ let t5;
1017
+ if ($[14] !== defaultCount || $[15] !== itemProps) {
1018
+ const itemContent = {};
1019
+ for (const [propName, propSchema] of Object.entries(itemProps)) if (propSchema && typeof propSchema === "object" && "default" in propSchema) itemContent[propName] = propSchema.default;
1020
+ t5 = Array.from({ length: defaultCount }, () => ({ ...itemContent }));
1021
+ $[14] = defaultCount;
1022
+ $[15] = itemProps;
1023
+ $[16] = t5;
1024
+ } else t5 = $[16];
1025
+ arrayValue = t5;
1026
+ }
1017
1027
  }
1018
1028
  }
1029
+ const settingsDefaultsForField = repeatableItemSettingsDefaults[fieldName];
1030
+ T0 = RepeaterHoverProvider;
1031
+ t1 = blockId;
1032
+ t2 = fieldName;
1033
+ let t5;
1034
+ if ($[17] !== blockId || $[18] !== children || $[19] !== fieldName || $[20] !== mode || $[21] !== settingsDefaultsForField) {
1035
+ t5 = (item_0, index) => {
1036
+ const isDbItem = item_0.content !== void 0 && item_0.id != null;
1037
+ const itemContent_0 = {
1038
+ ...repeatableItemDefaults[fieldName],
1039
+ ...isDbItem ? item_0.content : item_0
1040
+ };
1041
+ const itemSettings = {
1042
+ ...settingsDefaultsForField,
1043
+ ...(isDbItem ? item_0.settings : null) ?? {}
1044
+ };
1045
+ const itemId = isDbItem ? item_0.id : void 0;
1046
+ const useItemSetting = (settingName) => itemSettings[settingName];
1047
+ const itemApi = {
1048
+ Field: ItemField,
1049
+ Link: ItemLink,
1050
+ Embed: ItemEmbed,
1051
+ Image: ItemImage,
1052
+ File: ItemFile,
1053
+ Repeater: ItemRepeater,
1054
+ useSetting: useItemSetting
1055
+ };
1056
+ return /* @__PURE__ */ jsx(RepeaterItemContext.Provider, {
1057
+ value: {
1058
+ arrayFieldName: fieldName,
1059
+ itemIndex: index,
1060
+ itemContent: itemContent_0,
1061
+ itemSettings,
1062
+ itemId
1063
+ },
1064
+ children: /* @__PURE__ */ jsx(RepeaterItemWrapper, {
1065
+ itemId,
1066
+ blockId,
1067
+ mode,
1068
+ children: children(itemApi, index)
1069
+ })
1070
+ }, itemId ?? index);
1071
+ };
1072
+ $[17] = blockId;
1073
+ $[18] = children;
1074
+ $[19] = fieldName;
1075
+ $[20] = mode;
1076
+ $[21] = settingsDefaultsForField;
1077
+ $[22] = t5;
1078
+ } else t5 = $[22];
1079
+ t3 = arrayValue.map(t5);
1080
+ $[0] = blockId;
1081
+ $[1] = children;
1082
+ $[2] = fieldName;
1083
+ $[3] = itemsMap;
1084
+ $[4] = mode;
1085
+ $[5] = name;
1086
+ $[6] = parentRepeaterContext;
1087
+ $[7] = source;
1088
+ $[8] = T0;
1089
+ $[9] = t1;
1090
+ $[10] = t2;
1091
+ $[11] = t3;
1092
+ } else {
1093
+ T0 = $[8];
1094
+ t1 = $[9];
1095
+ t2 = $[10];
1096
+ t3 = $[11];
1019
1097
  }
1020
- const T0 = RepeaterHoverProvider;
1021
- const t2 = arrayValue.map((item_0, index) => {
1022
- const isDbItem = item_0.content !== void 0 && item_0.id != null;
1023
- const itemContent_0 = {
1024
- ...repeatableItemDefaults[fieldName],
1025
- ...isDbItem ? item_0.content : item_0
1026
- };
1027
- const itemId = isDbItem ? item_0.id : void 0;
1028
- return /* @__PURE__ */ jsx(RepeaterItemContext.Provider, {
1029
- value: {
1030
- arrayFieldName: fieldName,
1031
- itemIndex: index,
1032
- itemContent: itemContent_0,
1033
- itemId
1034
- },
1035
- children: /* @__PURE__ */ jsx(RepeaterItemWrapper, {
1036
- itemId,
1037
- blockId,
1038
- mode,
1039
- children: children(itemComponents, index)
1040
- })
1041
- }, itemId ?? index);
1042
- });
1043
- let t3;
1044
- if ($[5] !== T0 || $[6] !== blockId || $[7] !== fieldName || $[8] !== t2) {
1045
- t3 = /* @__PURE__ */ jsx(T0, {
1046
- blockId,
1047
- fieldName,
1048
- children: t2
1098
+ let t4;
1099
+ if ($[23] !== T0 || $[24] !== t1 || $[25] !== t2 || $[26] !== t3) {
1100
+ t4 = /* @__PURE__ */ jsx(T0, {
1101
+ blockId: t1,
1102
+ fieldName: t2,
1103
+ children: t3
1049
1104
  });
1050
- $[5] = T0;
1051
- $[6] = blockId;
1052
- $[7] = fieldName;
1053
- $[8] = t2;
1054
- $[9] = t3;
1055
- } else t3 = $[9];
1056
- return t3;
1105
+ $[23] = T0;
1106
+ $[24] = t1;
1107
+ $[25] = t2;
1108
+ $[26] = t3;
1109
+ $[27] = t4;
1110
+ } else t4 = $[27];
1111
+ return t4;
1057
1112
  };
1058
1113
  const BlockComponent = (t0) => {
1059
1114
  const $ = c(69);
@@ -1,5 +1,5 @@
1
1
  import * as _$_sinclair_typebox0 from "@sinclair/typebox";
2
- import { TArray, TObject, TSchema, TUnsafe } from "@sinclair/typebox";
2
+ import { Static, TArray, TObject, TSchema, TUnsafe } from "@sinclair/typebox";
3
3
 
4
4
  //#region src/core/lib/contentType.d.ts
5
5
  declare class FieldToken {
@@ -7,12 +7,40 @@ declare class FieldToken {
7
7
  constructor(fieldName: string);
8
8
  toString(): string;
9
9
  }
10
+ type SettingsScope = "block" | "item";
11
+ /**
12
+ * Serializable conditional block produced by the settings proxy. Emits Handlebars-style
13
+ * `{{#if ...}}...{{/if}}` syntax wrapping each child line, tagged with its scope so the
14
+ * server-side resolver knows whether to read from `settings` or `itemSettings`.
15
+ */
16
+ declare class Conditional {
17
+ readonly scope: SettingsScope;
18
+ readonly settingName: string;
19
+ readonly enumValue: string | null;
20
+ readonly children: ReadonlyArray<string | FieldToken | Conditional>;
21
+ constructor(scope: SettingsScope, settingName: string, enumValue: string | null, children: ReadonlyArray<string | FieldToken | Conditional>);
22
+ get openTag(): string;
23
+ get closeTag(): string;
24
+ }
25
+ type ConditionalChild = string | FieldToken | Conditional;
26
+ type ConditionalLines = ConditionalChild | ReadonlyArray<ConditionalChild>;
10
27
  type ContentProxy<TShape extends Record<string, TSchema>> = { [K in keyof TShape & string]: FieldToken };
11
- type ToMarkdownBuilder<TShape extends Record<string, TSchema>> = (c: ContentProxy<TShape>) => ReadonlyArray<string | FieldToken>;
28
+ /**
29
+ * Callable shape for one entry on the settings proxy. Booleans take a single `lines`
30
+ * argument; enums take `(value, lines)`. Settings of other shapes are disallowed — they
31
+ * don't make sense as conditions.
32
+ */
33
+ type SettingCallable<T extends TSchema> = Static<T> extends boolean ? (lines: ConditionalLines) => Conditional : Static<T> extends string ? (value: Static<T>, lines: ConditionalLines) => Conditional : never;
34
+ type SettingsProxy<TShape extends Record<string, TSchema>> = { [K in keyof TShape & string]: SettingCallable<TShape[K]> };
35
+ type ToMarkdownBuilder<TContent extends Record<string, TSchema>, TSettings extends Record<string, TSchema> = Record<string, never>> = (c: ContentProxy<TContent>, s: SettingsProxy<TSettings>) => ReadonlyArray<string | FieldToken | Conditional>;
12
36
  declare const EmbedURLBrand: unique symbol;
13
37
  type EmbedURL = string & {
14
38
  readonly [EmbedURLBrand]: true;
15
39
  };
40
+ declare const ItemSettingsBrand: unique symbol;
41
+ type WithItemSettings<S extends Record<string, TSchema>> = {
42
+ readonly [ItemSettingsBrand]?: S;
43
+ };
16
44
  declare const LinkBrand: unique symbol;
17
45
  type LinkValue = ({
18
46
  type: "external";
@@ -91,25 +119,33 @@ declare const Type$1: {
91
119
  * Creates a repeatable array of object items.
92
120
  * The default array is auto-generated based on minItems.
93
121
  *
122
+ * Items may also declare per-item `settings` (Enum/Boolean only) — not
123
+ * inline-editable; they appear in the sidebar when the item is selected,
124
+ * similar to block-level settings.
125
+ *
94
126
  * @example
95
127
  * Type.RepeatableItem({
96
128
  * content: {
97
129
  * title: Type.String({ default: 'Item' }),
98
130
  * description: Type.String({ default: 'Description' }),
99
131
  * },
132
+ * settings: {
133
+ * highlighted: Type.Boolean({ default: false, title: 'Highlighted' }),
134
+ * },
100
135
  * minItems: 1,
101
136
  * maxItems: 10,
102
137
  * title: 'Items',
103
138
  * toMarkdown: (c) => [`### ${c.title}`, c.description],
104
139
  * })
105
140
  */
106
- RepeatableItem: <T extends Record<string, TSchema>>(options: {
141
+ RepeatableItem: <T extends Record<string, TSchema>, S extends Record<string, TSchema> = Record<string, never>>(options: {
107
142
  content: T;
143
+ settings?: S;
108
144
  minItems: number;
109
145
  maxItems: number;
110
146
  title?: string;
111
- toMarkdown: ToMarkdownBuilder<T>;
112
- }) => TArray<TObject<T>>;
147
+ toMarkdown: ToMarkdownBuilder<T, S>;
148
+ }) => TArray<TObject<T>> & WithItemSettings<S>;
113
149
  /**
114
150
  * Creates an enum field with a set of predefined options.
115
151
  *
@@ -120,11 +156,11 @@ declare const Type$1: {
120
156
  * title: 'Alignment'
121
157
  * })
122
158
  */
123
- Enum: (options: {
124
- default: string;
125
- options: Record<string, string>;
159
+ Enum: <const O extends Record<string, string>>(options: {
160
+ default: keyof O & string;
161
+ options: O;
126
162
  title?: string;
127
- }) => TUnsafe<string>;
163
+ }) => TUnsafe<keyof O & string>;
128
164
  /**
129
165
  * Creates a boolean toggle field.
130
166
  *
@@ -169,4 +205,4 @@ declare const Type$1: {
169
205
  File: typeof _fileType;
170
206
  };
171
207
  //#endregion
172
- export { EmbedURL, FileValue, ImageValue, LinkValue, ToMarkdownBuilder, Type$1 as Type };
208
+ export { EmbedURL, FileValue, ImageValue, ItemSettingsBrand, LinkValue, ToMarkdownBuilder, Type$1 as Type };
@@ -9,14 +9,55 @@ var FieldToken = class {
9
9
  return `{{${this.fieldName}}}`;
10
10
  }
11
11
  };
12
+ /**
13
+ * Serializable conditional block produced by the settings proxy. Emits Handlebars-style
14
+ * `{{#if ...}}...{{/if}}` syntax wrapping each child line, tagged with its scope so the
15
+ * server-side resolver knows whether to read from `settings` or `itemSettings`.
16
+ */
17
+ var Conditional = class {
18
+ constructor(scope, settingName, enumValue, children) {
19
+ this.scope = scope;
20
+ this.settingName = settingName;
21
+ this.enumValue = enumValue;
22
+ this.children = children;
23
+ }
24
+ get openTag() {
25
+ const root = this.scope === "block" ? "settings" : "itemSettings";
26
+ if (this.enumValue === null) return `{{#if ${root}.${this.settingName}}}`;
27
+ return `{{#if (eq ${root}.${this.settingName} "${this.enumValue}")}}`;
28
+ }
29
+ get closeTag() {
30
+ return "{{/if}}";
31
+ }
32
+ };
12
33
  function createContentProxy() {
13
34
  return new Proxy({}, { get(_target, prop) {
14
35
  if (typeof prop !== "string") return void 0;
15
36
  return new FieldToken(prop);
16
37
  } });
17
38
  }
18
- function resolveToMarkdown(builder) {
19
- return builder(createContentProxy()).map((entry) => entry instanceof FieldToken ? entry.toString() : String(entry));
39
+ function createSettingsProxy(settingsShape, scope) {
40
+ return new Proxy({}, { get(_target, prop) {
41
+ if (typeof prop !== "string") return void 0;
42
+ const fieldType = (settingsShape?.[prop])?.fieldType;
43
+ if (fieldType === "Boolean") return (lines) => new Conditional(scope, prop, null, Array.isArray(lines) ? lines : [lines]);
44
+ if (fieldType === "Enum") return (value, lines) => new Conditional(scope, prop, value, Array.isArray(lines) ? lines : [lines]);
45
+ throw new Error(`toMarkdown settings proxy: "${prop}" is not a Boolean or Enum setting on this ${scope}.`);
46
+ } });
47
+ }
48
+ /** Flatten a `Conditional`'s children into wrapped lines, recursing into nested Conditionals. */
49
+ function serializeConditional(cond) {
50
+ const out = [];
51
+ for (const child of cond.children) if (child instanceof Conditional) for (const nested of serializeConditional(child)) out.push(`${cond.openTag}${nested}${cond.closeTag}`);
52
+ else out.push(`${cond.openTag}${String(child)}${cond.closeTag}`);
53
+ return out;
54
+ }
55
+ function resolveToMarkdown(builder, settingsShape, scope) {
56
+ const entries = builder(createContentProxy(), createSettingsProxy(settingsShape, scope));
57
+ const out = [];
58
+ for (const entry of entries) if (entry instanceof Conditional) out.push(...serializeConditional(entry));
59
+ else out.push(entry instanceof FieldToken ? entry.toString() : String(entry));
60
+ return out;
20
61
  }
21
62
  function _imageType(options) {
22
63
  const imageDefault = {
@@ -102,13 +143,25 @@ const Type$1 = {
102
143
  const defaultItem = {};
103
144
  for (const [key, prop] of Object.entries(objectSchema.properties)) if ("default" in prop) defaultItem[key] = prop.default;
104
145
  const defaultArray = Array(options.minItems).fill(null).map(() => ({ ...defaultItem }));
146
+ const settingsTypeboxSchema = options.settings ? Type.Object(options.settings) : null;
147
+ const itemSettingsSchema = settingsTypeboxSchema ? {
148
+ type: "object",
149
+ properties: settingsTypeboxSchema.properties,
150
+ required: Object.keys(options.settings)
151
+ } : void 0;
152
+ const defaultItemSettings = {};
153
+ if (settingsTypeboxSchema) {
154
+ for (const [key, prop] of Object.entries(settingsTypeboxSchema.properties)) if ("default" in prop) defaultItemSettings[key] = prop.default;
155
+ }
105
156
  return Type.Array(objectSchema, {
106
157
  minItems: options.minItems,
107
158
  maxItems: options.maxItems,
108
159
  default: defaultArray,
109
160
  title: options.title,
110
161
  fieldType: "RepeatableItem",
111
- toMarkdown: resolveToMarkdown(options.toMarkdown)
162
+ toMarkdown: resolveToMarkdown(options.toMarkdown, options.settings, "item"),
163
+ itemSettingsSchema,
164
+ defaultItemSettings: settingsTypeboxSchema ? defaultItemSettings : void 0
112
165
  });
113
166
  },
114
167
  Enum: (options) => {