Skip to content

Commit

Permalink
feat: refine add/remove UX
Browse files Browse the repository at this point in the history
Related to #796
  • Loading branch information
Skaiir committed Sep 26, 2023
1 parent 0ffddf5 commit 719e560
Show file tree
Hide file tree
Showing 14 changed files with 58 additions and 59 deletions.
3 changes: 2 additions & 1 deletion packages/form-js-editor/assets/form-js-editor-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@
}

.fjs-editor-container .fjs-repeat-render-footer {
font-size: var(--font-size-label);
background: var(--cds-field, var(--color-background-disabled));
color: var(--cds-text-disabled, var(--color-grey-225-10-55));
padding: 3px;
Expand All @@ -453,7 +454,7 @@
}

.fjs-editor-container .fjs-repeat-render-footer svg {
margin-right: 2px;
margin-right: 4px;
}

/* do not show resize handles on small screens */
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

import { simpleBoolEntryFactory } from './factories';

export default function GroupEntries(props) {
export default function GroupAppearanceEntry(props) {
const {
field,
} = props;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function ReadonlyEntry(props) {

const entries = [];

if (INPUTS.includes(type) || type === 'dynamiclist') {
if (INPUTS.includes(type)) {
entries.push({
id: 'readonly',
component: Readonly,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { simpleBoolEntryFactory, zeroPositiveIntegerEntryFactory } from './factories';
import { zeroPositiveIntegerEntryFactory, simpleBoolEntryFactory } from './factories';

export default function RepeatableDefaultEntry(props) {
export default function RepeatableEntry(props) {
const {
field,
getService
Expand All @@ -14,6 +14,18 @@ export default function RepeatableDefaultEntry(props) {
}

const entries = [
zeroPositiveIntegerEntryFactory({
id: 'defaultRepetitions',
path: [ 'defaultRepetitions' ],
label: 'Default number of items',
props
}),
simpleBoolEntryFactory({
id: 'allowAddRemove',
path: [ 'allowAddRemove' ],
label: 'Allow add/delete items',
props
}),
simpleBoolEntryFactory({
id: 'disableCollapse',
path: [ 'disableCollapse' ],
Expand All @@ -30,7 +42,6 @@ export default function RepeatableDefaultEntry(props) {
props
});

// @ts-ignore
entries.push(nonCollapseItemsEntry);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { get } from 'min-dash';
import { CheckboxEntry, isCheckboxEntryEdited } from '@bpmn-io/properties-panel';
import { ToggleSwitchEntry, isToggleSwitchEntryEdited } from '@bpmn-io/properties-panel';

export default function simpleBoolEntryFactory(options) {
const {
Expand All @@ -23,7 +23,7 @@ export default function simpleBoolEntryFactory(options) {
editField,
description,
component: SimpleBoolComponent,
isEdited: isCheckboxEntryEdited
isEdited: isToggleSwitchEntryEdited
};
}

Expand All @@ -41,12 +41,13 @@ const SimpleBoolComponent = (props) => {

const setValue = (value) => editField(field, path, value || false);

return CheckboxEntry({
return ToggleSwitchEntry({
element: field,
getValue,
id,
label,
setValue,
inline: true,
description
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export { default as DisabledEntry } from './DisabledEntry';
export { default as IdEntry } from './IdEntry';
export { default as KeyEntry } from './KeyEntry';
export { default as PathEntry } from './PathEntry';
export { default as GroupEntries } from './GroupEntries';
export { default as GroupAppearanceEntry } from './GroupAppearanceEntry';
export { default as LabelEntry } from './LabelEntry';
export { default as ImageSourceEntry } from './ImageSourceEntry';
export { default as TextEntry } from './TextEntry';
Expand All @@ -26,7 +26,6 @@ export { default as StaticValuesSourceEntry } from './StaticValuesSourceEntry';
export { default as AdornerEntry } from './AdornerEntry';
export { default as ReadonlyEntry } from './ReadonlyEntry';
export { default as LayouterAppearanceEntry } from './LayouterAppearanceEntry';
export { default as RepeatableAppearanceEntry } from './RepeatableAppearanceEntry';
export { default as RepeatableDefaultEntry } from './RepeatableDefaultEntry';
export { default as RepeatableEntry } from './RepeatableEntry';
export { default as ConditionEntry } from './ConditionEntry';
export { default as ValuesExpressionEntry } from './ValuesExpressionEntry';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
AdornerEntry,
RepeatableAppearanceEntry,
GroupAppearanceEntry,
LayouterAppearanceEntry
} from '../entries';

Expand All @@ -9,7 +9,7 @@ export default function AppearanceGroup(field, editField, getService) {

const entries = [
...AdornerEntry({ field, editField }),
...RepeatableAppearanceEntry({ field, editField, getService }),
...GroupAppearanceEntry({ field, editField }),
...LayouterAppearanceEntry({ field, editField })
];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
ImageSourceEntry,
KeyEntry,
PathEntry,
RepeatableDefaultEntry,
GroupEntries,
RepeatableEntry,
LabelEntry,
ReadonlyEntry,
SelectEntries,
Expand All @@ -28,8 +27,7 @@ export default function GeneralGroup(field, editField, getService) {
...DescriptionEntry({ field, editField }),
...KeyEntry({ field, editField, getService }),
...PathEntry({ field, editField, getService }),
...GroupEntries({ field, editField }),
...RepeatableDefaultEntry({ field, editField, getService }),
...RepeatableEntry({ field, editField, getService }),
...DefaultValueEntry({ field, editField }),
...ActionEntry({ field, editField }),
...DateTimeEntry({ field, editField }),
Expand Down
9 changes: 6 additions & 3 deletions packages/form-js-viewer/assets/form-js-base.css
Original file line number Diff line number Diff line change
Expand Up @@ -937,7 +937,10 @@
.fjs-container .fjs-repeat-row-container {
display: flex;
flex-direction: row;
align-items: center;
}

.fjs-container .fjs-repeat-row-rows {
flex: 1;
}

.fjs-container .fjs-repeat-row-container .fjs-repeat-row-delete {
Expand Down Expand Up @@ -966,7 +969,7 @@
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 16px;
padding: 16px 8px;
}

.fjs-container .fjs-repeat-render-footer button {
Expand All @@ -983,7 +986,7 @@
}

.fjs-container .fjs-repeat-render-footer button svg {
margin-right: 2px;
margin-right: 4px;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/form-js-viewer/src/Form.js
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ export default class Form {

// (a) Sanitize repeatable parents data if it is not an array
if (!valueData || !Array.isArray(valueData)) {
valueData = new Array(formField.defaultRepetitions || 0).fill().map(_ => ({})) || [];
valueData = new Array(isUndefined(formField.defaultRepetitions) ? 1 : formField.defaultRepetitions).fill().map(_ => ({})) || [];
}

// (b) Ensure all elements of the array are objects
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export default class RepeatRenderManager {

const nonCollapsedItems = this._getNonCollapsedItems(repeaterField);
const isCollapsed = sharedRepeatState.isCollapsed && values.length > nonCollapsedItems;
const hasChildren = repeaterField.components && repeaterField.components.length > 0;
const showRemove = repeaterField.allowAddRemove && hasChildren;

const displayValues = isCollapsed ? values.slice(0, nonCollapsedItems) : values;

Expand Down Expand Up @@ -86,14 +88,20 @@ export default class RepeatRenderManager {
i: [ ...parentExpressionContext.i , index + 1 ]
}), [ index, value ]);

return <div class="fjs-repeat-row-container">
return !showRemove ?
<LocalExpressionContext.Provider value={ localExpressionContext }>
<RowsRenderer { ...elementProps } />
</LocalExpressionContext.Provider>
<button class="fjs-repeat-row-delete" onClick={ () => onDeleteItem(index) }>
<DeleteSvg />
</button>
</div>;
</LocalExpressionContext.Provider> :
<div class="fjs-repeat-row-container">
<div class="fjs-repeat-row-rows">
<LocalExpressionContext.Provider value={ localExpressionContext }>
<RowsRenderer { ...elementProps } />
</LocalExpressionContext.Provider>
</div>
<button class="fjs-repeat-row-delete" onClick={ () => onDeleteItem(index) }>
<DeleteSvg />
</button>
</div>;
})}
</>
);
Expand All @@ -114,6 +122,9 @@ export default class RepeatRenderManager {
const collapseEnabled = !repeaterField.disableCollapse && (values.length > nonCollapsedItems);
const isCollapsed = sharedRepeatState.isCollapsed;

const hasChildren = repeaterField.components && repeaterField.components.length > 0;
const showAdd = repeaterField.allowAddRemove && hasChildren;

const toggle = () => {
setSharedRepeatState(state => ({ ...state, isCollapsed: !isCollapsed }));
};
Expand Down Expand Up @@ -146,9 +157,9 @@ export default class RepeatRenderManager {
offset: 20
}, [ shouldScroll ]);

return <div className="fjs-repeat-render-footer" style={ !repeaterField.readonly ? { marginRight: 32 } : {} }>
return <div className="fjs-repeat-render-footer" style={ repeaterField.allowAddRemove ? { marginRight: 32 } : { justifyContent: 'center' } }>
{
!repeaterField.readonly ? <button ref={ addButtonRef } onClick={ onAddItem }>
showAdd ? <button ref={ addButtonRef } onClick={ onAddItem }>
<><AddSvg /> { 'Add new' }</>
</button> : null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ DynamicList.config = {
components: [],
showOutline: true,
isRepeating: true,
allowAddRemove: true,
defaultRepetitions: 1,
...options
})
};
4 changes: 2 additions & 2 deletions packages/form-js-viewer/src/render/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export {
FormComponent,
FormField,
Group,
DynamicList,
Image,
Numberfield,
Radio,
Select,
Spacer,
DynamicList,
Taglist,
Text,
Textfield,
Expand All @@ -44,13 +44,13 @@ export const formFields = [
Checklist,
Default,
Group,
DynamicList,
Image,
Numberfield,
Datetime,
Radio,
Select,
Spacer,
DynamicList,
Taglist,
Text,
Textfield,
Expand Down

0 comments on commit 719e560

Please sign in to comment.