@dotcms/uve 1.2.1-next.7 → 1.2.1-next.8

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.
package/index.cjs.js CHANGED
@@ -17,7 +17,8 @@ require('@dotcms/types/internal');
17
17
  * extracts `placeholder` and `defaultValue` into config
18
18
  * - **Radio fields**: Normalizes options (preserves image properties like `imageURL`, `width`, `height`),
19
19
  * extracts `defaultValue` into config
20
- * - **Checkbox group fields**: Normalizes options and extracts `defaultValue` (as Record<string, boolean>) into config
20
+ * - **Checkbox group fields**: Normalizes options and derives `defaultValue` from option values
21
+ * (creates Record<string, boolean> mapping option keys to their boolean values)
21
22
  *
22
23
  * @experimental This method is experimental and may be subject to change.
23
24
  *
@@ -72,7 +73,6 @@ function normalizeField(field) {
72
73
  label: opt,
73
74
  value: opt
74
75
  } : opt);
75
- config.placeholder = field.type === 'dropdown' ? field.placeholder : undefined;
76
76
  config.defaultValue = field.defaultValue;
77
77
  // Handle radio-specific properties
78
78
  if (field.type === 'radio') {
@@ -80,12 +80,17 @@ function normalizeField(field) {
80
80
  }
81
81
  }
82
82
  if (field.type === 'checkboxGroup') {
83
- // Normalize options to consistent format
84
- config.options = field.options.map(opt => typeof opt === 'string' ? {
85
- label: opt,
86
- value: opt
87
- } : opt);
88
- config.defaultValue = field.defaultValue;
83
+ // Normalize checkbox options - convert to format expected by UVE
84
+ // Options already have label, key, and value (boolean)
85
+ config.options = field.options.map(opt => ({
86
+ label: opt.label,
87
+ value: opt.key // UVE expects 'value' to be the key identifier
88
+ }));
89
+ // Derive defaultValue from options - map key to boolean value
90
+ config.defaultValue = field.options.reduce((acc, opt) => {
91
+ acc[opt.key] = opt.value;
92
+ return acc;
93
+ }, {});
89
94
  }
90
95
  return {
91
96
  ...base,
@@ -320,24 +325,68 @@ const styleEditorField = {
320
325
  ...config
321
326
  }),
322
327
  /**
323
- * Creates a dropdown field definition.
328
+ * Creates a dropdown field definition with type-safe default values.
324
329
  *
325
330
  * Allows users to select a single value from a list of options.
326
331
  * Options can be provided as simple strings or as objects with label and value.
327
332
  *
333
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
334
+ * ```typescript
335
+ * const options = [
336
+ * { label: 'The one', value: 'one' },
337
+ * { label: 'The two', value: 'two' }
338
+ * ] as const;
339
+ *
340
+ * styleEditorField.dropdown({
341
+ * id: 'my-field',
342
+ * label: 'Select option',
343
+ * options,
344
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
345
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
346
+ * })
347
+ * ```
348
+ *
349
+ * Without `as const`, the function still works but won't provide autocomplete:
350
+ * ```typescript
351
+ * styleEditorField.dropdown({
352
+ * id: 'my-field',
353
+ * label: 'Select option',
354
+ * options: [
355
+ * { label: 'The one', value: 'one' },
356
+ * { label: 'The two', value: 'two' }
357
+ * ],
358
+ * defaultValue: 'one' // Works, but no autocomplete
359
+ * })
360
+ * ```
361
+ *
328
362
  * @experimental This method is experimental and may be subject to change.
329
363
  *
364
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
330
365
  * @param config - Dropdown field configuration (without the 'type' property)
366
+ * @param config.id - The unique identifier for this field
331
367
  * @param config.label - The label displayed for this dropdown field
332
- * @param config.options - Array of options. Can be strings or objects with label and value
333
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
334
- * @param config.placeholder - Optional placeholder text shown when no value is selected
368
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
369
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
335
370
  * @returns A complete dropdown field definition with type 'dropdown'
336
371
  *
337
372
  * @example
338
373
  * ```typescript
374
+ * // With type safety - use 'as const' for autocomplete
375
+ * const options = [
376
+ * { label: 'The one', value: 'one' },
377
+ * { label: 'The two', value: 'two' }
378
+ * ] as const;
379
+ *
380
+ * styleEditorField.dropdown({
381
+ * id: 'my-field',
382
+ * label: 'Select option',
383
+ * options,
384
+ * defaultValue: 'one' // ✓ Autocomplete works!
385
+ * })
386
+ *
339
387
  * // Simple string options
340
388
  * styleEditorField.dropdown({
389
+ * id: 'font-family',
341
390
  * label: 'Font Family',
342
391
  * options: ['Arial', 'Helvetica', 'Times New Roman'],
343
392
  * defaultValue: 'Arial',
@@ -346,6 +395,7 @@ const styleEditorField = {
346
395
  *
347
396
  * // Object options with custom labels
348
397
  * styleEditorField.dropdown({
398
+ * id: 'theme',
349
399
  * label: 'Theme',
350
400
  * options: [
351
401
  * { label: 'Light Theme', value: 'light' },
@@ -357,10 +407,12 @@ const styleEditorField = {
357
407
  */
358
408
  dropdown: config => ({
359
409
  type: 'dropdown',
360
- ...config
410
+ ...config,
411
+ options: config.options,
412
+ defaultValue: config.defaultValue
361
413
  }),
