mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
Merge pull request #12322 from ToolJet/feat/resizable-slots-form
feat: Makes header and footer resizable
This commit is contained in:
commit
23ca209a16
19 changed files with 818 additions and 752 deletions
|
|
@ -22,6 +22,8 @@ import {
|
||||||
handleActivateTargets,
|
handleActivateTargets,
|
||||||
handleDeactivateTargets,
|
handleDeactivateTargets,
|
||||||
handleActivateNonDraggingComponents,
|
handleActivateNonDraggingComponents,
|
||||||
|
computeScrollDelta,
|
||||||
|
computeScrollDeltaOnDrag,
|
||||||
} from './gridUtils';
|
} from './gridUtils';
|
||||||
import { dragContextBuilder, getAdjustedDropPosition } from './helpers/dragEnd';
|
import { dragContextBuilder, getAdjustedDropPosition } from './helpers/dragEnd';
|
||||||
import useStore from '@/AppBuilder/_stores/store';
|
import useStore from '@/AppBuilder/_stores/store';
|
||||||
|
|
@ -56,6 +58,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
const canvasWidth = NO_OF_GRIDS * gridWidth;
|
const canvasWidth = NO_OF_GRIDS * gridWidth;
|
||||||
const getHoveredComponentForGrid = useStore((state) => state.getHoveredComponentForGrid, shallow);
|
const getHoveredComponentForGrid = useStore((state) => state.getHoveredComponentForGrid, shallow);
|
||||||
const getResolvedComponent = useStore((state) => state.getResolvedComponent, shallow);
|
const getResolvedComponent = useStore((state) => state.getResolvedComponent, shallow);
|
||||||
|
const updateContainerAutoHeight = useStore((state) => state.updateContainerAutoHeight, shallow);
|
||||||
const [canvasBounds, setCanvasBounds] = useState(CANVAS_BOUNDS);
|
const [canvasBounds, setCanvasBounds] = useState(CANVAS_BOUNDS);
|
||||||
const draggingComponentId = useStore((state) => state.draggingComponentId, shallow);
|
const draggingComponentId = useStore((state) => state.draggingComponentId, shallow);
|
||||||
const resizingComponentId = useGridStore((state) => state.resizingComponentId, shallow);
|
const resizingComponentId = useGridStore((state) => state.resizingComponentId, shallow);
|
||||||
|
|
@ -345,6 +348,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
const handleDragEnd = useCallback(
|
const handleDragEnd = useCallback(
|
||||||
(boxPositions) => {
|
(boxPositions) => {
|
||||||
let newParent = null;
|
let newParent = null;
|
||||||
|
let oldParent = null;
|
||||||
const updatedLayouts = boxPositions.reduce((layouts, { id, x, y, parent }) => {
|
const updatedLayouts = boxPositions.reduce((layouts, { id, x, y, parent }) => {
|
||||||
const currentWidget = boxList.find((box) => box.id === id);
|
const currentWidget = boxList.find((box) => box.id === id);
|
||||||
const containerWidth = parent ? useGridStore.getState().subContainerWidths[parent] : gridWidth;
|
const containerWidth = parent ? useGridStore.getState().subContainerWidths[parent] : gridWidth;
|
||||||
|
|
@ -389,7 +393,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newParent = parent ? parent : null;
|
newParent = parent ? parent : null;
|
||||||
|
oldParent = currentWidget.component?.parent;
|
||||||
layouts[id] = {
|
layouts[id] = {
|
||||||
width: _width,
|
width: _width,
|
||||||
height: _height,
|
height: _height,
|
||||||
|
|
@ -400,6 +404,11 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
return layouts;
|
return layouts;
|
||||||
}, {});
|
}, {});
|
||||||
setComponentLayout(updatedLayouts, newParent, undefined, { updateParent: true });
|
setComponentLayout(updatedLayouts, newParent, undefined, { updateParent: true });
|
||||||
|
|
||||||
|
// const currentWidget = boxList.find((box) => box.id === id);
|
||||||
|
updateContainerAutoHeight(newParent);
|
||||||
|
updateContainerAutoHeight(oldParent);
|
||||||
|
|
||||||
toggleCanvasUpdater();
|
toggleCanvasUpdater();
|
||||||
},
|
},
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
|
@ -870,20 +879,19 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
|
|
||||||
const targetSlotId = target?.slotId;
|
const targetSlotId = target?.slotId;
|
||||||
const targetGridWidth = useGridStore.getState().subContainerWidths[targetSlotId] || gridWidth;
|
const targetGridWidth = useGridStore.getState().subContainerWidths[targetSlotId] || gridWidth;
|
||||||
|
|
||||||
// const restrictedWidgets = RESTRICTED_WIDGETS_CONFIG?.[source.widgetType] || [];
|
|
||||||
// const draggedWidgetType = dragged.widgetType;
|
|
||||||
const isParentChangeAllowed = dragContext.isDroppable;
|
const isParentChangeAllowed = dragContext.isDroppable;
|
||||||
|
|
||||||
// Compute new position
|
// Compute new position
|
||||||
let { left, top } = getAdjustedDropPosition(e, target, isParentChangeAllowed, targetGridWidth, dragged);
|
let { left, top } = getAdjustedDropPosition(e, target, isParentChangeAllowed, targetGridWidth, dragged);
|
||||||
|
|
||||||
const isModalToCanvas = source.isModal && target.slotId === 'real-canvas';
|
const isModalToCanvas = source.isModal && target.slotId === 'real-canvas';
|
||||||
|
let scrollDelta = computeScrollDelta({ source });
|
||||||
|
|
||||||
if (isParentChangeAllowed && !isModalToCanvas) {
|
if (isParentChangeAllowed && !isModalToCanvas) {
|
||||||
const parent = target.slotId === 'real-canvas' ? null : target.slotId;
|
|
||||||
// Special case for Modal; If source widget is modal, prevent drops to canvas
|
// Special case for Modal; If source widget is modal, prevent drops to canvas
|
||||||
handleDragEnd([{ id: e.target.id, x: left, y: top, parent }]);
|
const parent = target.slotId === 'real-canvas' ? null : target.slotId;
|
||||||
|
|
||||||
|
handleDragEnd([{ id: e.target.id, x: left, y: top + scrollDelta, parent }]);
|
||||||
} else {
|
} else {
|
||||||
const sourcegridWidth = useGridStore.getState().subContainerWidths[source.slotId] || gridWidth;
|
const sourcegridWidth = useGridStore.getState().subContainerWidths[source.slotId] || gridWidth;
|
||||||
|
|
||||||
|
|
@ -892,9 +900,8 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
!isModalToCanvas ??
|
!isModalToCanvas ??
|
||||||
toast.error(`${dragged.widgetType} is not compatible as a child component of ${target.widgetType}`);
|
toast.error(`${dragged.widgetType} is not compatible as a child component of ${target.widgetType}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply transform for smooth transition
|
// Apply transform for smooth transition
|
||||||
e.target.style.transform = `translate(${left}px, ${top}px)`;
|
e.target.style.transform = `translate(${left}px, ${top + scrollDelta}px)`;
|
||||||
|
|
||||||
// Force reordering of conatiner if the parent has not changed
|
// Force reordering of conatiner if the parent has not changed
|
||||||
const newParentId = target.slotId === 'real-canvas' ? 'canvas' : target.slotId;
|
const newParentId = target.slotId === 'real-canvas' ? 'canvas' : target.slotId;
|
||||||
|
|
@ -962,12 +969,6 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
setCanvasBounds({ ...relativePosition });
|
setCanvasBounds({ ...relativePosition });
|
||||||
}
|
}
|
||||||
|
|
||||||
e.target.style.transform = `translate(${left}px, ${top}px)`;
|
|
||||||
e.target.setAttribute(
|
|
||||||
'widget-pos2',
|
|
||||||
`translate: ${e.translate[0]} | Round: ${Math.round(e.translate[0] / gridWidth) * gridWidth} | ${gridWidth}`
|
|
||||||
);
|
|
||||||
|
|
||||||
// This block is to show grid lines on the canvas when the dragged element is over a new canvas
|
// This block is to show grid lines on the canvas when the dragged element is over a new canvas
|
||||||
if (document.elementFromPoint(e.clientX, e.clientY)) {
|
if (document.elementFromPoint(e.clientX, e.clientY)) {
|
||||||
const targetElems = document.elementsFromPoint(e.clientX, e.clientY);
|
const targetElems = document.elementsFromPoint(e.clientX, e.clientY);
|
||||||
|
|
@ -995,6 +996,17 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
handleActivateTargets(newParentId);
|
handleActivateTargets(newParentId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build the drag context from the event
|
||||||
|
const source = { slotId: oldParentId };
|
||||||
|
let scrollDelta = computeScrollDeltaOnDrag({ source });
|
||||||
|
|
||||||
|
e.target.style.transform = `translate(${left}px, ${top - scrollDelta}px)`;
|
||||||
|
e.target.setAttribute(
|
||||||
|
'widget-pos2',
|
||||||
|
`translate: ${e.translate[0]} | Round: ${Math.round(e.translate[0] / gridWidth) * gridWidth} | ${gridWidth}`
|
||||||
|
);
|
||||||
|
|
||||||
// Postion ghost element exactly as same at dragged element
|
// Postion ghost element exactly as same at dragged element
|
||||||
if (document.getElementById(`moveable-drag-ghost`)) {
|
if (document.getElementById(`moveable-drag-ghost`)) {
|
||||||
document.getElementById(`moveable-drag-ghost`).style.transform = `translate(${left}px, ${top}px)`;
|
document.getElementById(`moveable-drag-ghost`).style.transform = `translate(${left}px, ${top}px)`;
|
||||||
|
|
@ -1084,6 +1096,7 @@ export default function Grid({ gridWidth, currentLayout }) {
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
snapGridAll={true}
|
snapGridAll={true}
|
||||||
|
scrollable={true}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -415,6 +415,20 @@ export function hideGridLines() {
|
||||||
document.getElementById('real-canvas')?.classList.add('hide-grid');
|
document.getElementById('real-canvas')?.classList.add('hide-grid');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function showGridLinesOnSlot(slotId) {
|
||||||
|
var canvasElm = document.getElementById(`canvas-${slotId}`);
|
||||||
|
|
||||||
|
canvasElm.classList.remove('hide-grid');
|
||||||
|
canvasElm.classList.add('show-grid');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hideGridLinesOnSlot(slotId) {
|
||||||
|
var canvasElm = document.getElementById(`canvas-${slotId}`);
|
||||||
|
|
||||||
|
canvasElm.classList.remove('show-grid');
|
||||||
|
canvasElm.classList.add('hide-grid');
|
||||||
|
}
|
||||||
|
|
||||||
// Track previously active elements for efficient cleanup
|
// Track previously active elements for efficient cleanup
|
||||||
let previousActiveWidgets = null;
|
let previousActiveWidgets = null;
|
||||||
let previousActiveCanvas = null;
|
let previousActiveCanvas = null;
|
||||||
|
|
@ -488,3 +502,18 @@ export const handleDeactivateTargets = () => {
|
||||||
component.classList.remove('non-dragging-component');
|
component.classList.remove('non-dragging-component');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
export const computeScrollDelta = ({ source }) => {
|
||||||
|
// Only need to calculate scroll delta when moving from a sub-container
|
||||||
|
if (source.slotId !== 'real-canvas') {
|
||||||
|
const subContainerWrap = document
|
||||||
|
.querySelector(`#canvas-${source.slotId}`)
|
||||||
|
?.closest('.sub-container-overflow-wrap');
|
||||||
|
|
||||||
|
return subContainerWrap?.scrollTop || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default case: No scroll adjustment needed
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeScrollDeltaOnDrag = computeScrollDelta;
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,6 @@ export class DragContext {
|
||||||
|
|
||||||
const restrictedWidgets = [...restrictedWidgetsOnTarget, ...restrictedWidgetsOnTargetSlot];
|
const restrictedWidgets = [...restrictedWidgetsOnTarget, ...restrictedWidgetsOnTargetSlot];
|
||||||
return !restrictedWidgets.includes(dragged.widgetType);
|
return !restrictedWidgets.includes(dragged.widgetType);
|
||||||
ß;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ const SHOULD_ADD_BOX_SHADOW_AND_VISIBILITY = [
|
||||||
'Divider',
|
'Divider',
|
||||||
'VerticalDivider',
|
'VerticalDivider',
|
||||||
'Link',
|
'Link',
|
||||||
|
'Form',
|
||||||
];
|
];
|
||||||
|
|
||||||
const RenderWidget = ({
|
const RenderWidget = ({
|
||||||
|
|
|
||||||
|
|
@ -182,25 +182,6 @@ export const baseComponentProperties = (
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
items.push({
|
|
||||||
title: `${i18next.t('widget.common.general', 'General')}`,
|
|
||||||
isOpen: true,
|
|
||||||
children: (
|
|
||||||
<>
|
|
||||||
{renderElement(
|
|
||||||
component,
|
|
||||||
componentMeta,
|
|
||||||
layoutPropertyChanged,
|
|
||||||
dataQueries,
|
|
||||||
'tooltip',
|
|
||||||
'general',
|
|
||||||
currentState,
|
|
||||||
allComponents
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
title: `${i18next.t('widget.common.devices', 'Devices')}`,
|
title: `${i18next.t('widget.common.devices', 'Devices')}`,
|
||||||
isOpen: true,
|
isOpen: true,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ export const containerConfig = {
|
||||||
displayName: 'Container',
|
displayName: 'Container',
|
||||||
description: 'Group components',
|
description: 'Group components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 5,
|
width: 10,
|
||||||
height: 200,
|
height: 200,
|
||||||
},
|
},
|
||||||
component: 'Container',
|
component: 'Container',
|
||||||
|
|
@ -47,10 +47,16 @@ export const containerConfig = {
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
componentName: 'Text',
|
componentName: 'Text',
|
||||||
|
slotName: 'header',
|
||||||
layout: {
|
layout: {
|
||||||
top: 20,
|
top: 20,
|
||||||
left: 1,
|
left: 1,
|
||||||
|
|
@ -98,15 +104,6 @@ export const containerConfig = {
|
||||||
},
|
},
|
||||||
accordian: 'container',
|
accordian: 'container',
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'numberInput',
|
|
||||||
displayName: 'Height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'number' },
|
|
||||||
defaultValue: 80,
|
|
||||||
},
|
|
||||||
accordian: 'header',
|
|
||||||
},
|
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
type: 'numberInput',
|
type: 'numberInput',
|
||||||
displayName: 'Border',
|
displayName: 'Border',
|
||||||
|
|
@ -158,6 +155,7 @@ export const containerConfig = {
|
||||||
loadingState: { value: `{{false}}` },
|
loadingState: { value: `{{false}}` },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: `{{80}}` },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export const formConfig = {
|
||||||
description: 'Wrapper for multiple components',
|
description: 'Wrapper for multiple components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 13,
|
width: 13,
|
||||||
height: 480,
|
height: 450,
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
|
|
@ -19,8 +19,8 @@ export const formConfig = {
|
||||||
accessorKey: 'text',
|
accessorKey: 'text',
|
||||||
styles: ['fontWeight', 'textSize', 'textColor'],
|
styles: ['fontWeight', 'textSize', 'textColor'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Form title',
|
text: 'Form',
|
||||||
textSize: 20,
|
textSize: 16,
|
||||||
textColor: '#000',
|
textColor: '#000',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -34,203 +34,68 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['text'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Button2',
|
text: 'Submit',
|
||||||
padding: 'none',
|
padding: 'none',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 40,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
width: 17,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'User Details',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
textSize: 18,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 90,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Name',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 160,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Age',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 120,
|
top: 20,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['placeholder', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
placeholder: 'Enter your name',
|
placeholder: 'Enter your name',
|
||||||
label: '',
|
label: 'Name',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'NumberInput',
|
componentName: 'NumberInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 190,
|
top: 80,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['value', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
value: 24,
|
placeholder: 'Age',
|
||||||
label: '',
|
label: 'Age',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'Button',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 240,
|
top: 140,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 10,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Submit',
|
placeholder: 'Tomy',
|
||||||
|
label: 'Pet name',
|
||||||
|
width: '{{60}}',
|
||||||
|
alignment: 'side',
|
||||||
|
direction: 'left',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -276,6 +141,24 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
showHeader: { type: 'toggle', displayName: 'Header' },
|
showHeader: { type: 'toggle', displayName: 'Header' },
|
||||||
showFooter: { type: 'toggle', displayName: 'Footer' },
|
showFooter: { type: 'toggle', displayName: 'Footer' },
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
canvasHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Canvas height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
footerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Footer height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
displayName: 'Visibility',
|
displayName: 'Visibility',
|
||||||
|
|
@ -294,6 +177,13 @@ export const formConfig = {
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tooltip: {
|
||||||
|
type: 'code',
|
||||||
|
displayName: 'Tooltip',
|
||||||
|
validation: { schema: { type: 'string' } },
|
||||||
|
section: 'additionalActions',
|
||||||
|
placeholder: 'Enter tooltip text',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
onSubmit: { displayName: 'On submit' },
|
onSubmit: { displayName: 'On submit' },
|
||||||
|
|
@ -316,22 +206,6 @@ export const formConfig = {
|
||||||
defaultValue: '#ffffffff',
|
defaultValue: '#ffffffff',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Header height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
footerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Footer height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: 'colorSwatches',
|
type: 'colorSwatches',
|
||||||
displayName: 'Background color',
|
displayName: 'Background color',
|
||||||
|
|
@ -403,18 +277,18 @@ export const formConfig = {
|
||||||
value:
|
value:
|
||||||
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
||||||
},
|
},
|
||||||
showHeader: { value: '{{false}}' },
|
showHeader: { value: '{{true}}' },
|
||||||
showFooter: { value: '{{false}}' },
|
showFooter: { value: '{{true}}' },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: 60 },
|
||||||
|
footerHeight: { value: 60 },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
backgroundColor: { value: '#fff' },
|
backgroundColor: { value: '#fff' },
|
||||||
borderRadius: { value: '0' },
|
borderRadius: { value: '0' },
|
||||||
borderColor: { value: '#fff' },
|
borderColor: { value: '#fff' },
|
||||||
headerHeight: { value: '60px' },
|
|
||||||
footerHeight: { value: '60px' },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ export const Container = ({
|
||||||
shallow
|
shallow
|
||||||
);
|
);
|
||||||
|
|
||||||
const { borderRadius, borderColor, boxShadow, headerHeight = 80 } = styles;
|
const { borderRadius, borderColor, boxShadow } = styles;
|
||||||
|
const { headerHeight = 80 } = properties;
|
||||||
const contentBgColor = useMemo(() => {
|
const contentBgColor = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
import React, { useEffect } from 'react';
|
||||||
|
import { Container as SubContainer } from '@/AppBuilder/AppCanvas/Container';
|
||||||
|
import { showGridLinesOnSlot, hideGridLinesOnSlot } from '@/AppBuilder/AppCanvas/Grid/gridUtils';
|
||||||
|
import { useResizable } from '@/AppBuilder/_hooks/useMoveable';
|
||||||
|
|
||||||
|
export const HorizontalSlot = React.memo(
|
||||||
|
({
|
||||||
|
id,
|
||||||
|
height = 0,
|
||||||
|
width,
|
||||||
|
darkMode,
|
||||||
|
isDisabled,
|
||||||
|
isActive,
|
||||||
|
slotName = 'header', // 'header' or 'footer'
|
||||||
|
slotStyle = {},
|
||||||
|
onResize,
|
||||||
|
isEditing,
|
||||||
|
maxHeight,
|
||||||
|
}) => {
|
||||||
|
const parsedHeight = parseInt(height, 10);
|
||||||
|
|
||||||
|
const { getRootProps, getHandleProps, getResizeState } = useResizable({
|
||||||
|
initialHeight: parsedHeight,
|
||||||
|
initialWidth: '100%', // Now respects parent's width
|
||||||
|
minHeight: 10,
|
||||||
|
maxHeight: maxHeight || 400,
|
||||||
|
maxWidth: '100%',
|
||||||
|
stepHeight: 10, // Height will change in steps of 10px
|
||||||
|
onResize: () => {},
|
||||||
|
onDragEnd: (values) => {
|
||||||
|
onResize(values);
|
||||||
|
},
|
||||||
|
isReverseVerticalDrag: slotName === 'footer', // Reverse dragging for Footer
|
||||||
|
});
|
||||||
|
|
||||||
|
const { height: resizedHeight, isDragging } = getResizeState();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isDragging) {
|
||||||
|
showGridLinesOnSlot(id);
|
||||||
|
} else {
|
||||||
|
hideGridLinesOnSlot(id);
|
||||||
|
}
|
||||||
|
}, [isDragging, id]);
|
||||||
|
|
||||||
|
const canvasHeight = parseInt(resizedHeight, 10) / 10;
|
||||||
|
|
||||||
|
const resizeStyle = {
|
||||||
|
backgroundColor: darkMode ? '#1F2837' : '#fff',
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={`jet-form-${slotName} wj-form-${slotName}`} style={slotStyle}>
|
||||||
|
<div
|
||||||
|
className={`resizable-slot only-${slotName} ${isActive ? 'active' : ''} ${isEditing && 'is-editing'} ${
|
||||||
|
isDragging ? 'dragging' : ''
|
||||||
|
}`}
|
||||||
|
{...getRootProps()}
|
||||||
|
>
|
||||||
|
<SubContainer
|
||||||
|
id={id}
|
||||||
|
canvasHeight={canvasHeight}
|
||||||
|
canvasWidth={width}
|
||||||
|
allowContainerSelect={false}
|
||||||
|
darkMode={darkMode}
|
||||||
|
styles={{
|
||||||
|
margin: 0,
|
||||||
|
backgroundColor: 'transparent',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
componentType="Form"
|
||||||
|
/>
|
||||||
|
{isEditing && <div className="resize-handle" {...getHandleProps()} style={resizeStyle} />}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isDisabled && (
|
||||||
|
<div
|
||||||
|
id={`${id}-disabled`}
|
||||||
|
className="tj-form-disabled-overlay"
|
||||||
|
style={{ height: resizedHeight || '100%' }}
|
||||||
|
onClick={() => {}}
|
||||||
|
onDrop={(e) => e.stopPropagation()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
@ -2,7 +2,7 @@ import React, { useRef, useState, useEffect } from 'react';
|
||||||
import { Container as SubContainer } from '@/AppBuilder/AppCanvas/Container';
|
import { Container as SubContainer } from '@/AppBuilder/AppCanvas/Container';
|
||||||
// eslint-disable-next-line import/no-unresolved
|
// eslint-disable-next-line import/no-unresolved
|
||||||
import _, { debounce, omit } from 'lodash';
|
import _, { debounce, omit } from 'lodash';
|
||||||
import { generateUIComponents } from './FormUtils';
|
import { generateUIComponents, getBodyHeight } from './FormUtils';
|
||||||
import { useMounted } from '@/_hooks/use-mount';
|
import { useMounted } from '@/_hooks/use-mount';
|
||||||
import { onComponentClick, removeFunctionObjects } from '@/_helpers/appUtils';
|
import { onComponentClick, removeFunctionObjects } from '@/_helpers/appUtils';
|
||||||
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
import { deepClone } from '@/_helpers/utilities/utils.helpers';
|
||||||
|
|
@ -14,12 +14,10 @@ import {
|
||||||
CONTAINER_FORM_CANVAS_PADDING,
|
CONTAINER_FORM_CANVAS_PADDING,
|
||||||
SUBCONTAINER_CANVAS_BORDER_WIDTH,
|
SUBCONTAINER_CANVAS_BORDER_WIDTH,
|
||||||
} from '@/AppBuilder/AppCanvas/appCanvasConstants';
|
} from '@/AppBuilder/AppCanvas/appCanvasConstants';
|
||||||
import './form.scss';
|
import { HorizontalSlot } from './Components/HorizontalSlot';
|
||||||
|
import { useActiveSlot } from '@/AppBuilder/_hooks/useActiveSlot';
|
||||||
|
|
||||||
const getCanvasHeight = (height) => {
|
import './form.scss';
|
||||||
const parsedHeight = height.includes('px') ? parseInt(height, 10) : height;
|
|
||||||
return Math.ceil(parsedHeight);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const Form = function Form(props) {
|
export const Form = function Form(props) {
|
||||||
const {
|
const {
|
||||||
|
|
@ -35,26 +33,19 @@ export const Form = function Form(props) {
|
||||||
properties,
|
properties,
|
||||||
resetComponent = () => {},
|
resetComponent = () => {},
|
||||||
dataCy,
|
dataCy,
|
||||||
|
onComponentClick,
|
||||||
} = props;
|
} = props;
|
||||||
const childComponents = useStore((state) => state.getChildComponents(id), shallow);
|
const childComponents = useStore((state) => state.getChildComponents(id), shallow);
|
||||||
const {
|
const { borderRadius, borderColor, boxShadow, footerBackgroundColor, headerBackgroundColor } = styles;
|
||||||
borderRadius,
|
|
||||||
borderColor,
|
|
||||||
boxShadow,
|
|
||||||
headerHeight,
|
|
||||||
footerHeight,
|
|
||||||
footerBackgroundColor,
|
|
||||||
headerBackgroundColor,
|
|
||||||
} = styles;
|
|
||||||
const {
|
const {
|
||||||
buttonToSubmit,
|
buttonToSubmit,
|
||||||
loadingState,
|
|
||||||
advanced,
|
advanced,
|
||||||
JSONSchema,
|
JSONSchema,
|
||||||
showHeader = false,
|
showHeader = false,
|
||||||
showFooter = false,
|
showFooter = false,
|
||||||
visibility,
|
headerHeight = 80,
|
||||||
disabledState,
|
footerHeight = 80,
|
||||||
|
canvasHeight,
|
||||||
} = properties;
|
} = properties;
|
||||||
const { isDisabled, isVisible, isLoading } = useExposeState(
|
const { isDisabled, isVisible, isLoading } = useExposeState(
|
||||||
properties.loadingState,
|
properties.loadingState,
|
||||||
|
|
@ -65,6 +56,10 @@ export const Form = function Form(props) {
|
||||||
);
|
);
|
||||||
const backgroundColor =
|
const backgroundColor =
|
||||||
['#fff', '#ffffffff'].includes(styles.backgroundColor) && darkMode ? '#232E3C' : styles.backgroundColor;
|
['#fff', '#ffffffff'].includes(styles.backgroundColor) && darkMode ? '#232E3C' : styles.backgroundColor;
|
||||||
|
|
||||||
|
const computedFormBodyHeight = getBodyHeight(height, showHeader, showFooter, headerHeight, footerHeight);
|
||||||
|
const computedBorderRadius = `${borderRadius ? parseFloat(borderRadius) : 0}px`;
|
||||||
|
|
||||||
const computedStyles = {
|
const computedStyles = {
|
||||||
backgroundColor,
|
backgroundColor,
|
||||||
borderRadius: borderRadius ? parseFloat(borderRadius) : 0,
|
borderRadius: borderRadius ? parseFloat(borderRadius) : 0,
|
||||||
|
|
@ -74,16 +69,7 @@ export const Form = function Form(props) {
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
boxShadow,
|
boxShadow,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
};
|
clipPath: `inset(0 round ${computedBorderRadius})`,
|
||||||
|
|
||||||
const formHeader = {
|
|
||||||
flexShrink: 0,
|
|
||||||
paddingBottom: '3px',
|
|
||||||
paddingTop: '7px',
|
|
||||||
paddingLeft: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
|
||||||
paddingRight: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
|
||||||
backgroundColor:
|
|
||||||
['#fff', '#ffffffff'].includes(headerBackgroundColor) && darkMode ? '#1F2837' : headerBackgroundColor,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const formContent = {
|
const formContent = {
|
||||||
|
|
@ -96,13 +82,6 @@ export const Form = function Form(props) {
|
||||||
paddingRight: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
paddingRight: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
||||||
};
|
};
|
||||||
|
|
||||||
const formFooter = {
|
|
||||||
flexShrink: 0,
|
|
||||||
padding: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
|
||||||
backgroundColor:
|
|
||||||
['#fff', '#ffffffff'].includes(footerBackgroundColor) && darkMode ? '#1F2837' : footerBackgroundColor,
|
|
||||||
};
|
|
||||||
|
|
||||||
const parentRef = useRef(null);
|
const parentRef = useRef(null);
|
||||||
const childDataRef = useRef({});
|
const childDataRef = useRef({});
|
||||||
|
|
||||||
|
|
@ -110,8 +89,6 @@ export const Form = function Form(props) {
|
||||||
const [isValid, setValidation] = useState(true);
|
const [isValid, setValidation] = useState(true);
|
||||||
const [uiComponents, setUIComponents] = useState([]);
|
const [uiComponents, setUIComponents] = useState([]);
|
||||||
const mounted = useMounted();
|
const mounted = useMounted();
|
||||||
const canvasHeaderHeight = getCanvasHeight(headerHeight) / 10;
|
|
||||||
const canvasFooterHeight = getCanvasHeight(footerHeight) / 10;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const exposedVariables = {
|
const exposedVariables = {
|
||||||
|
|
@ -287,9 +264,61 @@ export const Form = function Form(props) {
|
||||||
setChildrenData(childDataRef.current);
|
setChildrenData(childDataRef.current);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mode = useStore((state) => state.currentMode, shallow);
|
||||||
|
const isEditing = mode === 'edit';
|
||||||
|
|
||||||
|
const activeSlot = useActiveSlot(isEditing ? id : null); // Track the active slot for this widget
|
||||||
|
const setComponentProperty = useStore((state) => state.setComponentProperty, shallow);
|
||||||
|
// const updateContainerAutoHeight = useStore((state) => state.updateContainerAutoHeight);
|
||||||
|
|
||||||
|
const updateHeaderSizeInStore = ({ newHeight }) => {
|
||||||
|
const _height = parseInt(newHeight, 10);
|
||||||
|
setComponentProperty(id, `headerHeight`, _height, 'properties', 'value', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateFooterSizeInStore = ({ newHeight }) => {
|
||||||
|
const _height = parseInt(newHeight, 10);
|
||||||
|
setComponentProperty(id, `footerHeight`, _height, 'properties', 'value', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const [canHeight, setCanHeight] = useState('100%');
|
||||||
|
useEffect(() => {
|
||||||
|
// const newHeight = parseInt(height, 10) - 14;
|
||||||
|
|
||||||
|
// const autoCanvasHeight = document.querySelector(`#canvas-${id}`)?.scrollHeight;
|
||||||
|
const wrapHeight = parseInt(computedFormBodyHeight, 10);
|
||||||
|
// Set height to the larger value between computed body height and canvas scroll height
|
||||||
|
const maxHeight = Math.max(wrapHeight, canvasHeight || 10);
|
||||||
|
|
||||||
|
const roundedHeight = Math.round(maxHeight / 10) * 10;
|
||||||
|
setCanHeight(`${roundedHeight}px`);
|
||||||
|
}, [computedFormBodyHeight, canvasHeight]);
|
||||||
|
const headerMaxHeight = parseInt(height, 10) - parseInt(footerHeight, 10) - 100 - 10;
|
||||||
|
const footerMaxHeight = parseInt(height, 10) - parseInt(headerHeight, 10) - 100 - 10;
|
||||||
|
const formFooter = {
|
||||||
|
flexShrink: 0,
|
||||||
|
paddingTop: '3px',
|
||||||
|
paddingBottom: '7px',
|
||||||
|
paddingLeft: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
||||||
|
paddingRight: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
||||||
|
maxHeight: `${footerMaxHeight}px`,
|
||||||
|
backgroundColor:
|
||||||
|
['#fff', '#ffffffff'].includes(footerBackgroundColor) && darkMode ? '#1F2837' : footerBackgroundColor,
|
||||||
|
};
|
||||||
|
const formHeader = {
|
||||||
|
flexShrink: 0,
|
||||||
|
paddingBottom: '3px',
|
||||||
|
paddingTop: '7px',
|
||||||
|
paddingLeft: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
||||||
|
paddingRight: `${CONTAINER_FORM_CANVAS_PADDING}px`,
|
||||||
|
maxHeight: `${headerMaxHeight}px`,
|
||||||
|
backgroundColor:
|
||||||
|
['#fff', '#ffffffff'].includes(headerBackgroundColor) && darkMode ? '#1F2837' : headerBackgroundColor,
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form
|
<form
|
||||||
className={`jet-container ${advanced && 'jet-container-json-form'}`}
|
className={`jet-container jet-form-widget ${advanced && 'jet-container-json-form'}`}
|
||||||
id={id}
|
id={id}
|
||||||
data-cy={dataCy}
|
data-cy={dataCy}
|
||||||
ref={parentRef}
|
ref={parentRef}
|
||||||
|
|
@ -300,31 +329,21 @@ export const Form = function Form(props) {
|
||||||
}} //Hack, should find a better solution - to prevent losing z index+1 when container element is clicked
|
}} //Hack, should find a better solution - to prevent losing z index+1 when container element is clicked
|
||||||
>
|
>
|
||||||
{!advanced && showHeader && (
|
{!advanced && showHeader && (
|
||||||
<div style={formHeader} className="wj-form-header">
|
<HorizontalSlot
|
||||||
<SubContainer
|
slotName="header"
|
||||||
id={`${id}-header`}
|
slotStyle={formHeader}
|
||||||
canvasHeight={canvasHeaderHeight}
|
isEditing={isEditing}
|
||||||
canvasWidth={width}
|
id={`${id}-header`}
|
||||||
allowContainerSelect={false}
|
height={headerHeight}
|
||||||
darkMode={darkMode}
|
width={width}
|
||||||
styles={{
|
darkMode={darkMode}
|
||||||
backgroundColor: 'transparent',
|
isDisabled={isDisabled}
|
||||||
height: headerHeight,
|
isActive={activeSlot === `${id}-header`}
|
||||||
}}
|
onResize={updateHeaderSizeInStore}
|
||||||
componentType="Form"
|
/>
|
||||||
/>
|
|
||||||
{isDisabled && (
|
|
||||||
<div
|
|
||||||
id={`${id}-header-disabled`}
|
|
||||||
className="tj-form-disabled-overlay"
|
|
||||||
style={{ height: headerHeight || '100%' }}
|
|
||||||
onClick={() => {}}
|
|
||||||
onDrop={(e) => e.stopPropagation()}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
<div className="jet-form-body" style={formContent}>
|
|
||||||
|
<div className="jet-form-body sub-container-overflow-wrap" style={formContent}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className="p-2 tw-flex tw-items-center tw-justify-center" style={{ margin: '0px auto' }}>
|
<div className="p-2 tw-flex tw-items-center tw-justify-center" style={{ margin: '0px auto' }}>
|
||||||
<div className="spinner-border" role="status"></div>
|
<div className="spinner-border" role="status"></div>
|
||||||
|
|
@ -332,14 +351,17 @@ export const Form = function Form(props) {
|
||||||
) : (
|
) : (
|
||||||
<fieldset disabled={isDisabled} style={{ width: '100%' }}>
|
<fieldset disabled={isDisabled} style={{ width: '100%' }}>
|
||||||
{!advanced && (
|
{!advanced && (
|
||||||
<div className={'json-form-wrapper-disabled'} style={{ width: '100%', height: '100%' }}>
|
<div className={'json-form-wrapper-disabled'} style={{ width: '100%', height: canHeight || '100%' }}>
|
||||||
<SubContainer
|
<SubContainer
|
||||||
id={id}
|
id={id}
|
||||||
canvasHeight={computedStyles.height}
|
canvasHeight={parseInt(computedFormBodyHeight, 10)}
|
||||||
canvasWidth={width}
|
canvasWidth={width}
|
||||||
onOptionChange={onOptionChange}
|
onOptionChange={onOptionChange}
|
||||||
onOptionsChange={onOptionsChange}
|
onOptionsChange={onOptionsChange}
|
||||||
styles={{ backgroundColor: computedStyles.backgroundColor }}
|
styles={{
|
||||||
|
backgroundColor: computedStyles.backgroundColor,
|
||||||
|
height: canHeight,
|
||||||
|
}}
|
||||||
darkMode={darkMode}
|
darkMode={darkMode}
|
||||||
componentType="Form"
|
componentType="Form"
|
||||||
/>
|
/>
|
||||||
|
|
@ -382,30 +404,18 @@ export const Form = function Form(props) {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{!advanced && showFooter && (
|
{!advanced && showFooter && (
|
||||||
<div className="jet-form-footer wj-form-footer" style={formFooter}>
|
<HorizontalSlot
|
||||||
<SubContainer
|
slotName="footer"
|
||||||
id={`${id}-footer`}
|
slotStyle={formFooter}
|
||||||
canvasHeight={canvasFooterHeight}
|
isEditing={isEditing}
|
||||||
canvasWidth={width}
|
id={`${id}-footer`}
|
||||||
allowContainerSelect={false}
|
height={footerHeight}
|
||||||
darkMode={darkMode}
|
width={width}
|
||||||
styles={{
|
darkMode={darkMode}
|
||||||
margin: 0,
|
isDisabled={isDisabled}
|
||||||
backgroundColor: 'transparent',
|
onResize={updateFooterSizeInStore}
|
||||||
height: footerHeight,
|
isActive={activeSlot === `${id}-footer`}
|
||||||
}}
|
/>
|
||||||
componentType="Form"
|
|
||||||
/>
|
|
||||||
{isDisabled && (
|
|
||||||
<div
|
|
||||||
id={`${id}-footer-disabled`}
|
|
||||||
className="tj-form-disabled-overlay"
|
|
||||||
style={{ height: footerHeight || '100%' }}
|
|
||||||
onClick={() => {}}
|
|
||||||
onDrop={(e) => e.stopPropagation()}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -533,3 +533,22 @@ const validBooleanChecker = (input) => {
|
||||||
if (/^(true|false)$/i.test(input) == true) return JSON.parse(input);
|
if (/^(true|false)$/i.test(input) == true) return JSON.parse(input);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getBodyHeight = (height, showHeader, showFooter, headerHeight = 60, footerHeight = 60) => {
|
||||||
|
let modalHeight = height ? parseInt(height, 10) : 0;
|
||||||
|
let parsedHeaderHeight = showHeader ? parseInt(headerHeight, 10) : 0;
|
||||||
|
let parsedFooterHeight = showFooter ? parseInt(footerHeight, 10) : 0;
|
||||||
|
|
||||||
|
if (showHeader) {
|
||||||
|
// 10 is header padding
|
||||||
|
modalHeight = modalHeight - parsedHeaderHeight - 10;
|
||||||
|
}
|
||||||
|
if (showFooter) {
|
||||||
|
// 14 is footer padding
|
||||||
|
modalHeight = modalHeight - parsedFooterHeight - 14;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rounded = Math.ceil(modalHeight / 10) * 10;
|
||||||
|
|
||||||
|
return `${Math.max(rounded - 20, 40)}px`;
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
|
.jet-form-widget {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
.wj-form-header {
|
.wj-form-header {
|
||||||
position: relative;
|
position: relative;
|
||||||
&::after {
|
&::after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: -7px;
|
left: -2px;
|
||||||
right: -7px;
|
right: -2px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: var(--border-weak);
|
background-color: var(--border-weak);
|
||||||
}
|
}
|
||||||
|
|
@ -17,8 +23,8 @@
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: -7px;
|
left: -2px;
|
||||||
right: -7px;
|
right: -2px;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: var(--border-weak);
|
background-color: var(--border-weak);
|
||||||
}
|
}
|
||||||
|
|
@ -39,6 +45,67 @@
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.resizable-slot {
|
||||||
|
position: relative;
|
||||||
|
height: auto;
|
||||||
|
box-shadow: 0 0 0 1px transparent; /* Acts as a border */
|
||||||
|
transition: box-shadow 0.15s ease-in-out;
|
||||||
|
max-height: 100%;
|
||||||
|
|
||||||
|
&.is-editing:hover {
|
||||||
|
box-shadow: 0 0 0 1px var(--border-weak);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-editing.active {
|
||||||
|
box-shadow: 0 0 0 1px var(--border-accent-weak);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-editing.dragging {
|
||||||
|
box-shadow: 0 0 0 1px var(--border-accent-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.resize-handle {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -4px;
|
||||||
|
left: 50%; /* Center horizontally */
|
||||||
|
transform: translateX(-50%); /* Ensure proper centering */
|
||||||
|
width: 24px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: initial;
|
||||||
|
border: 1px solid var(--background-accent-strong);
|
||||||
|
cursor: ns-resize;
|
||||||
|
z-index: 1;
|
||||||
|
visibility: hidden;
|
||||||
|
transition: visibility 0.15s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active .resize-handle {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.only-bottom {
|
||||||
|
}
|
||||||
|
|
||||||
|
.jet-form-header {
|
||||||
|
min-height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jet-form-body {
|
||||||
|
min-height: 100px;
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jet-form-footer {
|
||||||
|
min-height: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jet-form-footer .resize-handle {
|
||||||
|
top: -4px;
|
||||||
|
bottom: unset;
|
||||||
|
}
|
||||||
|
|
||||||
.jet-container.jet-container-json-form {
|
.jet-container.jet-container-json-form {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
|
||||||
|
|
|
||||||
84
frontend/src/AppBuilder/_hooks/useActiveSlot.js
Normal file
84
frontend/src/AppBuilder/_hooks/useActiveSlot.js
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import useStore from '@/AppBuilder/_stores/store';
|
||||||
|
import { shallow } from 'zustand/shallow';
|
||||||
|
|
||||||
|
const useIsWidgetSelected = (id) => {
|
||||||
|
// Get selected components from store using shallow comparison
|
||||||
|
const selectedComponents = useStore((state) => state.selectedComponents, shallow);
|
||||||
|
|
||||||
|
// Check if the only selected component is the provided `id`
|
||||||
|
return selectedComponents.length === 1 && selectedComponents[0] === id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useActiveSlot = (widgetId) => {
|
||||||
|
const [activeSlot, setActiveSlot] = useState(''); // Default to widget ID
|
||||||
|
const isSelected = useIsWidgetSelected(widgetId); // Check if widget is selected
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isSelected) {
|
||||||
|
setActiveSlot('');
|
||||||
|
}
|
||||||
|
}, [isSelected]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const handleDoubleClick = (event) => {
|
||||||
|
let target = event.target;
|
||||||
|
|
||||||
|
if (!widgetId) {
|
||||||
|
setActiveSlot(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse up to find a slot with an id
|
||||||
|
while (target && target !== document.body) {
|
||||||
|
if (target.id && target.id.startsWith('canvas-')) {
|
||||||
|
const slotId = target.id.replace(/^canvas-/, ''); // ✅ Strip "canvas-"
|
||||||
|
setActiveSlot(slotId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no slot is found, reset to widget ID
|
||||||
|
setActiveSlot(widgetId);
|
||||||
|
};
|
||||||
|
const handleSingleClick = (event) => {
|
||||||
|
let target = event.target;
|
||||||
|
|
||||||
|
if (!widgetId) {
|
||||||
|
setActiveSlot(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Traverse up to find a valid main slot (not header/footer)
|
||||||
|
while (target && target !== document.body) {
|
||||||
|
if (
|
||||||
|
target.id &&
|
||||||
|
target.id.startsWith('canvas-') &&
|
||||||
|
!target.id.endsWith('-header') &&
|
||||||
|
!target.id.endsWith('-footer')
|
||||||
|
) {
|
||||||
|
const slotId = target.id.replace(/^canvas-/, ''); // Strip "canvas-"
|
||||||
|
setActiveSlot(slotId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target = target.parentElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no main slot is found, fallback to widget ID
|
||||||
|
setActiveSlot(widgetId);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Attach single click if the widget is selected, otherwise listen for double-click
|
||||||
|
|
||||||
|
document.addEventListener('dblclick', handleDoubleClick);
|
||||||
|
document.addEventListener('click', handleSingleClick);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('dblclick', handleDoubleClick);
|
||||||
|
document.removeEventListener('click', handleSingleClick);
|
||||||
|
};
|
||||||
|
}, [widgetId]); // Re-run when widgetId or selection state changes
|
||||||
|
|
||||||
|
return activeSlot;
|
||||||
|
};
|
||||||
135
frontend/src/AppBuilder/_hooks/useMoveable.js
Normal file
135
frontend/src/AppBuilder/_hooks/useMoveable.js
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
import { useRef, useState } from 'react';
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
minHeight: 50,
|
||||||
|
maxHeight: 600,
|
||||||
|
minWidth: 50,
|
||||||
|
maxWidth: 600,
|
||||||
|
lockHorizontal: false,
|
||||||
|
lockVertical: false,
|
||||||
|
stepHeight: 10, // Default step size for height
|
||||||
|
stepWidth: 10, // Default step size for width
|
||||||
|
onResize: null,
|
||||||
|
onDragStart: null,
|
||||||
|
onDragEnd: null,
|
||||||
|
isReverseVerticalDrag: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useResizable = (options = {}) => {
|
||||||
|
const props = { ...defaultProps, ...options };
|
||||||
|
const parentRef = useRef(null);
|
||||||
|
const [isDragging, setIsDragging] = useState(false); // ✅ Track dragging state
|
||||||
|
|
||||||
|
const [height, setHeight] = useState(
|
||||||
|
typeof props.initialHeight === 'string' ? props.initialHeight : `${props.initialHeight || 200}px`
|
||||||
|
);
|
||||||
|
const [width, setWidth] = useState(
|
||||||
|
typeof props.initialWidth === 'string' ? props.initialWidth : `${props.initialWidth || 200}px`
|
||||||
|
);
|
||||||
|
|
||||||
|
const getRootProps = () => ({
|
||||||
|
ref: parentRef,
|
||||||
|
style: { height, width },
|
||||||
|
});
|
||||||
|
|
||||||
|
const getResizeState = () => ({
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
isDragging,
|
||||||
|
});
|
||||||
|
|
||||||
|
const getHandleProps = () => {
|
||||||
|
const handleMouseDown = (e) => {
|
||||||
|
// Prevent right-click drag activation (button === 2)
|
||||||
|
if (e.button === 2) return;
|
||||||
|
|
||||||
|
if (!parentRef.current) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
const startHeight = parseInt(parentRef.current.clientHeight);
|
||||||
|
const startWidth = parseInt(parentRef.current.clientWidth);
|
||||||
|
const parentWidth = parentRef.current.parentElement ? parentRef.current.parentElement.clientWidth : startWidth;
|
||||||
|
const startY = e.clientY;
|
||||||
|
const startX = e.clientX;
|
||||||
|
const isPercentage = typeof props.initialWidth === 'string' && props.initialWidth.includes('%');
|
||||||
|
|
||||||
|
setIsDragging(true); // ✅ Set dragging state to true
|
||||||
|
|
||||||
|
if (props.onDragStart) {
|
||||||
|
props.onDragStart({ newHeight: startHeight, newWidth: startWidth });
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleMouseMove = (moveEvent) => {
|
||||||
|
moveEvent.stopPropagation();
|
||||||
|
moveEvent.preventDefault();
|
||||||
|
let newHeight = startHeight;
|
||||||
|
let newWidth = startWidth;
|
||||||
|
|
||||||
|
if (!props.lockVertical) {
|
||||||
|
const deltaY = props.isReverseVerticalDrag ? startY - moveEvent.clientY : moveEvent.clientY - startY;
|
||||||
|
newHeight = startHeight + deltaY;
|
||||||
|
newHeight = Math.max(props.minHeight, Math.min(props.maxHeight, newHeight));
|
||||||
|
newHeight = Math.round(newHeight / props.stepHeight) * props.stepHeight; // Snap to stepHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!props.lockHorizontal) {
|
||||||
|
newWidth = startWidth + (moveEvent.clientX - startX);
|
||||||
|
newWidth = Math.max(props.minWidth, Math.min(props.maxWidth, newWidth));
|
||||||
|
newWidth = Math.round(newWidth / props.stepWidth) * props.stepWidth; // Snap to stepWidth
|
||||||
|
|
||||||
|
if (isPercentage) {
|
||||||
|
newWidth = (newWidth / parentWidth) * 100; // Convert to percentage
|
||||||
|
newWidth = `${newWidth.toFixed(2)}%`;
|
||||||
|
} else {
|
||||||
|
newWidth = `${newWidth}px`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setHeight(`${newHeight}px`);
|
||||||
|
setWidth(newWidth);
|
||||||
|
|
||||||
|
if (parentRef.current) {
|
||||||
|
parentRef.current.style.height = `${newHeight}px`;
|
||||||
|
parentRef.current.style.width = newWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props.onResize) {
|
||||||
|
props.onResize({
|
||||||
|
newHeight,
|
||||||
|
newWidth,
|
||||||
|
heightDiff: newHeight - startHeight,
|
||||||
|
widthDiff: isPercentage
|
||||||
|
? parseInt(newWidth) - (startWidth / parentWidth) * 100
|
||||||
|
: parseInt(newWidth) - startWidth,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseUp = () => {
|
||||||
|
setIsDragging(false); // ✅ Set dragging state to false
|
||||||
|
|
||||||
|
document.removeEventListener('mousemove', handleMouseMove);
|
||||||
|
document.removeEventListener('mouseup', handleMouseUp);
|
||||||
|
|
||||||
|
if (props.onDragEnd) {
|
||||||
|
// Get the updated height and width from the DOM instead of relying on state
|
||||||
|
const finalHeight = parentRef.current ? parseInt(parentRef.current.clientHeight) : parseInt(height);
|
||||||
|
const finalWidth = parentRef.current ? parseInt(parentRef.current.clientWidth) : parseInt(width);
|
||||||
|
|
||||||
|
props.onDragEnd({ newHeight: finalHeight, newWidth: finalWidth });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', handleMouseMove);
|
||||||
|
document.addEventListener('mouseup', handleMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onMouseDown: handleMouseDown,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return { rootRef: parentRef, getRootProps, getHandleProps, getResizeState };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useResizable;
|
||||||
|
|
@ -1896,4 +1896,28 @@ export const createComponentsSlice = (set, get) => ({
|
||||||
state.modalsOpenOnCanvas = newModalOpenOnCanvas;
|
state.modalsOpenOnCanvas = newModalOpenOnCanvas;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateContainerAutoHeight: (componentId) => {
|
||||||
|
if (
|
||||||
|
!componentId ||
|
||||||
|
componentId === 'canvas' ||
|
||||||
|
componentId.includes('-header') ||
|
||||||
|
componentId.includes('-footer')
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { currentLayout, getCurrentPageComponents, setComponentProperty } = get();
|
||||||
|
const allComponents = getCurrentPageComponents();
|
||||||
|
|
||||||
|
const childComponents = getAllChildComponents(allComponents, componentId);
|
||||||
|
const maxHeight = Object.values(childComponents).reduce((max, component) => {
|
||||||
|
const layout = component?.layouts?.[currentLayout];
|
||||||
|
if (!layout) {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
const sum = layout.top + layout.height;
|
||||||
|
return Math.max(max, sum);
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
setComponentProperty(componentId, `canvasHeight`, maxHeight, 'properties', 'value', false);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ export const containerConfig = {
|
||||||
displayName: 'Container',
|
displayName: 'Container',
|
||||||
description: 'Group components',
|
description: 'Group components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 5,
|
width: 10,
|
||||||
height: 200,
|
height: 200,
|
||||||
},
|
},
|
||||||
component: 'Container',
|
component: 'Container',
|
||||||
|
|
@ -47,10 +47,16 @@ export const containerConfig = {
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
componentName: 'Text',
|
componentName: 'Text',
|
||||||
|
slotName: 'header',
|
||||||
layout: {
|
layout: {
|
||||||
top: 20,
|
top: 20,
|
||||||
left: 1,
|
left: 1,
|
||||||
|
|
@ -98,15 +104,6 @@ export const containerConfig = {
|
||||||
},
|
},
|
||||||
accordian: 'container',
|
accordian: 'container',
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'numberInput',
|
|
||||||
displayName: 'Height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'number' },
|
|
||||||
defaultValue: 80,
|
|
||||||
},
|
|
||||||
accordian: 'header',
|
|
||||||
},
|
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
type: 'numberInput',
|
type: 'numberInput',
|
||||||
displayName: 'Border',
|
displayName: 'Border',
|
||||||
|
|
@ -158,6 +155,7 @@ export const containerConfig = {
|
||||||
loadingState: { value: `{{false}}` },
|
loadingState: { value: `{{false}}` },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: `{{80}}` },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export const formConfig = {
|
||||||
description: 'Wrapper for multiple components',
|
description: 'Wrapper for multiple components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 13,
|
width: 13,
|
||||||
height: 480,
|
height: 450,
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
|
|
@ -19,8 +19,8 @@ export const formConfig = {
|
||||||
accessorKey: 'text',
|
accessorKey: 'text',
|
||||||
styles: ['fontWeight', 'textSize', 'textColor'],
|
styles: ['fontWeight', 'textSize', 'textColor'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Form title',
|
text: 'Form',
|
||||||
textSize: 20,
|
textSize: 16,
|
||||||
textColor: '#000',
|
textColor: '#000',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -34,203 +34,68 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['text'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Button2',
|
text: 'Submit',
|
||||||
padding: 'none',
|
padding: 'none',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 40,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
width: 17,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'User Details',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
textSize: 18,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 90,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Name',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 160,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Age',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 120,
|
top: 20,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['placeholder', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
placeholder: 'Enter your name',
|
placeholder: 'Enter your name',
|
||||||
label: '',
|
label: 'Name',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'NumberInput',
|
componentName: 'NumberInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 190,
|
top: 80,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['value', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
value: 24,
|
placeholder: 'Age',
|
||||||
label: '',
|
label: 'Age',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'Button',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 240,
|
top: 140,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 10,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Submit',
|
placeholder: 'Tomy',
|
||||||
|
label: 'Pet name',
|
||||||
|
width: '{{60}}',
|
||||||
|
alignment: 'side',
|
||||||
|
direction: 'left',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -276,6 +141,24 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
showHeader: { type: 'toggle', displayName: 'Header' },
|
showHeader: { type: 'toggle', displayName: 'Header' },
|
||||||
showFooter: { type: 'toggle', displayName: 'Footer' },
|
showFooter: { type: 'toggle', displayName: 'Footer' },
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
canvasHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Canvas height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
footerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Footer height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
displayName: 'Visibility',
|
displayName: 'Visibility',
|
||||||
|
|
@ -294,6 +177,13 @@ export const formConfig = {
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tooltip: {
|
||||||
|
type: 'code',
|
||||||
|
displayName: 'Tooltip',
|
||||||
|
validation: { schema: { type: 'string' } },
|
||||||
|
section: 'additionalActions',
|
||||||
|
placeholder: 'Enter tooltip text',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
onSubmit: { displayName: 'On submit' },
|
onSubmit: { displayName: 'On submit' },
|
||||||
|
|
@ -316,24 +206,8 @@ export const formConfig = {
|
||||||
defaultValue: '#ffffffff',
|
defaultValue: '#ffffffff',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Header height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
footerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Footer height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: 'color',
|
type: 'colorSwatches',
|
||||||
displayName: 'Background color',
|
displayName: 'Background color',
|
||||||
validation: {
|
validation: {
|
||||||
schema: { type: 'string' },
|
schema: { type: 'string' },
|
||||||
|
|
@ -351,7 +225,7 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
borderColor: {
|
borderColor: {
|
||||||
type: 'color',
|
type: 'colorSwatches',
|
||||||
displayName: 'Border color',
|
displayName: 'Border color',
|
||||||
validation: {
|
validation: {
|
||||||
schema: { type: 'string' },
|
schema: { type: 'string' },
|
||||||
|
|
@ -403,18 +277,18 @@ export const formConfig = {
|
||||||
value:
|
value:
|
||||||
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
||||||
},
|
},
|
||||||
showHeader: { value: '{{false}}' },
|
showHeader: { value: '{{true}}' },
|
||||||
showFooter: { value: '{{false}}' },
|
showFooter: { value: '{{true}}' },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: 60 },
|
||||||
|
footerHeight: { value: 60 },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
backgroundColor: { value: '#fff' },
|
backgroundColor: { value: '#fff' },
|
||||||
borderRadius: { value: '0' },
|
borderRadius: { value: '0' },
|
||||||
borderColor: { value: '#fff' },
|
borderColor: { value: '#fff' },
|
||||||
headerHeight: { value: '60px' },
|
|
||||||
footerHeight: { value: '60px' },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ export const containerConfig = {
|
||||||
displayName: 'Container',
|
displayName: 'Container',
|
||||||
description: 'Group components',
|
description: 'Group components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 5,
|
width: 10,
|
||||||
height: 200,
|
height: 200,
|
||||||
},
|
},
|
||||||
component: 'Container',
|
component: 'Container',
|
||||||
|
|
@ -47,10 +47,16 @@ export const containerConfig = {
|
||||||
defaultValue: true,
|
defaultValue: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
componentName: 'Text',
|
componentName: 'Text',
|
||||||
|
slotName: 'header',
|
||||||
layout: {
|
layout: {
|
||||||
top: 20,
|
top: 20,
|
||||||
left: 1,
|
left: 1,
|
||||||
|
|
@ -98,15 +104,6 @@ export const containerConfig = {
|
||||||
},
|
},
|
||||||
accordian: 'container',
|
accordian: 'container',
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'numberInput',
|
|
||||||
displayName: 'Height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'number' },
|
|
||||||
defaultValue: 80,
|
|
||||||
},
|
|
||||||
accordian: 'header',
|
|
||||||
},
|
|
||||||
borderRadius: {
|
borderRadius: {
|
||||||
type: 'numberInput',
|
type: 'numberInput',
|
||||||
displayName: 'Border',
|
displayName: 'Border',
|
||||||
|
|
@ -158,6 +155,7 @@ export const containerConfig = {
|
||||||
loadingState: { value: `{{false}}` },
|
loadingState: { value: `{{false}}` },
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: `{{80}}` },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ export const formConfig = {
|
||||||
description: 'Wrapper for multiple components',
|
description: 'Wrapper for multiple components',
|
||||||
defaultSize: {
|
defaultSize: {
|
||||||
width: 13,
|
width: 13,
|
||||||
height: 480,
|
height: 450,
|
||||||
},
|
},
|
||||||
defaultChildren: [
|
defaultChildren: [
|
||||||
{
|
{
|
||||||
|
|
@ -19,8 +19,8 @@ export const formConfig = {
|
||||||
accessorKey: 'text',
|
accessorKey: 'text',
|
||||||
styles: ['fontWeight', 'textSize', 'textColor'],
|
styles: ['fontWeight', 'textSize', 'textColor'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Form title',
|
text: 'Form',
|
||||||
textSize: 20,
|
textSize: 16,
|
||||||
textColor: '#000',
|
textColor: '#000',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -34,203 +34,68 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['text'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Button2',
|
text: 'Submit',
|
||||||
padding: 'none',
|
padding: 'none',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 40,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
width: 17,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'User Details',
|
|
||||||
fontWeight: 'bold',
|
|
||||||
textSize: 18,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 90,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Name',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
layout: {
|
|
||||||
top: 160,
|
|
||||||
left: 10,
|
|
||||||
height: 30,
|
|
||||||
},
|
|
||||||
properties: ['text'],
|
|
||||||
styles: [
|
|
||||||
'textSize',
|
|
||||||
'fontWeight',
|
|
||||||
'fontStyle',
|
|
||||||
'textColor',
|
|
||||||
'isScrollRequired',
|
|
||||||
'lineHeight',
|
|
||||||
'textIndent',
|
|
||||||
'textAlign',
|
|
||||||
'verticalAlignment',
|
|
||||||
'decoration',
|
|
||||||
'transformation',
|
|
||||||
'letterSpacing',
|
|
||||||
'wordSpacing',
|
|
||||||
'fontVariant',
|
|
||||||
'backgroundColor',
|
|
||||||
'borderColor',
|
|
||||||
'borderRadius',
|
|
||||||
'boxShadow',
|
|
||||||
'padding',
|
|
||||||
],
|
|
||||||
defaultValue: {
|
|
||||||
text: 'Age',
|
|
||||||
fontWeight: 'normal',
|
|
||||||
textSize: 14,
|
|
||||||
textColor: '#000',
|
|
||||||
backgroundColor: '#fff00000',
|
|
||||||
textAlign: 'left',
|
|
||||||
decoration: 'none',
|
|
||||||
transformation: 'none',
|
|
||||||
fontStyle: 'normal',
|
|
||||||
lineHeight: 1.5,
|
|
||||||
textIndent: '0',
|
|
||||||
letterSpacing: '0',
|
|
||||||
wordSpacing: '0',
|
|
||||||
fontVariant: 'normal',
|
|
||||||
verticalAlignment: 'top',
|
|
||||||
padding: 'default',
|
|
||||||
boxShadow: '0px 0px 0px 0px #00000090',
|
|
||||||
borderRadius: '0',
|
|
||||||
isScrollRequired: 'enabled',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
componentName: 'TextInput',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 120,
|
top: 20,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['placeholder', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
placeholder: 'Enter your name',
|
placeholder: 'Enter your name',
|
||||||
label: '',
|
label: 'Name',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'NumberInput',
|
componentName: 'NumberInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 190,
|
top: 80,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 25,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['value', 'label'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
value: 24,
|
placeholder: 'Age',
|
||||||
label: '',
|
label: 'Age',
|
||||||
|
width: '{{60}}',
|
||||||
|
direction: 'left',
|
||||||
|
alignment: 'side',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
componentName: 'Button',
|
componentName: 'TextInput',
|
||||||
layout: {
|
layout: {
|
||||||
top: 240,
|
top: 140,
|
||||||
left: 10,
|
left: 5,
|
||||||
height: 30,
|
height: 40,
|
||||||
width: 10,
|
width: 31,
|
||||||
},
|
},
|
||||||
properties: ['text'],
|
properties: ['placeholder', 'label'],
|
||||||
|
styles: ['alignment', 'width', 'auto', 'padding', 'direction'],
|
||||||
defaultValue: {
|
defaultValue: {
|
||||||
text: 'Submit',
|
placeholder: 'Tomy',
|
||||||
|
label: 'Pet name',
|
||||||
|
width: '{{60}}',
|
||||||
|
alignment: 'side',
|
||||||
|
direction: 'left',
|
||||||
|
auto: '{{false}}',
|
||||||
|
padding: 'default',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
@ -276,6 +141,24 @@ export const formConfig = {
|
||||||
},
|
},
|
||||||
showHeader: { type: 'toggle', displayName: 'Header' },
|
showHeader: { type: 'toggle', displayName: 'Header' },
|
||||||
showFooter: { type: 'toggle', displayName: 'Footer' },
|
showFooter: { type: 'toggle', displayName: 'Footer' },
|
||||||
|
headerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Header height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
canvasHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Canvas height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
|
footerHeight: {
|
||||||
|
type: 'numberInput',
|
||||||
|
displayName: 'Footer height',
|
||||||
|
isHidden: true,
|
||||||
|
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 80 },
|
||||||
|
},
|
||||||
visibility: {
|
visibility: {
|
||||||
type: 'toggle',
|
type: 'toggle',
|
||||||
displayName: 'Visibility',
|
displayName: 'Visibility',
|
||||||
|
|
@ -294,6 +177,13 @@ export const formConfig = {
|
||||||
defaultValue: false,
|
defaultValue: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
tooltip: {
|
||||||
|
type: 'code',
|
||||||
|
displayName: 'Tooltip',
|
||||||
|
validation: { schema: { type: 'string' } },
|
||||||
|
section: 'additionalActions',
|
||||||
|
placeholder: 'Enter tooltip text',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
events: {
|
events: {
|
||||||
onSubmit: { displayName: 'On submit' },
|
onSubmit: { displayName: 'On submit' },
|
||||||
|
|
@ -316,22 +206,6 @@ export const formConfig = {
|
||||||
defaultValue: '#ffffffff',
|
defaultValue: '#ffffffff',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
headerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Header height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
footerHeight: {
|
|
||||||
type: 'code',
|
|
||||||
displayName: 'Footer height',
|
|
||||||
validation: {
|
|
||||||
schema: { type: 'string' },
|
|
||||||
defaultValue: '80px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
backgroundColor: {
|
backgroundColor: {
|
||||||
type: 'colorSwatches',
|
type: 'colorSwatches',
|
||||||
displayName: 'Background color',
|
displayName: 'Background color',
|
||||||
|
|
@ -403,19 +277,18 @@ export const formConfig = {
|
||||||
value:
|
value:
|
||||||
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
"{{ {title: 'User registration form', properties: {firstname: {type: 'textinput',value: 'Maria',label:'First name', validation:{maxLength:6}, styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},lastname:{type: 'textinput',value: 'Doe', label:'Last name', styles: {backgroundColor: '#f6f5ff',textColor: 'black'},},age:{type:'number', label:'Age'},}, submitButton: {value: 'Submit', styles: {backgroundColor: '#3a433b',borderColor:'#595959'}}} }}",
|
||||||
},
|
},
|
||||||
buttonToSubmit: { value: '{{"none"}}' },
|
showHeader: { value: '{{true}}' },
|
||||||
showHeader: { value: '{{false}}' },
|
showFooter: { value: '{{true}}' },
|
||||||
showFooter: { value: '{{false}}' },
|
|
||||||
visibility: { value: '{{true}}' },
|
visibility: { value: '{{true}}' },
|
||||||
disabledState: { value: '{{false}}' },
|
disabledState: { value: '{{false}}' },
|
||||||
|
headerHeight: { value: 60 },
|
||||||
|
footerHeight: { value: 60 },
|
||||||
},
|
},
|
||||||
events: [],
|
events: [],
|
||||||
styles: {
|
styles: {
|
||||||
backgroundColor: { value: '#fff' },
|
backgroundColor: { value: '#fff' },
|
||||||
borderRadius: { value: '0' },
|
borderRadius: { value: '0' },
|
||||||
borderColor: { value: '#fff' },
|
borderColor: { value: '#fff' },
|
||||||
headerHeight: { value: '60px' },
|
|
||||||
footerHeight: { value: '60px' },
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue