@firecms/core 3.0.0-beta.11 → 3.0.0-beta.13
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/dist/app/Scaffold.d.ts +4 -0
- package/dist/components/ArrayContainer.d.ts +14 -3
- package/dist/components/EntityCollectionTable/EntityCollectionRowActions.d.ts +2 -1
- package/dist/components/EntityCollectionTable/EntityCollectionTable.d.ts +2 -2
- package/dist/components/EntityCollectionTable/EntityCollectionTableProps.d.ts +15 -1
- package/dist/components/EntityCollectionTable/index.d.ts +1 -1
- package/dist/components/EntityCollectionView/EntityCollectionView.d.ts +8 -0
- package/dist/components/EntityJsonPreview.d.ts +3 -0
- package/dist/components/PropertyIdCopyTooltip.d.ts +1 -1
- package/dist/components/SelectableTable/SelectableTable.d.ts +12 -2
- package/dist/components/SelectableTable/filters/ReferenceFilterField.d.ts +1 -1
- package/dist/components/UnsavedChangesDialog.d.ts +8 -0
- package/dist/components/VirtualTable/VirtualTableProps.d.ts +13 -0
- package/dist/components/common/default_entity_actions.d.ts +0 -2
- package/dist/components/common/index.d.ts +1 -1
- package/dist/components/common/useColumnsIds.d.ts +1 -0
- package/dist/components/common/{useDataSourceEntityCollectionTableController.d.ts → useDataSourceTableController.d.ts} +10 -2
- package/dist/components/common/useDebouncedCallback.d.ts +1 -0
- package/dist/components/common/useScrollRestoration.d.ts +14 -0
- package/dist/contexts/BreacrumbsContext.d.ts +8 -0
- package/dist/core/DefaultAppBar.d.ts +8 -2
- package/dist/core/EntityEditView.d.ts +36 -21
- package/dist/core/EntityEditViewFormActions.d.ts +2 -0
- package/dist/core/FireCMS.d.ts +2 -2
- package/dist/core/FireCMSRouter.d.ts +4 -0
- package/dist/core/NavigationRoutes.d.ts +0 -1
- package/dist/core/SideDialogs.d.ts +4 -2
- package/dist/core/index.d.ts +2 -1
- package/dist/form/EntityForm.d.ts +49 -0
- package/dist/form/EntityFormActions.d.ts +17 -0
- package/dist/form/PropertyFieldBinding.d.ts +1 -1
- package/dist/form/components/FormEntry.d.ts +6 -0
- package/dist/form/components/FormLayout.d.ts +5 -0
- package/dist/form/components/index.d.ts +2 -0
- package/dist/form/field_bindings/ArrayCustomShapedFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/ArrayOfReferencesFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/BlockFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MapFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/MarkdownEditorFieldBinding.d.ts +1 -1
- package/dist/form/field_bindings/RepeatFieldBinding.d.ts +1 -1
- package/dist/form/index.d.ts +16 -16
- package/dist/hooks/data/save.d.ts +1 -1
- package/dist/hooks/data/useEntityFetch.d.ts +2 -1
- package/dist/hooks/useBreadcrumbsController.d.ts +26 -0
- package/dist/hooks/useBuildNavigationController.d.ts +4 -1
- package/dist/hooks/useModeController.d.ts +1 -2
- package/dist/index.es.js +15842 -14396
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +15833 -14389
- package/dist/index.umd.js.map +1 -1
- package/dist/internal/useBuildDataSource.d.ts +3 -2
- package/dist/internal/useBuildSideEntityController.d.ts +3 -3
- package/dist/internal/useUnsavedChangesDialog.d.ts +7 -9
- package/dist/routes/CustomCMSRoute.d.ts +4 -0
- package/dist/routes/FireCMSRoute.d.ts +1 -0
- package/dist/routes/HomePageRoute.d.ts +3 -0
- package/dist/types/collections.d.ts +36 -10
- package/dist/types/datasource.d.ts +2 -2
- package/dist/types/dialogs_controller.d.ts +7 -3
- package/dist/types/entities.d.ts +1 -1
- package/dist/types/entity_actions.d.ts +10 -0
- package/dist/types/fields.d.ts +13 -3
- package/dist/types/firecms.d.ts +1 -1
- package/dist/types/navigation.d.ts +33 -12
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/properties.d.ts +40 -4
- package/dist/types/side_entity_controller.d.ts +6 -1
- package/dist/util/builders.d.ts +1 -1
- package/dist/util/createFormexStub.d.ts +2 -0
- package/dist/util/entity_actions.d.ts +2 -0
- package/dist/util/entity_cache.d.ts +23 -0
- package/dist/util/index.d.ts +1 -0
- package/dist/util/navigation_from_path.d.ts +6 -1
- package/dist/util/navigation_utils.d.ts +13 -1
- package/dist/util/objects.d.ts +1 -1
- package/dist/util/property_utils.d.ts +2 -2
- package/dist/util/references.d.ts +2 -2
- package/dist/util/resolutions.d.ts +12 -2
- package/package.json +20 -21
- package/src/app/Scaffold.tsx +13 -3
- package/src/components/ArrayContainer.tsx +60 -24
- package/src/components/CircularProgressCenter.tsx +1 -1
- package/src/components/DeleteEntityDialog.tsx +5 -3
- package/src/components/EntityCollectionTable/EntityCollectionRowActions.tsx +46 -23
- package/src/components/EntityCollectionTable/EntityCollectionTable.tsx +10 -4
- package/src/components/EntityCollectionTable/EntityCollectionTableProps.tsx +18 -1
- package/src/components/EntityCollectionTable/index.tsx +1 -1
- package/src/components/EntityCollectionTable/internal/CollectionTableToolbar.tsx +3 -3
- package/src/components/EntityCollectionTable/internal/popup_field/PopupFormField.tsx +10 -13
- package/src/components/EntityCollectionView/EntityCollectionView.tsx +105 -47
- package/src/components/EntityCollectionView/EntityCollectionViewActions.tsx +4 -2
- package/src/components/EntityJsonPreview.tsx +66 -0
- package/src/components/EntityPreview.tsx +10 -3
- package/src/components/EntityView.tsx +4 -1
- package/src/components/NotFoundPage.tsx +2 -2
- package/src/components/PropertyIdCopyTooltip.tsx +2 -3
- package/src/components/ReferenceTable/ReferenceSelectionTable.tsx +14 -7
- package/src/components/SelectableTable/SelectableTable.tsx +18 -3
- package/src/components/SelectableTable/filters/ReferenceFilterField.tsx +7 -7
- package/src/components/UnsavedChangesDialog.tsx +42 -0
- package/src/components/VirtualTable/VirtualTable.tsx +48 -3
- package/src/components/VirtualTable/VirtualTableProps.tsx +15 -0
- package/src/components/VirtualTable/fields/VirtualTableInput.tsx +1 -1
- package/src/components/common/default_entity_actions.tsx +37 -37
- package/src/components/common/index.ts +1 -1
- package/src/components/common/useColumnsIds.tsx +1 -1
- package/src/components/common/useDataSourceTableController.tsx +420 -0
- package/src/components/common/useDebouncedCallback.tsx +20 -0
- package/src/components/common/useScrollRestoration.tsx +68 -0
- package/src/contexts/BreacrumbsContext.tsx +38 -0
- package/src/contexts/DialogsProvider.tsx +3 -2
- package/src/contexts/ModeController.tsx +1 -3
- package/src/core/DefaultAppBar.tsx +59 -17
- package/src/core/DefaultDrawer.tsx +1 -1
- package/src/core/EntityEditView.tsx +354 -1000
- package/src/core/EntityEditViewFormActions.tsx +199 -0
- package/src/core/EntitySidePanel.tsx +85 -15
- package/src/core/FireCMS.tsx +20 -16
- package/src/core/FireCMSRouter.tsx +17 -0
- package/src/core/NavigationRoutes.tsx +23 -32
- package/src/core/SideDialogs.tsx +20 -11
- package/src/core/index.tsx +4 -2
- package/src/form/EntityForm.tsx +782 -0
- package/src/form/EntityFormActions.tsx +169 -0
- package/src/form/PropertyFieldBinding.tsx +21 -16
- package/src/form/components/FormEntry.tsx +22 -0
- package/src/form/components/FormLayout.tsx +16 -0
- package/src/form/components/LabelWithIcon.tsx +6 -3
- package/src/form/components/StorageUploadProgress.tsx +1 -1
- package/src/form/components/index.tsx +2 -0
- package/src/form/field_bindings/ArrayCustomShapedFieldBinding.tsx +8 -5
- package/src/form/field_bindings/ArrayOfReferencesFieldBinding.tsx +5 -2
- package/src/form/field_bindings/BlockFieldBinding.tsx +5 -3
- package/src/form/field_bindings/DateTimeFieldBinding.tsx +1 -0
- package/src/form/field_bindings/KeyValueFieldBinding.tsx +1 -1
- package/src/form/field_bindings/MapFieldBinding.tsx +14 -16
- package/src/form/field_bindings/MarkdownEditorFieldBinding.tsx +15 -8
- package/src/form/field_bindings/MultiSelectFieldBinding.tsx +3 -3
- package/src/form/field_bindings/ReadOnlyFieldBinding.tsx +2 -2
- package/src/form/field_bindings/ReferenceFieldBinding.tsx +1 -1
- package/src/form/field_bindings/RepeatFieldBinding.tsx +13 -4
- package/src/form/field_bindings/SelectFieldBinding.tsx +2 -2
- package/src/form/field_bindings/StorageUploadFieldBinding.tsx +11 -6
- package/src/form/field_bindings/SwitchFieldBinding.tsx +1 -0
- package/src/form/field_bindings/TextFieldBinding.tsx +1 -0
- package/src/form/index.tsx +16 -32
- package/src/form/validation.ts +12 -6
- package/src/hooks/data/save.ts +25 -30
- package/src/hooks/data/useCollectionFetch.tsx +1 -1
- package/src/hooks/data/useEntityFetch.tsx +5 -1
- package/src/hooks/useBreadcrumbsController.tsx +31 -0
- package/src/hooks/useBuildModeController.tsx +15 -28
- package/src/hooks/useBuildNavigationController.tsx +81 -24
- package/src/hooks/useFireCMSContext.tsx +0 -30
- package/src/hooks/useLargeLayout.tsx +0 -35
- package/src/hooks/useModeController.tsx +1 -2
- package/src/hooks/useResolvedNavigationFrom.tsx +4 -6
- package/src/internal/useBuildDataSource.ts +9 -5
- package/src/internal/useBuildSideDialogsController.tsx +3 -2
- package/src/internal/useBuildSideEntityController.tsx +135 -88
- package/src/internal/useUnsavedChangesDialog.tsx +126 -92
- package/src/preview/PropertyPreview.tsx +12 -10
- package/src/preview/components/UrlComponentPreview.tsx +17 -18
- package/src/preview/property_previews/ArrayOfMapsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfReferencesPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOfStorageComponentsPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayOfStringsPreview.tsx +4 -3
- package/src/preview/property_previews/ArrayOneOfPreview.tsx +4 -2
- package/src/preview/property_previews/ArrayPropertyPreview.tsx +4 -2
- package/src/preview/property_previews/MapPropertyPreview.tsx +3 -2
- package/src/routes/CustomCMSRoute.tsx +21 -0
- package/src/routes/FireCMSRoute.tsx +246 -0
- package/src/routes/HomePageRoute.tsx +17 -0
- package/src/types/collections.ts +45 -13
- package/src/types/datasource.ts +2 -1
- package/src/types/dialogs_controller.tsx +7 -3
- package/src/types/entities.ts +1 -1
- package/src/types/entity_actions.tsx +12 -0
- package/src/types/fields.tsx +18 -3
- package/src/types/firecms.tsx +1 -1
- package/src/types/navigation.ts +41 -16
- package/src/types/plugins.tsx +2 -0
- package/src/types/properties.ts +48 -4
- package/src/types/side_dialogs_controller.tsx +2 -0
- package/src/types/side_entity_controller.tsx +11 -1
- package/src/util/builders.ts +5 -3
- package/src/util/createFormexStub.tsx +62 -0
- package/src/util/entity_actions.ts +28 -0
- package/src/util/entity_cache.ts +204 -0
- package/src/util/index.ts +1 -0
- package/src/util/join_collections.ts +6 -1
- package/src/util/navigation_from_path.ts +18 -7
- package/src/util/navigation_utils.ts +115 -14
- package/src/util/objects.ts +9 -2
- package/src/util/parent_references_from_path.ts +3 -3
- package/src/util/property_utils.tsx +7 -3
- package/src/util/references.ts +8 -6
- package/src/util/resolutions.ts +41 -12
- package/src/util/useStorageUploadController.tsx +60 -23
- package/src/components/common/useDataSourceEntityCollectionTableController.tsx +0 -236
- /package/src/util/{common.tsx → common.ts} +0 -0
|
@@ -3,13 +3,15 @@ import {
|
|
|
3
3
|
FieldHelperText,
|
|
4
4
|
FieldProps,
|
|
5
5
|
getIconForProperty,
|
|
6
|
-
LabelWithIconAndTooltip,
|
|
6
|
+
LabelWithIconAndTooltip,
|
|
7
|
+
PropertyOrBuilder,
|
|
7
8
|
randomString,
|
|
8
9
|
ResolvedArrayProperty,
|
|
9
10
|
ResolvedStringProperty,
|
|
11
|
+
useAuthController,
|
|
10
12
|
useStorageSource
|
|
11
13
|
} from "../../index";
|
|
12
|
-
import { cls, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
|
|
14
|
+
import { cls, fieldBackgroundDisabledMixin, fieldBackgroundHoverMixin, fieldBackgroundMixin } from "@firecms/ui";
|
|
13
15
|
import { FireCMSEditor, FireCMSEditorProps } from "@firecms/editor";
|
|
14
16
|
import { resolveProperty, resolveStorageFilenameString, resolveStoragePathString } from "../../util";
|
|
15
17
|
|
|
@@ -27,11 +29,14 @@ export function MarkdownEditorFieldBinding({
|
|
|
27
29
|
showError,
|
|
28
30
|
error,
|
|
29
31
|
minimalistView,
|
|
32
|
+
disabled: disabledProp,
|
|
30
33
|
isSubmitting,
|
|
31
34
|
context,
|
|
32
35
|
customProps,
|
|
33
36
|
}: FieldProps<string, MarkdownEditorFieldProps>) {
|
|
34
37
|
|
|
38
|
+
const authController = useAuthController();
|
|
39
|
+
const disabled = disabledProp || isSubmitting;
|
|
35
40
|
const highlight = customProps?.highlight;
|
|
36
41
|
const editorProps = customProps?.editorProps;
|
|
37
42
|
const storageSource = useStorageSource();
|
|
@@ -54,14 +59,13 @@ export function MarkdownEditorFieldBinding({
|
|
|
54
59
|
if (internalValue.current !== value) {
|
|
55
60
|
internalValue.current = value;
|
|
56
61
|
setFieldVersion(fieldVersion + 1);
|
|
57
|
-
// fieldVersion.current = fieldVersion.current + 1;
|
|
58
62
|
}
|
|
59
63
|
}, [value]);
|
|
60
64
|
|
|
61
|
-
|
|
62
65
|
const resolvedProperty = resolveProperty({
|
|
63
66
|
propertyOrBuilder: property as PropertyOrBuilder,
|
|
64
|
-
values: entityValues
|
|
67
|
+
values: entityValues,
|
|
68
|
+
authController
|
|
65
69
|
}) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
|
|
66
70
|
|
|
67
71
|
const fileNameBuilder = useCallback(async (file: File) => {
|
|
@@ -88,7 +92,8 @@ export function MarkdownEditorFieldBinding({
|
|
|
88
92
|
if (!storage) return "/";
|
|
89
93
|
const resolvedProperty = resolveProperty({
|
|
90
94
|
propertyOrBuilder: property,
|
|
91
|
-
values: entityValues
|
|
95
|
+
values: entityValues,
|
|
96
|
+
authController
|
|
92
97
|
}) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
|
|
93
98
|
return resolveStoragePathString({
|
|
94
99
|
input: storage.storagePath,
|
|
@@ -107,6 +112,7 @@ export function MarkdownEditorFieldBinding({
|
|
|
107
112
|
onMarkdownContentChange={onContentChange}
|
|
108
113
|
version={context.formex.version + fieldVersion}
|
|
109
114
|
highlight={highlight}
|
|
115
|
+
disabled={disabled}
|
|
110
116
|
handleImageUpload={async (file: File) => {
|
|
111
117
|
const storagePath = storagePathBuilder(file);
|
|
112
118
|
const fileName = await fileNameBuilder(file);
|
|
@@ -135,8 +141,9 @@ export function MarkdownEditorFieldBinding({
|
|
|
135
141
|
icon={getIconForProperty(property, "small")}
|
|
136
142
|
required={property.validation?.required}
|
|
137
143
|
title={property.name}
|
|
138
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
139
|
-
<div
|
|
144
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
145
|
+
<div
|
|
146
|
+
className={cls("rounded-md", fieldBackgroundMixin, disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin)}>
|
|
140
147
|
{editor}
|
|
141
148
|
</div>
|
|
142
149
|
<FieldHelperText includeDescription={includeDescription}
|
|
@@ -23,7 +23,7 @@ export function MultiSelectFieldBinding({
|
|
|
23
23
|
disabled,
|
|
24
24
|
property,
|
|
25
25
|
includeDescription,
|
|
26
|
-
size = "
|
|
26
|
+
size = "large",
|
|
27
27
|
autoFocus
|
|
28
28
|
}: FieldProps<EnumType[], any, any>) {
|
|
29
29
|
|
|
@@ -83,7 +83,7 @@ export function MultiSelectFieldBinding({
|
|
|
83
83
|
<>
|
|
84
84
|
<MultiSelect
|
|
85
85
|
className={"w-full mt-2"}
|
|
86
|
-
size={size
|
|
86
|
+
size={size}
|
|
87
87
|
value={validValue ? value.map((v) => v.toString()) : []}
|
|
88
88
|
disabled={disabled}
|
|
89
89
|
modalPopover={true}
|
|
@@ -92,7 +92,7 @@ export function MultiSelectFieldBinding({
|
|
|
92
92
|
icon={getIconForProperty(property, "small")}
|
|
93
93
|
required={property.validation?.required}
|
|
94
94
|
title={property.name}
|
|
95
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
95
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
96
96
|
onValueChange={(updatedValue: string[]) => {
|
|
97
97
|
let newValue: EnumType[] | null;
|
|
98
98
|
if (of && (of as ResolvedProperty)?.dataType === "number") {
|
|
@@ -39,11 +39,11 @@ export function ReadOnlyFieldBinding({
|
|
|
39
39
|
icon={getIconForProperty(property, "small")}
|
|
40
40
|
required={property.validation?.required}
|
|
41
41
|
title={property.name}
|
|
42
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
42
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
<div
|
|
46
|
-
className={cls(paperMixin, "min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
|
|
46
|
+
className={cls(paperMixin, "w-full min-h-14 p-4 md:p-6 overflow-x-scroll no-scrollbar")}>
|
|
47
47
|
|
|
48
48
|
<ErrorBoundary>
|
|
49
49
|
<PropertyPreview propertyKey={propertyKey}
|
|
@@ -90,7 +90,7 @@ function ReferenceFieldBindingInternal({
|
|
|
90
90
|
icon={getIconForProperty(property, "small")}
|
|
91
91
|
required={property.validation?.required}
|
|
92
92
|
title={property.name}
|
|
93
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
93
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
94
94
|
|
|
95
95
|
{!collection && <ErrorView
|
|
96
96
|
error={"The specified collection does not exist. Check console"}/>}
|
|
@@ -6,6 +6,7 @@ import { getArrayResolvedProperties, getDefaultValueFor, getIconForProperty, mer
|
|
|
6
6
|
import { PropertyFieldBinding } from "../PropertyFieldBinding";
|
|
7
7
|
import { ExpandablePanel, Typography } from "@firecms/ui";
|
|
8
8
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
9
|
+
import { useAuthController } from "../../hooks";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Generic array field that allows reordering and renders the child property
|
|
@@ -23,7 +24,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
23
24
|
isSubmitting,
|
|
24
25
|
setValue,
|
|
25
26
|
setFieldValue,
|
|
26
|
-
minimalistView,
|
|
27
|
+
minimalistView: minimalistViewProp,
|
|
27
28
|
property,
|
|
28
29
|
includeDescription,
|
|
29
30
|
underlyingValueHasChanged,
|
|
@@ -31,6 +32,9 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
31
32
|
disabled
|
|
32
33
|
}: FieldProps<T>) {
|
|
33
34
|
|
|
35
|
+
const authController = useAuthController();
|
|
36
|
+
const minimalistView = minimalistViewProp || property.minimalistView;
|
|
37
|
+
|
|
34
38
|
if (!property.of)
|
|
35
39
|
throw Error("RepeatFieldBinding misconfiguration. Property `of` not set");
|
|
36
40
|
|
|
@@ -40,7 +44,8 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
40
44
|
propertyValue: value,
|
|
41
45
|
propertyKey,
|
|
42
46
|
property,
|
|
43
|
-
ignoreMissingFields: false
|
|
47
|
+
ignoreMissingFields: false,
|
|
48
|
+
authController
|
|
44
49
|
})
|
|
45
50
|
}
|
|
46
51
|
|
|
@@ -79,15 +84,19 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
79
84
|
</ErrorBoundary>;
|
|
80
85
|
};
|
|
81
86
|
|
|
87
|
+
const canAddElements = !property.disabled && !isSubmitting && !disabled && (property.canAddElements || property.canAddElements === undefined);
|
|
88
|
+
const sortable = property.sortable === undefined ? true : property.sortable;
|
|
82
89
|
const arrayContainer = <ArrayContainer droppableId={propertyKey}
|
|
83
90
|
addLabel={property.name ? "Add entry to " + property.name : "Add entry"}
|
|
84
91
|
value={value}
|
|
85
92
|
buildEntry={buildEntry}
|
|
86
93
|
onInternalIdAdded={setLastAddedId}
|
|
87
94
|
disabled={isSubmitting || Boolean(property.disabled)}
|
|
88
|
-
|
|
95
|
+
canAddElements={canAddElements}
|
|
96
|
+
sortable={sortable}
|
|
89
97
|
newDefaultEntry={getDefaultValueFor(property.of)}
|
|
90
98
|
onValueChange={(value) => setFieldValue(propertyKey, value)}
|
|
99
|
+
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
91
100
|
/>;
|
|
92
101
|
|
|
93
102
|
const title = (<>
|
|
@@ -96,7 +105,7 @@ export function RepeatFieldBinding<T extends Array<any>>({
|
|
|
96
105
|
icon={getIconForProperty(property, "small")}
|
|
97
106
|
required={property.validation?.required}
|
|
98
107
|
title={property.name}
|
|
99
|
-
className={"flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
108
|
+
className={"h-8 flex flex-grow text-text-secondary dark:text-text-secondary-dark"}/>
|
|
100
109
|
{Array.isArray(value) && <Typography variant={"caption"} className={"px-4"}>({value.length})</Typography>}
|
|
101
110
|
</>);
|
|
102
111
|
|
|
@@ -62,11 +62,11 @@ export function SelectFieldBinding<T extends EnumType>({
|
|
|
62
62
|
icon={getIconForProperty(property, "small")}
|
|
63
63
|
required={property.validation?.required}
|
|
64
64
|
title={property.name}
|
|
65
|
-
className={"text-text-secondary dark:text-text-secondary-dark ml-3.5"}
|
|
65
|
+
className={"h-8 text-text-secondary dark:text-text-secondary-dark ml-3.5 my-0"}
|
|
66
66
|
/>
|
|
67
67
|
</PropertyIdCopyTooltip>}
|
|
68
68
|
endAdornment={
|
|
69
|
-
property.clearable && <IconButton
|
|
69
|
+
property.clearable && !disabled && <IconButton
|
|
70
70
|
onClick={handleClearClick}>
|
|
71
71
|
<CloseIcon/>
|
|
72
72
|
</IconButton>
|
|
@@ -13,7 +13,7 @@ import { PreviewSize } from "../../preview";
|
|
|
13
13
|
import { FieldHelperText, LabelWithIconAndTooltip } from "../components";
|
|
14
14
|
|
|
15
15
|
import { getIconForProperty, isReadOnly, resolveProperty } from "../../util";
|
|
16
|
-
import { useSnackbarController, useStorageSource } from "../../hooks";
|
|
16
|
+
import { useAuthController, useSnackbarController, useStorageSource } from "../../hooks";
|
|
17
17
|
import { DragDropContext, Draggable, Droppable } from "@hello-pangea/dnd";
|
|
18
18
|
import { StorageFieldItem, useStorageUploadController } from "../../util/useStorageUploadController";
|
|
19
19
|
import { StorageUploadProgress } from "../components/StorageUploadProgress";
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
import { useClearRestoreValue } from "../useClearRestoreValue";
|
|
29
29
|
|
|
30
30
|
const dropZoneClasses = "box-border relative pt-[2px] items-center border border-transparent min-h-[254px] outline-none rounded-md duration-200 ease-[cubic-bezier(0.4,0,0.2,1)] focus:border-primary-solid";
|
|
31
|
-
const disabledClasses =
|
|
31
|
+
const disabledClasses = fieldBackgroundDisabledMixin;
|
|
32
32
|
const nonActiveDropClasses = fieldBackgroundHoverMixin
|
|
33
33
|
const activeDropClasses = "pt-0 border-2 border-solid"
|
|
34
34
|
const acceptDropClasses = "transition-colors duration-200 ease-[cubic-bezier(0,0,0.2,1)] border-2 border-solid border-green-500"
|
|
@@ -57,11 +57,13 @@ export function StorageUploadFieldBinding({
|
|
|
57
57
|
isSubmitting,
|
|
58
58
|
}: StorageUploadFieldProps) {
|
|
59
59
|
|
|
60
|
+
const authController = useAuthController();
|
|
61
|
+
|
|
60
62
|
if (!context.entityId)
|
|
61
63
|
throw new Error("StorageUploadFieldBinding: Entity id is null");
|
|
62
64
|
|
|
63
65
|
const storageSource = useStorageSource(context.collection);
|
|
64
|
-
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting;
|
|
66
|
+
const disabled = isReadOnly(property) || !!property.disabled || isSubmitting || context.disabled;
|
|
65
67
|
|
|
66
68
|
const {
|
|
67
69
|
internalValue,
|
|
@@ -91,6 +93,7 @@ export function StorageUploadFieldBinding({
|
|
|
91
93
|
|
|
92
94
|
const resolvedProperty = resolveProperty({
|
|
93
95
|
propertyOrBuilder: property as PropertyOrBuilder,
|
|
96
|
+
authController
|
|
94
97
|
}) as ResolvedStringProperty | ResolvedArrayProperty<string[]>;
|
|
95
98
|
|
|
96
99
|
return (
|
|
@@ -103,7 +106,7 @@ export function StorageUploadFieldBinding({
|
|
|
103
106
|
icon={getIconForProperty(property, "small")}
|
|
104
107
|
required={property.validation?.required}
|
|
105
108
|
title={property.name}
|
|
106
|
-
className={"
|
|
109
|
+
className={"h-8text-text-secondary dark:text-text-secondary-dark ml-3.5"}/>}
|
|
107
110
|
|
|
108
111
|
<StorageUpload
|
|
109
112
|
value={internalValue}
|
|
@@ -206,6 +209,7 @@ function FileDropComponent({
|
|
|
206
209
|
className={cls(
|
|
207
210
|
fieldBackgroundMixin,
|
|
208
211
|
disabled ? fieldBackgroundDisabledMixin : fieldBackgroundHoverMixin,
|
|
212
|
+
disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : "",
|
|
209
213
|
dropZoneClasses,
|
|
210
214
|
multipleFilesSupported && internalValue.length ? "" : "flex",
|
|
211
215
|
{
|
|
@@ -248,7 +252,7 @@ function FileDropComponent({
|
|
|
248
252
|
metadata={metadata}
|
|
249
253
|
storagePath={storagePathBuilder(entry.file)}
|
|
250
254
|
onFileUploadComplete={onFileUploadComplete}
|
|
251
|
-
imageSize={size === "
|
|
255
|
+
imageSize={size === "large" ? 220 : 118}
|
|
252
256
|
simple={false}
|
|
253
257
|
/>
|
|
254
258
|
);
|
|
@@ -285,7 +289,8 @@ function FileDropComponent({
|
|
|
285
289
|
<div
|
|
286
290
|
className="flex-grow min-h-[38px] box-border m-2 text-center">
|
|
287
291
|
<Typography align={"center"}
|
|
288
|
-
variant={"label"}
|
|
292
|
+
variant={"label"}
|
|
293
|
+
className={disabled ? "text-surface-accent-600 dark:text-surface-accent-500" : ""}>
|
|
289
294
|
{helpText}
|
|
290
295
|
</Typography>
|
|
291
296
|
</div>
|
|
@@ -43,6 +43,7 @@ export const SwitchFieldBinding = function SwitchFieldBinding({
|
|
|
43
43
|
value={value}
|
|
44
44
|
onValueChange={(v) => setValue(v)}
|
|
45
45
|
error={showError}
|
|
46
|
+
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
46
47
|
label={<LabelWithIcon
|
|
47
48
|
icon={getIconForProperty(property, "small")}
|
|
48
49
|
required={property.validation?.required}
|
|
@@ -75,6 +75,7 @@ export function TextFieldBinding<T extends string | number>({
|
|
|
75
75
|
value={value}
|
|
76
76
|
onChange={onChange}
|
|
77
77
|
autoFocus={autoFocus}
|
|
78
|
+
className={property.widthPercentage !== undefined ? "mt-8" : undefined}
|
|
78
79
|
label={<LabelWithIcon
|
|
79
80
|
icon={getIconForProperty(property, "small")}
|
|
80
81
|
required={property.validation?.required}
|
package/src/form/index.tsx
CHANGED
|
@@ -1,36 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
import { MultiSelectFieldBinding } from "./field_bindings/MultiSelectFieldBinding";
|
|
3
|
-
import { ArrayOfReferencesFieldBinding } from "./field_bindings/ArrayOfReferencesFieldBinding";
|
|
4
|
-
import { StorageUploadFieldBinding } from "./field_bindings/StorageUploadFieldBinding";
|
|
5
|
-
import { TextFieldBinding } from "./field_bindings/TextFieldBinding";
|
|
6
|
-
import { SwitchFieldBinding } from "./field_bindings/SwitchFieldBinding";
|
|
7
|
-
import { DateTimeFieldBinding } from "./field_bindings/DateTimeFieldBinding";
|
|
8
|
-
import { ReferenceFieldBinding } from "./field_bindings/ReferenceFieldBinding";
|
|
9
|
-
import { MapFieldBinding } from "./field_bindings/MapFieldBinding";
|
|
10
|
-
import { KeyValueFieldBinding } from "./field_bindings/KeyValueFieldBinding";
|
|
11
|
-
import { RepeatFieldBinding } from "./field_bindings/RepeatFieldBinding";
|
|
12
|
-
import { BlockFieldBinding } from "./field_bindings/BlockFieldBinding";
|
|
13
|
-
import { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
|
|
14
|
-
import { MarkdownEditorFieldBinding } from "./field_bindings/MarkdownEditorFieldBinding";
|
|
15
|
-
import { ArrayCustomShapedFieldBinding } from "./field_bindings/ArrayCustomShapedFieldBinding";
|
|
1
|
+
export * from "./EntityForm";
|
|
16
2
|
|
|
17
|
-
export {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
TextFieldBinding
|
|
33
|
-
};
|
|
3
|
+
export { SelectFieldBinding } from "./field_bindings/SelectFieldBinding";
|
|
4
|
+
export { MultiSelectFieldBinding } from "./field_bindings/MultiSelectFieldBinding";
|
|
5
|
+
export { ArrayOfReferencesFieldBinding } from "./field_bindings/ArrayOfReferencesFieldBinding";
|
|
6
|
+
export { StorageUploadFieldBinding } from "./field_bindings/StorageUploadFieldBinding";
|
|
7
|
+
export { TextFieldBinding } from "./field_bindings/TextFieldBinding";
|
|
8
|
+
export { SwitchFieldBinding } from "./field_bindings/SwitchFieldBinding";
|
|
9
|
+
export { DateTimeFieldBinding } from "./field_bindings/DateTimeFieldBinding";
|
|
10
|
+
export { ReferenceFieldBinding } from "./field_bindings/ReferenceFieldBinding";
|
|
11
|
+
export { MapFieldBinding } from "./field_bindings/MapFieldBinding";
|
|
12
|
+
export { KeyValueFieldBinding } from "./field_bindings/KeyValueFieldBinding";
|
|
13
|
+
export { RepeatFieldBinding } from "./field_bindings/RepeatFieldBinding";
|
|
14
|
+
export { BlockFieldBinding } from "./field_bindings/BlockFieldBinding";
|
|
15
|
+
export { ReadOnlyFieldBinding } from "./field_bindings/ReadOnlyFieldBinding";
|
|
16
|
+
export { MarkdownEditorFieldBinding } from "./field_bindings/MarkdownEditorFieldBinding";
|
|
17
|
+
export { ArrayCustomShapedFieldBinding } from "./field_bindings/ArrayCustomShapedFieldBinding";
|
|
34
18
|
|
|
35
19
|
export * from "./components";
|
|
36
20
|
|
package/src/form/validation.ts
CHANGED
|
@@ -90,11 +90,11 @@ export function mapPropertyToYup<T extends CMSType>(propertyContext: PropertyCon
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
export function getYupMapObjectSchema({
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
property,
|
|
94
|
+
entityId,
|
|
95
|
+
customFieldValidator,
|
|
96
|
+
name
|
|
97
|
+
}: PropertyContext<Record<string, any>>): ObjectSchema<any> {
|
|
98
98
|
const objectSchema: any = {};
|
|
99
99
|
const validation = property.validation;
|
|
100
100
|
if (property.properties)
|
|
@@ -159,7 +159,13 @@ function getYupStringSchema({
|
|
|
159
159
|
if (validation.lowercase) collection = collection.lowercase();
|
|
160
160
|
if (validation.uppercase) collection = collection.uppercase();
|
|
161
161
|
if (property.email) collection = collection.email(`${property.name} must be an email`);
|
|
162
|
-
if (property.url)
|
|
162
|
+
if (property.url) {
|
|
163
|
+
if (!property.storage || property.storage?.storeUrl) {
|
|
164
|
+
collection = collection.url(`${property.name} must be a url`);
|
|
165
|
+
} else {
|
|
166
|
+
console.warn(`Property ${property.name} has a url validation but its storage configuration is not set to store urls`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
163
169
|
} else {
|
|
164
170
|
collection = collection.notRequired().nullable(true);
|
|
165
171
|
}
|
package/src/hooks/data/save.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DataSource,
|
|
3
|
-
Entity,
|
|
4
|
-
EntityCollection,
|
|
5
|
-
EntityValues,
|
|
6
|
-
FireCMSContext,
|
|
7
|
-
SaveEntityProps,
|
|
8
|
-
User
|
|
9
|
-
} from "../../types";
|
|
1
|
+
import { DataSource, Entity, EntityCollection, EntityValues, FireCMSContext, SaveEntityProps, User } from "../../types";
|
|
10
2
|
import { useDataSource } from "./useDataSource";
|
|
11
3
|
import { resolveCollection } from "../../util";
|
|
12
4
|
|
|
@@ -49,23 +41,23 @@ export type SaveEntityWithCallbacksProps<M extends Record<string, any>> =
|
|
|
49
41
|
* @group Hooks and utilities
|
|
50
42
|
*/
|
|
51
43
|
export async function saveEntityWithCallbacks<M extends Record<string, any>, USER extends User>({
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
44
|
+
collection,
|
|
45
|
+
path,
|
|
46
|
+
entityId,
|
|
47
|
+
values,
|
|
48
|
+
previousValues,
|
|
49
|
+
status,
|
|
50
|
+
dataSource,
|
|
51
|
+
context,
|
|
52
|
+
onSaveSuccess,
|
|
53
|
+
onSaveFailure,
|
|
54
|
+
onPreSaveHookError,
|
|
55
|
+
onSaveSuccessHookError
|
|
56
|
+
}: SaveEntityWithCallbacksProps<M> & {
|
|
57
|
+
collection: EntityCollection<M, USER>,
|
|
58
|
+
dataSource: DataSource,
|
|
59
|
+
context: FireCMSContext,
|
|
60
|
+
}
|
|
69
61
|
): Promise<void> {
|
|
70
62
|
|
|
71
63
|
if (status !== "new" && !entityId) {
|
|
@@ -75,7 +67,7 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, USE
|
|
|
75
67
|
|
|
76
68
|
const customizationController = context.customizationController;
|
|
77
69
|
|
|
78
|
-
const resolvedPath = context.navigation.
|
|
70
|
+
const resolvedPath = context.navigation.resolveIdsFrom(path);
|
|
79
71
|
|
|
80
72
|
const callbacks = collection.callbacks;
|
|
81
73
|
if (callbacks?.onPreSave) {
|
|
@@ -85,7 +77,8 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, USE
|
|
|
85
77
|
path,
|
|
86
78
|
values: previousValues as EntityValues<M>,
|
|
87
79
|
entityId,
|
|
88
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
80
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
81
|
+
authController: context.authController
|
|
89
82
|
});
|
|
90
83
|
updatedValues = await callbacks.onPreSave({
|
|
91
84
|
collection: resolvedCollection,
|
|
@@ -127,7 +120,8 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, USE
|
|
|
127
120
|
path,
|
|
128
121
|
values: updatedValues as EntityValues<M>,
|
|
129
122
|
entityId,
|
|
130
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
123
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
124
|
+
authController: context.authController
|
|
131
125
|
});
|
|
132
126
|
callbacks.onSaveSuccess({
|
|
133
127
|
collection: resolvedCollection,
|
|
@@ -156,7 +150,8 @@ export async function saveEntityWithCallbacks<M extends Record<string, any>, USE
|
|
|
156
150
|
path,
|
|
157
151
|
values: updatedValues as EntityValues<M>,
|
|
158
152
|
entityId,
|
|
159
|
-
propertyConfigs: customizationController.propertyConfigs
|
|
153
|
+
propertyConfigs: customizationController.propertyConfigs,
|
|
154
|
+
authController: context.authController
|
|
160
155
|
});
|
|
161
156
|
callbacks.onSaveFailure({
|
|
162
157
|
collection: resolvedCollection,
|
|
@@ -73,7 +73,7 @@ export function useCollectionFetch<M extends Record<string, any>, USER extends U
|
|
|
73
73
|
const dataSource = useDataSource(collection);
|
|
74
74
|
const navigationController = useNavigationController();
|
|
75
75
|
|
|
76
|
-
const path = navigationController.
|
|
76
|
+
const path = navigationController.resolveIdsFrom(inputPath);
|
|
77
77
|
|
|
78
78
|
const sortByProperty = sortBy ? sortBy[0] : undefined;
|
|
79
79
|
const currentSort = sortBy ? sortBy[1] : undefined;
|
|
@@ -10,6 +10,7 @@ import { useFireCMSContext } from "../useFireCMSContext";
|
|
|
10
10
|
export interface EntityFetchProps<M extends Record<string, any>, USER extends User = User> {
|
|
11
11
|
path: string;
|
|
12
12
|
entityId?: string;
|
|
13
|
+
databaseId?: string;
|
|
13
14
|
collection: EntityCollection<M, USER>;
|
|
14
15
|
useCache?: boolean;
|
|
15
16
|
}
|
|
@@ -40,13 +41,14 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
|
|
|
40
41
|
path: inputPath,
|
|
41
42
|
entityId,
|
|
42
43
|
collection,
|
|
44
|
+
databaseId,
|
|
43
45
|
useCache = false
|
|
44
46
|
}: EntityFetchProps<M, USER>): EntityFetchResult<M> {
|
|
45
47
|
|
|
46
48
|
const dataSource = useDataSource(collection);
|
|
47
49
|
const navigationController = useNavigationController();
|
|
48
50
|
|
|
49
|
-
const path = navigationController.
|
|
51
|
+
const path = navigationController.resolveIdsFrom(inputPath);
|
|
50
52
|
|
|
51
53
|
const context: FireCMSContext<USER> = useFireCMSContext();
|
|
52
54
|
|
|
@@ -96,6 +98,7 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
|
|
|
96
98
|
return dataSource.listenEntity<M>({
|
|
97
99
|
path,
|
|
98
100
|
entityId,
|
|
101
|
+
databaseId,
|
|
99
102
|
collection,
|
|
100
103
|
onUpdate: onEntityUpdate,
|
|
101
104
|
onError
|
|
@@ -104,6 +107,7 @@ export function useEntityFetch<M extends Record<string, any>, USER extends User>
|
|
|
104
107
|
dataSource.fetchEntity<M>({
|
|
105
108
|
path,
|
|
106
109
|
entityId,
|
|
110
|
+
databaseId,
|
|
107
111
|
collection
|
|
108
112
|
})
|
|
109
113
|
.then(onEntityUpdate)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { BreadcrumbContext } from "../contexts/BreacrumbsContext";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @group Hooks and utilities
|
|
6
|
+
*/
|
|
7
|
+
export interface BreadcrumbsController {
|
|
8
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
9
|
+
set: (props: {
|
|
10
|
+
breadcrumbs: BreadcrumbEntry[];
|
|
11
|
+
}) => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @group Hooks and utilities
|
|
16
|
+
*/
|
|
17
|
+
export interface BreadcrumbEntry {
|
|
18
|
+
title: string;
|
|
19
|
+
url: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook to retrieve the BreadcrumbsController.
|
|
24
|
+
*
|
|
25
|
+
* Consider that in order to use this hook you need to have a parent
|
|
26
|
+
* `FireCMS`
|
|
27
|
+
*
|
|
28
|
+
* @see BreadcrumbsController
|
|
29
|
+
* @group Hooks and utilities
|
|
30
|
+
*/
|
|
31
|
+
export const useBreadcrumbsController = (): BreadcrumbsController => useContext(BreadcrumbContext);
|
|
@@ -16,7 +16,7 @@ export function useBuildModeController(): ModeController {
|
|
|
16
16
|
}, []);
|
|
17
17
|
|
|
18
18
|
const prefersDarkModeStorage: boolean | null = localStorage.getItem("prefers-dark-mode") != null ? localStorage.getItem("prefers-dark-mode") === "true" : null;
|
|
19
|
-
const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery;
|
|
19
|
+
const prefersDarkMode = prefersDarkModeStorage ?? prefersDarkModeQuery();
|
|
20
20
|
const [mode, setMode] = useState<"light" | "dark">(prefersDarkMode ? "dark" : "light");
|
|
21
21
|
|
|
22
22
|
useEffect(() => {
|
|
@@ -24,43 +24,30 @@ export function useBuildModeController(): ModeController {
|
|
|
24
24
|
setDocumentMode(prefersDarkMode ? "dark" : "light");
|
|
25
25
|
}, [prefersDarkMode]);
|
|
26
26
|
|
|
27
|
-
// color-scheme: dark;
|
|
28
|
-
const setDarkMode = useCallback(() => {
|
|
29
|
-
setMode("dark");
|
|
30
|
-
setDocumentMode("dark");
|
|
31
|
-
}, []);
|
|
32
|
-
|
|
33
|
-
const setLightMode = useCallback(() => {
|
|
34
|
-
setMode("light");
|
|
35
|
-
setDocumentMode("light");
|
|
36
|
-
}, []);
|
|
37
|
-
|
|
38
27
|
const setDocumentMode = (mode: "light" | "dark") => {
|
|
39
28
|
document.body.style.setProperty("color-scheme", mode);
|
|
40
29
|
document.documentElement.dataset.theme = mode;
|
|
41
30
|
};
|
|
42
31
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const prefersDarkModeQueryResult = prefersDarkModeQuery();
|
|
32
|
+
const setModeInternal = useCallback((mode: "light" | "dark" | "system") => {
|
|
46
33
|
if (mode === "light") {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
setDocumentMode("light");
|
|
35
|
+
localStorage.setItem("prefers-dark-mode", "false");
|
|
36
|
+
setMode("light");
|
|
37
|
+
} else if (mode === "dark") {
|
|
38
|
+
setDocumentMode("dark");
|
|
39
|
+
localStorage.setItem("prefers-dark-mode", "true");
|
|
40
|
+
setMode("dark");
|
|
52
41
|
} else {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
setLightMode();
|
|
42
|
+
const preferredMode = prefersDarkModeQuery() ? "dark" : "light";
|
|
43
|
+
setDocumentMode(preferredMode);
|
|
44
|
+
localStorage.removeItem("prefers-dark-mode");
|
|
45
|
+
setMode(preferredMode);
|
|
58
46
|
}
|
|
59
|
-
}, [
|
|
47
|
+
}, [prefersDarkModeQuery]);
|
|
60
48
|
|
|
61
49
|
return {
|
|
62
50
|
mode,
|
|
63
|
-
setMode
|
|
64
|
-
toggleMode
|
|
51
|
+
setMode: setModeInternal
|
|
65
52
|
};
|
|
66
53
|
}
|