362
414
  /**
363
- * Creates a radio button field definition.
415
+ * Creates a radio button field definition with type-safe default values.
364
416
  *
365
417
  * Allows users to select a single option from a list. Supports visual
366
418
  * options with background images for enhanced UI. Options can be provided
@@ -370,19 +422,64 @@ const styleEditorField = {
370
422
  * - `columns: 1` (default): Single column list layout
371
423
  * - `columns: 2`: Two-column grid layout, ideal for visual options with images
372
424
  *
425
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
426
+ * ```typescript
427
+ * const options = [
428
+ * { label: 'The one', value: 'one' },
429
+ * { label: 'The two', value: 'two' }
430
+ * ] as const;
431
+ *
432
+ * styleEditorField.radio({
433
+ * id: 'my-field',
434
+ * label: 'Select option',
435
+ * options,
436
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
437
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
438
+ * })
439
+ * ```
440
+ *
441
+ * Without `as const`, the function still works but won't provide autocomplete:
442
+ * ```typescript
443
+ * styleEditorField.radio({
444
+ * id: 'my-field',
445
+ * label: 'Select option',
446
+ * options: [
447
+ * { label: 'The one', value: 'one' },
448
+ * { label: 'The two', value: 'two' }
449
+ * ],
450
+ * defaultValue: 'one' // Works, but no autocomplete
451
+ * })
452
+ * ```
453
+ *
373
454
  * @experimental This method is experimental and may be subject to change.
374
455
  *
456
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
375
457
  * @param config - Radio field configuration (without the 'type' property)
458
+ * @param config.id - The unique identifier for this field
376
459
  * @param config.label - The label displayed for this radio group
377
- * @param config.options - Array of options. Can be strings or objects with label, value, and optional imageURL
378
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
460
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
461
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
379
462
  * @param config.columns - Optional number of columns (1 or 2). Defaults to 1 (single column)
380
463
  * @returns A complete radio field definition with type 'radio'
381
464
  *
382
465
  * @example
383
466
  * ```typescript
467
+ * // With type safety - use 'as const' for autocomplete
468
+ * const options = [
469
+ * { label: 'The one', value: 'one' },
470
+ * { label: 'The two', value: 'two' }
471
+ * ] as const;
472
+ *
473
+ * styleEditorField.radio({
474
+ * id: 'my-field',
475
+ * label: 'Select option',
476
+ * options,
477
+ * defaultValue: 'one' // ✓ Autocomplete works!
478
+ * })
479
+ *
384
480
  * // Simple string options (single column)
385
481
  * styleEditorField.radio({
482
+ * id: 'alignment',
386
483
  * label: 'Alignment',
387
484
  * options: ['Left', 'Center', 'Right'],
388
485
  * defaultValue: 'Left'
@@ -390,6 +487,7 @@ const styleEditorField = {
390
487
  *
391
488
  * // Two-column grid layout with images
392
489
  * styleEditorField.radio({
490
+ * id: 'layout',
393
491
  * label: 'Layout',
394
492
  * columns: 2,
395
493
  * options: [
@@ -412,37 +510,59 @@ const styleEditorField = {
412
510
  */
413
511
  radio: config => ({
414
512
  type: 'radio',
415
- ...config
513
+ ...config,
514
+ options: config.options,
515
+ defaultValue: config.defaultValue
416
516
  }),
417
517
  /**
418
518
  * Creates a checkbox group field definition.
419
519
  *
420
520
  * Allows users to select multiple options simultaneously. Each option
421
- * can be independently checked or unchecked. The defaultValue is a
422
- * record mapping option values to their boolean checked state.
521
+ * can be independently checked or unchecked. The default checked state
522
+ * is defined directly in each option's `value` property (boolean).
523
+ *
524
+ * **Key Differences from Other Field Types:**
525
+ * - Uses `key` instead of `value` for the identifier (to avoid confusion)
526
+ * - Uses `value` for the default boolean checked state (the actual value)
527
+ * - No separate `defaultValue` property - defaults are embedded in options
528
+ *
529
+ * **Why `key` instead of `value`?**
530
+ * In dropdown and radio fields, `value` represents the actual selected value (string).
531
+ * In checkbox groups, the actual value is boolean (checked/unchecked), so we use
532
+ * `key` for the identifier to avoid confusion. This makes it clear that `value`
533
+ * is the boolean state, not just an identifier.
423
534
  *
424
535
  * @experimental This method is experimental and may be subject to change.
425
536
  *
426
537
  * @param config - Checkbox group field configuration (without the 'type' property)
538
+ * @param config.id - The unique identifier for this field
427
539
  * @param config.label - The label displayed for this checkbox group
428
- * @param config.options - Array of options. Can be strings or objects with label and value
429
- * @param config.defaultValue - Optional default checked state as a record of option values to boolean
540
+ * @param config.options - Array of checkbox options with label, key, and value (boolean)
430
541
  * @returns A complete checkbox group field definition with type 'checkboxGroup'
431
542
  *
432
543
  * @example
433
544
  * ```typescript
434
545
  * styleEditorField.checkboxGroup({
546
+ * id: 'text-decoration',
435
547
  * label: 'Text Decoration',
436
548
  * options: [
437
- * { label: 'Underline', value: 'underline' },
438
- * { label: 'Overline', value: 'overline' },
439
- * { label: 'Line Through', value: 'line-through' }
440
- * ],
441
- * defaultValue: {
442
- * 'underline': true,
443
- * 'overline': false,
444
- * 'line-through': false
445
- * }
549
+ * { label: 'Underline', key: 'underline', value: true },
550
+ * { label: 'Overline', key: 'overline', value: false },
551
+ * { label: 'Line Through', key: 'line-through', value: false }
552
+ * ]
553
+ * // No defaultValue needed - it's automatically derived from options
554
+ * })
555
+ *
556
+ * // Example with type settings
557
+ * styleEditorField.checkboxGroup({
558
+ * id: 'type-settings',
559
+ * label: 'Type settings',
560
+ * options: [
561
+ * { label: 'Bold', key: 'bold', value: true },
562
+ * { label: 'Italic', key: 'italic', value: false },
563
+ * { label: 'Underline', key: 'underline', value: false },
564
+ * { label: 'Strikethrough', key: 'strikethrough', value: false }
565
+ * ]
446
566
  * })
447
567
  * ```
448
568
  */
package/index.esm.js CHANGED
@@ -16,7 +16,8 @@ import '@dotcms/types/internal';
16
16
  * extracts `placeholder` and `defaultValue` into config
17
17
  * - **Radio fields**: Normalizes options (preserves image properties like `imageURL`, `width`, `height`),
18
18
  * extracts `defaultValue` into config
19
- * - **Checkbox group fields**: Normalizes options and extracts `defaultValue` (as Record<string, boolean>) into config
19
+ * - **Checkbox group fields**: Normalizes options and derives `defaultValue` from option values
20
+ * (creates Record<string, boolean> mapping option keys to their boolean values)
20
21
  *
21
22
  * @experimental This method is experimental and may be subject to change.
