@firecms/collection_editor 3.0.0-canary.136 → 3.0.0-canary.138

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.
@@ -21,6 +21,7 @@ export type PropertyFormProps = {
21
21
  property?: Property;
22
22
  onPropertyChanged?: (params: OnPropertyChangedParams) => void;
23
23
  onPropertyChangedImmediate?: boolean;
24
+ onDismiss?: () => void;
24
25
  onDelete?: (id?: string, namespace?: string) => void;
25
26
  onError?: (id: string, namespace?: string, error?: Record<string, any>) => void;
26
27
  initialErrors?: Record<string, any>;
@@ -38,3 +39,10 @@ export declare function PropertyFormDialog({ open, onCancel, onOkClicked, onProp
38
39
  onOkClicked?: () => void;
39
40
  onCancel?: () => void;
40
41
  }): import("react/jsx-runtime").JSX.Element;
42
+ export interface PropertySelectItemProps {
43
+ onClick?: () => void;
44
+ initialProperty?: PropertyWithId;
45
+ propertyConfig: PropertyConfig;
46
+ existing: boolean;
47
+ }
48
+ export declare function WidgetSelectViewItem({ onClick, initialProperty, propertyConfig, existing }: PropertySelectItemProps): import("react/jsx-runtime").JSX.Element;
@@ -5,3 +5,10 @@ export declare function CollectionEditorImportMapping({ importConfig, propertyCo
5
5
  propertyConfigs: Record<string, PropertyConfig>;
6
6
  collectionEditable: boolean;
7
7
  }): import("react/jsx-runtime").JSX.Element;
8
+ export interface PropertySelectItemProps {
9
+ value: string;
10
+ optionDisabled: boolean;
11
+ propertyConfig: PropertyConfig;
12
+ existing: boolean;
13
+ }
14
+ export declare function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps): import("react/jsx-runtime").JSX.Element;
package/package.json CHANGED
@@ -1,18 +1,18 @@
1
1
  {
2
2
  "name": "@firecms/collection_editor",
3
3
  "type": "module",
4
- "version": "3.0.0-canary.136",
4
+ "version": "3.0.0-canary.138",
5
5
  "main": "./dist/index.umd.js",
6
6
  "module": "./dist/index.es.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "source": "src/index.ts",
9
9
  "dependencies": {
10
- "@firecms/data_export": "^3.0.0-canary.136",
11
- "@firecms/data_import": "^3.0.0-canary.136",
12
- "@firecms/data_import_export": "^3.0.0-canary.136",
13
- "@firecms/formex": "^3.0.0-canary.136",
14
- "@firecms/schema_inference": "^3.0.0-canary.136",
15
- "@firecms/ui": "^3.0.0-canary.136",
10
+ "@firecms/data_export": "^3.0.0-canary.138",
11
+ "@firecms/data_import": "^3.0.0-canary.138",
12
+ "@firecms/data_import_export": "^3.0.0-canary.138",
13
+ "@firecms/formex": "^3.0.0-canary.138",
14
+ "@firecms/schema_inference": "^3.0.0-canary.138",
15
+ "@firecms/ui": "^3.0.0-canary.138",
16
16
  "json5": "^2.2.3",
17
17
  "prism-react-renderer": "^2.4.0"
18
18
  },
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "10606ac1472f57203a5571b7b5433b2625aafdb9"
70
+ "gitHead": "055055d2b116aa0a4dfd6252cd3f0e9da323770a"
71
71
  }
