pl-fe: Allow reordering profile fields
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
9227eef670
commit
b016dbec2b
4 changed files with 40 additions and 3 deletions
|
@ -31,7 +31,10 @@ const spaces = {
|
|||
8: 'gap-8',
|
||||
};
|
||||
|
||||
interface IHStack extends Pick<React.HTMLAttributes<HTMLDivElement>, 'children' | 'className' | 'onClick' | 'style' | 'title'> {
|
||||
interface IHStack extends Pick<
|
||||
React.HTMLAttributes<HTMLDivElement>,
|
||||
'children' | 'className' | 'draggable' | 'onClick' | 'onDragEnd' | 'onDragEnter' | 'onDragStart' | 'style' | 'title'
|
||||
> {
|
||||
/** Vertical alignment of children. */
|
||||
alignItems?: keyof typeof alignItemsOptions;
|
||||
/** Horizontal alignment of children. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from 'react';
|
||||
import React, { useRef } from 'react';
|
||||
import { useIntl, defineMessages } from 'react-intl';
|
||||
|
||||
import Button from '../button/button';
|
||||
|
@ -39,6 +39,8 @@ interface IStreamfield {
|
|||
minItems?: number;
|
||||
/** Maximum number of allowed inputs. */
|
||||
maxItems?: number;
|
||||
/** Allow changing order of the items. */
|
||||
draggable?: boolean;
|
||||
}
|
||||
|
||||
/** List of inputs that can be added or removed. */
|
||||
|
@ -52,9 +54,29 @@ const Streamfield: React.FC<IStreamfield> = ({
|
|||
component: Component,
|
||||
maxItems = Infinity,
|
||||
minItems = 0,
|
||||
draggable,
|
||||
}) => {
|
||||
const intl = useIntl();
|
||||
|
||||
const dragItem = useRef<number | null>();
|
||||
const dragOverItem = useRef<number | null>();
|
||||
|
||||
const handleDragStart = (i: number) => () => {
|
||||
dragItem.current = i;
|
||||
};
|
||||
|
||||
const handleDragEnter = (i: number) => () => {
|
||||
dragOverItem.current = i;
|
||||
};
|
||||
|
||||
const handleDragEnd = () => {
|
||||
const newData = [...values];
|
||||
const item = newData.splice(dragItem.current!, 1)[0];
|
||||
newData.splice(dragOverItem.current!, 0, item);
|
||||
|
||||
onChange(newData);
|
||||
};
|
||||
|
||||
const handleChange = (i: number) => (value: any) => {
|
||||
const newData = [...values];
|
||||
newData[i] = value;
|
||||
|
@ -71,7 +93,15 @@ const Streamfield: React.FC<IStreamfield> = ({
|
|||
{(values.length > 0) && (
|
||||
<Stack space={1}>
|
||||
{values.map((value, i) => value?._destroy ? null : (
|
||||
<HStack key={i} space={2} alignItems='center'>
|
||||
<HStack
|
||||
key={i}
|
||||
space={2}
|
||||
alignItems='center'
|
||||
draggable={draggable}
|
||||
onDragStart={handleDragStart(i)}
|
||||
onDragEnter={handleDragEnter(i)}
|
||||
onDragEnd={handleDragEnd}
|
||||
>
|
||||
<Component
|
||||
key={i}
|
||||
index={i}
|
||||
|
|
|
@ -452,6 +452,7 @@ const EditProfile: React.FC = () => {
|
|||
onRemoveItem={handleRemoveField}
|
||||
component={ProfileField}
|
||||
maxItems={maxFields}
|
||||
draggable
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
|
@ -288,6 +288,7 @@ const PlFeConfig: React.FC = () => {
|
|||
onChange={handleStreamItemChange(['promoPanel', 'items'])}
|
||||
onAddItem={addStreamItem(['promoPanel', 'items'], templates.promoPanel)}
|
||||
onRemoveItem={deleteStreamItem(['promoPanel', 'items'])}
|
||||
draggable
|
||||
/>
|
||||
|
||||
<Streamfield
|
||||
|
@ -298,6 +299,7 @@ const PlFeConfig: React.FC = () => {
|
|||
onChange={handleStreamItemChange(['navlinks', 'homeFooter'])}
|
||||
onAddItem={addStreamItem(['navlinks', 'homeFooter'], templates.footerItem)}
|
||||
onRemoveItem={deleteStreamItem(['navlinks', 'homeFooter'])}
|
||||
draggable
|
||||
/>
|
||||
|
||||
<FormGroup labelText={intl.formatMessage(messages.copyrightFooterLabel)}>
|
||||
|
@ -347,6 +349,7 @@ const PlFeConfig: React.FC = () => {
|
|||
onChange={handleStreamItemChange(['cryptoAddresses'])}
|
||||
onAddItem={addStreamItem(['cryptoAddresses'], templates.cryptoAddress)}
|
||||
onRemoveItem={deleteStreamItem(['cryptoAddresses'])}
|
||||
draggable
|
||||
/>
|
||||
|
||||
<FormGroup labelText={intl.formatMessage(messages.cryptoDonatePanelLimitLabel)}>
|
||||
|
|
Loading…
Reference in a new issue