22
23
  *
@@ -71,7 +72,6 @@ function normalizeField(field) {
71
72
  label: opt,
72
73
  value: opt
73
74
  } : opt);
74
- config.placeholder = field.type === 'dropdown' ? field.placeholder : undefined;
75
75
  config.defaultValue = field.defaultValue;
76
76
  // Handle radio-specific properties
77
77
  if (field.type === 'radio') {
@@ -79,12 +79,17 @@ function normalizeField(field) {
79
79
  }
80
80
  }
81
81
  if (field.type === 'checkboxGroup') {
82
- // Normalize options to consistent format
83
- config.options = field.options.map(opt => typeof opt === 'string' ? {
84
- label: opt,
85
- value: opt
86
- } : opt);
87
- config.defaultValue = field.defaultValue;
82
+ // Normalize checkbox options - convert to format expected by UVE
83
+ // Options already have label, key, and value (boolean)
84
+ config.options = field.options.map(opt => ({
85
+ label: opt.label,
86
+ value: opt.key // UVE expects 'value' to be the key identifier
87
+ }));
88
+ // Derive defaultValue from options - map key to boolean value
89
+ config.defaultValue = field.options.reduce((acc, opt) => {
90
+ acc[opt.key] = opt.value;
91
+ return acc;
92
+ }, {});
88
93
  }
89
94
  return {
90
95
  ...base,
@@ -319,24 +324,68 @@ const styleEditorField = {
319
324
  ...config
320
325
  }),
321
326
  /**
322
- * Creates a dropdown field definition.
327
+ * Creates a dropdown field definition with type-safe default values.
323
328
  *
324
329
  * Allows users to select a single value from a list of options.
325
330
  * Options can be provided as simple strings or as objects with label and value.
326
331
  *
332
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
333
+ * ```typescript
334
+ * const options = [
335
+ * { label: 'The one', value: 'one' },
336
+ * { label: 'The two', value: 'two' }
337
+ * ] as const;
338
+ *
339
+ * styleEditorField.dropdown({
340
+ * id: 'my-field',
341
+ * label: 'Select option',
342
+ * options,
343
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
344
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
345
+ * })
346
+ * ```
347
+ *
348
+ * Without `as const`, the function still works but won't provide autocomplete:
349
+ * ```typescript
350
+ * styleEditorField.dropdown({
351
+ * id: 'my-field',
352
+ * label: 'Select option',
353
+ * options: [
354
+ * { label: 'The one', value: 'one' },
355
+ * { label: 'The two', value: 'two' }
356
+ * ],
357
+ * defaultValue: 'one' // Works, but no autocomplete
358
+ * })
359
+ * ```
360
+ *
327
361
  * @experimental This method is experimental and may be subject to change.
328
362
  *
363
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
329
364
  * @param config - Dropdown field configuration (without the 'type' property)
365
+ * @param config.id - The unique identifier for this field
330
366
  * @param config.label - The label displayed for this dropdown field
331
- * @param config.options - Array of options. Can be strings or objects with label and value
332
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
333
- * @param config.placeholder - Optional placeholder text shown when no value is selected
367
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
368
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
334
369
  * @returns A complete dropdown field definition with type 'dropdown'
335
370
  *
336
371
  * @example
337
372
  * ```typescript
373
+ * // With type safety - use 'as const' for autocomplete
374
+ * const options = [
375
+ * { label: 'The one', value: 'one' },
376
+ * { label: 'The two', value: 'two' }
377
+ * ] as const;
378
+ *
379
+ * styleEditorField.dropdown({
380
+ * id: 'my-field',
381
+ * label: 'Select option',
382
+ * options,
383
+ * defaultValue: 'one' // ✓ Autocomplete works!
384
+ * })
385
+ *
338
386
  * // Simple string options
339
387
  * styleEditorField.dropdown({
388
+ * id: 'font-family',
340
389
  * label: 'Font Family',
341
390
  * options: ['Arial', 'Helvetica', 'Times New Roman'],
342
391
  * defaultValue: 'Arial',
@@ -345,6 +394,7 @@ const styleEditorField = {
345
394
  *
346
395
  * // Object options with custom labels
347
396
  * styleEditorField.dropdown({
397
+ * id: 'theme',
348
398
  * label: 'Theme',
349
399
  * options: [
350
400
  * { label: 'Light Theme', value: 'light' },
@@ -356,10 +406,12 @@ const styleEditorField = {
356
406
  */
357
407
  dropdown: config => ({
358
408
  type: 'dropdown',
359
- ...config
409
+ ...config,
410
+ options: config.options,
411
+ defaultValue: config.defaultValue
360
412
  }),
361
413
  /**
362
- * Creates a radio button field definition.
414
+ * Creates a radio button field definition with type-safe default values.
363
415
  *
364
416
  * Allows users to select a single option from a list. Supports visual
365
417
  * options with background images for enhanced UI. Options can be provided
@@ -369,19 +421,64 @@ const styleEditorField = {
369
421
  * - `columns: 1` (default): Single column list layout
370
422
  * - `columns: 2`: Two-column grid layout, ideal for visual options with images
371
423
  *
424
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
425
+ * ```typescript
426
+ * const options = [
427
+ * { label: 'The one', value: 'one' },
428
+ * { label: 'The two', value: 'two' }
429
+ * ] as const;
430
+ *
431
+ * styleEditorField.radio({
432
+ * id: 'my-field',
433
+ * label: 'Select option',
434
+ * options,
435
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
436
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
437
+ * })
438
+ * ```
439
+ *
440
+ * Without `as const`, the function still works but won't provide autocomplete:
441
+ * ```typescript
442
+ * styleEditorField.radio({
443
+ * id: 'my-field',
444
+ * label: 'Select option',
445
+ * options: [
446
+ * { label: 'The one', value: 'one' },
447
+ * { label: 'The two', value: 'two' }
448
+ * ],
449
+ * defaultValue: 'one' // Works, but no autocomplete
450
+ * })
451
+ * ```
452
+ *
372
453
  * @experimental This method is experimental and may be subject to change.
373
454
  *
455
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
374
456
  * @param config - Radio field configuration (without the 'type' property)
457
+ * @param config.id - The unique identifier for this field
375
458
  * @param config.label - The label displayed for this radio group
376
- * @param config.options - Array of options. Can be strings or objects with label, value, and optional imageURL
377
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
459
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
460
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
378
461
  * @param config.columns - Optional number of columns (1 or 2). Defaults to 1 (single column)
379
462
  * @returns A complete radio field definition with type 'radio'
380
463
  *
381
464
  * @example
382
465
  * ```typescript
466
+ * // With type safety - use 'as const' for autocomplete
467
+ * const options = [
468
+ * { label: 'The one', value: 'one' },
469
+ * { label: 'The two', value: 'two' }
470
+ * ] as const;
471
+ *
472
+ * styleEditorField.radio({
473
+ * id: 'my-field',
474
+ * label: 'Select option',
475
+ * options,
476
+ * defaultValue: 'one' // ✓ Autocomplete works!
477
+ * })
478
+ *
383
479
  * // Simple string options (single column)
384
480
  * styleEditorField.radio({
481
+ * id: 'alignment',
385
482
  * label: 'Alignment',
386
483
  * options: ['Left', 'Center', 'Right'],
387
484
  * defaultValue: 'Left'
@@ -389,6 +486,7 @@ const styleEditorField = {
389
486
  *
390
487
  * // Two-column grid layout with images
391
488
  * styleEditorField.radio({
489
+ * id: 'layout',
392
490
  * label: 'Layout',
393
491
  * columns: 2,
394
492
  * options: [
@@ -411,37 +509,59 @@ const styleEditorField = {
411
509
  */
