@object-ui/fields 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/fields/src/complex-widgets.test.d.ts +1 -0
  2. package/dist/fields/src/datetime-widgets.test.d.ts +1 -0
  3. package/dist/fields/src/fields.stories.d.ts +56 -0
  4. package/dist/fields/src/index.d.ts +48 -0
  5. package/dist/fields/src/new-widgets.test.d.ts +8 -0
  6. package/dist/fields/src/remaining-widgets.test.d.ts +1 -0
  7. package/dist/fields/src/standard-widgets.test.d.ts +0 -0
  8. package/dist/fields/src/text-rich-widgets.test.d.ts +1 -0
  9. package/dist/fields/src/visual-widgets.test.d.ts +1 -0
  10. package/dist/fields/src/widgets/AddressField.d.ts +16 -0
  11. package/dist/fields/src/widgets/AutoNumberField.d.ts +6 -0
  12. package/dist/fields/src/widgets/AvatarField.d.ts +6 -0
  13. package/dist/fields/src/widgets/CodeField.d.ts +7 -0
  14. package/dist/fields/src/widgets/ColorField.d.ts +6 -0
  15. package/dist/fields/src/widgets/CurrencyField.d.ts +1 -1
  16. package/dist/fields/src/widgets/DateTimeField.d.ts +2 -0
  17. package/dist/fields/src/widgets/FileField.d.ts +2 -0
  18. package/dist/fields/src/widgets/FormulaField.d.ts +6 -0
  19. package/dist/fields/src/widgets/GeolocationField.d.ts +14 -0
  20. package/dist/fields/src/widgets/GridField.d.ts +7 -0
  21. package/dist/fields/src/widgets/ImageField.d.ts +2 -0
  22. package/dist/fields/src/widgets/LocationField.d.ts +2 -0
  23. package/dist/fields/src/widgets/LookupField.d.ts +1 -1
  24. package/dist/fields/src/widgets/MasterDetailField.d.ts +14 -0
  25. package/dist/fields/src/widgets/ObjectField.d.ts +6 -0
  26. package/dist/fields/src/widgets/PasswordField.d.ts +2 -0
  27. package/dist/fields/src/widgets/PercentField.d.ts +2 -0
  28. package/dist/fields/src/widgets/QRCodeField.d.ts +6 -0
  29. package/dist/fields/src/widgets/RatingField.d.ts +6 -0
  30. package/dist/fields/src/widgets/SignatureField.d.ts +6 -0
  31. package/dist/fields/src/widgets/SliderField.d.ts +6 -0
  32. package/dist/fields/src/widgets/SummaryField.d.ts +6 -0
  33. package/dist/fields/src/widgets/TimeField.d.ts +2 -0
  34. package/dist/fields/src/widgets/UserField.d.ts +6 -0
  35. package/dist/fields/src/widgets/VectorField.d.ts +6 -0
  36. package/dist/fields/src/widgets/types.d.ts +2 -0
  37. package/dist/index.cjs +4 -2
  38. package/dist/index.js +2003 -618
  39. package/package.json +10 -8
  40. package/src/complex-widgets.test.tsx +146 -0
  41. package/src/datetime-widgets.test.tsx +93 -0
  42. package/src/fields.stories.tsx +566 -0
  43. package/src/index.tsx +303 -68
  44. package/src/new-widgets.test.tsx +302 -0
  45. package/src/remaining-widgets.test.tsx +172 -0
  46. package/src/standard-widgets.test.tsx +278 -0
  47. package/src/text-rich-widgets.test.tsx +104 -0
  48. package/src/visual-widgets.test.tsx +97 -0
  49. package/src/widgets/AddressField.tsx +112 -0
  50. package/src/widgets/AutoNumberField.tsx +16 -0
  51. package/src/widgets/AvatarField.tsx +110 -0
  52. package/src/widgets/BooleanField.tsx +19 -11
  53. package/src/widgets/CodeField.tsx +34 -0
  54. package/src/widgets/ColorField.tsx +44 -0
  55. package/src/widgets/CurrencyField.tsx +8 -7
  56. package/src/widgets/DateField.tsx +5 -2
  57. package/src/widgets/DateTimeField.tsx +28 -0
  58. package/src/widgets/EmailField.tsx +7 -3
  59. package/src/widgets/FileField.tsx +114 -0
  60. package/src/widgets/FormulaField.tsx +31 -0
  61. package/src/widgets/GeolocationField.tsx +151 -0
  62. package/src/widgets/GridField.tsx +63 -0
  63. package/src/widgets/ImageField.tsx +108 -0
  64. package/src/widgets/LocationField.tsx +46 -0
  65. package/src/widgets/LookupField.tsx +5 -5
  66. package/src/widgets/MasterDetailField.tsx +131 -0
  67. package/src/widgets/NumberField.tsx +8 -4
  68. package/src/widgets/ObjectField.tsx +85 -0
  69. package/src/widgets/PasswordField.tsx +45 -0
  70. package/src/widgets/PercentField.tsx +49 -0
  71. package/src/widgets/PhoneField.tsx +7 -3
  72. package/src/widgets/QRCodeField.tsx +96 -0
  73. package/src/widgets/RatingField.tsx +66 -0
  74. package/src/widgets/RichTextField.tsx +5 -5
  75. package/src/widgets/SelectField.tsx +7 -5
  76. package/src/widgets/SignatureField.tsx +140 -0
  77. package/src/widgets/SliderField.tsx +39 -0
  78. package/src/widgets/SummaryField.tsx +29 -0
  79. package/src/widgets/TextAreaField.tsx +9 -6
  80. package/src/widgets/TextField.tsx +13 -8
  81. package/src/widgets/TimeField.tsx +22 -0
  82. package/src/widgets/UrlField.tsx +7 -3
  83. package/src/widgets/UserField.tsx +88 -0
  84. package/src/widgets/VectorField.tsx +28 -0
  85. package/src/widgets/types.ts +2 -0
