Skip to content

Commit

Permalink
feat(editor): expandable json editor (#6446)
Browse files Browse the repository at this point in the history
* Update spacing

* Fix pointer events css

* Add expand button

* Add whitespace to gutters

* Adjust expand button offset
  • Loading branch information
kraenhansen authored Nov 6, 2024
1 parent 05a557b commit f055892
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
13 changes: 11 additions & 2 deletions packages/compass-crud/src/components/json-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ const editorDarkModeStyles = css({
});

const actionsGroupStyles = css({
paddingTop: spacing[2],
paddingRight: spacing[2],
padding: spacing[200],
});

export type JSONEditorProps = {
Expand Down Expand Up @@ -258,6 +257,14 @@ const JSONEditor: React.FunctionComponent<JSONEditorProps> = ({
onDeletionFinished,
]);

const toggleExpandCollapse = useCallback(() => {
if (doc.expanded) {
doc.collapse();
} else {
doc.expand();
}
}, [doc]);

// Trying to change CodeMirror editor state when an update "effect" is in
// progress results in an error which is why we timeout the code mirror update
// itself.
Expand Down Expand Up @@ -297,6 +304,8 @@ const JSONEditor: React.FunctionComponent<JSONEditorProps> = ({
className={cx(editorStyles, darkMode && editorDarkModeStyles)}
actionsClassName={actionsGroupStyles}
completer={completer}
onExpand={editing ? undefined : toggleExpandCollapse}
expanded={expanded}
/>
<DocumentList.DocumentEditActionsFooter
doc={doc}
Expand Down
13 changes: 11 additions & 2 deletions packages/compass-editor/src/action-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ export type Action = {

const actionButtonStyle = css({
flex: 'none',
pointerEvents: 'all',
});

const actionCompactButtonStyle = css({
'& > div:has(svg)': {
paddingLeft: 3,
paddingRight: 3,
},
});

const actionButtonContentStyle = css({
Expand Down Expand Up @@ -52,7 +60,8 @@ export const ActionButton: React.FunctionComponent<{
...args: Parameters<React.MouseEventHandler<HTMLButtonElement>>
) => boolean | void;
'data-testid'?: string;
}> = ({ label, icon, onClick, ...props }) => {
compact?: boolean;
}> = ({ label, icon, onClick, compact, ...props }) => {
const [clickResult, setClickResult] = useState<'success' | 'error'>(
'success'
);
Expand Down Expand Up @@ -89,7 +98,7 @@ export const ActionButton: React.FunctionComponent<{
aria-label={label}
title={label}
onClick={onButtonClick}
className={actionButtonStyle}
className={cx(actionButtonStyle, { [actionCompactButtonStyle]: compact })}
data-testid={props['data-testid'] ?? `editor-action-${label}`}
>
<div className={actionButtonContentStyle}>
Expand Down
34 changes: 31 additions & 3 deletions packages/compass-editor/src/actions-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,29 @@ type ActionsContainerProps = {
customActions?: Action[];
className?: string;
editorRef: RefObject<EditorRef>;
onExpand?: () => void;
expanded?: boolean;
};

const actionsContainerStyle = css({
position: 'absolute',
top: spacing[1],
right: spacing[2],
top: spacing[100],
right: spacing[100],
left: spacing[100],
display: 'none',
gap: spacing[2],
gap: spacing[200],
pointerEvents: 'none',
});

const expandContainerStyle = css({
position: 'relative',
top: -spacing[100],
left: -spacing[100],
});

const actionsGroupItemSeparator = css({
flex: '1 0 auto',
pointerEvents: 'none',
});

export const ActionsContainer = ({
Expand All @@ -26,6 +41,8 @@ export const ActionsContainer = ({
customActions,
className,
editorRef,
onExpand,
expanded,
}: ActionsContainerProps) => {
return (
<div
Expand All @@ -35,6 +52,17 @@ export const ActionsContainer = ({
className
)}
>
{onExpand && (
<div className={expandContainerStyle}>
<ActionButton
label={expanded ? 'Collapse all' : 'Expand all'}
icon={expanded ? 'CaretDown' : 'CaretRight'}
onClick={onExpand}
compact
/>
</div>
)}
<span className={actionsGroupItemSeparator}></span>
{copyable && (
<ActionButton
label="Copy"
Expand Down
16 changes: 15 additions & 1 deletion packages/compass-editor/src/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,13 @@ const multilineEditorContainerWithActionsStyle = css({
minHeight: spacing[5] - 2,
});

const multilineEditorContainerWithExpandStyle = css({
['& .cm-gutters']: {
// Offset to prevent the "expand" button from overlapping with fold / unfold icons
paddingLeft: spacing[500],
},
});

const multilineEditorContainerDarkModeStyle = css({
backgroundColor: editorPalette.dark.backgroundColor,
});
Expand All @@ -1399,6 +1406,8 @@ type MultilineEditorProps = EditorProps & {
formattable?: boolean;
editorClassName?: string;
actionsClassName?: string;
onExpand?: () => void;
expanded?: boolean;
};

const MultilineEditor = React.forwardRef<EditorRef, MultilineEditorProps>(
Expand All @@ -1411,8 +1420,10 @@ const MultilineEditor = React.forwardRef<EditorRef, MultilineEditorProps>(
editorClassName,
actionsClassName,
darkMode: _darkMode,
onExpand,
expanded,
...props
},
}: MultilineEditorProps,
ref
) {
const darkMode = useDarkMode(_darkMode);
Expand Down Expand Up @@ -1469,6 +1480,7 @@ const MultilineEditor = React.forwardRef<EditorRef, MultilineEditorProps>(
multilineEditorContainerStyle,
darkMode && multilineEditorContainerDarkModeStyle,
hasActions && multilineEditorContainerWithActionsStyle,
onExpand && multilineEditorContainerWithExpandStyle,
className
)}
// We want folks to be able to click into the container element
Expand All @@ -1492,6 +1504,8 @@ const MultilineEditor = React.forwardRef<EditorRef, MultilineEditorProps>(
></BaseEditor>
{hasActions && (
<ActionsContainer
onExpand={onExpand}
expanded={expanded}
copyable={copyable}
formattable={formattable}
editorRef={editorRef}
Expand Down

0 comments on commit f055892

Please sign in to comment.