412
510
  radio: config => ({
413
511
  type: 'radio',
414
- ...config
512
+ ...config,
513
+ options: config.options,
514
+ defaultValue: config.defaultValue
415
515
  }),
416
516
  /**
417
517
  * Creates a checkbox group field definition.
418
518
  *
419
519
  * Allows users to select multiple options simultaneously. Each option
420
- * can be independently checked or unchecked. The defaultValue is a
421
- * record mapping option values to their boolean checked state.
520
+ * can be independently checked or unchecked. The default checked state
521
+ * is defined directly in each option's `value` property (boolean).
522
+ *
523
+ * **Key Differences from Other Field Types:**
524
+ * - Uses `key` instead of `value` for the identifier (to avoid confusion)
525
+ * - Uses `value` for the default boolean checked state (the actual value)
526
+ * - No separate `defaultValue` property - defaults are embedded in options
527
+ *
528
+ * **Why `key` instead of `value`?**
529
+ * In dropdown and radio fields, `value` represents the actual selected value (string).
530
+ * In checkbox groups, the actual value is boolean (checked/unchecked), so we use
531
+ * `key` for the identifier to avoid confusion. This makes it clear that `value`
532
+ * is the boolean state, not just an identifier.
422
533
  *
423
534
  * @experimental This method is experimental and may be subject to change.
424
535
  *
425
536
  * @param config - Checkbox group field configuration (without the 'type' property)
537
+ * @param config.id - The unique identifier for this field
426
538
  * @param config.label - The label displayed for this checkbox group
427
- * @param config.options - Array of options. Can be strings or objects with label and value
428
- * @param config.defaultValue - Optional default checked state as a record of option values to boolean
539
+ * @param config.options - Array of checkbox options with label, key, and value (boolean)
429
540
  * @returns A complete checkbox group field definition with type 'checkboxGroup'
430
541
  *
431
542
  * @example
432
543
  * ```typescript
433
544
  * styleEditorField.checkboxGroup({
545
+ * id: 'text-decoration',
434
546
  * label: 'Text Decoration',
435
547
  * options: [
436
- * { label: 'Underline', value: 'underline' },
437
- * { label: 'Overline', value: 'overline' },
438
- * { label: 'Line Through', value: 'line-through' }
439
- * ],
440
- * defaultValue: {
441
- * 'underline': true,
442
- * 'overline': false,
443
- * 'line-through': false
444
- * }
548
+ * { label: 'Underline', key: 'underline', value: true },
549
+ * { label: 'Overline', key: 'overline', value: false },
550
+ * { label: 'Line Through', key: 'line-through', value: false }
551
+ * ]
552
+ * // No defaultValue needed - it's automatically derived from options
553
+ * })
554
+ *
555
+ * // Example with type settings
556
+ * styleEditorField.checkboxGroup({
557
+ * id: 'type-settings',
558
+ * label: 'Type settings',
559
+ * options: [
560
+ * { label: 'Bold', key: 'bold', value: true },
561
+ * { label: 'Italic', key: 'italic', value: false },
562
+ * { label: 'Underline', key: 'underline', value: false },
563
+ * { label: 'Strikethrough', key: 'strikethrough', value: false }
564
+ * ]
445
565
  * })
446
566
  * ```
447
567
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotcms/uve",
3
- "version": "1.2.1-next.7",
3
+ "version": "1.2.1-next.8",
4
4
  "description": "Official JavaScript library for interacting with Universal Visual Editor (UVE)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { StyleEditorFormSchema, StyleEditorForm, StyleEditorInputField, StyleEditorDropdownField, StyleEditorRadioField, StyleEditorCheckboxGroupField, StyleEditorFieldInputType, StyleEditorInputFieldConfig } from './types';
1
+ import { StyleEditorFormSchema, StyleEditorForm, StyleEditorInputField, StyleEditorDropdownField, StyleEditorRadioField, StyleEditorCheckboxGroupField, StyleEditorFieldInputType, StyleEditorInputFieldConfig, StyleEditorOption, StyleEditorRadioOption, StyleEditorOptionValues, StyleEditorRadioOptionValues } from './types';
2
2
  /**
3
3
  * Helper functions for creating style editor field definitions.
4
4
  *
@@ -98,24 +98,68 @@ export declare const styleEditorField: {
98
98
  */
99
99
  input: <T extends StyleEditorFieldInputType>(config: StyleEditorInputFieldConfig<T>) => StyleEditorInputField;