@@ -474,6 +474,7 @@ export function CollectionPropertiesEditorForm({
474
474
  getData={getData}
475
475
  propertyConfigs={propertyConfigs}
476
476
  collectionEditable={collectionEditable}
477
+ onCancel={closePropertyDialog}
477
478
  onOkClicked={asDialog
478
479
  ? closePropertyDialog
479
480
  : undefined
@@ -3,8 +3,8 @@ import equal from "react-fast-compare"
3
3
 
4
4
  import { Formex, FormexController, getIn, useCreateFormex } from "@firecms/formex";
5
5
  import {
6
- DEFAULT_FIELD_CONFIGS,
7
6
  ConfirmationDialog,
7
+ DEFAULT_FIELD_CONFIGS,
8
8
  getFieldConfig,
9
9
  getFieldId,
10
10
  isPropertyBuilder,
@@ -17,15 +17,21 @@ import {
17
17
  } from "@firecms/core";
18
18
  import {
19
19
  Button,
20
+ Card,
20
21
  cls,
21
22
  DeleteIcon,
22
23
  Dialog,
23
24
  DialogActions,
24
25
  DialogContent,
26
+ DialogTitle,
27
+ fieldBackgroundDisabledMixin,
28
+ fieldBackgroundHoverMixin,
29
+ fieldBackgroundMixin,
25
30
  IconButton,
26
31
  InfoLabel,
27
- Select,
28
- Typography
32
+ Tooltip,
33
+ Typography,
34
+ WarningOffIcon
29
35
  } from "@firecms/ui";
30
36
  import { EnumPropertyField } from "./properties/EnumPropertyField";
31
37
  import { StoragePropertyField } from "./properties/StoragePropertyField";
@@ -42,7 +48,6 @@ import { AdvancedPropertyValidation } from "./properties/advanced/AdvancedProper
42
48
  import { editableProperty } from "../../utils/entities";
43
49
  import { KeyValuePropertyField } from "./properties/KeyValuePropertyField";
44
50
  import { updatePropertyFromWidget } from "./utils/update_property_for_widget";
45
- import { PropertySelectItem } from "./PropertySelectItem";
46
51
  import { UrlPropertyField } from "./properties/UrlPropertyField";
47
52
  import { supportedFields } from "./utils/supported_fields";
48
53
  import { MarkdownPropertyField } from "./properties/MarkdownPropertyField";
@@ -69,6 +74,7 @@ export type PropertyFormProps = {
69
74
  property?: Property;
70
75
  onPropertyChanged?: (params: OnPropertyChangedParams) => void;
71
76
  onPropertyChangedImmediate?: boolean;
77
+ onDismiss?: () => void;
72
78
  onDelete?: (id?: string, namespace?: string) => void;
73
79
  onError?: (id: string, namespace?: string, error?: Record<string, any>) => void;
74
80
  initialErrors?: Record<string, any>;
@@ -96,6 +102,7 @@ export const PropertyForm = React.memo(
96
102
  property,
97
103
  onPropertyChanged,
98
104
  onPropertyChangedImmediate = true,
105
+ onDismiss,
99
106
  onDelete,
100
107
  onError,
101
108
  initialErrors,
@@ -213,6 +220,7 @@ export const PropertyForm = React.memo(
213
220
  includeIdAndTitle={includeIdAndName}
214
221
  propertyNamespace={propertyNamespace}
215
222
  onError={onError}
223
+ onDismiss={onDismiss}
216
224
  showErrors={forceShowErrors || formexController.submitCount > 0}
217
225
  existing={existingProperty}
218
226
  autoUpdateId={autoUpdateId}
@@ -268,6 +276,7 @@ export function PropertyFormDialog({
268
276
  }}>
269
277
  <DialogContent>
270
278
  <PropertyForm {...formProps}
279
+ onDismiss={onCancel}
271
280
  onPropertyChanged={(params) => {
272
281
  onPropertyChanged?.(params);
273
282
  onOkClicked?.();
@@ -312,6 +321,7 @@ function PropertyEditFormFields({
312
321
  onPropertyChanged,
313
322
  onDelete,
314
323
  propertyNamespace,
324
+ onDismiss,
315
325
  onError,
316
326
  showErrors,
317
327
  disabled,
@@ -326,6 +336,7 @@ function PropertyEditFormFields({
326
336
  autoUpdateId?: boolean;
327
337
  autoOpenTypeSelect: boolean;
328
338
  propertyNamespace?: string;
339
+ onDismiss?: () => void;
329
340
  onPropertyChanged?: (params: OnPropertyChangedParams) => void;
330
341
  onDelete?: (id?: string, namespace?: string) => void;
331
342
  onError?: (id: string, namespace?: string, error?: Record<string, any>) => void;
@@ -342,12 +353,6 @@ function PropertyEditFormFields({
342
353
  const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
343
354
  const [selectedFieldConfigId, setSelectedFieldConfigId] = useState<string | undefined>(values?.dataType ? getFieldId(values) : undefined);
344
355
 
345
- const allSupportedFields = Object.entries(supportedFields).concat(Object.entries(propertyConfigs));
346
-
347
- const displayedWidgets = inArray
348
- ? allSupportedFields.filter(([_, propertyConfig]) => !isPropertyBuilder(propertyConfig.property) && propertyConfig.property?.dataType !== "array")
349
- : allSupportedFields;
350
-
351
356
  const deferredValues = useDeferredValue(values);
352
357
  const nameFieldRef = useRef<HTMLInputElement>(null);
353
358
 
@@ -489,62 +494,22 @@ function PropertyEditFormFields({
489
494
 
490
495
  <div className="flex mt-2 justify-between">
491
496
  <div className={"w-full flex flex-col gap-2"}>
492
- <Select
493
- // className={"w-full"}
494
- error={Boolean(selectedWidgetError)}
495
- value={selectedFieldConfigId ?? ""}
496
- placeholder={"Select a property widget"}
497
+ <WidgetSelectView
498
+ initialProperty={values}
499
+ value={selectedFieldConfigId as PropertyConfigId}
500
+ onValueChange={(value) => onWidgetSelectChanged(value as PropertyConfigId)}
497
501
  open={selectOpen}
498
- onOpenChange={setSelectOpen}
499
- position={"item-aligned"}
500
- disabled={disabled}
501
- renderValue={(value) => {
502
- if (!value) {
503
- return <em>Select a property
504
- widget</em>;
502
+ onOpenChange={(open, hasValue) => {
503
+ if (!hasValue) {
504
+ onDismiss?.();
505
505
  }
506
- const key = value as PropertyConfigId;
507
- const propertyConfig = DEFAULT_FIELD_CONFIGS[key] ?? propertyConfigs[key];
508
- const baseProperty = propertyConfig.property;
509
- const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, propertyConfigs) : undefined;
510
- const optionDisabled = isPropertyBuilder(baseProperty) || (existing && baseProperty.dataType !== values?.dataType);
511
- const computedFieldConfig = baseFieldConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
512
- return <div
513
- onClick={(e) => {
514
- if (optionDisabled) {
515
- e.stopPropagation();
516
- e.preventDefault();
517
- }
518
- }}
519
- className={cls(
520
- "flex items-center",
521
- optionDisabled ? "w-full pointer-events-none opacity-50" : "")}>
522
- <div className={"mr-8"}>
523
- <PropertyConfigBadge propertyConfig={computedFieldConfig}/>
524
- </div>
525
- <div className={"flex flex-col items-start text-base text-left"}>
526
- <div>{computedFieldConfig.name}</div>
527
- <Typography variant={"caption"}
528
- color={"disabled"}>
529
- {optionDisabled ? "You can only switch to widgets that use the same data type" : computedFieldConfig.description}
530
- </Typography>
531
- </div>
532
- </div>
506
+ setSelectOpen(open);
533
507
  }}
534
- onValueChange={(value) => {
535
- onWidgetSelectChanged(value as PropertyConfigId);
536
- }}>
537
- {displayedWidgets.map(([key, propertyConfig]) => {
538
- const baseProperty = propertyConfig.property;
539
- const optionDisabled = existing && !isPropertyBuilder(baseProperty) && baseProperty.dataType !== values?.dataType;
540
- return <PropertySelectItem
541
- key={key}
542
- value={key}
543
- optionDisabled={optionDisabled}
544
- propertyConfig={propertyConfig}
545
- existing={existing}/>;
546
- })}
547
- </Select>
508
+ disabled={disabled}
509
+ showError={Boolean(selectedWidgetError)}
510
+ existing={existing}
511
+ propertyConfigs={propertyConfigs}
512
+ inArray={inArray}/>
548
513
 
549
514
  {selectedWidgetError &&
550
515
  <Typography variant="caption"
@@ -588,10 +553,10 @@ function PropertyEditFormFields({
588
553
  onCancel={() => setDeleteDialogOpen(false)}
589
554
  title={<div>Delete this property?</div>}
590
555
  body={
591
- <div> This will <b>not delete any
592
- data</b>, only modify the
593
- collection.</div>
594
- }/>}
556
+ <div> This will <b>not delete any
557
+ data</b>, only modify the
558
+ collection.</div>
559
+ }/>}
595
560
 
596
561
  </>
597
562
  );
@@ -621,3 +586,204 @@ function validateName(value: string) {
621
586
  }
622
587
  return error;
623
588
  }
589
+
590
+ const WIDGET_TYPE_MAP: Record<PropertyConfigId, string> = {
591
+ text_field: "Text",
592
+ multiline: "Text",
593
+ markdown: "Text",
594
+ url: "Text",
595
+ email: "Text",
596
+ switch: "Boolean",
597
+ select: "Select",
598
+ multi_select: "Select",
599
+ number_input: "Number",
600
+ number_select: "Select",
601
+ multi_number_select: "Select",
602
+ file_upload: "File",
603
+ multi_file_upload: "File",
604
+ reference: "Reference",
605
+ multi_references: "Reference",
606
+ date_time: "Date",
607
+ group: "Group",
608
+ key_value: "Group",
609
+ repeat: "Array",
610
+ custom_array: "Array",
611
+ block: "Group"
612
+ };
613
+
614
+ function WidgetSelectView({
615
+ initialProperty,
616
+ value,
617
+ onValueChange,
618
+ open,
619
+ onOpenChange,
620
+ disabled,
621
+ showError,
622
+ existing,
623
+ propertyConfigs,
624
+ inArray
625
+ }: {
626
+ initialProperty?: PropertyWithId,
627
+ value?: PropertyConfigId,
628
+ onValueChange: (value: string) => void,
629
+ showError: boolean,
630
+ open: boolean,
631
+ onOpenChange: (open: boolean, hasValue: boolean) => void,
632
+ disabled: boolean,
633
+ existing: boolean,
634
+ propertyConfigs: Record<string, PropertyConfig>,
635
+ inArray?: boolean
636
+ }) {
637
+
638
+ const allSupportedFields = Object.entries(supportedFields).concat(Object.entries(propertyConfigs));
639
+
640
+ const displayedWidgets = (inArray
641
+ ? allSupportedFields.filter(([_, propertyConfig]) => !isPropertyBuilder(propertyConfig.property) && propertyConfig.property?.dataType !== "array")
642
+ : allSupportedFields)
643
+ .map(([key, propertyConfig]) => ({
644
+ [key]: propertyConfig
645
+ }))
646
+ .reduce((a, b) => {
647
+ return {
648
+ ...a,
649
+ ...b
650
+ }
651
+ }, {});
652
+
653
+ const key = value;
654
+ const propertyConfig = key ? (DEFAULT_FIELD_CONFIGS[key] ?? propertyConfigs[key]) : undefined;
655
+ const baseProperty = propertyConfig?.property;
656
+ const baseFieldConfig = baseProperty && !isPropertyBuilder(baseProperty) ? getFieldConfig(baseProperty, propertyConfigs) : undefined;
657
+ const computedFieldConfig = baseFieldConfig && propertyConfig ? mergeDeep(baseFieldConfig, propertyConfig) : propertyConfig;
658
+
659
+ const groups: string[] = [...new Set(Object.keys(displayedWidgets).map(key => {
660
+ const group = WIDGET_TYPE_MAP[key as PropertyConfigId];
661
+ if (group) {
662
+ return group;
663
+ }
664
+ return "Custom/Other"
665
+ }))];
666
+
667
+ return <>
668
+ <div
669
+ onClick={() => {
670
+ if (!disabled) {
671
+ onOpenChange(!open, Boolean(value));
672
+ }
673
+ }}
674
+ className={cls(
675
+ "select-none rounded-md text-sm p-4",
676
+ fieldBackgroundMixin,
677
+ disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
678
+ "relative flex items-center",
679
+ )}>
680
+ {!value && <em>Select a property widget</em>}
681
+ {value && computedFieldConfig && <div
682
+ className={cls(
683
+ "flex items-center")}>
684
+ <div className={"mr-8"}>
685
+ <PropertyConfigBadge propertyConfig={computedFieldConfig}/>
686
+ </div>
687
+ <div className={"flex flex-col items-start text-base text-left"}>
688
+ <div>{computedFieldConfig.name}</div>
689
+ <Typography variant={"caption"}
690
+ color={"secondary"}>
691
+ {computedFieldConfig.description}
692
+ </Typography>
693
+ </div>
694
+ </div>}
695
+ </div>
696
+ <Dialog open={open}
697
+ onOpenChange={(open) => onOpenChange(open, Boolean(value))}
698
+ maxWidth={"4xl"}>
699
+ <DialogTitle>
700
+ Select a property widget
701
+ </DialogTitle>
702
+ <DialogContent>
703
+ <div>
704
+ {groups.map(group => {
705
+ return <div key={group} className={"mt-4"}>
706
+ <Typography variant={"label"}>{group}</Typography>
707
+ <div className={"grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-2 mt-4"}>
708
+ {Object.entries(displayedWidgets).map(([key, propertyConfig]) => {
709
+ const groupKey = WIDGET_TYPE_MAP[key as PropertyConfigId];
710
+ if (groupKey === group) {
711
+ return <WidgetSelectViewItem
712
+ key={key}
713
+ initialProperty={initialProperty}
714
+ onClick={() => {
715
+ onValueChange(key);
716
+ onOpenChange(false, true);
717
+ }}
718
+ propertyConfig={propertyConfig}
719
+ existing={existing}/>;
720
+ }
721
+ return null;
722
+ })}
723
+ </div>
724
+ </div>;
725
+ })}
726
+ {/*{displayedWidgets.map(([key, propertyConfig]) => {*/}
727
+ {/* return <WidgetSelectViewItem*/}
728
+ {/* key={key}*/}
729
+ {/* initialProperty={initialProperty}*/}
730
+ {/* onClick={() => {*/}
731
+ {/* onValueChange(key);*/}
732
+ {/* onOpenChange(false);*/}
733
+ {/* }}*/}
734
+ {/* propertyConfig={propertyConfig}*/}
735
+ {/* existing={existing}/>;*/}
736
+ {/*})}*/}
737
+ </div>
738
+ </DialogContent>
739
+ </Dialog>
740
+ </>;
741
+ }
742
+
743
+ export interface PropertySelectItemProps {
744
+ onClick?: () => void;
745
+ initialProperty?: PropertyWithId;
746
+ propertyConfig: PropertyConfig;
747
+ existing: boolean;
748
+ }
749
+
750
+ export function WidgetSelectViewItem({
751
+ onClick,
752
+ initialProperty,
753
+ // optionDisabled,
754
+ propertyConfig,
755
+ existing
756
+ }: PropertySelectItemProps) {
757
+ const baseProperty = propertyConfig.property;
758
+ const shouldWarnChangingDataType = existing && !isPropertyBuilder(baseProperty) && baseProperty.dataType !== initialProperty?.dataType;
759
+
760
+ return <Card
761
+ onClick={onClick}
762
+ className={"flex flex-row items-center px-4 py-2"}>
763
+ <div
764
+ className={cls(
765
+ "flex flex-row items-center text-base min-h-[48px]",
766
+ )}>
767
+ <div className={"mr-8"}>
768
+ <PropertyConfigBadge propertyConfig={propertyConfig} disabled={shouldWarnChangingDataType}/>
769
+ </div>
770
+ <div>
771
+ <div className={"flex flex-row gap-2 items-center"}>
772
+ {shouldWarnChangingDataType && <Tooltip
773
+ title={"This widget uses a different data type than the initially selected widget. This can cause errors with existing data."}>
774
+ <WarningOffIcon size="smallest" className={"w-4"}/>
775
+ </Tooltip>}
776
+ <Typography
777
+ color={shouldWarnChangingDataType ? "secondary" : undefined}>{propertyConfig.name}</Typography>
778
+ </div>
779
+
780
+ <Typography variant={"caption"}
781
+ color={"secondary"}
782
+ className={"max-w-sm"}>
783
+ {propertyConfig.description}
784
+ </Typography>
785
+
786
+ </div>
787
+ </div>
788
+ </Card>
789
+ }
@@ -7,13 +7,12 @@ import {
7
7
  import { getIn, useFormex } from "@firecms/formex";
8
8
 
9
9
  import { getFieldConfig, getFieldId, Properties, Property, PropertyConfig, PropertyConfigBadge, } from "@firecms/core";
10
- import { Container, Select, Tooltip, Typography } from "@firecms/ui";
10
+ import { cls, Container, Select, SelectItem, Tooltip, Typography } from "@firecms/ui";
11
11
  import React, { useState } from "react";
12
12
  import { OnPropertyChangedParams, PropertyFormDialog, PropertyWithId } from "../PropertyEditView";
13
13
  import { getFullId, idToPropertiesPath, namespaceToPropertiesOrderPath } from "../util";
14
14
  import { PersistedCollection } from "../../../types/persisted_collection";
15
15
  import { updatePropertyFromWidget } from "../utils/update_property_for_widget";
16
- import { PropertySelectItem } from "../PropertySelectItem";
17
16
  import { supportedFields } from "../utils/supported_fields";
18
17
  import { buildPropertyFromData } from "@firecms/schema_inference";
19
18
 
@@ -268,3 +267,33 @@ function PropertySelect({
268
267
  </Select>
269
268
  </Tooltip>;
270
269
  }
270
+
271
+ export interface PropertySelectItemProps {
272
+ value: string;
273
+ optionDisabled: boolean;
274
+ propertyConfig: PropertyConfig;
275
+ existing: boolean;
276
+ }
277
+
278
+ export function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps) {
279
+ return <SelectItem value={value}
280
+ disabled={optionDisabled}
281
+ className={"flex flex-row items-center"}>
282
+ <div
283
+ className={cls(
284
+ "flex flex-row items-center text-base min-h-[48px]",
285
+ optionDisabled ? "w-full" : "")}>
286
+ <div className={"mr-8"}>
287
+ <PropertyConfigBadge propertyConfig={propertyConfig}/>
288
+ </div>
289
+ <div>
290
+ <div>{propertyConfig.name}</div>
291
+ <Typography variant={"caption"}
292
+ color={"disabled"}
293
+ className={"max-w-sm"}>
294
+ {existing && optionDisabled ? "You can only switch to widgets that use the same data type" : propertyConfig.description}
295
+ </Typography>
296
+ </div>
297
+ </div>
298
+ </SelectItem>
299
+ }
@@ -1,8 +0,0 @@
1
- import { PropertyConfig } from "@firecms/core";
2
- export interface PropertySelectItemProps {
3
- value: string;
4
- optionDisabled: boolean;
5
- propertyConfig: PropertyConfig;
6
- existing: boolean;
7
- }
8
- export declare function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps): import("react/jsx-runtime").JSX.Element;
@@ -1,32 +0,0 @@
1
- import { PropertyConfigBadge, PropertyConfig } from "@firecms/core";
2
- import { cls, SelectItem, Typography } from "@firecms/ui";
3
-
4
- export interface PropertySelectItemProps {
5
- value: string;
6
- optionDisabled: boolean;
7
- propertyConfig: PropertyConfig;
8
- existing: boolean;
9
- }
10
-
11
- export function PropertySelectItem({ value, optionDisabled, propertyConfig, existing }: PropertySelectItemProps) {
12
- return <SelectItem value={value}
13
- disabled={optionDisabled}
14
- className={"flex flex-row items-center"}>
15
- <div
16
- className={cls(
17
- "flex flex-row items-center text-base min-h-[48px]",
18
- optionDisabled ? "w-full" : "")}>
19
- <div className={"mr-8"}>
20
- <PropertyConfigBadge propertyConfig={propertyConfig}/>
21
- </div>
22
- <div>
23
- <div>{propertyConfig.name}</div>
24
- <Typography variant={"caption"}
25
- color={"disabled"}
26
- className={"max-w-sm"}>
27
- {existing && optionDisabled ? "You can only switch to widgets that use the same data type" : propertyConfig.description}
28
- </Typography>
29
- </div>
30
- </div>
31
- </SelectItem>
32
- }