@dotcms/uve 1.2.1 → 1.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.
@@ -0,0 +1,372 @@
1
+ import { StyleEditorCheckboxGroupField, StyleEditorDropdownField, StyleEditorFieldInputType, StyleEditorForm, StyleEditorFormSchema, StyleEditorInputField, StyleEditorInputFieldConfig, StyleEditorRadioField } from './types';
2
+ /**
3
+ * Helper functions for creating style editor field definitions.
4
+ *
5
+ * Provides type-safe factory functions for creating different types of form fields
6
+ * used in the style editor. Each function creates a field definition with the
7
+ * appropriate `type` property automatically set, eliminating the need to manually
8
+ * specify the type discriminator.
9
+ *
10
+ * **Available Field Types:**
11
+ * - `input`: Text or number input fields
12
+ * - `dropdown`: Single-value selection from a dropdown list
13
+ * - `radio`: Single-value selection from radio button options (supports visual options with images)
14
+ * - `checkboxGroup`: Multiple-value selection from checkbox options
15
+ *
16
+ * These factory functions ensure type safety by inferring the correct field type
17
+ * based on the configuration provided, and they automatically set the `type` property
18
+ * to match the factory function used.
19
+ *
20
+ * @experimental This API is experimental and may be subject to change.
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const form = defineStyleEditorSchema({
25
+ * contentType: 'my-content-type',
26
+ * sections: [
27
+ * {
28
+ * title: 'Typography',
29
+ * fields: [
30
+ * styleEditorField.input({
31
+ * id: 'font-size',
32
+ * label: 'Font Size',
33
+ * inputType: 'number'
34
+ * }),
35
+ * styleEditorField.dropdown({
36
+ * id: 'font-family',
37
+ * label: 'Font Family',
38
+ * options: ['Arial', 'Helvetica']
39
+ * }),
40
+ * styleEditorField.radio({
41
+ * id: 'alignment',
42
+ * label: 'Alignment',
43
+ * options: ['Left', 'Center', 'Right']
44
+ * })
45
+ * ]
46
+ * }
47
+ * ]
48
+ * });
49
+ * ```
50
+ */
51
+ export declare const styleEditorField: {
52
+ /**
53
+ * Creates an input field definition.
54
+ *
55
+ * Supports both text and number input types for different value types.
56
+ *
57
+ * @experimental This method is experimental and may be subject to change.
58
+ *
59
+ * @typeParam T - The input type ('text' or 'number'), inferred from `config.inputType`
60
+ * @param config - Input field configuration
61
+ * @param config.id - The unique identifier for this field
62
+ * @param config.label - The label displayed for this input field
63
+ * @param config.inputType - The type of input ('text' or 'number')
64
+ * @param config.placeholder - Optional placeholder text for the input
65
+ * @returns A complete input field definition with type 'input'
66
+ *
67
+ * @example
68
+ * ```typescript
69
+ * // Number input
70
+ * styleEditorField.input({
71
+ * id: 'font-size',
72
+ * label: 'Font Size',
73
+ * inputType: 'number',
74
+ * placeholder: 'Enter font size'
75
+ * })
76
+ *
77
+ * // Text input
78
+ * styleEditorField.input({
79
+ * id: 'font-name',
80
+ * label: 'Font Name',
81
+ * inputType: 'text',
82
+ * placeholder: 'Enter font name'
83
+ * })
84
+ * ```
85
+ */
86
+ input: <T extends StyleEditorFieldInputType>(config: StyleEditorInputFieldConfig<T>) => StyleEditorInputField;
87
+ /**
88
+ * Creates a dropdown field definition.
89
+ *
90
+ * Allows users to select a single value from a list of options.
91
+ * Options can be provided as simple strings or as objects with label and value.
92
+ *
93
+ * **Best Practice:** Use `as const` when defining options for better type safety:
94
+ * ```typescript
95
+ * const OPTIONS = [
96
+ * { label: '18', value: '18px' },
97
+ * { label: '24', value: '24px' }
98
+ * ] as const;
99
+ *
100
+ * styleEditorField.dropdown({
101
+ * id: 'size',
102
+ * label: 'Size',
103
+ * options: OPTIONS
104
+ * });
105
+ * ```
106
+ *
107
+ * @experimental This method is experimental and may be subject to change.
108
+ *
109
+ * @param config - Dropdown field configuration (without the 'type' property)
110
+ * @param config.id - The unique identifier for this field
111
+ * @param config.label - The label displayed for this dropdown field
112
+ * @param config.options - Array of options. Can be strings or objects with label and value. Use `as const` for best type safety.
113
+ * @returns A complete dropdown field definition with type 'dropdown'
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * // Simple string options
118
+ * styleEditorField.dropdown({
119
+ * id: 'font-family',
120
+ * label: 'Font Family',
121
+ * options: ['Arial', 'Helvetica', 'Times New Roman']
122
+ * })
123
+ *
124
+ * // Object options with custom labels (recommended: use 'as const')
125
+ * const OPTIONS = [
126
+ * { label: 'Light Theme', value: 'light' },
127
+ * { label: 'Dark Theme', value: 'dark' }
128
+ * ] as const;
129
+ *
130
+ * styleEditorField.dropdown({
131
+ * id: 'theme',
132
+ * label: 'Theme',
133
+ * options: OPTIONS
134
+ * })
135
+ * ```
136
+ */
137
+ dropdown: (config: Omit<StyleEditorDropdownField, "type">) => StyleEditorDropdownField;
138
+ /**
139
+ * Creates a radio button field definition.
140
+ *
141
+ * Allows users to select a single option from a list. Supports visual
142
+ * options with background images for enhanced UI. Options can be provided
143
+ * as simple strings or as objects with label, value, and optional image properties.
144
+ *
145
+ * **Layout Options:**
146
+ * - `columns: 1` (default): Single column list layout
147
+ * - `columns: 2`: Two-column grid layout, ideal for visual options with images
148
+ *
149
+ * **Best Practice:** Use `as const` when defining options for better type safety:
150
+ * ```typescript
151
+ * const RADIO_OPTIONS = [
152
+ * { label: 'Left', value: 'left' },
153
+ * { label: 'Right', value: 'right' }
154
+ * ] as const;
155
+ *
156
+ * styleEditorField.radio({
157
+ * id: 'layout',
158
+ * label: 'Layout',
159
+ * options: RADIO_OPTIONS
160
+ * });
161
+ * ```
162
+ *
163
+ * @experimental This method is experimental and may be subject to change.
164
+ *
165
+ * @param config - Radio field configuration (without the 'type' property)
166
+ * @param config.id - The unique identifier for this field
167
+ * @param config.label - The label displayed for this radio group
168
+ * @param config.options - Array of options. Can be strings or objects with label, value, and optional image properties. Use `as const` for best type safety.
169
+ * @param config.columns - Optional number of columns (1 or 2). Defaults to 1 (single column)
170
+ * @returns A complete radio field definition with type 'radio'
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * // Simple string options (single column)
175
+ * styleEditorField.radio({
176
+ * id: 'alignment',
177
+ * label: 'Alignment',
178
+ * options: ['Left', 'Center', 'Right']
179
+ * })
180
+ *
181
+ * // Two-column grid layout with images (recommended: use 'as const')
182
+ * const LAYOUT_OPTIONS = [
183
+ * {
184
+ * label: 'Left',
185
+ * value: 'left',
186
+ * imageURL: 'https://example.com/layout-left.png',
187
+ * },
188
+ * {
189
+ * label: 'Right',
190
+ * value: 'right',
191
+ * imageURL: 'https://example.com/layout-right.png',
192
+ * },
193
+ * { label: 'Center', value: 'center' },
194
+ * { label: 'Overlap', value: 'overlap' }
195
+ * ] as const;
196
+ *
197
+ * styleEditorField.radio({
198
+ * id: 'layout',
199
+ * label: 'Layout',
200
+ * columns: 2,
201
+ * options: LAYOUT_OPTIONS
202
+ * })
203
+ * ```
204
+ */
205
+ radio: (config: Omit<StyleEditorRadioField, "type">) => StyleEditorRadioField;
206
+ /**
207
+ * Creates a checkbox group field definition.
208
+ *
209
+ * Allows users to select multiple options simultaneously. Each option
210
+ * can be independently checked or unchecked. The default checked state
211
+ * is defined directly in each option's `value` property (boolean).
212
+ *
213
+ * **Key Differences from Other Field Types:**
214
+ * - Uses `key` instead of `value` for the identifier (to avoid confusion)
215
+ * - Checked state is managed by the form system, not stored in the option definition
216
+ *
217
+ * **Why `key` instead of `value`?**
218
+ * In dropdown and radio fields, `value` represents the actual selected value (string).
219
+ * In checkbox groups, the actual value is boolean (checked/unchecked), so we use
220
+ * `key` for the identifier to avoid confusion. This makes it clear that `value`
221
+ * is the boolean state, not just an identifier.
222
+ *
223
+ * @experimental This method is experimental and may be subject to change.
224
+ *
225
+ * @param config - Checkbox group field configuration (without the 'type' property)
226
+ * @param config.id - The unique identifier for this field
227
+ * @param config.label - The label displayed for this checkbox group
228
+ * @param config.options - Array of checkbox options with label and key
229
+ * @returns A complete checkbox group field definition with type 'checkboxGroup'
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * styleEditorField.checkboxGroup({
234
+ * id: 'text-decoration',
235
+ * label: 'Text Decoration',
236
+ * options: [
237
+ * { label: 'Underline', key: 'underline' },
238
+ * { label: 'Overline', key: 'overline' },
239
+ * { label: 'Line Through', key: 'line-through' }
240
+ * ]
241
+ * })
242
+ *
243
+ * // Example with type settings
244
+ * styleEditorField.checkboxGroup({
245
+ * id: 'type-settings',
246
+ * label: 'Type settings',
247
+ * options: [
248
+ * { label: 'Bold', key: 'bold' },
249
+ * { label: 'Italic', key: 'italic' },
250
+ * { label: 'Underline', key: 'underline' },
251
+ * { label: 'Strikethrough', key: 'strikethrough' }
252
+ * ]
253
+ * })
254
+ * ```
255
+ */
256
+ checkboxGroup: (config: Omit<StyleEditorCheckboxGroupField, "type">) => StyleEditorCheckboxGroupField;
257
+ };
258
+ /**
259
+ * Normalizes and validates a style editor form definition.
260
+ *
261
+ * Converts the developer-friendly form structure into the schema format
262
+ * expected by UVE (Universal Visual Editor). This function processes the
263
+ * form definition and transforms it into the normalized schema format where:
264
+ *
265
+ * - All field-specific properties are moved into `config` objects
266
+ * - String options are normalized to `{ label, value }` objects
267
+ * - Sections are organized into the multi-dimensional array structure required by UVE
268
+ *
269
+ * The normalization process ensures consistency and type safety in the schema
270
+ * format sent to UVE. After normalization, use `registerStyleEditorSchemas`
271
+ * to register the schema with the UVE editor.
272
+ *
273
+ * @experimental This method is experimental and may be subject to change.
274
+ *
275
+ * @param form - The style editor form definition containing contentType and sections
276
+ * @param form.contentType - The content type identifier for this form
277
+ * @param form.sections - Array of sections, each containing a title and fields array
278
+ * @returns The normalized form schema ready to be sent to UVE
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const formSchema = defineStyleEditorSchema({
283
+ * contentType: 'my-content-type',
284
+ * sections: [
285
+ * {
286
+ * title: 'Typography',
287
+ * fields: [
288
+ * styleEditorField.input({
289
+ * id: 'font-size',
290
+ * label: 'Font Size',
291
+ * inputType: 'number'
292
+ * }),
293
+ * styleEditorField.dropdown({
294
+ * id: 'font-family',
295
+ * label: 'Font Family',
296
+ * options: ['Arial', 'Helvetica']
297
+ * })
298
+ * ]
299
+ * },
300
+ * {
301
+ * title: 'Colors',
302
+ * fields: [
303
+ * styleEditorField.input({
304
+ * id: 'primary-color',
305
+ * label: 'Primary Color',
306
+ * inputType: 'text'
307
+ * }),
308
+ * styleEditorField.input({
309
+ * id: 'secondary-color',
310
+ * label: 'Secondary Color',
311
+ * inputType: 'text'
312
+ * })
313
+ * ]
314
+ * }
315
+ * ]
316
+ * });
317
+ *
318
+ * // Register the schema with UVE
319
+ * registerStyleEditorSchemas([formSchema]);
320
+ * ```
321
+ */
322
+ export declare function defineStyleEditorSchema(form: StyleEditorForm): StyleEditorFormSchema;
323
+ /**
324
+ * Registers style editor form schemas with the UVE editor.
325
+ *
326
+ * Sends normalized style editor schemas to the UVE (Universal Visual Editor)
327
+ * for registration. The schemas must be normalized using `defineStyleEditorSchema`
328
+ * before being passed to this function.
329
+ *
330
+ * **Behavior:**
331
+ * - Only registers schemas when UVE is in EDIT mode
332
+ * - Validates that each schema has a `contentType` property
333
+ * - Skips schemas without `contentType` and logs a warning
334
+ * - Sends the validated schemas to UVE via the `REGISTER_STYLE_SCHEMAS` action
335
+ *
336
+ * **Note:** This function will silently return early if UVE is not in EDIT mode,
337
+ * so it's safe to call even when the editor is not active.
338
+ *
339
+ * @experimental This method is experimental and may be subject to change.
340
+ *
341
+ * @param schemas - Array of normalized style editor form schemas to register with UVE
342
+ * @returns void - This function does not return a value
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * // Create and normalize a form schema
347
+ * const formSchema = defineStyleEditorSchema({
348
+ * contentType: 'my-content-type',
349
+ * sections: [
350
+ * {
351
+ * title: 'Typography',
352
+ * fields: [
353
+ * styleEditorField.input({
354
+ * id: 'font-size',
355
+ * label: 'Font Size',
356
+ * inputType: 'number'
357
+ * })
358
+ * ]
359
+ * }
360
+ * ]
361
+ * });
362
+ *
363
+ * // Register the schema with UVE
364
+ * registerStyleEditorSchemas([formSchema]);
365
+ *
366
+ * // Register multiple schemas at once
367
+ * const schema1 = defineStyleEditorSchema({ ... });
368
+ * const schema2 = defineStyleEditorSchema({ ... });
369
+ * registerStyleEditorSchemas([schema1, schema2]);
370
+ * ```
371
+ */
372
+ export declare function registerStyleEditorSchemas(schemas: StyleEditorFormSchema[]): void;