100
100
  /**
101
- * Creates a dropdown field definition.
101
+ * Creates a dropdown field definition with type-safe default values.
102
102
  *
103
103
  * Allows users to select a single value from a list of options.
104
104
  * Options can be provided as simple strings or as objects with label and value.
105
105
  *
106
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
107
+ * ```typescript
108
+ * const options = [
109
+ * { label: 'The one', value: 'one' },
110
+ * { label: 'The two', value: 'two' }
111
+ * ] as const;
112
+ *
113
+ * styleEditorField.dropdown({
114
+ * id: 'my-field',
115
+ * label: 'Select option',
116
+ * options,
117
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
118
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
119
+ * })
120
+ * ```
121
+ *
122
+ * Without `as const`, the function still works but won't provide autocomplete:
123
+ * ```typescript
124
+ * styleEditorField.dropdown({
125
+ * id: 'my-field',
126
+ * label: 'Select option',
127
+ * options: [
128
+ * { label: 'The one', value: 'one' },
129
+ * { label: 'The two', value: 'two' }
130
+ * ],
131
+ * defaultValue: 'one' // Works, but no autocomplete
132
+ * })
133
+ * ```
134
+ *
106
135
  * @experimental This method is experimental and may be subject to change.
107
136
  *
137
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
108
138
  * @param config - Dropdown field configuration (without the 'type' property)
139
+ * @param config.id - The unique identifier for this field
109
140
  * @param config.label - The label displayed for this dropdown field
110
- * @param config.options - Array of options. Can be strings or objects with label and value
111
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
112
- * @param config.placeholder - Optional placeholder text shown when no value is selected
141
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
142
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
113
143
  * @returns A complete dropdown field definition with type 'dropdown'
114
144
  *
115
145
  * @example
116
146
  * ```typescript
147
+ * // With type safety - use 'as const' for autocomplete
148
+ * const options = [
149
+ * { label: 'The one', value: 'one' },
150
+ * { label: 'The two', value: 'two' }
151
+ * ] as const;
152
+ *
153
+ * styleEditorField.dropdown({
154
+ * id: 'my-field',
155
+ * label: 'Select option',
156
+ * options,
157
+ * defaultValue: 'one' // ✓ Autocomplete works!
158
+ * })
159
+ *
117
160
  * // Simple string options
118
161
  * styleEditorField.dropdown({
162
+ * id: 'font-family',
119
163
  * label: 'Font Family',
120
164
  * options: ['Arial', 'Helvetica', 'Times New Roman'],
121
165
  * defaultValue: 'Arial',
@@ -124,6 +168,7 @@ export declare const styleEditorField: {
124
168
  *
125
169
  * // Object options with custom labels
126
170
  * styleEditorField.dropdown({
171
+ * id: 'theme',
127
172
  * label: 'Theme',
128
173
  * options: [
129
174
  * { label: 'Light Theme', value: 'light' },
@@ -133,9 +178,12 @@ export declare const styleEditorField: {
133
178
  * })
134
179
  * ```
135
180
  */
136
- dropdown: (config: Omit<StyleEditorDropdownField, "type">) => StyleEditorDropdownField;
181
+ dropdown: <TOptions extends readonly StyleEditorOption[]>(config: Omit<StyleEditorDropdownField, "type" | "options" | "defaultValue"> & {
182
+ options: TOptions;
183
+ defaultValue?: StyleEditorOptionValues<TOptions>;
184
+ }) => StyleEditorDropdownField;
137
185
  /**
138
- * Creates a radio button field definition.
186
+ * Creates a radio button field definition with type-safe default values.
139
187
  *
140
188
  * Allows users to select a single option from a list. Supports visual
141
189
  * options with background images for enhanced UI. Options can be provided
@@ -145,19 +193,64 @@ export declare const styleEditorField: {
145
193
  * - `columns: 1` (default): Single column list layout
146
194
  * - `columns: 2`: Two-column grid layout, ideal for visual options with images
147
195
  *
196
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
197
+ * ```typescript
198
+ * const options = [
199
+ * { label: 'The one', value: 'one' },
200
+ * { label: 'The two', value: 'two' }
201
+ * ] as const;
202
+ *
203
+ * styleEditorField.radio({
204
+ * id: 'my-field',
205
+ * label: 'Select option',
206
+ * options,
207
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
208
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
209
+ * })
210
+ * ```
211
+ *
212
+ * Without `as const`, the function still works but won't provide autocomplete:
213
+ * ```typescript
214
+ * styleEditorField.radio({
215
+ * id: 'my-field',
216
+ * label: 'Select option',
217
+ * options: [
218
+ * { label: 'The one', value: 'one' },
219
+ * { label: 'The two', value: 'two' }
220
+ * ],
221
+ * defaultValue: 'one' // Works, but no autocomplete
222
+ * })
223
+ * ```
224
+ *
148
225
  * @experimental This method is experimental and may be subject to change.
149
226
  *
227
+ * @typeParam TOptions - The options array type (inferred from config, use `as const` for type safety)
150
228
  * @param config - Radio field configuration (without the 'type' property)
229
+ * @param config.id - The unique identifier for this field
151
230
  * @param config.label - The label displayed for this radio group
152
- * @param config.options - Array of options. Can be strings or objects with label, value, and optional imageURL
153
- * @param config.defaultValue - Optional default selected value (must match one of the option values)
231
+ * @param config.options - Array of options. Use `as const` for type safety and autocomplete
232
+ * @param config.defaultValue - Optional default selected value (type-safe when options are `as const`)
154
233
  * @param config.columns - Optional number of columns (1 or 2). Defaults to 1 (single column)
155
234
  * @returns A complete radio field definition with type 'radio'
156
235
  *
157
236
  * @example
158
237
  * ```typescript
238
+ * // With type safety - use 'as const' for autocomplete
239
+ * const options = [
240
+ * { label: 'The one', value: 'one' },
241
+ * { label: 'The two', value: 'two' }
242
+ * ] as const;
243
+ *
244
+ * styleEditorField.radio({
245
+ * id: 'my-field',
246
+ * label: 'Select option',
247
+ * options,
248
+ * defaultValue: 'one' // ✓ Autocomplete works!
249
+ * })
250
+ *
159
251
  * // Simple string options (single column)
160
252
  * styleEditorField.radio({
253
+ * id: 'alignment',
161
254
  * label: 'Alignment',
162
255
  * options: ['Left', 'Center', 'Right'],
163
256
  * defaultValue: 'Left'
@@ -165,6 +258,7 @@ export declare const styleEditorField: {
165
258
  *
166
259
  * // Two-column grid layout with images
167
260
  * styleEditorField.radio({
261
+ * id: 'layout',
168
262
  * label: 'Layout',
169
263
  * columns: 2,
170
264
  * options: [
@@ -185,36 +279,59 @@ export declare const styleEditorField: {
185
279
  * })
186
280
  * ```
187
281
  */