package/src/index.tsx CHANGED
@@ -8,9 +8,48 @@
8
8
 
9
9
  import React from 'react';
10
10
  import type { FieldMetadata, SelectOptionMetadata } from '@object-ui/types';
11
+ import { ComponentRegistry } from '@object-ui/core';
11
12
  import { Badge, Avatar, AvatarFallback, Button } from '@object-ui/components';
12
13
  import { Check, X } from 'lucide-react';
13
14
 
15
+ import { TextField } from './widgets/TextField';
16
+ import { NumberField } from './widgets/NumberField';
17
+ import { BooleanField } from './widgets/BooleanField';
18
+ import { SelectField } from './widgets/SelectField';
19
+ import { DateField } from './widgets/DateField';
20
+ import { EmailField } from './widgets/EmailField';
21
+ import { PhoneField } from './widgets/PhoneField';
22
+ import { UrlField } from './widgets/UrlField';
23
+ import { CurrencyField } from './widgets/CurrencyField';
24
+ import { TextAreaField } from './widgets/TextAreaField';
25
+ import { RichTextField } from './widgets/RichTextField';
26
+ import { LookupField } from './widgets/LookupField';
27
+ import { DateTimeField } from './widgets/DateTimeField';
28
+ import { TimeField } from './widgets/TimeField';
29
+ import { PercentField } from './widgets/PercentField';
30
+ import { PasswordField } from './widgets/PasswordField';
31
+ import { FileField } from './widgets/FileField';
32
+ import { ImageField } from './widgets/ImageField';
33
+ import { LocationField } from './widgets/LocationField';
34
+ import { FormulaField } from './widgets/FormulaField';
35
+ import { SummaryField } from './widgets/SummaryField';
36
+ import { AutoNumberField } from './widgets/AutoNumberField';
37
+ import { UserField } from './widgets/UserField';
38
+ import { ObjectField } from './widgets/ObjectField';
39
+ import { VectorField } from './widgets/VectorField';
40
+ import { GridField } from './widgets/GridField';
41
+ // New widgets according to @objectstack/spec
42
+ import { ColorField } from './widgets/ColorField';
43
+ import { SliderField } from './widgets/SliderField';
44
+ import { RatingField } from './widgets/RatingField';
45
+ import { CodeField } from './widgets/CodeField';
46
+ import { AvatarField } from './widgets/AvatarField';
47
+ import { AddressField } from './widgets/AddressField';
48
+ import { GeolocationField } from './widgets/GeolocationField';
49
+ import { SignatureField } from './widgets/SignatureField';
50
+ import { QRCodeField } from './widgets/QRCodeField';
51
+ import { MasterDetailField } from './widgets/MasterDetailField';
52
+
14
53
  /**
15
54
  * Cell renderer props
16
55
  */
