diff --git a/.changeset/moody-buttons-grow.md b/.changeset/moody-buttons-grow.md new file mode 100644 index 000000000..b0108e730 --- /dev/null +++ b/.changeset/moody-buttons-grow.md @@ -0,0 +1,5 @@ +--- +'@keystatic/core': patch +--- + +Editor: fields editing in a modal instead of in-document diff --git a/packages/keystatic/src/form/fields/document/DocumentEditor/component-blocks/chromeful-element.tsx b/packages/keystatic/src/form/fields/document/DocumentEditor/component-blocks/chromeful-element.tsx index 26313f83a..2fb75582d 100644 --- a/packages/keystatic/src/form/fields/document/DocumentEditor/component-blocks/chromeful-element.tsx +++ b/packages/keystatic/src/form/fields/document/DocumentEditor/component-blocks/chromeful-element.tsx @@ -3,22 +3,25 @@ import { ReactNode, useMemo, useState, - useCallback, Fragment, PropsWithChildren, forwardRef, Ref, + useId, + useCallback, } from 'react'; import { RenderElementProps, useSelected } from 'slate-react'; -import { ActionButton, Button } from '@keystar/ui/button'; +import { ActionButton, Button, ButtonGroup } from '@keystar/ui/button'; +import { Dialog, DialogContainer } from '@keystar/ui/dialog'; import { FieldMessage } from '@keystar/ui/field'; import { trash2Icon } from '@keystar/ui/icon/icons/trash2Icon'; import { Icon } from '@keystar/ui/icon'; import { Flex } from '@keystar/ui/layout'; +import { Content } from '@keystar/ui/slots'; import { css, tokenSchema } from '@keystar/ui/style'; import { Tooltip, TooltipTrigger } from '@keystar/ui/tooltip'; -import { Text } from '@keystar/ui/typography'; +import { Heading, Text } from '@keystar/ui/typography'; import l10nMessages from '../../../../../app/l10n/index.json'; import { @@ -33,6 +36,11 @@ import { FormValueContentFromPreviewProps, NonChildFieldComponentSchema, } from '../../../../form-from-preview'; +import { + previewPropsToValue, + setValueToPreviewProps, +} from '../../../../get-value'; +import { createGetPreviewProps } from '../../../../preview-props'; import { NotEditable } from '../primitives'; import { blockElementSpacing } from '../ui-utils'; @@ -83,26 +91,31 @@ export function ChromefulComponentBlockElement(props: { {props.componentBlock.label} - {editMode ? ( - - -
{props.children}
-
- ) : ( - - {props.renderedBlock} - - - )} + + {props.renderedBlock} + + onCloseEditMode()}> + {(() => { + if (!editMode) { + return; + } + return ( + + Edit {props.componentBlock.label} + + + ); + })()} + + ); @@ -190,38 +203,50 @@ function DefaultToolbarWithChrome({ function FormValue({ onClose, props, - isValid, }: { props: GenericPreviewProps; onClose(): void; - isValid: boolean; }) { + const stringFormatter = useLocalizedStringFormatter(l10nMessages); + const formId = useId(); const [forceValidation, setForceValidation] = useState(false); + const [state, setState] = useState(() => previewPropsToValue(props)); + const previewProps = useMemo( + () => createGetPreviewProps(props.schema, setState, () => undefined), + [props.schema] + )(state); return ( - - - - + <> + + { + if (event.target !== event.currentTarget) return; + event.preventDefault(); + if (!clientSideValidateProp(props.schema, state, undefined)) { + setForceValidation(true); + } else { + setValueToPreviewProps(state, props); + onClose(); + } + }} + direction="column" + gap="xxlarge" + > + + + + + + + + ); }