188
- radio: (config: Omit<StyleEditorRadioField, "type">) => StyleEditorRadioField;
282
+ radio: <TOptions extends readonly StyleEditorRadioOption[]>(config: Omit<StyleEditorRadioField, "type" | "options" | "defaultValue"> & {
283
+ options: TOptions;
284
+ defaultValue?: StyleEditorRadioOptionValues<TOptions>;
285
+ }) => StyleEditorRadioField;
189
286
  /**
190
287
  * Creates a checkbox group field definition.
191
288
  *
192
289
  * Allows users to select multiple options simultaneously. Each option
193
- * can be independently checked or unchecked. The defaultValue is a
194
- * record mapping option values to their boolean checked state.
290
+ * can be independently checked or unchecked. The default checked state
291
+ * is defined directly in each option's `value` property (boolean).
292
+ *
293
+ * **Key Differences from Other Field Types:**
294
+ * - Uses `key` instead of `value` for the identifier (to avoid confusion)
295
+ * - Uses `value` for the default boolean checked state (the actual value)
296
+ * - No separate `defaultValue` property - defaults are embedded in options
297
+ *
298
+ * **Why `key` instead of `value`?**
299
+ * In dropdown and radio fields, `value` represents the actual selected value (string).
300
+ * In checkbox groups, the actual value is boolean (checked/unchecked), so we use
301
+ * `key` for the identifier to avoid confusion. This makes it clear that `value`
302
+ * is the boolean state, not just an identifier.
195
303
  *
196
304
  * @experimental This method is experimental and may be subject to change.
197
305
  *
198
306
  * @param config - Checkbox group field configuration (without the 'type' property)
307
+ * @param config.id - The unique identifier for this field
199
308
  * @param config.label - The label displayed for this checkbox group
200
- * @param config.options - Array of options. Can be strings or objects with label and value
201
- * @param config.defaultValue - Optional default checked state as a record of option values to boolean
309
+ * @param config.options - Array of checkbox options with label, key, and value (boolean)
202
310
  * @returns A complete checkbox group field definition with type 'checkboxGroup'
203
311
  *
204
312
  * @example
205
313
  * ```typescript
206
314
  * styleEditorField.checkboxGroup({
315
+ * id: 'text-decoration',
207
316
  * label: 'Text Decoration',
208
317
  * options: [
209
- * { label: 'Underline', value: 'underline' },
210
- * { label: 'Overline', value: 'overline' },
211
- * { label: 'Line Through', value: 'line-through' }
212
- * ],
213
- * defaultValue: {
214
- * 'underline': true,
215
- * 'overline': false,
216
- * 'line-through': false
217
- * }
318
+ * { label: 'Underline', key: 'underline', value: true },
319
+ * { label: 'Overline', key: 'overline', value: false },
320
+ * { label: 'Line Through', key: 'line-through', value: false }
321
+ * ]
322
+ * // No defaultValue needed - it's automatically derived from options
323
+ * })
324
+ *
325
+ * // Example with type settings
326
+ * styleEditorField.checkboxGroup({
327
+ * id: 'type-settings',
328
+ * label: 'Type settings',
329
+ * options: [
330
+ * { label: 'Bold', key: 'bold', value: true },
331
+ * { label: 'Italic', key: 'italic', value: false },
332
+ * { label: 'Underline', key: 'underline', value: false },
333
+ * { label: 'Strikethrough', key: 'strikethrough', value: false }
334
+ * ]
218
335
  * })
219
336
  * ```
220
337
  */
@@ -120,7 +120,69 @@ export interface StyleEditorRadioOptionObject extends StyleEditorOptionObject {
120
120
  * };
121
121
  * ```
122
122
  */
123
- export type StyleEditorOption = string | StyleEditorOptionObject;
123
+ export type StyleEditorOption = StyleEditorOptionObject;
124
+ /**
125
+ * Helper type that extracts the union of all option values from an array of options.
126
+ *
127
+ * This type extracts the `value` property from each option object and creates
128
+ * a union type of all possible values. This enables type-safe `defaultValue`
129
+ * that can only be one of the option values when used with `as const`.
130
+ *
131
+ * **Note:** For full type safety and autocomplete, use `as const` when defining options:
132
+ * ```typescript
133
+ * const options = [
134
+ * { label: 'The one', value: 'one' },
135
+ * { label: 'The two', value: 'two' }
136
+ * ] as const;
137
+ * ```
138
+ *
139
+ * @typeParam T - Array of option objects (should be `as const` for best results)
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * const options = [
144
+ * { label: 'The one', value: 'one' },
145
+ * { label: 'The two', value: 'two' }
146
+ * ] as const;
147
+ *
148
+ * type OptionValues = StyleEditorOptionValues<typeof options>;
149
+ * // Result: 'one' | 'two'
150
+ * ```
151
+ */
152
+ export type StyleEditorOptionValues<T extends readonly StyleEditorOption[]> = T[number] extends {
153
+ value: infer V;
154
+ } ? V : never;
155
+ /**
156
+ * Helper type that extracts the union of all radio option values from an array of radio options.
157
+ *
158
+ * Similar to `StyleEditorOptionValues`, but handles radio options which can be
159
+ * strings or objects. Extracts the `value` property from option objects, or uses
160
+ * the string itself if the option is a string.
161
+ *
162
+ * **Note:** For full type safety and autocomplete, use `as const` when defining options:
163
+ * ```typescript
164
+ * const options = [
165
+ * { label: 'The one', value: 'one' },
166
+ * { label: 'The two', value: 'two' }
167
+ * ] as const;
168
+ * ```
169
+ *
170
+ * @typeParam T - Array of radio option objects or strings (should be `as const` for best results)
171
+ *
172
+ * @example
173
+ * ```typescript
174
+ * const options = [
175
+ * { label: 'The one', value: 'one' },
176
+ * { label: 'The two', value: 'two' }
177
+ * ] as const;
178
+ *
179
+ * type RadioOptionValues = StyleEditorRadioOptionValues<typeof options>;
180
+ * // Result: 'one' | 'two'
181
+ * ```
182
+ */
183
+ export type StyleEditorRadioOptionValues<T extends readonly StyleEditorRadioOption[]> = T[number] extends infer U ? U extends string ? U : U extends {
184
+ value: infer V;
185
+ } ? V : never : never;
124
186
  /**
125
187
  * Option type for radio fields with visual support.
126
188
  *
@@ -141,11 +203,40 @@ export type StyleEditorOption = string | StyleEditorOptionObject;
141
203
  * ```
142
204
  */