@@ -519,54 +558,49 @@ registerFieldRenderer('select', SelectCellRenderer);
519
558
  export function mapFieldTypeToFormType(fieldType: string): string {
520
559
  const typeMap: Record<string, string> = {
521
560
  // Text-based fields
522
- text: 'input',
523
- textarea: 'textarea',
524
- markdown: 'textarea', // Markdown editor (fallback to textarea)
525
- html: 'textarea', // Rich text editor (fallback to textarea)
561
+ text: 'field:text',
562
+ textarea: 'field:textarea',
563
+ markdown: 'field:markdown', // Markdown editor (fallback to textarea)
564
+ html: 'field:html', // Rich text editor (fallback to textarea)
526
565
 
527
566
  // Numeric fields
528
- number: 'input',
529
- currency: 'input',
530
- percent: 'input',
567
+ number: 'field:number',
568
+ currency: 'field:currency',
569
+ percent: 'field:percent',
531
570
 
532
571
  // Date/Time fields
533
- date: 'date-picker',
534
- datetime: 'date-picker',
535
- time: 'input', // Time picker (fallback to input with type="time")
572
+ date: 'field:date',
573
+ datetime: 'field:datetime',
574
+ time: 'field:time',
536
575
 
537
576
  // Boolean
538
- boolean: 'switch',
577
+ boolean: 'field:boolean',
539
578
 
540
579
  // Selection fields
541
- select: 'select',
542
- lookup: 'select',
543
- master_detail: 'select',
580
+ select: 'field:select',
581
+ lookup: 'field:lookup',
582
+ master_detail: 'field:master_detail',
544
583
 
545
584
  // Contact fields
546
- email: 'input',
547
- phone: 'input',
548
- url: 'input',
585
+ email: 'field:email',
586
+ phone: 'field:phone',
587
+ url: 'field:url',
549
588
 
550
589
  // File fields
551
- file: 'file-upload',
552
- image: 'file-upload',
590
+ file: 'field:file',
591
+ image: 'field:image',
553
592
 
554
593
  // Special fields
555
- password: 'input',
556
- location: 'input', // Location/map field (fallback to input)
594
+ password: 'field:password',
595
+ location: 'field:location', // Location/map field (fallback to input)
557
596
 
558
597
  // Auto-generated/computed fields (typically read-only)
559
- formula: 'input',
560
- summary: 'input',
561
- auto_number: 'input',
562
-
563
- // Complex data types
564
- object: 'input', // JSON object (fallback to input)
565
- vector: 'input', // Vector/embedding data (fallback to input)
566
- grid: 'input', // Grid/table data (fallback to input)
598
+ formula: 'field:formula',
599
+ summary: 'field:summary',
600
+ auto_number: 'field:auto_number',
567
601
  };
568
602
 
569
- return typeMap[fieldType] || 'input';
603
+ return typeMap[fieldType] || 'field:text';
570
604
  }
571
605
 
