Skip to content

Commit 597467c

Browse files
committed
Fix #70: Add collapsible feature
1 parent 95ace46 commit 597467c

File tree

2 files changed

+100
-49
lines changed

2 files changed

+100
-49
lines changed

src/components/containers.js

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import Button from './buttons';
3+
import {getSchemaType} from '../util.js';
34

45

56
export function GroupTitle(props) {
@@ -8,10 +9,24 @@ export function GroupTitle(props) {
89

910
return (
1011
<div className="rjf-form-group-title">
11-
{props.editable ?
12-
<span>{props.children} <Button className="edit" onClick={props.onEdit} title="Edit">Edit</Button></span>
13-
:
14-
props.children
12+
{props.children}
13+
14+
{props.editable &&
15+
<React.Fragment>
16+
{' '}
17+
<Button className="edit" onClick={props.onEdit} title="Edit">
18+
Edit
19+
</Button>
20+
</React.Fragment>
21+
}
22+
23+
{props.collapsible &&
24+
<React.Fragment>
25+
{' '}
26+
<Button className="collapse" onClick={props.onCollapse} title={props.collapsed ? "Expand" : "Collapse"}>
27+
{props.collapsed ? "[+]" : "[-]"}
28+
</Button>
29+
</React.Fragment>
1530
}
1631
</div>
1732
);
@@ -133,28 +148,67 @@ export function FormRow(props) {
133148

134149

135150
export function FormGroup(props) {
151+
const [collapsed, setCollapsed] = React.useState(false);
152+
153+
let type = getSchemaType(props.schema);
154+
136155
let hasChildren = React.Children.count(props.children);
137156

138-
let innerClassName = props.level === 0 && !hasChildren
139-
? ""
140-
: "rjf-form-group-inner";
157+
let innerClassName = props.level === 0 && props.childrenType === 'groups'
158+
? ''
159+
: 'rjf-form-group-inner';
160+
161+
let addButtonText;
162+
let addButtonTitle;
163+
164+
if (type === 'object') {
165+
addButtonText = 'Add key';
166+
addButtonTitle = 'Add new key';
167+
} else {
168+
addButtonText = 'Add item';
169+
addButtonTitle = 'Add new item';
170+
}
141171

142172
return (
143173
<div className="rjf-form-group">
144-
{props.level === 0 && <GroupTitle editable={props.editable} onEdit={props.onEdit}>{props.schema.title}</GroupTitle>}
174+
{props.level === 0 &&
175+
<GroupTitle
176+
editable={props.editable}
177+
onEdit={props.onEdit}
178+
collapsible={props.collapsible}
179+
onCollapse={() => setCollapsed(!collapsed)}
180+
collapsed={collapsed}
181+
>
182+
{props.schema.title}
183+
</GroupTitle>
184+
}
185+
145186
{props.level === 0 && <GroupDescription>{props.schema.description}</GroupDescription>}
187+
146188
<div className={innerClassName}>
147-
{props.level > 0 && <GroupTitle editable={props.editable} onEdit={props.onEdit}>{props.schema.title}</GroupTitle>}
189+
{props.level > 0 &&
190+
<GroupTitle
191+
editable={props.editable}
192+
onEdit={props.onEdit}
193+
collapsible={props.collapsible}
194+
onCollapse={() => setCollapsed(!collapsed)}
195+
collapsed={collapsed}
196+
>
197+
{props.schema.title}
198+
</GroupTitle>
199+
}
200+
148201
{props.level > 0 && <GroupDescription>{props.schema.description}</GroupDescription>}
149-
{props.children}
150-
{props.addable &&
151-
<Button
152-
className="add"
153-
onClick={(e) => props.onAdd()}
154-
title={props.schema.type === 'object' ? 'Add new key' : 'Add new item'}
155-
>
156-
{props.schema.type === 'object' ? 'Add key' : 'Add item'}
157-
</Button>
202+
203+
{collapsed && <div className="rjf-collapsed-indicator"><span>Collapsed</span></div>}
204+
<div className={collapsed ? "rjf-form-group-children rjf-collapsed" : "rjf-form-group-children"}>
205+
{props.children}
206+
</div>
207+
208+
{!collapsed && props.addable &&
209+
<Button className="add" onClick={(e) => props.onAdd()} title={addButtonTitle}>
210+
{addButtonText}
211+
</Button>
158212
}
159213
</div>
160214
</div>

src/ui.js

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,8 @@ export function getArrayFormRow(args) {
315315
editable={args.editable}
316316
onEdit={args.onKeyEdit}
317317
key={'row_group_' + name}
318+
collapsible={data.length > 0}
319+
childrenType="rows"
318320
>
319321
{rowError && rowError.map((error, i) => <div className="rjf-error-text" key={i}>{error}</div>)}
320322
{rows}
@@ -338,45 +340,38 @@ export function getArrayFormRow(args) {
338340
if (typeof groupError === 'string')
339341
groupError = [groupError];
340342

341-
let groupTitle = schema.title ? <GroupTitle editable={args.editable} onEdit={args.onKeyEdit}>{schema.title}</GroupTitle> : null;
342-
let groupDescription = schema.description ? <GroupDescription>{schema.description}</GroupDescription> : null;
343-
344343
groups = (
345344
<div key={'group_' + name} className="rjf-form-group-wrapper">
346345
{args.parentType === 'object' && args.removable &&
347346
<FormRowControls
348347
onRemove={(e) => onRemove(name)}
349348
/>
350349
}
351-
<div className="rjf-form-group">
352-
<div className={level > 0 ? "rjf-form-group-inner" : ""}>
353-
{groupTitle}
354-
{groupDescription}
355-
{groupError && groupError.map((error, i) => <div className="rjf-error-text" key={i}>{error}</div>)}
356-
{groups.map((i, index) => (
357-
<div className="rjf-form-group-wrapper" key={'group_wrapper_' + name + '_' + index}>
358-
<FormRowControls
359-
onRemove={removable ? (e) => onRemove(joinCoords(name, index)) : null}
360-
onMoveUp={index > 0 && !isReadonly ? (e) => onMove(joinCoords(name, index), joinCoords(name, index - 1)) : null}
361-
onMoveDown={index < groups.length - 1 && !isReadonly ? (e) => onMove(joinCoords(name, index), joinCoords(name, index + 1)) : null}
362-
/>
363-
{i}
364-
</div>
365-
)
366-
)}
367-
{addable &&
368-
<Button
369-
className="add"
370-
onClick={(e) => onAdd(getBlankData(schema.items, args.getRef), coords)}
371-
title="Add new item"
372-
>
373-
Add item
374-
</Button>
375-
}
376-
</div>
377-
</div>
350+
<FormGroup
351+
level={level}
352+
schema={schema}
353+
addable={addable}
354+
onAdd={() => onAdd(getBlankData(schema.items, args.getRef), coords)}
355+
editable={args.editable}
356+
onEdit={args.onKeyEdit}
357+
collapsible={data.length > 0}
358+
childrenType="groups"
359+
>
360+
{groupError && groupError.map((error, i) => <div className="rjf-error-text" key={i}>{error}</div>)}
361+
{groups.map((i, index) => (
362+
<div className="rjf-form-group-wrapper" key={'group_wrapper_' + name + '_' + index}>
363+
<FormRowControls
364+
onRemove={removable ? (e) => onRemove(joinCoords(name, index)) : null}
365+
onMoveUp={index > 0 && !isReadonly ? (e) => onMove(joinCoords(name, index), joinCoords(name, index - 1)) : null}
366+
onMoveDown={index < groups.length - 1 && !isReadonly ? (e) => onMove(joinCoords(name, index), joinCoords(name, index + 1)) : null}
367+
/>
368+
{i}
369+
</div>
370+
)
371+
)}
372+
</FormGroup>
378373
</div>
379-
)
374+
);
380375
}
381376

382377
return [...rows, ...groups];
@@ -504,6 +499,8 @@ export function getObjectFormRow(args) {
504499
editable={args.editable}
505500
onEdit={args.onKeyEdit}
506501
key={'row_group_' + name}
502+
collapsible={keys.length > 0}
503+
childrenType="rows"
507504
>
508505
{groupError && groupError.map((error, i) => <div className="rjf-error-text" key={i}>{error}</div>)}
509506
{rows}

0 commit comments

Comments
 (0)