143
205
  export type StyleEditorRadioOption = string | StyleEditorRadioOptionObject;
206
+ /**
207
+ * Checkbox option object with label, key identifier, and default boolean value.
208
+ *
209
+ * Unlike dropdown and radio options where `value` represents the actual value,
210
+ * checkbox options use `key` as the identifier and `value` as the default checked state (boolean).
211
+ * This distinction makes it clear that the boolean is the actual value, not just an identifier.
212
+ *
213
+ * @property label - Display label shown to users
214
+ * @property key - Unique identifier/key used in the defaultValue object
215
+ * @property value - Default checked state (true or false)
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * const checkboxOption: StyleEditorCheckboxOption = {
220
+ * label: 'Underline',
221
+ * key: 'underline',
222
+ * value: true
223
+ * };
224
+ * ```
225
+ */
226
+ export interface StyleEditorCheckboxOption {
227
+ /** Display label shown to users */
228
+ label: string;
229
+ /** Unique identifier/key used in the defaultValue object */
230
+ key: string;
231
+ /** Default checked state (true = checked by default, false = unchecked by default) */
232
+ value: boolean;
233
+ }
144
234
  /**
145
235
  * Default value type for checkbox group fields.
146
236
  *
147
- * A record mapping option values to their boolean checked state.
148
- * Keys should match the option values, values indicate whether the option is checked.
237
+ * A record mapping option keys to their boolean checked state.
238
+ * This is derived automatically from checkbox options during normalization.
239
+ * Keys match the `key` property from checkbox options, values indicate whether the option is checked.
149
240
  *
150
241
  * @example
151
242
  * ```typescript
@@ -243,10 +334,22 @@ export type StyleEditorInputField = (StyleEditorBaseField & {
243
334
  * Options can be provided as simple strings or as objects with
244
335
  * separate label and value properties for more flexibility.
245
336
  *
337
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
338
+ * ```typescript
339
+ * const options = [
340
+ * { label: 'The one', value: 'one' },
341
+ * { label: 'The two', value: 'two' }
342
+ * ] as const;
343
+ *
344
+ * styleEditorField.dropdown({
345
+ * options,
346
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
347
+ * })
348
+ * ```
349
+ *
246
350
  * @property type - Must be 'dropdown'
247
351
  * @property options - Array of selectable options. Can be strings or objects with label/value
248
352
  * @property defaultValue - Optional default selected value (must match one of the option values)
249
- * @property placeholder - Optional placeholder text shown when no value is selected
250
353
  *
251
354
  * @example
252
355
  * ```typescript
@@ -254,8 +357,7 @@ export type StyleEditorInputField = (StyleEditorBaseField & {
254
357
  * type: 'dropdown',
255
358
  * label: 'Font Family',
256
359
  * options: ['Arial', 'Helvetica', { label: 'Times New Roman', value: 'times' }],
257
- * defaultValue: 'Arial',
258
- * placeholder: 'Select a font'
360
+ * defaultValue: 'Arial'
259
361
  * };
260
362
  * ```
261
363
  */
@@ -266,8 +368,6 @@ export interface StyleEditorDropdownField extends StyleEditorBaseField {
266
368
  options: StyleEditorOption[];
267
369
  /** Optional default selected value (must match one of the option values) */
268
370
  defaultValue?: string;
269
- /** Optional placeholder text shown when no value is selected */
270
- placeholder?: string;
271
371
  }