572
606
  /**
@@ -714,50 +748,223 @@ export function evaluateCondition(condition: any, formData: any): boolean {
714
748
  return true;
715
749
  }
716
750
 
717
- import { ComponentRegistry } from '@object-ui/core';
718
- import { TextField } from './widgets/TextField';
719
- import { NumberField } from './widgets/NumberField';
720
- import { BooleanField } from './widgets/BooleanField';
721
- import { SelectField } from './widgets/SelectField';
722
- import { DateField } from './widgets/DateField';
723
- import { EmailField } from './widgets/EmailField';
724
- import { PhoneField } from './widgets/PhoneField';
725
- import { UrlField } from './widgets/UrlField';
726
- import { CurrencyField } from './widgets/CurrencyField';
727
- import { TextAreaField } from './widgets/TextAreaField';
728
- import { RichTextField } from './widgets/RichTextField';
729
- import { LookupField } from './widgets/LookupField';
751
+ // Create wrapper renderers for field widgets to work with ComponentDemo
752
+ function createFieldRenderer(FieldWidget: React.ComponentType<any>) {
753
+ const FieldRenderer: React.FC<any> = ({ schema, className, value: initialValue, ...props }) => {
754
+ const [value, setValue] = React.useState(initialValue ?? schema?.value ?? '');
755
+
756
+ const field = {
757
+ name: schema?.name || 'field',
758
+ label: schema?.label,
759
+ type: schema?.type,
760
+ placeholder: schema?.placeholder,
761
+ required: schema?.required,
762
+ readonly: schema?.readonly || schema?.readOnly,
763
+ help: schema?.help,
764
+ description: schema?.description,
765
+ defaultValue: schema?.defaultValue || schema?.value,
766
+ ...schema,
767
+ };
730
768
 
731
- export function registerFields() {
769
+ const handleChange = React.useCallback((newValue: any) => {
770
+ setValue(newValue);
771
+ if (props.onChange) {
772
+ props.onChange(newValue);
773
+ }
774
+ }, [props]);
775
+
776
+ const readonly = schema?.readonly || schema?.readOnly || false;
777
+
778
+ return (
779
+ <div
780
+ className="grid w-full items-center gap-1.5"
781
+ data-obj-id={schema?.id}
782
+ data-obj-type={schema?.type}
783
+ >
784
+ {schema?.label && (
785
+ <label htmlFor={schema.id} className={schema.required ? "after:content-['*'] after:ml-0.5 after:text-red-500" : ""}>
786
+ {schema.label}
787
+ </label>
788
+ )}
789
+ <FieldWidget
790
+ value={value}
791
+ onChange={handleChange}
792
+ field={field}
793
+ readonly={readonly}
794
+ className={className}
795
+ />
796
+ {schema?.description && (
797
+ <p className="text-sm text-gray-500">{schema.description}</p>
798
+ )}
799
+ </div>
800
+ );
801
+ };
802
+
803
+ FieldRenderer.displayName = `FieldRenderer(${FieldWidget.displayName || FieldWidget.name || 'Component'})`;
804
+
805
+ return FieldRenderer;
806
+ }
807
+
808
+ /**
809
+ * Field widget map for lazy loading
810
+ * Maps field type to widget component
811
+ */
812
+ const fieldWidgetMap: Record<string, () => Promise<{ default: React.ComponentType<any> }>> = {
732
813
  // Basic fields
733
- ComponentRegistry.register('text', TextField);
734
- ComponentRegistry.register('textarea', TextAreaField);
735
- ComponentRegistry.register('number', NumberField);
736
- ComponentRegistry.register('boolean', BooleanField);
737
- ComponentRegistry.register('select', SelectField);
738
- ComponentRegistry.register('date', DateField);
814
+ 'text': () => import('./widgets/TextField').then(m => ({ default: m.TextField })),
815
+ 'textarea': () => import('./widgets/TextAreaField').then(m => ({ default: m.TextAreaField })),
816
+ 'number': () => import('./widgets/NumberField').then(m => ({ default: m.NumberField })),
817
+ 'boolean': () => import('./widgets/BooleanField').then(m => ({ default: m.BooleanField })),
818
+ 'select': () => import('./widgets/SelectField').then(m => ({ default: m.SelectField })),
819
+ 'date': () => import('./widgets/DateField').then(m => ({ default: m.DateField })),
820
+ 'datetime': () => import('./widgets/DateTimeField').then(m => ({ default: m.DateTimeField })),
821
+ 'time': () => import('./widgets/TimeField').then(m => ({ default: m.TimeField })),
739
822
 
740
823
  // Contact fields
741
- ComponentRegistry.register('email', EmailField);
742
- ComponentRegistry.register('phone', PhoneField);
743
- ComponentRegistry.register('url', UrlField);
824
+ 'email': () => import('./widgets/EmailField').then(m => ({ default: m.EmailField })),
825
+ 'phone': () => import('./widgets/PhoneField').then(m => ({ default: m.PhoneField })),
826
+ 'url': () => import('./widgets/UrlField').then(m => ({ default: m.UrlField })),
744
827
 
745
828
  // Specialized fields
746
- ComponentRegistry.register('currency', CurrencyField);
747
- ComponentRegistry.register('markdown', RichTextField);
748
- ComponentRegistry.register('html', RichTextField);
749
- ComponentRegistry.register('lookup', LookupField);
750
- ComponentRegistry.register('master_detail', LookupField);
751
-
752
- // Register with field: prefix for explicit field widgets
753
- ComponentRegistry.register('field:text', TextField);
754
- ComponentRegistry.register('field:textarea', TextAreaField);
755
- ComponentRegistry.register('field:number', NumberField);
756
- ComponentRegistry.register('field:email', EmailField);
757
- ComponentRegistry.register('field:phone', PhoneField);
758
- ComponentRegistry.register('field:url', UrlField);
759
- ComponentRegistry.register('field:currency', CurrencyField);
760
- ComponentRegistry.register('field:lookup', LookupField);
829
+ 'currency': () => import('./widgets/CurrencyField').then(m => ({ default: m.CurrencyField })),
830
+ 'percent': () => import('./widgets/PercentField').then(m => ({ default: m.PercentField })),
831
+ 'password': () => import('./widgets/PasswordField').then(m => ({ default: m.PasswordField })),
832
+ 'markdown': () => import('./widgets/RichTextField').then(m => ({ default: m.RichTextField })),
833
+ 'html': () => import('./widgets/RichTextField').then(m => ({ default: m.RichTextField })),
834
+ 'lookup': () => import('./widgets/LookupField').then(m => ({ default: m.LookupField })),
835
+ 'master_detail': () => import('./widgets/MasterDetailField').then(m => ({ default: m.MasterDetailField })),
836
+
837
+ // File fields
838
+ 'file': () => import('./widgets/FileField').then(m => ({ default: m.FileField })),
839
+ 'image': () => import('./widgets/ImageField').then(m => ({ default: m.ImageField })),
840
+
841
+ // Location field
842
+ 'location': () => import('./widgets/LocationField').then(m => ({ default: m.LocationField })),
843
+
844
+ // Computed/Read-only fields
845
+ 'formula': () => import('./widgets/FormulaField').then(m => ({ default: m.FormulaField })),
846
+ 'summary': () => import('./widgets/SummaryField').then(m => ({ default: m.SummaryField })),
847
+ 'auto_number': () => import('./widgets/AutoNumberField').then(m => ({ default: m.AutoNumberField })),
848
+
849
+ // User fields
850
+ 'user': () => import('./widgets/UserField').then(m => ({ default: m.UserField })),
851
+ 'owner': () => import('./widgets/UserField').then(m => ({ default: m.UserField })),
852
+
853
+ // Complex data types
854
+ 'object': () => import('./widgets/ObjectField').then(m => ({ default: m.ObjectField })),
855
+ 'vector': () => import('./widgets/VectorField').then(m => ({ default: m.VectorField })),
856
+ 'grid': () => import('./widgets/GridField').then(m => ({ default: m.GridField })),
857
+
858
+ // Additional field types from @objectstack/spec
859
+ 'color': () => import('./widgets/ColorField').then(m => ({ default: m.ColorField })),
860
+ 'slider': () => import('./widgets/SliderField').then(m => ({ default: m.SliderField })),
861
+ 'rating': () => import('./widgets/RatingField').then(m => ({ default: m.RatingField })),
862
+ 'code': () => import('./widgets/CodeField').then(m => ({ default: m.CodeField })),
863
+ 'avatar': () => import('./widgets/AvatarField').then(m => ({ default: m.AvatarField })),
864
+ 'address': () => import('./widgets/AddressField').then(m => ({ default: m.AddressField })),
865
+ 'geolocation': () => import('./widgets/GeolocationField').then(m => ({ default: m.GeolocationField })),
866
+ 'signature': () => import('./widgets/SignatureField').then(m => ({ default: m.SignatureField })),
867
+ 'qrcode': () => import('./widgets/QRCodeField').then(m => ({ default: m.QRCodeField })),
868
+ };
869
+
870
+ /**
871
+ * Register a specific field type lazily
872
+ * @param fieldType - The field type to register (e.g., 'text', 'number')
873
+ *
874
+ * @example
875
+ * // Register only the text field
876
+ * registerField('text');
877
+ */
878
+ export function registerField(fieldType: string): void {
879
+ const loader = fieldWidgetMap[fieldType];
880
+ if (!loader) {
881
+ console.warn(`Unknown field type: ${fieldType}`);
882
+ return;
883
+ }
884
+
885
+ // Create lazy component
886
+ const LazyFieldWidget = React.lazy(loader);
887
+
888
+ // Register with field namespace - NO WRAPPER to allow form renderer to control label/layout
889
+ ComponentRegistry.register(fieldType, LazyFieldWidget, { namespace: 'field' });
890
+ }
891
+
892
+ /**
893
+ * Register all field types (for backward compatibility)
894
+ * This function auto-registers all field widgets on import.
895
+ *
896
+ * For better tree-shaking, use registerField() to register only needed fields.
897
+ *
898
+ * @example
899
+ * // Register all fields at once
900
+ * registerAllFields();
901
+ */
902
+ export function registerAllFields(): void {
903
+ Object.keys(fieldWidgetMap).forEach(fieldType => {
904
+ registerField(fieldType);
905
+ });
906
+ }
907
+
908
+ /**
909
+ * Legacy function - kept for backward compatibility
910
+ * @deprecated Use registerAllFields() instead
911
+ */
912
+ export function registerFields() {
913
+ // Basic fields - wrapped for documentation compatibility
914
+ ComponentRegistry.register('text', createFieldRenderer(TextField), { namespace: 'field' });
915
+ ComponentRegistry.register('textarea', createFieldRenderer(TextAreaField), { namespace: 'field' });
916
+ ComponentRegistry.register('number', createFieldRenderer(NumberField), { namespace: 'field' });
917
+ ComponentRegistry.register('boolean', createFieldRenderer(BooleanField), { namespace: 'field' });
918
+ ComponentRegistry.register('select', createFieldRenderer(SelectField), { namespace: 'field' });
919
+ ComponentRegistry.register('date', createFieldRenderer(DateField), { namespace: 'field' });
920
+ ComponentRegistry.register('datetime', createFieldRenderer(DateTimeField), { namespace: 'field' });
921
+ ComponentRegistry.register('time', createFieldRenderer(TimeField), { namespace: 'field' });
922
+
923
+ // Contact fields - wrapped for documentation compatibility
924
+ ComponentRegistry.register('email', createFieldRenderer(EmailField), { namespace: 'field' });
925
+ ComponentRegistry.register('phone', createFieldRenderer(PhoneField), { namespace: 'field' });
926
+ ComponentRegistry.register('url', createFieldRenderer(UrlField), { namespace: 'field' });
927
+
928
+ // Specialized fields - wrapped for documentation compatibility
929
+ ComponentRegistry.register('currency', createFieldRenderer(CurrencyField), { namespace: 'field' });
930
+ ComponentRegistry.register('percent', createFieldRenderer(PercentField), { namespace: 'field' });
931
+ ComponentRegistry.register('password', createFieldRenderer(PasswordField), { namespace: 'field' });
932
+ ComponentRegistry.register('markdown', createFieldRenderer(RichTextField), { namespace: 'field' });
933
+ ComponentRegistry.register('html', createFieldRenderer(RichTextField), { namespace: 'field' });
934
+ ComponentRegistry.register('lookup', createFieldRenderer(LookupField), { namespace: 'field' });
935
+ ComponentRegistry.register('master_detail', createFieldRenderer(MasterDetailField), { namespace: 'field' });
936
+
937
+ // File fields
938
+ ComponentRegistry.register('file', createFieldRenderer(FileField), { namespace: 'field' });
939
+ ComponentRegistry.register('image', createFieldRenderer(ImageField), { namespace: 'field' });
940
+
941
+ // Location field
942
+ ComponentRegistry.register('location', createFieldRenderer(LocationField), { namespace: 'field' });
943
+
944
+ // Computed/Read-only fields
945
+ ComponentRegistry.register('formula', createFieldRenderer(FormulaField), { namespace: 'field' });
946
+ ComponentRegistry.register('summary', createFieldRenderer(SummaryField), { namespace: 'field' });
947
+ ComponentRegistry.register('auto_number', createFieldRenderer(AutoNumberField), { namespace: 'field' });
948
+
949
+ // User fields
950
+ ComponentRegistry.register('user', createFieldRenderer(UserField), { namespace: 'field' });
951
+ ComponentRegistry.register('owner', createFieldRenderer(UserField), { namespace: 'field' });
952
+
953
+ // Complex data types
954
+ ComponentRegistry.register('object', createFieldRenderer(ObjectField), { namespace: 'field' });
955
+ ComponentRegistry.register('vector', createFieldRenderer(VectorField), { namespace: 'field' });
956
+ ComponentRegistry.register('grid', createFieldRenderer(GridField), { namespace: 'field' });
957
+
958
+ // NEW: Additional field types from @objectstack/spec
959
+ ComponentRegistry.register('color', createFieldRenderer(ColorField), { namespace: 'field' });
960
+ ComponentRegistry.register('slider', createFieldRenderer(SliderField), { namespace: 'field' });
961
+ ComponentRegistry.register('rating', createFieldRenderer(RatingField), { namespace: 'field' });
962
+ ComponentRegistry.register('code', createFieldRenderer(CodeField), { namespace: 'field' });
963
+ ComponentRegistry.register('avatar', createFieldRenderer(AvatarField), { namespace: 'field' });
964
+ ComponentRegistry.register('address', createFieldRenderer(AddressField), { namespace: 'field' });
965
+ ComponentRegistry.register('geolocation', createFieldRenderer(GeolocationField), { namespace: 'field' });
966
+ ComponentRegistry.register('signature', createFieldRenderer(SignatureField), { namespace: 'field' });
967
+ ComponentRegistry.register('qrcode', createFieldRenderer(QRCodeField), { namespace: 'field' });
761
968
  }
