11import styled from '@emotion/styled' ;
22import { fontWeights } from '@leafygreen-ui/tokens' ;
3+ import Icon from '@leafygreen-ui/icon' ;
4+ import { useTheme } from '@emotion/react' ;
35import { useCallback , useEffect , useRef , useState } from 'react' ;
46
57import { ellipsisTruncation } from '@/styles/styles' ;
68import { FieldDepth } from '@/components/field/field-depth' ;
79import { FieldType } from '@/components/field/field-type' ;
10+ import { DiagramIconButton } from '@/components/buttons/diagram-icon-button' ;
811import { FieldId , NodeField } from '@/types' ;
912import { useEditableDiagramInteractions } from '@/hooks/use-editable-diagram-interactions' ;
1013
@@ -26,14 +29,31 @@ interface FieldContentProps extends NodeField {
2629 id : FieldId ;
2730 isEditable : boolean ;
2831 isDisabled : boolean ;
32+ isExpandable ?: boolean ;
2933 nodeId : string ;
3034}
3135
32- export const FieldContent = ( { isEditable, isDisabled, depth = 0 , name, type, id, nodeId } : FieldContentProps ) => {
36+ export const FieldContent = ( {
37+ isEditable,
38+ isDisabled,
39+ isExpandable,
40+ depth = 0 ,
41+ name,
42+ type,
43+ id,
44+ nodeId,
45+ expanded,
46+ } : FieldContentProps ) => {
3347 const [ isEditing , setIsEditing ] = useState ( false ) ;
3448 const fieldContentRef = useRef < HTMLDivElement > ( null ) ;
49+ const theme = useTheme ( ) ;
50+
51+ const { onChangeFieldName, onChangeFieldType, fieldTypes, onFieldExpandToggle } = useEditableDiagramInteractions ( ) ;
52+
53+ const hasCollapseFunctionality = ! ! onFieldExpandToggle ;
54+ const hasCollapseButton = hasCollapseFunctionality && isExpandable ;
55+ const placeholderCollapse = hasCollapseFunctionality && ! hasCollapseButton ;
3556
36- const { onChangeFieldName, onChangeFieldType, fieldTypes } = useEditableDiagramInteractions ( ) ;
3757 const handleNameChange = useCallback (
3858 ( newName : string ) => onChangeFieldName ?.( nodeId , Array . isArray ( id ) ? id : [ id ] , newName ) ,
3959 [ onChangeFieldName , id , nodeId ] ,
@@ -47,6 +67,16 @@ export const FieldContent = ({ isEditable, isDisabled, depth = 0, name, type, id
4767 setIsEditing ( true ) ;
4868 } , [ ] ) ;
4969
70+ const handleFieldExpandToggle = useCallback (
71+ ( event : React . MouseEvent < HTMLButtonElement > ) => {
72+ if ( ! onFieldExpandToggle ) return ;
73+ // Don't click on the field element.
74+ event . stopPropagation ( ) ;
75+ onFieldExpandToggle ( event , nodeId , Array . isArray ( id ) ? id : [ id ] ) ;
76+ } ,
77+ [ onFieldExpandToggle , nodeId , id ] ,
78+ ) ;
79+
5080 useEffect ( ( ) => {
5181 // When clicking outside of the field content while editing, stop editing.
5282 const container = fieldContentRef . current ;
@@ -98,7 +128,18 @@ export const FieldContent = ({ isEditable, isDisabled, depth = 0, name, type, id
98128 isEditing = { isTypeEditable }
99129 isDisabled = { isDisabled }
100130 onChange = { handleTypeChange }
131+ placeholderCollapse = { placeholderCollapse }
101132 />
133+ { hasCollapseButton && (
134+ < DiagramIconButton
135+ data-testid = { `object-field-expand-toggle-${ nodeId } -${ typeof id === 'string' ? id : id . join ( '.' ) } ` }
136+ onClick = { handleFieldExpandToggle }
137+ aria-label = { expanded ? 'Collapse Field' : 'Expand Field' }
138+ title = { expanded ? 'Collapse Field' : 'Expand Field' }
139+ >
140+ < Icon glyph = { expanded ? 'ChevronDown' : 'ChevronLeft' } color = { theme . node . fieldIconButton } size = { 14 } />
141+ </ DiagramIconButton >
142+ ) }
102143 </ FieldContentWrapper >
103144 ) ;
104145} ;
0 commit comments