272
372
  /**
273
373
  * Radio button field definition for single-value selection with visual options.
@@ -281,6 +381,35 @@ export interface StyleEditorDropdownField extends StyleEditorBaseField {
281
381
  * - `columns: 1` (default): Single column list layout
282
382
  * - `columns: 2`: Two-column grid layout, ideal for visual options with images
283
383
  *
384
+ * **Type Safety Tip:** For autocomplete on `defaultValue`, use `as const` when defining options:
385
+ * ```typescript
386
+ * const options = [
387
+ * { label: 'The one', value: 'one' },
388
+ * { label: 'The two', value: 'two' }
389
+ * ] as const;
390
+ *
391
+ * styleEditorField.radio({
392
+ * id: 'my-field',
393
+ * label: 'Select option',
394
+ * options,
395
+ * defaultValue: 'one' // ✓ Autocomplete works! TypeScript knows 'one' | 'two'
396
+ * // defaultValue: 'three' // ✗ TypeScript error: not assignable
397
+ * })
398
+ * ```
399
+ *
400
+ * Without `as const`, the function still works but won't provide autocomplete:
401
+ * ```typescript
402
+ * styleEditorField.radio({
403
+ * id: 'my-field',
404
+ * label: 'Select option',
405
+ * options: [
406
+ * { label: 'The one', value: 'one' },
407
+ * { label: 'The two', value: 'two' }
408
+ * ],
409
+ * defaultValue: 'one' // Works, but no autocomplete
410
+ * })
411
+ * ```
412
+ *
284
413
  * @property type - Must be 'radio'
285
414
  * @property options - Array of selectable options. Can be strings or objects with label, value, and optional image properties
286
415
  * @property defaultValue - Optional default selected value (must match one of the option values)
@@ -288,17 +417,33 @@ export interface StyleEditorDropdownField extends StyleEditorBaseField {
288
417
  *
289
418
  * @example
290
419
  * ```typescript
291
- * // Single column layout (default)
420
+ * // With type safety - use 'as const' for autocomplete
421
+ * const options = [
422
+ * { label: 'The one', value: 'one' },
423
+ * { label: 'The two', value: 'two' }
424
+ * ] as const;
425
+ *
292
426
  * const radioField: StyleEditorRadioField = {
293
427
  * type: 'radio',
428
+ * id: 'my-field',
429
+ * label: 'Select option',
430
+ * options,
431
+ * defaultValue: 'one' // ✓ Autocomplete works!
432
+ * };
433
+ *
434
+ * // Single column layout (default)
435
+ * const alignmentField: StyleEditorRadioField = {
436
+ * type: 'radio',
437
+ * id: 'alignment',
294
438
  * label: 'Alignment',
295
439
  * options: ['Left', 'Center', 'Right'],
296
- * defaultValue: 'left'
440
+ * defaultValue: 'Left'
297
441
  * };
298
442
  *
299
443
  * // Two-column grid layout with images
300
444
  * const layoutField: StyleEditorRadioField = {
301
445
  * type: 'radio',
446
+ * id: 'layout',
302
447
  * label: 'Layout',
303
448
  * columns: 2,
304
449
  * options: [
@@ -341,41 +486,42 @@ export interface StyleEditorRadioField extends StyleEditorBaseField {
341
486
  * Checkbox group field definition for multiple-value selection.
342
487
  *
343
488
  * Allows users to select multiple options simultaneously. Each option
344
- * can be independently checked or unchecked. The defaultValue is a
345
- * record mapping option values to their boolean checked state.
489
+ * can be independently checked or unchecked. The default checked state
490
+ * is defined directly in each option's `value` property (boolean).
491
+ *
492
+ * **Key Differences from Other Field Types:**
493
+ * - Uses `key` instead of `value` for the identifier (to avoid confusion)
494
+ * - Uses `value` for the default boolean checked state (the actual value)
495
+ * - No separate `defaultValue` property - defaults are embedded in options
346
496
  *
347
497
  * @property type - Must be 'checkboxGroup'
348
- * @property options - Array of selectable options. Can be strings or objects with label/value
349
- * @property defaultValue - Optional default checked state as a record mapping option values to boolean
498
+ * @property options - Array of checkbox options with label, key, and value (boolean)
350
499
  *
351
500
  * @example
352
501
  * ```typescript
353
502
  * const checkboxField: StyleEditorCheckboxGroupField = {
354
503
  * type: 'checkboxGroup',
504
+ * id: 'text-decoration',
355
505
  * label: 'Text Decoration',
356
506
  * options: [
357
- * { label: 'Underline', value: 'underline' },
358
- * { label: 'Overline', value: 'overline' },
359
- * { label: 'Line Through', value: 'line-through' }
360
- * ],
361
- * defaultValue: {
362
- * 'underline': true,
363
- * 'overline': false,
364
- * 'line-through': false
365
- * }
507
+ * { label: 'Underline', key: 'underline', value: true },
508
+ * { label: 'Overline', key: 'overline', value: false },
509
+ * { label: 'Line Through', key: 'line-through', value: false }
510
+ * ]
511
+ * // No defaultValue needed - it's derived from options during normalization
366
512
  * };
367
513
  * ```
368
514
  */
369
515
  export interface StyleEditorCheckboxGroupField extends StyleEditorBaseField {
370
516
  /** Discriminator: must be 'checkboxGroup' */
371
517
  type: 'checkboxGroup';
372
- /** Array of selectable options. Can be strings or objects with label and value properties */
373
- options: StyleEditorOption[];
374
518
  /**
375
- * Optional default checked state as a record mapping option values to boolean.
376
- * Keys should match the option values, values indicate whether the option is checked.
519
+ * Array of checkbox options. Each option contains:
520
+ * - `label`: Display text shown to users
521
+ * - `key`: Unique identifier used in the normalized defaultValue object
522
+ * - `value`: Default checked state (true = checked, false = unchecked)
377
523
  */
378
- defaultValue?: StyleEditorCheckboxDefaultValue;
524
+ options: StyleEditorCheckboxOption[];
379
525
  }
380
526
  /**
381
527
  * Union type of all possible field definitions.
@@ -397,10 +543,18 @@ export interface StyleEditorCheckboxGroupField extends StyleEditorBaseField {
397
543
  * @example
398
544
  * ```typescript
399
545
  * const fields: StyleEditorField[] = [
400
- * { type: 'input', label: 'Font Size', inputType: 'number', defaultValue: 16 },
401
- * { type: 'dropdown', label: 'Font Family', options: ['Arial', 'Helvetica'] },
402
- * { type: 'radio', label: 'Theme', options: ['Light', 'Dark'] },
403
- * { type: 'checkboxGroup', label: 'Styles', options: ['Bold', 'Italic'] }
546
+ * { type: 'input', id: 'font-size', label: 'Font Size', inputType: 'number', defaultValue: 16 },
547
+ * { type: 'dropdown', id: 'font-family', label: 'Font Family', options: ['Arial', 'Helvetica'] },
548
+ * { type: 'radio', id: 'theme', label: 'Theme', options: ['Light', 'Dark'] },
549
+ * {
550
+ * type: 'checkboxGroup',
551
+ * id: 'styles',
552
+ * label: 'Styles',
553
+ * options: [
554
+ * { label: 'Bold', key: 'bold', value: true },
555
+ * { label: 'Italic', key: 'italic', value: false }
556
+ * ]
557
+ * }
404
558
  * ];
405
559
  *
406
560
  * // TypeScript can narrow the type based on the discriminator
@@ -508,9 +662,9 @@ export interface StyleEditorForm {
508
662
  *
509
663
  * **Note:** All properties are optional since different field types use different subsets:
510
664
  * - Input fields use: `inputType`, `placeholder`, `defaultValue`
511
- * - Dropdown fields use: `options`, `placeholder`, `defaultValue`
665
+ * - Dropdown fields use: `options`, `defaultValue`
512
666
  * - Radio fields use: `options`, `columns`, `defaultValue`
513
- * - Checkbox fields use: `options`, `defaultValue`
667
+ * - Checkbox fields use: `options`, `defaultValue` (derived from option values during normalization)
514
668
  */
515
669
  export interface StyleEditorFieldSchemaConfig {
516
670
  /** Optional input type for input fields ('text' or 'number') */