762
969
 
763
970
  export * from './widgets/types';
@@ -766,10 +973,38 @@ export * from './widgets/NumberField';
766
973
  export * from './widgets/BooleanField';
767
974
  export * from './widgets/SelectField';
768
975
  export * from './widgets/DateField';
976
+ export * from './widgets/DateTimeField';
977
+ export * from './widgets/TimeField';
769
978
  export * from './widgets/EmailField';
770
979
  export * from './widgets/PhoneField';
771
980
  export * from './widgets/UrlField';
772
981
  export * from './widgets/CurrencyField';
982
+ export * from './widgets/PercentField';
983
+ export * from './widgets/PasswordField';
773
984
  export * from './widgets/TextAreaField';
774
985
  export * from './widgets/RichTextField';
775
986
  export * from './widgets/LookupField';
987
+ export * from './widgets/FileField';
988
+ export * from './widgets/ImageField';
989
+ export * from './widgets/LocationField';
990
+ export * from './widgets/FormulaField';
991
+ export * from './widgets/SummaryField';
992
+ export * from './widgets/AutoNumberField';
993
+ export * from './widgets/UserField';
994
+ export * from './widgets/ObjectField';
995
+ export * from './widgets/VectorField';
996
+ export * from './widgets/GridField';
997
+ // New widgets according to @objectstack/spec
998
+ export * from './widgets/ColorField';
999
+ export * from './widgets/SliderField';
1000
+ export * from './widgets/RatingField';
1001
+ export * from './widgets/CodeField';
1002
+ export * from './widgets/AvatarField';
1003
+ export * from './widgets/AddressField';
1004
+ export * from './widgets/GeolocationField';
1005
+ export * from './widgets/SignatureField';
1006
+ export * from './widgets/QRCodeField';
1007
+ export * from './widgets/MasterDetailField';
1008
+
1009
+ // Initialize registry
1010
+ registerAllFields();