Merge pull request #12464 from ToolJet/appbuilder/sprint-10

Release: Appbuilder sprint 10
This commit is contained in:
Johnson Cherian 2025-04-08 18:23:40 +05:30 committed by GitHub
commit 64692e73da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
326 changed files with 14939 additions and 1833 deletions

View file

@ -1 +1 @@
3.8.0
3.9.0

View file

@ -1 +1 @@
3.8.0
3.9.0

View file

@ -0,0 +1,39 @@
import React from 'react';
const EmailInput = ({ fill = '#D7DBDF', width = 24, className = '', viewBox = '0 0 49 48' }) => (
<svg
width={width}
height={width}
viewBox={viewBox}
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M2.39498 1.9349C3.35945 0.97044 4.66757 0.428589 6.03153 0.428589H43.7458C45.1097 0.428589 46.418 0.97044 47.3825 1.9349C48.347 2.89935 48.8887 4.20746 48.8887 5.57145V17.3819C47.4096 16.4176 45.6432 15.8572 43.7458 15.8572H28.3172C23.11 15.8572 18.8887 20.0785 18.8887 25.2857V31.2857H6.03153C4.66754 31.2857 3.35945 30.7439 2.39498 29.7794C1.43051 28.815 0.888672 27.5068 0.888672 26.1429V5.57145C0.888672 4.20749 1.43051 2.89935 2.39498 1.9349Z"
fill="#CCD1D5"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12.8886 10.2858C14.0721 10.2858 15.0315 11.2451 15.0315 12.4286V19.2858C15.0315 20.4692 14.0721 21.4286 12.8886 21.4286C11.7052 21.4286 10.7458 20.4692 10.7458 19.2858V12.4286C10.7458 11.2451 11.7052 10.2858 12.8886 10.2858Z"
fill="#4368E3"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M28.3172 20.1428C25.4769 20.1428 23.1744 22.4453 23.1744 25.2857V36.4285C23.1744 39.2688 25.4769 41.5714 28.3172 41.5714H43.7458C46.586 41.5714 48.8887 39.2688 48.8887 36.4285V25.2857C48.8887 22.4453 46.586 20.1428 43.7458 20.1428H28.3172Z"
fill="#4368E3"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M48.7087 23.9319L36.0315 29.7828L23.3545 23.9318C23.2371 24.3631 23.1744 24.8171 23.1744 25.2857V28.5688L35.1337 34.0886C35.7034 34.3515 36.36 34.3515 36.9298 34.0886L48.8887 28.5689V25.2857C48.8887 24.8172 48.8259 24.3632 48.7087 23.9319Z"
fill="#CCD1D5"
/>
</svg>
);
export default EmailInput;

View file

@ -59,6 +59,8 @@ import Upstatistics from './upstatistics.jsx';
import Verticaldivider from './verticaldivider.jsx';
import TimePicker from './timepicker.jsx';
import DatepickerV2 from './datepickerv2.jsx';
import PhoneInput from './phoneinput.jsx';
import EmailInput from './emailinput.jsx';
const WidgetIcon = (props) => {
switch (props.name) {
@ -99,6 +101,10 @@ const WidgetIcon = (props) => {
return <Datepicker {...props} />;
case 'datetimepickerv2':
return <DateTimePickerV2 {...props} />;
case 'emailinput':
return <EmailInput {...props} />;
case 'phoneinput':
return <PhoneInput {...props} />;
case 'daterangepicker':
return <Daterangepicker {...props} />;
case 'horizontaldivider':
@ -180,6 +186,7 @@ const WidgetIcon = (props) => {
case 'text':
return <Text {...props} />;
case 'textarea':
case 'textarealegacy':
return <TextArea {...props} />;
case 'textinput':
return <Textinput {...props} />;

View file

@ -0,0 +1,36 @@
import React from 'react';
const PhoneInput = ({ fill = '#D7DBDF', width = 24, className = '', viewBox = '0 0 49 48' }) => (
<svg
width={width}
height={width}
viewBox={viewBox}
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.60296 9.85718C4.99933 9.85718 2.88867 11.9678 2.88867 14.5715V33.4286C2.88867 36.0322 4.99933 38.1429 7.60296 38.1429H42.1744C44.7779 38.1429 46.8887 36.0322 46.8887 33.4286V14.5715C46.8887 11.9678 44.7779 9.85718 42.1744 9.85718H7.60296Z"
fill="#CCD1D5"
/>
<path
d="M26.853 27.0714C25.7681 27.0714 24.8887 27.9508 24.8887 29.0357C24.8887 30.1205 25.7681 31 26.853 31H32.8884C33.9733 31 34.8527 30.1205 34.8527 29.0357C34.8527 27.9508 33.9733 27.0714 32.8884 27.0714H26.853Z"
fill="#4368E3"
/>
<g clip-path="url(#clip0_39_14)">
<path
d="M14.113 30.4517C13.4512 30.8793 12.6626 31.0657 11.8797 30.9794C11.0969 30.8932 10.3675 30.5396 9.81433 29.9781L9.33073 29.5045C9.11871 29.2873 9 28.9956 9 28.6919C9 28.3881 9.11871 28.0965 9.33073 27.8793L11.3834 25.845C11.5984 25.6333 11.8879 25.5147 12.1894 25.5147C12.4909 25.5147 12.7803 25.6333 12.9954 25.845C13.2122 26.0573 13.5035 26.1762 13.8068 26.1762C14.11 26.1762 14.4013 26.0573 14.6181 25.845L17.8422 22.616C17.9497 22.5099 18.0351 22.3834 18.0934 22.2439C18.1517 22.1043 18.1817 21.9546 18.1817 21.8034C18.1817 21.6522 18.1517 21.5024 18.0934 21.3629C18.0351 21.2234 17.9497 21.0969 17.8422 20.9908C17.6308 20.7754 17.5124 20.4855 17.5124 20.1835C17.5124 19.8815 17.6308 19.5916 17.8422 19.3763L19.8841 17.3312C20.1009 17.1189 20.3922 17 20.6954 17C20.9987 17 21.29 17.1189 21.5068 17.3312L21.9797 17.8156C22.5403 18.3696 22.8933 19.1001 22.9794 19.8842C23.0656 20.6682 22.8795 21.4581 22.4525 22.1209C20.2279 25.4045 17.3973 28.2321 14.113 30.4517Z"
fill="#4368E3"
/>
</g>
<defs>
<clipPath id="clip0_39_14">
<rect width="14" height="14" fill="white" transform="translate(9 17)" />
</clipPath>
</defs>
</svg>
);
export default PhoneInput;

@ -1 +1 @@
Subproject commit 96d68bb9801411de58e6ec62c9d0e84bba631fdd
Subproject commit dcd948d284b5f14a868480830e09b90496db8572

View file

@ -38,6 +38,7 @@
"@sentry/react": "^7.100.1",
"@sentry/webpack-plugin": "^2.14.0",
"@tabler/icons-react": "^2.4.0",
"@tanstack/react-table": "^8.20.5",
"@tanstack/react-virtual": "^3.10.8",
"@textea/json-viewer": "^3.3.2",
"@tooljet/plugins": "../plugins",
@ -96,6 +97,7 @@
"react-circular-progressbar": "^2.1.0",
"react-color": "^2.19.3",
"react-copy-to-clipboard": "^5.1.0",
"react-currency-input-field": "^3.10.0",
"react-datepicker": "^7.6.0",
"react-dates": "^21.8.0",
"react-datetime": "^3.2.0",
@ -118,6 +120,7 @@
"react-multi-select-component": "^4.3.4",
"react-pdf": "^6.2.2",
"react-phone-input-2": "^2.15.1",
"react-phone-number-input": "^3.4.12",
"react-plotly.js": "^2.6.0",
"react-qr-reader": "^2.2.1",
"react-rnd": "^10.4.1",
@ -25856,6 +25859,25 @@
"react": "^16.5.1 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/@tanstack/react-table": {
"version": "8.21.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.21.2.tgz",
"integrity": "sha512-11tNlEDTdIhMJba2RBH+ecJ9l1zgS2kjmexDPAraulc8jeNA4xocSNeyzextT0XJyASil4XsCYlJmf5jEWAtYg==",
"dependencies": {
"@tanstack/table-core": "8.21.2"
},
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/@tanstack/react-virtual": {
"version": "3.10.8",
"license": "MIT",
@ -25871,6 +25893,18 @@
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/@tanstack/table-core": {
"version": "8.21.2",
"resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.21.2.tgz",
"integrity": "sha512-uvXk/U4cBiFMxt+p9/G7yUWI/UbHYbyghLCjlpWZ3mLeIZiUBSKcUnw9UnKkdRz7Z/N4UBuFLWQdJCjUe7HjvA==",
"engines": {
"node": ">=12"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@tanstack/virtual-core": {
"version": "3.10.8",
"license": "MIT",
@ -29820,6 +29854,11 @@
"node": ">=10"
}
},
"node_modules/country-flag-icons": {
"version": "1.5.18",
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.18.tgz",
"integrity": "sha512-z+Uzesi8u8IdkViqqbzzbkf3+a7WJpcET5B7sPwTg7GXqPYpVEgNlZ/FC3l8KO4mEf+mNkmzKLppKTN4PlCJEQ=="
},
"node_modules/country-regex": {
"version": "1.1.0",
"license": "MIT",
@ -34649,6 +34688,26 @@
"version": "0.2.4",
"license": "MIT"
},
"node_modules/input-format": {
"version": "0.3.14",
"resolved": "https://registry.npmjs.org/input-format/-/input-format-0.3.14.tgz",
"integrity": "sha512-gHMrgrbCgmT4uK5Um5eVDUohuV9lcs95ZUUN9Px2Y0VIfjTzT2wF8Q3Z4fwLFm7c5Z2OXCm53FHoovj6SlOKdg==",
"dependencies": {
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": ">=18.1.0",
"react-dom": ">=18.1.0"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/internal-slot": {
"version": "1.0.7",
"license": "MIT",
@ -36786,6 +36845,11 @@
"url": "https://github.com/sponsors/dmonad"
}
},
"node_modules/libphonenumber-js": {
"version": "1.12.6",
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.6.tgz",
"integrity": "sha512-PJiS4ETaUfCOFLpmtKzAbqZQjCCKVu2OhTV4SVNNE7c2nu/dACvtCqj4L0i/KWNnIgRv7yrILvBj5Lonv5Ncxw=="
},
"node_modules/lie": {
"version": "3.1.1",
"license": "MIT",
@ -41248,6 +41312,14 @@
"framework-utils": "^1.1.0"
}
},
"node_modules/react-currency-input-field": {
"version": "3.10.0",
"resolved": "https://registry.npmjs.org/react-currency-input-field/-/react-currency-input-field-3.10.0.tgz",
"integrity": "sha512-GRmZogHh1e1LrmgXg/fKHSuRLYUnj/c/AumfvfuDMA0UX1mDR6u2NR0fzDemRdq4tNHNLucJeJ2OKCr3ehqyDA==",
"peerDependencies": {
"react": "^16.9.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/react-date-picker": {
"version": "10.6.0",
"license": "MIT",
@ -42035,6 +42107,22 @@
"react-dom": "^16.12.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^20.0.0 || ^21.0.0"
}
},
"node_modules/react-phone-number-input": {
"version": "3.4.12",
"resolved": "https://registry.npmjs.org/react-phone-number-input/-/react-phone-number-input-3.4.12.tgz",
"integrity": "sha512-Raob77KdtLGm49iC6nuOX9qy6Mg16idkgC7Y1mHmvG2WBYoauHpzxYNlfmFskQKeiztrJIwPhPzBhjFwjenNCA==",
"dependencies": {
"classnames": "^2.5.1",
"country-flag-icons": "^1.5.17",
"input-format": "^0.3.10",
"libphonenumber-js": "^1.11.20",
"prop-types": "^15.8.1"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-plotly.js": {
"version": "2.6.0",
"license": "MIT",

View file

@ -33,6 +33,7 @@
"@sentry/react": "^7.100.1",
"@sentry/webpack-plugin": "^2.14.0",
"@tabler/icons-react": "^2.4.0",
"@tanstack/react-table": "^8.20.5",
"@tanstack/react-virtual": "^3.10.8",
"@textea/json-viewer": "^3.3.2",
"@tooljet/plugins": "../plugins",
@ -91,6 +92,7 @@
"react-circular-progressbar": "^2.1.0",
"react-color": "^2.19.3",
"react-copy-to-clipboard": "^5.1.0",
"react-currency-input-field": "^3.10.0",
"react-datepicker": "^7.6.0",
"react-dates": "^21.8.0",
"react-datetime": "^3.2.0",
@ -113,6 +115,7 @@
"react-multi-select-component": "^4.3.4",
"react-pdf": "^6.2.2",
"react-phone-input-2": "^2.15.1",
"react-phone-number-input": "^3.4.12",
"react-plotly.js": "^2.6.0",
"react-qr-reader": "^2.2.1",
"react-rnd": "^10.4.1",
@ -260,4 +263,4 @@
"jsx"
]
}
}
}

View file

@ -18,6 +18,7 @@ export const ConfigHandle = ({
showHandle,
componentType,
visibility,
subContainerIndex,
}) => {
const shouldFreeze = useStore((state) => state.getShouldFreeze());
const componentName = useStore((state) => state.getComponentDefinition(id)?.component?.name || '', shallow);
@ -40,12 +41,13 @@ export const ConfigHandle = ({
const anyComponentHovered = state.getHoveredComponentForGrid() !== '' || state.hoveredComponentBoundaryId !== '';
// If one component is hovered and one is selected, show the handle for the hovered component
return (
isWidgetHovered ||
(showHandle && (!isMultipleComponentsSelected || (isModal && isModalOpen)) && !anyComponentHovered)
(subContainerIndex === 0 || subContainerIndex === null) &&
(isWidgetHovered ||
(showHandle && (!isMultipleComponentsSelected || (isModal && isModalOpen)) && !anyComponentHovered))
);
}, shallow);
let height = visibility === false ? 10 : widgetHeight;
let height = visibility === false ? 10 : widgetHeight;
return (
<div
className={`config-handle ${customClassName}`}
@ -57,7 +59,7 @@ export const ConfigHandle = ({
: position === 'top'
? '-20px'
: `${height - (CONFIG_HANDLE_HEIGHT + BUFFER_HEIGHT)}px`,
visibility: _showHandle ? 'visible' : 'hidden',
visibility: _showHandle || visibility === false ? 'visible' : 'hidden',
left: '-1px',
}}
onClick={(e) => {

View file

@ -5,7 +5,12 @@ import WidgetWrapper from './WidgetWrapper';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import { useDrop } from 'react-dnd';
import { addChildrenWidgetsToParent, addNewWidgetToTheEditor, computeViewerBackgroundColor } from './appCanvasUtils';
import {
addChildrenWidgetsToParent,
addNewWidgetToTheEditor,
computeViewerBackgroundColor,
getSubContainerWidthAfterPadding,
} from './appCanvasUtils';
import {
CANVAS_WIDTHS,
NO_OF_GRIDS,
@ -20,6 +25,7 @@ import NoComponentCanvasContainer from './NoComponentCanvasContainer';
import { RIGHT_SIDE_BAR_TAB } from '../RightSideBar/rightSidebarConstants';
import { isPDFSupported } from '@/_helpers/appUtils';
import toast from 'react-hot-toast';
import useSortedComponents from '../_hooks/useSortedComponents';
//TODO: Revisit the logic of height (dropRef)
@ -103,12 +109,7 @@ export const Container = React.memo(
if (canvasWidth !== undefined) {
if (componentType === 'Listview' && listViewMode == 'grid') return canvasWidth / columns - 2;
if (id === 'canvas') return canvasWidth;
if (componentType === 'Container' || componentType === 'Form') {
return (
canvasWidth - (2 * CONTAINER_FORM_CANVAS_PADDING + 2 * SUBCONTAINER_CANVAS_BORDER_WIDTH + 2 * BOX_PADDING)
);
}
return canvasWidth - 2; // Need to update this 2 to correct value for other subcontainers
return getSubContainerWidthAfterPadding(canvasWidth, componentType, id);
}
return realCanvasRef?.current?.offsetWidth;
}
@ -146,6 +147,8 @@ export const Container = React.memo(
[setLastCanvasClickPosition]
);
const sortedComponents = useSortedComponents(components, currentLayout, id);
return (
<div
// {...(config.COMMENT_FEATURE_ENABLE && showComments && { onClick: handleAddThread })}
@ -197,7 +200,7 @@ export const Container = React.memo(
data-parent-type={id === 'canvas' ? 'canvas' : componentType}
style={{ height: !showEmptyContainer ? '100%' : 'auto' }} //TODO: remove hardcoded height & canvas condition
>
{components.map((id) => (
{sortedComponents.map((id) => (
<WidgetWrapper
id={id}
key={id}

View file

@ -23,8 +23,6 @@ import {
handleDeactivateTargets,
handleActivateNonDraggingComponents,
} from './gridUtils';
import { useAppVersionStore } from '@/_stores/appVersionStore';
import { resolveWidgetFieldValue } from '@/_helpers/utils';
import { dragContextBuilder, getAdjustedDropPosition } from './helpers/dragEnd';
import useStore from '@/AppBuilder/_stores/store';
import './Grid.css';
@ -67,6 +65,9 @@ export default function Grid({ gridWidth, currentLayout }) {
const prevDragParentId = useRef(null);
const newDragParentId = useRef(null);
const [isGroupDragging, setIsGroupDragging] = useState(false);
const checkIfAnyWidgetVisibilityChanged = useStore((state) => state.checkIfAnyWidgetVisibilityChanged(), shallow);
const getExposedValueOfComponent = useStore((state) => state.getExposedValueOfComponent, shallow);
const setReorderContainerChildren = useStore((state) => state.setReorderContainerChildren, shallow);
useEffect(() => {
const selectedSet = new Set(selectedComponents);
@ -318,7 +319,7 @@ export default function Grid({ gridWidth, currentLayout }) {
useEffect(() => {
reloadGrid();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedComponents, openModalWidgetId, boxList, currentLayout]);
}, [selectedComponents, openModalWidgetId, boxList, currentLayout, checkIfAnyWidgetVisibilityChanged]);
const updateNewPosition = (events, parent = null) => {
const posWithParent = {
@ -330,6 +331,8 @@ export default function Grid({ gridWidth, currentLayout }) {
const isComponentVisible = (id) => {
const component = getResolvedComponent(id);
const componentExposedVisibility = getExposedValueOfComponent(id)?.isVisible;
if (componentExposedVisibility === false) return false;
let visibility;
if (isArray(component)) {
visibility = component?.[0]?.properties?.visibility ?? component?.[0]?.styles?.visibility ?? null;
@ -536,6 +539,7 @@ export default function Grid({ gridWidth, currentLayout }) {
})
);
}
setReorderContainerChildren(draggedOverElemId ?? 'canvas');
} catch (error) {
console.error('Error dragging group', error);
}
@ -631,13 +635,13 @@ export default function Grid({ gridWidth, currentLayout }) {
// When clicked on widget boundary/resizer, select the component
setSelectedComponents([e.target.id]);
}
showGridLines();
if (!isComponentVisible(e.target.id)) {
return false;
}
handleActivateNonDraggingComponents();
useGridStore.getState().actions.setResizingComponentId(e.target.id);
e.setMin([gridWidth, GRID_HEIGHT]);
showGridLines();
}}
onResizeEnd={(e) => {
try {
@ -646,10 +650,12 @@ export default function Grid({ gridWidth, currentLayout }) {
return id === e.target.id;
});
hideGridLines();
if (!e.lastEvent) {
return;
}
let _gridWidth = useGridStore.getState().subContainerWidths[currentWidget.component?.parent] || gridWidth;
let width = Math.round(e?.lastEvent?.width / _gridWidth) * _gridWidth;
const height = Math.round(e?.lastEvent?.height / GRID_HEIGHT) * GRID_HEIGHT;
const currentWidth = currentWidget.width * _gridWidth;
const diffWidth = e.lastEvent?.width - currentWidth;
const diffHeight = e.lastEvent?.height - currentWidget?.height;
@ -696,6 +702,7 @@ export default function Grid({ gridWidth, currentLayout }) {
resizeData.gw = _gridWidth;
}
handleResizeStop([resizeData]);
setReorderContainerChildren(currentWidget?.parent ?? 'canvas');
} catch (error) {
console.error('ResizeEnd error ->', error);
}
@ -775,6 +782,11 @@ export default function Grid({ gridWidth, currentLayout }) {
ev.target.style.transform = `translate(${posX}px, ${posY}px)`;
});
}
const groupParentId =
boxList.find(({ id }) => id === groupResizeDataRef.current[0].target.id)?.parent ?? 'canvas';
setReorderContainerChildren(groupParentId);
groupResizeDataRef.current = [];
reloadGrid();
} catch (error) {
@ -841,6 +853,8 @@ export default function Grid({ gridWidth, currentLayout }) {
useStore.getState().setDraggingComponentId(null);
isDraggingRef.current = false;
}
const oldParentId = boxList.find((b) => b.id === e.target.id)?.parent ?? 'canvas';
prevDragParentId.current = null;
newDragParentId.current = null;
setDragParentId(null);
@ -872,7 +886,6 @@ export default function Grid({ gridWidth, currentLayout }) {
left = dragged.left * sourcegridWidth;
top = dragged.top;
!isModalToCanvas ??
toast.error(`${dragged.widgetType} is not compatible as a child component of ${target.widgetType}`);
}
@ -880,6 +893,12 @@ export default function Grid({ gridWidth, currentLayout }) {
// Apply transform for smooth transition
e.target.style.transform = `translate(${left}px, ${top}px)`;
// Force reordering of conatiner if the parent has not changed
const newParentId = target.slotId === 'real-canvas' ? 'canvas' : target.slotId;
if (oldParentId === newParentId) {
setReorderContainerChildren(newParentId);
}
// Select the dragged component after drop
setTimeout(() => setSelectedComponents([dragged.id]));
} catch (error) {

View file

@ -7,10 +7,15 @@ import { renderTooltip } from '@/_helpers/appUtils';
import { useTranslation } from 'react-i18next';
import ErrorBoundary from '@/_ui/ErrorBoundary';
import { BOX_PADDING } from './appCanvasConstants';
const shouldAddBoxShadowAndVisibility = [
'Table',
'TextInput',
'TextArea',
'PasswordInput',
'EmailInput',
'PhoneInput',
'CurrencyInput',
'NumberInput',
'Text',
'Checkbox',
@ -25,6 +30,7 @@ const shouldAddBoxShadowAndVisibility = [
'DaterangePicker',
'DatePickerV2',
'TimePicker',
'Link',
];
const RenderWidget = ({
@ -86,6 +92,7 @@ const RenderWidget = ({
...{ widgetValue: value },
...{ validationObject: unResolvedValidation },
customResolveObjects: customResolvables,
componentType,
}),
// eslint-disable-next-line react-hooks/exhaustive-deps
[validateWidget, customResolvables, unResolvedValidation, resolvedValidation]

View file

@ -37,6 +37,8 @@ const WidgetWrapper = memo(
});
const visibility = useStore((state) => {
const component = state.getResolvedComponent(id, subContainerIndex);
const componentExposedVisibility = state.getExposedValueOfComponent(id)?.isVisible;
if (componentExposedVisibility === false) return false;
if (component?.properties?.visibility === false || component?.styles?.visibility === false) return false;
return true;
});
@ -52,7 +54,7 @@ const WidgetWrapper = memo(
height: visibility === false ? '10px' : `${height}px`,
transform: `translate(${layoutData.left * gridWidth}px, ${layoutData.top}px)`,
WebkitFontSmoothing: 'antialiased',
border: visibility === false ? `1px solid var(--border-default)` : 'none',
border: visibility === false && mode === 'edit' ? `1px solid var(--border-default)` : 'none',
};
if (!componentType) return null;
@ -91,6 +93,7 @@ const WidgetWrapper = memo(
showHandle={isWidgetActive}
componentType={componentType}
visibility={visibility}
subContainerIndex={subContainerIndex}
/>
)}
<RenderWidget

View file

@ -23,3 +23,7 @@ export const CONTAINER_FORM_CANVAS_PADDING = 7;
export const SUBCONTAINER_CANVAS_BORDER_WIDTH = 1;
export const BOX_PADDING = 2;
export const TAB_CANVAS_PADDING = 7.5;
export const MODAL_CANVAS_PADDING = 5;

View file

@ -6,7 +6,16 @@ import { toast } from 'react-hot-toast';
import _, { debounce } from 'lodash';
import { useGridStore } from '@/_stores/gridStore';
import { findHighestLevelofSelection } from './Grid/gridUtils';
import { CANVAS_WIDTHS, NO_OF_GRIDS, WIDGETS_WITH_DEFAULT_CHILDREN } from './appCanvasConstants';
import {
CANVAS_WIDTHS,
NO_OF_GRIDS,
WIDGETS_WITH_DEFAULT_CHILDREN,
CONTAINER_FORM_CANVAS_PADDING,
SUBCONTAINER_CANVAS_BORDER_WIDTH,
BOX_PADDING,
TAB_CANVAS_PADDING,
MODAL_CANVAS_PADDING,
} from './appCanvasConstants';
export function snapToGrid(canvasWidth, x, y) {
const gridX = canvasWidth / 43;
@ -40,8 +49,16 @@ export const addNewWidgetToTheEditor = (componentType, eventMonitorObject, curre
left = Math.round(left / gridWidth);
// Adjust widget width based on the dropping canvas width
const mainCanvasWidth = useGridStore.getState().subContainerWidths['canvas'];
const width = Math.round((defaultWidth * mainCanvasWidth) / gridWidth);
let width = Math.round((defaultWidth * mainCanvasWidth) / gridWidth);
// Ensure minimum width
width = Math.max(width, 1);
// Adjust position and width if exceeding grid bounds
if (width + left > NO_OF_GRIDS) {
left = Math.max(0, NO_OF_GRIDS - width);
width = Math.min(width, NO_OF_GRIDS);
}
if (currentLayout === 'mobile') {
componentData.definition.others.showOnDesktop.value = `{{false}}`;
componentData.definition.others.showOnMobile.value = `{{true}}`;
@ -248,6 +265,12 @@ const getSelectedText = () => {
// TODO: Move this function to componentSlice
export const copyComponents = ({ isCut = false, isCloning = false }) => {
const selectedText = window.getSelection()?.toString().trim();
if (selectedText) {
navigator.clipboard.writeText(selectedText);
return;
}
const selectedComponents = useStore.getState().getSelectedComponentsDefinition();
if (selectedComponents.length < 1) return getSelectedText();
const allComponents = useStore.getState().getCurrentPageComponents();
@ -498,7 +521,7 @@ export function pasteComponents(targetParentId, copiedComponentObj) {
targetParentId === key ||
(components?.[key]?.component.component === 'Tabs' &&
targetParentId?.split('-')?.slice(0, -1)?.join('-') === key) ||
(['Container', 'Form', 'Modal'].includes(components?.[key]?.component.component) &&
(['Container', 'Form', 'ModalV2'].includes(components?.[key]?.component.component) &&
['header', 'footer'].some((section) => targetParentId.includes(section)))
)
) {
@ -510,6 +533,7 @@ export function pasteComponents(targetParentId, copiedComponentObj) {
}
pastedComponents.forEach((component) => {
component = deepClone(component);
const newComponentId = isCut ? component.id : uuidv4();
const componentName = computeComponentName(component.component.component, {
...components,
@ -550,15 +574,28 @@ export function pasteComponents(targetParentId, copiedComponentObj) {
componentData.definition.others.showOnMobile.value = currentLayout === 'mobile' ? `{{true}}` : `{{false}}`;
// Adjust width if parent changed
let width = component.layouts.desktop.width;
let width = component.layouts[currentLayout].width;
if (targetParentId !== component.component?.parent) {
const containerWidth = useGridStore.getState().subContainerWidths[targetParentId || 'canvas'];
const oldContainerWidth = useGridStore.getState().subContainerWidths[component?.component?.parent || 'canvas'];
width = Math.round((width * oldContainerWidth) / containerWidth);
// Ensure minimum width
width = Math.max(width, 1);
// Adjust position and width if exceeding grid bounds
if (width + component.layouts[currentLayout].left > NO_OF_GRIDS) {
component.layouts[currentLayout].left = Math.max(0, NO_OF_GRIDS - width);
width = Math.min(width, NO_OF_GRIDS);
}
}
component.layouts[currentLayout].width = width;
component.layouts[currentLayout] = {
...component.layouts[currentLayout],
width,
};
const newComponent = {
component: {
...componentData,
@ -706,3 +743,25 @@ export const getSubContainerIdWithSlots = (parentId) => {
}
return cleanParentId;
};
export const getSubContainerWidthAfterPadding = (canvasWidth, componentType, componentId) => {
let padding = 2; //Need to update this 2 to correct value for other subcontainers
if (componentType === 'Container' || componentType === 'Form') {
padding = 2 * CONTAINER_FORM_CANVAS_PADDING + 2 * SUBCONTAINER_CANVAS_BORDER_WIDTH + 2 * BOX_PADDING;
}
if (componentType === 'Tabs') {
padding = 2 * TAB_CANVAS_PADDING + 2 * SUBCONTAINER_CANVAS_BORDER_WIDTH + 2 * BOX_PADDING;
}
if (componentType === 'ModalV2') {
const isModalHeader = componentId?.includes('header');
if (isModalHeader) {
const isModalHeaderCloseBtnEnabled = !useStore.getState().getResolvedComponent(componentId)?.properties
?.hideCloseButton;
console.log('isModalHeaderCloseBtnEnabled', isModalHeaderCloseBtnEnabled);
padding = 2 * (MODAL_CANVAS_PADDING + (isModalHeaderCloseBtnEnabled ? 56 : 0));
} else {
padding = 2 * MODAL_CANVAS_PADDING;
}
}
return canvasWidth - padding;
};

View file

@ -1,5 +1,5 @@
.active-target {
outline: 1px solid #4af;
outline: 1px solid #4af !important;
}
.main-editor-canvas .widget-target:not(:has(.widget-target:hover)):hover {

View file

@ -9,12 +9,16 @@ export const Color = ({
value,
onChange,
pickerStyle = {},
colorMap = {},
cyLabel,
asBoxShadowPopover = true,
meta,
outerWidth = '142px',
component,
styleDefinition,
componentType = 'color',
CustomOptionList = () => {},
SwatchesToggle = () => {},
}) => {
value = component == 'Button' ? computeColor(styleDefinition, value, meta) : value;
const [showPicker, setShowPicker] = useState(false);
@ -68,9 +72,11 @@ export const Color = ({
const ColorPicker = () => {
return (
<>
{showPicker && (
{SwatchesToggle()}
{showPicker && componentType === 'swatches' && CustomOptionList()}
{showPicker && componentType === 'color' && (
<div>
<div style={coverStyles} onClick={() => setShowPicker(false)} />
{/* <div style={coverStyles} onClick={() => setShowPicker(false)} /> */}
<div style={pickerStyle}>
<SketchPicker
onFocus={() => setShowPicker(true)}
@ -107,7 +113,9 @@ export const Color = ({
></div>
<div className="col tj-text-xsm p-0 color-slate12" data-cy={`${String(cyLabel)}-value`}>
{value}
{colorMap?.[value]
? 'Brand/' + colorMap?.[value]?.charAt(0).toUpperCase() + colorMap?.[value]?.slice(1)
: value}
</div>
</div>
);

View file

@ -74,6 +74,7 @@ export function getSuggestionKeys(refState) {
'setVariable',
'getVariable',
'unSetVariable',
'unsetAllVariables',
'showAlert',
'logout',
'showModal',
@ -85,6 +86,7 @@ export function getSuggestionKeys(refState) {
'setPageVariable',
'getPageVariable',
'unsetPageVariable',
'unsetAllPageVariables',
'switchPage',
];

View file

@ -18,9 +18,11 @@ import { NumberInput } from '../CodeBuilder/Elements/NumberInput';
import { Datepicker } from '../CodeBuilder/Elements/Datepicker';
import TableRowHeightInput from '../CodeBuilder/Elements/TableRowHeightInput';
import { TimePicker } from '../CodeBuilder/Elements/TimePicker';
import { ColorSwatches } from '@/modules/Appbuilder/components';
const AllElements = {
Color,
ColorSwatches,
Json,
Toggle,
Select,

View file

@ -294,13 +294,9 @@ const PreviewContainer = ({
...restProps
}) => {
const { validationSchema, isWorkspaceVariable, errorStateActive, previewPlacement, validationFn } = restProps;
const [errorMessage, setErrorMessage] = useState('');
const typeofError = getCurrentNodeType(errorMessage);
const errorMsg = typeofError === 'Array' ? errorMessage[0] : errorMessage;
const darkMode = localStorage.getItem('darkMode') === 'true';
const popover = (
<Popover
@ -423,10 +419,12 @@ const PreviewContainer = ({
<>
{!isPortalOpen && (
<Overlay
placement="left"
placement={previewPlacement || 'left'}
{...(previewRef?.current ? { target: previewRef.current } : {})}
show={showPreview}
rootClose
shouldUpdatePosition={true}
container={document.body}
popperConfig={{
modifiers: [
{
@ -441,6 +439,7 @@ const PreviewContainer = ({
{
name: 'preventOverflow',
options: {
enabled: true,
boundary: 'viewport',
altAxis: true,
tether: false,
@ -449,10 +448,17 @@ const PreviewContainer = ({
{
name: 'offset',
options: {
offset: [33, 15],
offset: [0, 3],
},
},
],
onFirstUpdate: (state) => {
// Force position update on first render
// This is done to avoid scroll issue
if (state.elements.popper) {
state.elements.popper.style.position = 'fixed';
}
},
}}
>
{(props) => React.cloneElement(popover, props)}

View file

@ -1,5 +1,5 @@
/* eslint-disable import/no-unresolved */
import React, { useContext, useEffect, useMemo, useRef, useState } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import { PreviewBox } from './PreviewBox';
import { ToolTip } from '@/Editor/Inspector/Elements/Components/ToolTip';
import { useTranslation } from 'react-i18next';
@ -31,6 +31,7 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r
const [currentValue, setCurrentValue] = useState('');
const [errorStateActive, setErrorStateActive] = useState(false);
const [cursorInsidePreview, setCursorInsidePreview] = useState(false);
const [showSuggestions, setShowSuggestions] = useState(true);
const validationFn = restProps?.validationFn;
const componentDefinition = useStore((state) => state.getComponentDefinition(componentId), shallow);
const parentId = componentDefinition?.component?.parent;
@ -38,6 +39,30 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r
const customVariables = customResolvables?.[parentId]?.[0] || {};
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
if (entry.intersectionRatio < 1) {
setShowPreview(false);
setShowSuggestions(false);
} else {
setShowSuggestions(true);
}
},
{ root: null, threshold: [1] } // Fires when any part of the element is out of view
);
if (wrapperRef.current) {
observer.observe(wrapperRef.current);
}
return () => {
if (wrapperRef.current) {
observer.unobserve(wrapperRef.current);
}
};
}, []);
const isPreviewFocused = useRef(false);
const wrapperRef = useRef(null);
@ -136,6 +161,7 @@ const SingleLineCodeEditor = ({ componentName, fieldMeta = {}, componentId, ...r
componentName={componentName}
setShowPreview={setShowPreview}
showPreview={showPreview}
showSuggestions={showSuggestions}
{...restProps}
/>
</div>
@ -168,6 +194,7 @@ const EditorInput = ({
previewRef,
setShowPreview,
onInputChange,
showSuggestions,
}) => {
const getSuggestions = useStore((state) => state.getSuggestions, shallow);
function autoCompleteExtensionConfig(context) {
@ -223,7 +250,7 @@ const EditorInput = ({
defaultKeymap: true,
positionInfo: () => {
return {
class: 'cm-completionInfo-top cm-custom-completion-info',
class: 'cm-completionInfo-top cm-custom-completion-info cm-custom-singleline-completion-info',
};
},
maxRenderedOptions: 10,
@ -286,7 +313,7 @@ const EditorInput = ({
const isInsideQueryPane = !!currentEditorHeightRef?.current?.closest('.query-details');
const showLineNumbers = lang == 'jsx' || type === 'extendedSingleLine' || false;
const customClassNames = cx('codehinter-input', {
const customClassNames = cx('codehinter-input single-line-codehinter-input', {
'border-danger': error,
focused: isFocused,
'focus-box-shadow-active': firstTimeFocus,
@ -339,15 +366,6 @@ const EditorInput = ({
data-cy={`${cyLabel.replace(/_/g, '-')}-input-field`}
>
{/* sticky element to position the preview box correctly on top without flowing out of container */}
<div
style={{
position: 'sticky',
top: 0,
left: 0,
zIndex: 1000,
}}
ref={previewRef}
></div>
{usePortalEditor && (
<CodeHinter.PopupIcon
callback={handleTogglePopupExapand}
@ -372,39 +390,55 @@ const EditorInput = ({
callgpt={null}
>
<ErrorBoundary>
<CodeMirror
value={currentValue}
placeholder={placeholder}
height={isInsideQueryPane ? '100%' : showLineNumbers ? '400px' : '100%'}
width="100%"
extensions={[
javascript({ jsx: lang === 'jsx' }),
autoCompleteConfig,
keymap.of([...customKeyMaps]),
customTabKeymap,
]}
onChange={(val) => {
setFirstTimeFocus(false);
handleOnChange(val);
onInputChange && onInputChange(val);
<div
style={{
position: 'relative',
top: 0,
left: 0,
width: '100%',
height: '100%',
}}
basicSetup={{
lineNumbers: showLineNumbers,
syntaxHighlighting: true,
bracketMatching: true,
foldGutter: false,
highlightActiveLine: false,
autocompletion: true,
completionKeymap: true,
searchKeymap: false,
}}
onMouseDown={() => handleFocus()}
onBlur={() => handleOnBlur()}
className={customClassNames}
theme={theme}
indentWithTab={false}
readOnly={disabled}
/>
className="check-here"
ref={previewRef}
>
<CodeMirror
value={currentValue}
placeholder={placeholder}
height={isInsideQueryPane ? '100%' : showLineNumbers ? '400px' : '100%'}
width="100%"
extensions={
showSuggestions
? [
javascript({ jsx: lang === 'jsx' }),
autoCompleteConfig,
keymap.of([...customKeyMaps]),
customTabKeymap,
]
: [javascript({ jsx: lang === 'jsx' })]
}
onChange={(val) => {
setFirstTimeFocus(false);
handleOnChange(val);
onInputChange && onInputChange(val);
}}
basicSetup={{
lineNumbers: showLineNumbers,
syntaxHighlighting: true,
bracketMatching: true,
foldGutter: false,
highlightActiveLine: false,
autocompletion: showSuggestions,
completionKeymap: true,
searchKeymap: false,
}}
onMouseDown={() => handleFocus()}
onBlur={() => handleOnBlur()}
className={customClassNames}
theme={theme}
indentWithTab={false}
readOnly={disabled}
/>
</div>
</ErrorBoundary>
</CodeHinter.Portal>
</div>

View file

@ -655,6 +655,11 @@
background-color: #F28F2D !important;
}
.cm-custom-singleline-completion-info {
display: none;
}
.tjdb-hinter-portal{
.cm-theme{
height: 100% ;

View file

@ -337,6 +337,7 @@ export const FxParamTypeMapping = Object.freeze({
color: 'Color',
json: 'Json',
code: 'Code',
colorSwatches: 'ColorSwatches',
toggle: 'Toggle',
select: 'Select',
alignButtons: 'AlignButtons',

View file

@ -3,6 +3,7 @@ import { Button } from '@/components/ui/Button/Button';
import ExportAppModal from '@/HomePage/ExportAppModal';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import cx from 'classnames';
const AppExport = ({ darkMode }) => {
const { app } = useStore(
@ -28,22 +29,20 @@ const AppExport = ({ darkMode }) => {
darkMode={darkMode}
/>
)}
<div className="d-flex align-items-center global-popover-div-wrap mb-3">
<p className="tj-text-xsm color-slate12 w-full m-auto">Export app</p>
<div>
<Button
fill="var(--indigo9)"
leadingIcon="fileupload"
className="tw-w-[158px] !tw-text-[var(--indigo9)] !tw-bg-[var(--indigo3)] hover:!tw-text-[var(--indigo10)] hover:!tw-bg-[var(--indigo4)] active:!tw-text-[var(--indigo9)] active:!tw-bg-[var(--indigo5) focus-visible:!tw-text-[var(--indigo10)] focus-visible:!tw-bg-[var(--indigo3)]"
onClick={() => {
setIsExportingApp(true);
document.getElementById('maintenance-app-modal').click();
}}
data-cy="button-user-status-change"
>
Export this app
</Button>
</div>
<div className={cx({ 'dark-theme': darkMode })}>
<Button
fill="rgb(172, 178, 185)"
leadingIcon="fileupload"
variant="tertiary"
className={cx('app-export-btn')}
onClick={() => {
setIsExportingApp(true);
document.getElementById('maintenance-app-modal').click();
}}
data-cy="button-user-status-change"
>
Export app
</Button>
</div>
{/* {isExportingApp && <ExportAppModal app={app} setIsExportingApp={toggleExportingApp} darkMode={darkMode} />} */}
</>

View file

@ -34,7 +34,7 @@ const AppModeToggle = ({ darkMode }) => {
exposedTheme = darkMode ? 'dark' : 'light';
}
onAppModeChange({ appMode: value });
globalSettingsChanged({ theme: { name: exposedTheme } });
// globalSettingsChanged({ theme: { name: exposedTheme } });
setResolvedGlobals('theme', { name: exposedTheme });
}}
defaultValue={appMode}

View file

@ -13,20 +13,11 @@ import { Confirm } from '@/Editor/Viewer/Confirm';
import { shallow } from 'zustand/shallow';
const CanvasSettings = ({ darkMode }) => {
const {
globalSettings,
globalSettingsChanged,
isMaintenanceOn,
toggleAppMaintenance,
resolveOthers,
getCanvasBackgroundColor,
} = useStore(
const { globalSettings, globalSettingsChanged, resolveOthers, getCanvasBackgroundColor } = useStore(
(state) => ({
globalSettings: state.globalSettings,
updateGlobalSettings: state.updateGlobalSettings,
isMaintenanceOn: state.app.isMaintenanceOn,
globalSettingsChanged: state.globalSettingsChanged,
toggleAppMaintenance: state.toggleAppMaintenance,
resolveOthers: state.resolveOthers,
getCanvasBackgroundColor: state.getCanvasBackgroundColor,
}),
@ -73,43 +64,10 @@ const CanvasSettings = ({ darkMode }) => {
boxShadow: showPicker && '0px 0px 0px 1px #C6D4F9',
};
const { hideHeader, canvasMaxWidth, canvasMaxWidthType, backgroundFxQuery } = globalSettings ?? {};
const { canvasMaxWidth, canvasMaxWidthType, backgroundFxQuery } = globalSettings ?? {};
return (
<>
<Confirm
show={showConfirmation}
message={
isMaintenanceOn
? 'Users will now be able to launch the released version of this app, do you wish to continue?'
: 'Users will not be able to launch the app until maintenance mode is turned off, do you wish to continue?'
}
onConfirm={() => toggleAppMaintenance()}
onCancel={() => setConfirmationShow(false)}
darkMode={darkMode}
/>
<div className="tw-flex tw-mb-3">
<SwitchComponent
align="right"
label="Hide header for launched apps"
size="default"
checked={hideHeader}
onCheckedChange={(e) => globalSettingsChanged({ hideHeader: e })}
data-cy={`toggle-hide-header-for-launched-apps`}
className="tw-w-full"
/>
</div>
<div className="tw-flex tw-mb-3">
<SwitchComponent
align="right"
label="Maintenance mode"
size="default"
checked={isMaintenanceOn}
onCheckedChange={() => setConfirmationShow(true)}
data-cy={`toggle-maintenance-mode`}
className="tw-w-full"
/>
</div>
<div className="d-flex mb-3">
<span data-cy={`label-max-canvas-width`} className="w-full m-auto">
{t('leftSidebar.Settings.maxWidthOfCanvas', 'Max width of canvas')}

View file

@ -0,0 +1,31 @@
import React from 'react';
import SwitchComponent from '@/components/ui/Switch/Index';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
const HideHeaderToggle = () => {
const { globalSettings, globalSettingsChanged } = useStore(
(state) => ({
globalSettings: state.globalSettings,
globalSettingsChanged: state.globalSettingsChanged,
}),
shallow
);
const { hideHeader } = globalSettings || {};
return (
<div className="tw-flex tw-mb-3">
<SwitchComponent
align="right"
label="Hide header for launched apps"
size="default"
checked={hideHeader}
onCheckedChange={(e) => globalSettingsChanged({ hideHeader: e })}
data-cy={`toggle-hide-header-for-launched-apps`}
className="tw-w-full"
/>
</div>
);
};
export default HideHeaderToggle;

View file

@ -0,0 +1,45 @@
import React, { useState } from 'react';
import useStore from '@/AppBuilder/_stores/store';
import SwitchComponent from '@/components/ui/Switch/Index';
import { shallow } from 'zustand/shallow';
import { Confirm } from '@/Editor/Viewer/Confirm';
const MaintenanceMode = ({ darkMode }) => {
const [showConfirmation, setConfirmationShow] = useState(false);
const { isMaintenanceOn, toggleAppMaintenance } = useStore(
(state) => ({
isMaintenanceOn: state.app.isMaintenanceOn,
toggleAppMaintenance: state.toggleAppMaintenance,
}),
shallow
);
return (
<>
<Confirm
show={showConfirmation}
message={
isMaintenanceOn
? 'Users will now be able to launch the released version of this app, do you wish to continue?'
: 'Users will not be able to launch the app until maintenance mode is turned off, do you wish to continue?'
}
onConfirm={() => toggleAppMaintenance()}
onCancel={() => setConfirmationShow(false)}
darkMode={darkMode}
/>
<div className="tw-flex tw-mb-3">
<SwitchComponent
align="right"
label="Maintenance mode"
size="default"
checked={isMaintenanceOn}
onCheckedChange={() => setConfirmationShow(true)}
data-cy={`toggle-maintenance-mode`}
className="tw-w-full"
/>
</div>
</>
);
};
export default MaintenanceMode;

View file

@ -132,7 +132,11 @@ const SlugInput = () => {
</div>
)}
</div>
<label className="label label-success label-updated" data-cy="app-link-success-label">
<label
className="label label-success label-updated"
data-cy="app-link-success-label"
style={{ padding: '0px' }}
>
{isSlugUpdated ? `Link updated successfully!` : ''}
</label>
</div>

View file

@ -7,6 +7,9 @@ import AppExport from './AppExport';
import useStore from '@/AppBuilder/_stores/store';
import { shallow } from 'zustand/shallow';
import AppModeToggle from './AppModeToggle';
import { ThemeSelect } from '@/modules/Appbuilder/components';
import MaintenanceMode from './MaintenanceMode';
import HideHeaderToggle from './HideHeaderToggle';
const GlobalSettings = ({ darkMode }) => {
const shouldFreeze = useStore((state) => state.getShouldFreeze());
@ -16,16 +19,27 @@ const GlobalSettings = ({ darkMode }) => {
<div>
<div bsPrefix="global-settings-popover" className="global-settings-panel">
<HeaderSection>
<HeaderSection.PanelHeader title="Global settings" />
<HeaderSection.PanelHeader title="Global settings">
<div className="d-flex w-100 justify-content-end">
<AppExport darkMode={darkMode} />
</div>
</HeaderSection.PanelHeader>
</HeaderSection>
<div className="card-body">
<div className="card-body" style={{ paddingBottom: '0px' }}>
<SlugInput />
</div>
<div style={{ padding: '12px 16px' }} className={cx({ disabled: shouldFreeze })}>
<MaintenanceMode darkMode={darkMode} />
<HideHeaderToggle darkMode={darkMode} />
</div>
<div className={cx({ 'dark-theme': darkMode })}>
<span className="canvas-styles-header">Canvas Styles</span>
</div>
<div style={{ padding: '12px 16px' }} className={cx({ disabled: shouldFreeze })}>
<div className="tj-text-xsm color-slate12 ">
<CanvasSettings darkMode={darkMode} />
<AppModeToggle darkMode={darkMode} />
<AppExport darkMode={darkMode} />
<ThemeSelect darkMode={darkMode} />
</div>
</div>
</div>

View file

@ -34,6 +34,7 @@ export const BaseLeftSidebar = ({
resetUnreadErrorCount,
toggleLeftSidebar,
isSidebarOpen,
isDraggingQueryPane,
] = useStore(
(state) => [
state.isLeftSideBarPinned,
@ -46,6 +47,7 @@ export const BaseLeftSidebar = ({
state.debugger.resetUnreadErrorCount,
state.toggleLeftSidebar,
state.isSidebarOpen,
state.queryPanel.isDraggingQueryPane,
],
shallow
);
@ -68,11 +70,15 @@ export const BaseLeftSidebar = ({
};
useEffect(() => {
setPopoverContentHeight(
((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100
);
if (!isDraggingQueryPane) {
setPopoverContentHeight(
((window.innerHeight - (queryPanelHeight == 0 ? 40 : queryPanelHeight) - 45) / window.innerHeight) * 100
);
} else {
setPopoverContentHeight(100);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [queryPanelHeight]);
}, [queryPanelHeight, isDraggingQueryPane]);
const renderPopoverContent = () => {
if (selectedSidebarItem === null || !isSidebarOpen) return null;

View file

@ -4,6 +4,7 @@ import cx from 'classnames';
import PlusRectangle from '@/_ui/Icon/solidIcons/PlusRectangle';
import Remove from '@/_ui/Icon/bulkIcons/Remove';
import ParameterForm from './ParameterForm';
import usePopoverObserver from '@/AppBuilder/_hooks/usePopoverObserver';
const ParameterDetails = ({ darkMode, onSubmit, isEdit, name, defaultValue, onRemove, otherParams }) => {
const [showModal, setShowModal] = useState(false);
@ -47,6 +48,17 @@ const ParameterDetails = ({ darkMode, onSubmit, isEdit, name, defaultValue, onRe
}
};
usePopoverObserver(
document.getElementsByClassName('query-details')[0],
isEdit
? document.getElementById(`query-param-${String(name).toLowerCase()}`)
: document.getElementById('runjs-param-add-btn'),
document.getElementById('parameter-form-popover'),
showModal,
() => setShowModal(true),
closeMenu
);
return (
<OverlayTrigger
trigger="click"

View file

@ -1,4 +1,4 @@
import React, { useState, forwardRef, useRef, useEffect } from 'react';
import React, { useState, forwardRef, useRef, useEffect, useCallback } from 'react';
import RenameIcon from '../Icons/RenameIcon';
import Eye1 from '@/_ui/Icon/solidIcons/Eye1';
import Play from '@/_ui/Icon/solidIcons/Play';
@ -13,6 +13,7 @@ import { decodeEntities } from '@/_helpers/utils';
import { canDeleteDataSource, canReadDataSource, canUpdateDataSource } from '@/_helpers';
import useStore from '@/AppBuilder/_stores/store';
import { useModuleId } from '@/AppBuilder/_contexts/ModuleContext';
import { debounce } from 'lodash';
export const QueryManagerHeader = forwardRef(({ darkMode, setActiveTab, activeTab }, ref) => {
const moduleId = useModuleId();
@ -166,16 +167,17 @@ const NameInput = ({ onInput, value, darkMode, isDiabled, selectedQuery }) => {
}
}, [isFocused]);
const debouncedHandleInput = useCallback(
debounce((newName) => {
onInput(newName);
}, 300),
[onInput]
);
const handleChange = (event) => {
const sanitizedValue = event.target.value.replace(/[ \t&]/g, '');
setName(sanitizedValue);
};
const handleInput = (newName) => {
const result = onInput(newName);
if (!result) {
setName(value);
}
debouncedHandleInput(sanitizedValue);
};
return (
@ -200,12 +202,12 @@ const NameInput = ({ onInput, value, darkMode, isDiabled, selectedQuery }) => {
event.persist();
if (event.keyCode === 13) {
setIsFocused(false);
handleInput(event.target.value);
debouncedHandleInput(event.target.value);
}
}}
onBlur={({ target }) => {
setIsFocused(false);
handleInput(target.value);
debouncedHandleInput(target.value);
}}
/>
) : (

View file

@ -108,7 +108,8 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende
const [codeEditorKey, setCodeEditorKey] = useState(uuidv4());
const [state, setState] = useState({
...defaultValue,
[options.transformationLanguage ?? 'javascript']: options?.transformation,
...(options?.transformation ? { [options.transformationLanguage ?? 'javascript']: options?.transformation } : {}),
...options?.transformations,
});
const { t } = useTranslation();
@ -119,7 +120,6 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende
useEffect(() => {
if (lang !== (options.transformationLanguage ?? 'javascript')) {
changeOption('transformationLanguage', lang);
changeOption('transformation', state[lang]);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [lang]);
@ -127,20 +127,24 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende
useEffect(() => {
if (prevQueryId.current === queryId) {
lang !== (options.transformationLanguage ?? 'javascript') && changeOption('transformationLanguage', lang);
setState({ ...state, [lang]: options.transformation ?? state[lang] ?? defaultValue[lang] });
setState((prevState) => {
return {
...prevState,
...(options?.transformation
? { [options.transformationLanguage ?? 'javascript']: options?.transformation }
: {}),
...options?.transformations,
};
});
}
prevQueryId.current = queryId;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [JSON.stringify(options.transformation)]);
}, [JSON.stringify(options?.transformation || {}), JSON.stringify(options.transformations)]);
useEffect(() => {
if (selectedQueryId !== queryId) {
const nonLangdefaultCode = getNonActiveTransformations(options?.transformationLanguage ?? 'javascript');
const finalState = _.merge(
{},
{ [options?.transformationLanguage ?? lang]: options.transformation ?? defaultValue[lang] },
nonLangdefaultCode
);
const olderTransformation = options?.transformation ? { [lang]: options?.transformation } : {};
const finalState = _.merge({}, defaultValue, olderTransformation, options?.transformations);
setState(finalState);
}
@ -206,8 +210,6 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende
activeKey={lang}
onSelect={(value) => {
setLang(value);
changeOption('transformationLanguage', value);
changeOption('transformation', state[value]);
}}
defaultActiveKey="javascript"
>
@ -250,7 +252,7 @@ export const Transformation = ({ changeOption, options, darkMode, queryId, rende
height={400}
className="query-hinter"
onChange={(value) => {
changeOption('transformation', value);
changeOption('transformations', { ...state, [lang]: value });
}}
renderCopilot={renderCopilot}
componentName={`transformation`}

View file

@ -30,7 +30,7 @@ export default ({
return (
<>
<div className="row-container query-manager-border-color" key={index}>
<div className="fields-container mb-1">
<div className="fields-container mb-1 restapi-key-value">
<div className="field col-4 rounded-start rest-api-codehinter-key-field">
<CodeHinter
type="basic"
@ -52,7 +52,7 @@ export default ({
/>
</div>
<button
className={`d-flex justify-content-center align-items-center delete-field-option bg-transparent border-0 rounded-0 border-top border-bottom border-end rounded-end ${
className={`d-flex justify-content-center align-items-center delete-field-option bg-transparent border-0 rounded-0 border-top border-bottom border-end rounded-end qm-delete-btn ${
darkMode ? 'delete-field-option-dark' : ''
}`}
role="button"

View file

@ -9,6 +9,7 @@ import Remove from '@/_ui/Icon/bulkIcons/Remove';
import { v4 as uuidv4 } from 'uuid';
import { isEmpty } from 'lodash';
import { ToolTip } from '@/_components/ToolTip';
import usePopoverObserver from '@/AppBuilder/_hooks/usePopoverObserver';
const DropDownSelect = ({
darkMode,
@ -130,6 +131,15 @@ const DropDownSelect = ({
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selected]);
usePopoverObserver(
document.getElementsByClassName('query-details')[0],
document.getElementById(popoverBtnId.current),
document.getElementById(popoverId.current),
showMenu,
() => setShowMenu(true),
() => setShowMenu(false)
);
function checkElementPosition() {
if (isForeignKeyInEditCell) {
return 'bottom-start';
@ -298,7 +308,7 @@ const DropDownSelect = ({
</p>
</div>
) : (
<div className={`col-auto ${buttonClasses}`} id={popoverBtnId.current}>
<div className={`col-auto ${buttonClasses} h-100`} id={popoverBtnId.current}>
<ButtonSolid
size="sm"
variant="tertiary"
@ -322,6 +332,8 @@ const DropDownSelect = ({
},
'gap-0',
'w-100',
'h-100',
'align-items-start',
'rounded-0',
'position-relative',
'font-weight-normal',

View file

@ -645,10 +645,9 @@ const JoinOn = ({
</div>
{index > 0 && (
<ButtonSolid
customStyles={{ height: '30px' }}
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border border-start-0 rounded-end"
className="px-1 rounded-0 border border-start-0 rounded-en qm-delete-btn"
onClick={onRemove}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -340,10 +340,7 @@ const JsonBfieldsForSelect = ({ selectedJsonbColumns, handleJSonChange, table })
<ButtonSolid
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end"
customStyles={{
height: '30px',
}}
className="px-1 rounded-0 border rounded-end qm-delete-btn"
onClick={() => handleRemove(colDetails.id, colDetails.name, colDetails.table)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -164,10 +164,7 @@ export default function JoinSort({ darkMode }) {
<ButtonSolid
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end"
customStyles={{
height: '30px',
}}
className="px-1 rounded-0 border rounded-end qm-delete-btn"
onClick={() => setJoinOrderByOptions(joinOrderByOptions.filter((opt, idx) => idx !== i))}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -535,12 +535,11 @@ const RenderFilterSection = ({ darkMode }) => {
<ButtonSolid
customStyles={{
height: '30px',
maxWidth: '30px',
}}
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end col-2"
className="px-1 rounded-0 border rounded-end col-2 qm-delete-btn"
onClick={() => removeFilterConditionEntry(index)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -54,10 +54,7 @@ const RenderColumnUI = ({
<ButtonSolid
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end"
customStyles={{
height: '30px',
}}
className="px-1 rounded-0 border rounded-end qm-delete-btn"
onClick={() => removeColumnOptionsPair(id)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -117,10 +117,7 @@ const RenderFilterSectionUI = ({
<ButtonSolid
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end"
customStyles={{
height: '30px',
}}
className="px-1 rounded-0 border rounded-end qm-delete-btn"
onClick={() => removeFilterConditionPair(id)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -86,10 +86,7 @@ const RenderSortUI = ({
<ButtonSolid
size="sm"
variant="ghostBlack"
className="px-1 rounded-0 border rounded-end"
customStyles={{
height: '30px',
}}
className="px-1 rounded-0 border rounded-end qm-delete-btn"
onClick={() => removeSortConditionPair(id)}
>
<Trash fill="var(--slate9)" style={{ height: '16px' }} />

View file

@ -185,6 +185,7 @@ export const QueryPanel = ({ darkMode }) => {
id="query-manager"
style={{
height: `calc(100% - ${isExpanded ? height : 100}%)`,
maxHeight: '93.5%',
cursor: isDraggingQueryPane || isTopOfQueryPanel ? 'row-resize' : 'default',
...(!isExpanded && {
border: 'none',

View file

@ -118,7 +118,10 @@ export const ComponentsManagerTab = ({ darkMode }) => {
'TextInput',
'NumberInput',
'PasswordInput',
'Textarea',
'TextArea',
'EmailInput',
'PhoneInput',
'CurrencyInput',
'ToggleSwitchV2',
'DropdownV2',
'MultiselectV2',

View file

@ -42,12 +42,18 @@ const CustomDragLayer = ({ size }) => {
const canvasBounds = item?.canvasRef?.getBoundingClientRect();
const height = size.height;
const width = (canvasWidth * size.width) / NO_OF_GRIDS;
const mainCanvasWidth = document.getElementById('real-canvas')?.offsetWidth || 0;
let width = (mainCanvasWidth * size.width) / NO_OF_GRIDS;
// Calculate position relative to the current canvas (parent or child)
const left = currentOffset.x - (canvasBounds?.left || 0);
const top = currentOffset.y - (canvasBounds?.top || 0);
// Adjust position and width if exceeding grid bounds
if (width >= canvasWidth) {
width = canvasWidth;
}
const [x, y] = snapToGrid(canvasWidth, left, top);
return (
<div

View file

@ -1 +1,9 @@
export const LEGACY_ITEMS = ['ToggleSwitch', 'DropDown', 'Multiselect', 'RadioButton', 'Datepicker', 'Modal'];
export const LEGACY_ITEMS = [
'ToggleSwitch',
'DropDown',
'Multiselect',
'RadioButton',
'Datepicker',
'Modal',
'TextArea',
];

View file

@ -0,0 +1,132 @@
import React, { useMemo, useState } from 'react';
import Accordion from '@/_ui/Accordion';
import { baseComponentProperties } from '../DefaultComponent';
import Select from '@/_ui/Select';
import useStore from '@/AppBuilder/_stores/store';
import flags from 'react-phone-number-input/flags';
import FxButton from '@/AppBuilder/CodeBuilder/Elements/FxButton';
import CodeHinter from '@/AppBuilder/CodeEditor';
import cx from 'classnames';
import { CurrencyMap } from '@/AppBuilder/Widgets/PhoneCurrency/constants';
export const CurrencyInput = ({ componentMeta, darkMode, ...restProps }) => {
const {
layoutPropertyChanged,
component,
paramUpdated,
dataQueries,
currentState,
eventsChanged,
apps,
allComponents,
} = restProps;
const properties = Object.keys(componentMeta.properties);
const events = Object.keys(componentMeta.events);
const validations = Object.keys(componentMeta.validation || {});
const resolvedProperties = useStore((state) => state.getResolvedComponent(component.id)?.properties);
const defaultCountry = resolvedProperties?.defaultCountry || 'US';
const isDefaultCountryFxOn = componentMeta?.definition?.properties?.dateFormat?.fxActive || false;
const options = useMemo(() => {
return Object.keys(CurrencyMap).map((country) => ({
label: `${CurrencyMap[country].prefix} (${CurrencyMap[country].currency})`,
value: country,
}));
}, []);
const renderCustomOption = ({ label, value: optionValue }) => {
const optionStyle = {
display: 'flex',
alignItems: 'center',
justifyContent: 'start',
height: '18px',
gap: '6px',
cursor: 'pointer',
fontFamily: 'IBM Plex Sans',
fontSize: '12px',
lineHeight: '18px',
fontWeight: '400',
color: darkMode ? '#fff' : '#1B1F24',
};
const FlagIcon = flags[optionValue];
return (
<div style={optionStyle} className={`selectedOption ${optionValue !== 'none' && 'custom-phone-input-options'}`}>
<div>{FlagIcon ? <FlagIcon style={{ width: '22px', height: '16px' }} /> : null}</div>
{label}
</div>
);
};
const getCountryDropdown = () => {
return (
<div className="mb-2">
<div className="d-flex justify-content-between mb-1">
<label className="form-label"> Default Currency</label>
<div
className={cx({
'hide-fx': !isDefaultCountryFxOn,
})}
>
<FxButton
active={isDefaultCountryFxOn}
onPress={() => {
paramUpdated({ name: 'dateFormat' }, 'fxActive', !isDefaultCountryFxOn, 'properties');
}}
/>
</div>
</div>
{isDefaultCountryFxOn ? (
<CodeHinter
initialValue={defaultCountry}
theme={darkMode ? 'monokai' : 'default'}
mode="javascript"
lineNumbers={false}
onChange={(value) => paramUpdated({ name: 'defaultCountry' }, 'value', value, 'properties')}
/>
) : (
<Select
width="100%"
options={options}
value={defaultCountry}
customOption={renderCustomOption}
onChange={(value) => {
paramUpdated({ name: 'defaultCountry' }, 'value', value, 'properties');
}}
/>
)}
</div>
);
};
const filteredProperties = properties.filter(
(property) => componentMeta.properties[property].section !== 'additionalActions'
);
const additionalActions = properties.filter(
(property) => componentMeta.properties[property].section === 'additionalActions'
);
const accordionItems = baseComponentProperties(
filteredProperties,
events,
component,
componentMeta,
layoutPropertyChanged,
paramUpdated,
dataQueries,
currentState,
eventsChanged,
apps,
allComponents,
validations,
darkMode,
null,
additionalActions
);
accordionItems[0].children.splice(4, 0, getCountryDropdown());
return <Accordion items={accordionItems} />;
};

View file

@ -14,8 +14,12 @@ const SHOW_ADDITIONAL_ACTIONS = [
'Text',
'Container',
'TextInput',
'TextArea',
'NumberInput',
'PasswordInput',
'EmailInput',
'PhoneInput',
'CurrencyInput',
'ToggleSwitchV2',
'Checkbox',
'DropdownV2',
@ -24,6 +28,7 @@ const SHOW_ADDITIONAL_ACTIONS = [
'RichTextEditor',
'Image',
'ModalV2',
'Link',
];
const PROPERTIES_VS_ACCORDION_TITLE = {
Text: 'Data',
@ -32,10 +37,12 @@ const PROPERTIES_VS_ACCORDION_TITLE = {
NumberInput: 'Data',
ToggleSwitchV2: 'Data',
Checkbox: 'Data',
TextArea: 'Data',
Button: 'Data',
Image: 'Data',
Container: 'Data',
ModalV2: 'Data',
Link: 'Data',
};
export const DefaultComponent = ({ componentMeta, darkMode, ...restProps }) => {
@ -120,6 +127,10 @@ export const baseComponentProperties = (
'Modal',
'TextInput',
'PasswordInput',
'TextArea',
'EmailInput',
'PhoneInput',
'CurrencyInput',
'NumberInput',
'Text',
'Table',
@ -129,6 +140,7 @@ export const baseComponentProperties = (
'DropdownV2',
'MultiselectV2',
'Image',
'Link',
],
Layout: [],
};

View file

@ -0,0 +1,135 @@
import React, { useMemo, useState } from 'react';
import Accordion from '@/_ui/Accordion';
import { baseComponentProperties } from '../DefaultComponent';
import Select from '@/_ui/Select';
import useStore from '@/AppBuilder/_stores/store';
import { getCountries } from 'react-phone-number-input/input';
import en from 'react-phone-number-input/locale/en';
import flags from 'react-phone-number-input/flags';
import FxButton from '@/AppBuilder/CodeBuilder/Elements/FxButton';
import CodeHinter from '@/AppBuilder/CodeEditor';
import cx from 'classnames';
export const PhoneInput = ({ componentMeta, darkMode, ...restProps }) => {
const {
layoutPropertyChanged,
component,
paramUpdated,
dataQueries,
currentState,
eventsChanged,
apps,
allComponents,
} = restProps;
const properties = Object.keys(componentMeta.properties);
const events = Object.keys(componentMeta.events);
const validations = Object.keys(componentMeta.validation || {});
const resolvedProperties = useStore((state) => state.getResolvedComponent(component.id)?.properties);
const defaultCountry = resolvedProperties?.defaultCountry || 'US';
const isDefaultCountryFxOn = componentMeta?.definition?.properties?.dateFormat?.fxActive || false;
const options = useMemo(
() =>
getCountries().map((country) => ({
label: `${en[country]}`,
value: country,
})),
[]
);
const renderCustomOption = ({ label, value: optionValue }) => {
const optionStyle = {
display: 'flex',
alignItems: 'center',
justifyContent: 'start',
height: '18px',
gap: '6px',
cursor: 'pointer',
fontFamily: 'IBM Plex Sans',
fontSize: '12px',
lineHeight: '18px',
fontWeight: '400',
color: darkMode ? '#fff' : '#1B1F24',
};
const FlagIcon = flags[optionValue];
return (
<div style={optionStyle} className={`selectedOption ${optionValue !== 'none' && 'custom-phone-input-options'}`}>
<div>{FlagIcon ? <FlagIcon style={{ width: '22px', height: '16px' }} /> : null}</div>
{label}
</div>
);
};
const getCountryDropdown = () => {
return (
<div className="mb-2">
<div className="d-flex justify-content-between mb-1">
<label className="form-label"> Default Country</label>
<div
className={cx({
'hide-fx': !isDefaultCountryFxOn,
})}
>
<FxButton
active={isDefaultCountryFxOn}
onPress={() => {
paramUpdated({ name: 'dateFormat' }, 'fxActive', !isDefaultCountryFxOn, 'properties');
}}
/>
</div>
</div>
{isDefaultCountryFxOn ? (
<CodeHinter
initialValue={defaultCountry}
theme={darkMode ? 'monokai' : 'default'}
mode="javascript"
lineNumbers={false}
onChange={(value) => paramUpdated({ name: 'defaultCountry' }, 'value', value, 'properties')}
/>
) : (
<Select
width="100%"
options={options}
value={defaultCountry}
customOption={renderCustomOption}
onChange={(value) => {
paramUpdated({ name: 'defaultCountry' }, 'value', value, 'properties');
}}
/>
)}
</div>
);
};
const filteredProperties = properties.filter(
(property) => componentMeta.properties[property].section !== 'additionalActions'
);
const additionalActions = properties.filter(
(property) => componentMeta.properties[property].section === 'additionalActions'
);
const accordionItems = baseComponentProperties(
filteredProperties,
events,
component,
componentMeta,
layoutPropertyChanged,
paramUpdated,
dataQueries,
currentState,
eventsChanged,
apps,
allComponents,
validations,
darkMode,
null,
additionalActions
);
accordionItems[0].children.splice(3, 0, getCountryDropdown());
return <Accordion items={accordionItems} />;
};

View file

@ -295,7 +295,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
</div>
<div className="field mb-2" data-cy={`input-and-label-column-name`}>
<CodeHinter
initialValue={isMultiSelect ? `{{${markedAsDefault.includes(item.value)}}}` : item?.default?.value}
initialValue={isMultiSelect ? `{{${markedAsDefault?.includes(item?.value)}}}` : item?.default?.value}
theme={darkMode ? 'monokai' : 'default'}
mode="javascript"
lineNumbers={false}
@ -372,7 +372,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
<div className="w-100" {...droppableProps} ref={innerRef}>
{options?.map((item, index) => {
return (
<Draggable key={item.value} draggableId={item.value} index={index}>
<Draggable key={item?.value} draggableId={item?.value} index={index}>
{(provided, snapshot) => (
<div
key={index}
@ -386,8 +386,13 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
placement="left"
rootClose
overlay={_renderOverlay(item, index)}
onToggle={(isOpen) => {
if (!isOpen) {
document.activeElement?.blur(); // Manually trigger blur when popover closes
}
}}
>
<div key={item.value}>
<div key={item?.value}>
<ListGroup.Item
style={{ marginBottom: '8px', backgroundColor: 'var(--slate3)' }}
onMouseEnter={() => setHoveredOptionIndex(index)}
@ -399,7 +404,7 @@ export function Select({ componentMeta, darkMode, ...restProps }) {
<SortableList.DragHandle show />
</div>
<div className="col text-truncate cursor-pointer" style={{ padding: '0px' }}>
{getResolvedValue(item.label)}
{getResolvedValue(item?.label)}
</div>
<div className="col-auto">
{index === hoveredOptionIndex && (

View file

@ -53,6 +53,7 @@ export const PropertiesTabElements = ({
{ label: 'Image', value: 'image' },
{ label: 'Link', value: 'link' },
{ label: 'JSON', value: 'json' },
{ label: 'Markdown', value: 'markdown' },
// Following column types are deprecated
{ label: 'Default', value: 'default' },
{ label: 'Dropdown', value: 'dropdown' },

View file

@ -128,6 +128,7 @@ export const StylesTabElements = ({
undefined,
'number',
'json',
'markdown',
'boolean',
'select',
'text',

View file

@ -177,7 +177,7 @@ class TableComponent extends React.Component {
style={{
width: '280px',
maxHeight: resolveReferences(column.isEditable) ? '100vh' : 'inherit',
overflowY: 'auto',
// overflowY: 'auto',
zIndex: '9999',
}}
>
@ -327,7 +327,12 @@ class TableComponent extends React.Component {
placement="left"
rootClose={this.state.actionPopOverRootClose}
overlay={this.actionPopOver(action, index)}
onToggle={(showing) => this.setState({ showPopOver: showing })}
onToggle={(showing) => {
if (!showing) {
document.activeElement?.blur(); // Manually trigger blur when popover closes
}
this.setState({ showPopOver: showing });
}}
>
<div>
<List>
@ -626,6 +631,8 @@ class TableComponent extends React.Component {
return 'Multiselect';
case 'json':
return 'JSON';
case 'markdown':
return 'Markdown';
default:
capitalize(text ?? '');
}
@ -649,6 +656,7 @@ class TableComponent extends React.Component {
if (show) {
this.handleToggleColumnPopover(index);
} else {
document.activeElement?.blur(); // Manually trigger blur when popover closes
this.handleToggleColumnPopover(null);
}
}}

View file

@ -30,6 +30,8 @@ import { appService } from '@/_services';
import { deepClone } from '@/_helpers/utilities/utils.helpers';
import useStore from '@/AppBuilder/_stores/store';
import { useEventActions, useEvents } from '@/AppBuilder/_stores/slices/eventsSlice';
import ToggleGroup from '@/ToolJetUI/SwitchGroup/ToggleGroup';
import ToggleGroupItem from '@/ToolJetUI/SwitchGroup/ToggleGroupItem';
export const EventManager = ({
sourceId,
@ -503,7 +505,7 @@ export const EventManager = ({
)}
{event.actionId === 'open-webpage' && (
<div className="p-1">
<div>
<label className="form-label mt-1">{t('editor.inspector.eventManager.url', 'URL')}</label>
<CodeHinter
type="basic"
@ -512,6 +514,17 @@ export const EventManager = ({
usePortalEditor={false}
component={component}
/>
<div className="d-flex align-items-center justify-content-between mt-3">
<label className="form-label mt-1">Open in</label>
<ToggleGroup
onValueChange={(_value) => handlerChanged(index, 'windowTarget', _value)}
defaultValue={event?.windowTarget || 'newTab'}
style={{ width: '74%' }}
>
<ToggleGroupItem value="newTab">New tab</ToggleGroupItem>
<ToggleGroupItem value="currentTab">Current tab</ToggleGroupItem>
</ToggleGroup>
</div>
</div>
)}

View file

@ -8,6 +8,8 @@ import { validateQueryName, convertToKebabCase, resolveReferences } from '@/_hel
import { useHotkeys } from 'react-hotkeys-hook';
import { DefaultComponent } from './Components/DefaultComponent';
import { FilePicker } from './Components/FilePicker';
import { PhoneInput } from './Components/PhoneInput/PhoneInput.jsx';
import { CurrencyInput } from './Components/CurrencyInput/CurrencyInput.jsx';
import { Modal } from './Components/Modal';
import { ModalV2 } from './Components/ModalV2';
import { CustomComponent } from './Components/CustomComponent';
@ -36,6 +38,7 @@ import { EMPTY_ARRAY } from '@/_stores/editorStore';
import { Select } from './Components/Select';
import { deepClone } from '@/_helpers/utilities/utils.helpers';
import useStore from '@/AppBuilder/_stores/store';
// import { componentTypes } from '@/Editor/WidgetManager/components';
import { componentTypes } from '@/AppBuilder/WidgetManager/componentTypes';
import { copyComponents } from '@/AppBuilder/AppCanvas/appCanvasUtils.js';
import DatetimePickerV2 from './Components/DatetimePickerV2.jsx';
@ -66,7 +69,11 @@ const INSPECTOR_HEADER_OPTIONS = [
const NEW_REVAMPED_COMPONENTS = [
'Text',
'TextInput',
'TextArea',
'PasswordInput',
'EmailInput',
'PhoneInput',
'CurrencyInput',
'NumberInput',
'Table',
'ToggleSwitchV2',
@ -80,6 +87,7 @@ const NEW_REVAMPED_COMPONENTS = [
'Image',
'Container',
'ModalV2',
'Link',
];
export const Inspector = ({ componentDefinitionChanged, darkMode, pages, selectedComponentId }) => {
@ -730,6 +738,10 @@ const GetAccordion = React.memo(
case 'DatePickerV2':
case 'TimePicker':
return <DatetimePickerV2 {...restProps} componentName={componentName} />;
case 'PhoneInput':
return <PhoneInput {...restProps} />;
case 'CurrencyInput':
return <CurrencyInput {...restProps} componentName={componentName} />;
default: {
return <DefaultComponent {...restProps} />;

View file

@ -43,6 +43,9 @@ export function renderCustomStyles(
componentConfig.component == 'TextInput' ||
componentConfig.component == 'NumberInput' ||
componentConfig.component == 'PasswordInput' ||
componentConfig.component == 'EmailInput' ||
componentConfig.component == 'PhoneInput' ||
componentConfig.component == 'CurrencyInput' ||
componentConfig.component == 'ToggleSwitchV2' ||
componentConfig.component == 'Checkbox' ||
componentConfig.component == 'Table' ||

View file

@ -13,6 +13,7 @@ const NEW_WIDGETS = [
'DatePickerV2',
'TimePicker',
'ModalV2',
'TextArea',
];
export const WidgetBox = ({ component, darkMode }) => {

View file

@ -134,7 +134,7 @@ const MobileNavigationMenu = ({ pages, switchPage, currentPageId, darkMode, chan
version: selectedVersionName,
env: selectedEnvironmentName,
};
switchPage(pageId, pages.find((page) => page.id === pageId)?.handle, Object.entries(queryParams), true);
switchPage(pageId, pages.find((page) => page.id === pageId)?.handle, Object.entries(queryParams));
};
var styles = {
bmBurgerButton: {

View file

@ -95,7 +95,7 @@ export const ViewerSidebarNavigation = ({
version: selectedVersionName,
env: selectedEnvironmentName,
};
switchPage(pageId, pages.find((page) => page.id === pageId)?.handle, Object.entries(queryParams), true);
switchPage(pageId, pages.find((page) => page.id === pageId)?.handle, Object.entries(queryParams));
};
const isLicensed =

View file

@ -58,6 +58,9 @@ import {
linkConfig,
iconConfig,
boundedBoxConfig,
emailinputConfig,
phoneinputConfig,
currencyinputConfig,
} from '../widgets';
export const widgets = [
@ -70,6 +73,9 @@ export const widgets = [
textinputConfig,
numberinputConfig,
passinputConfig,
emailinputConfig,
phoneinputConfig,
currencyinputConfig,
datepickerConfig,
datetimePickerV2Config,
datePickerV2Config,

View file

@ -61,7 +61,7 @@ export const buttonConfig = {
accordian: 'button',
},
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: {
schema: { type: 'string' },
@ -74,7 +74,7 @@ export const buttonConfig = {
accordian: 'button',
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -83,7 +83,7 @@ export const buttonConfig = {
accordian: 'button',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border color',
validation: {
schema: { type: 'string' },
@ -92,7 +92,7 @@ export const buttonConfig = {
accordian: 'button',
},
loaderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Loader color',
validation: {
schema: { type: 'string' },
@ -110,7 +110,7 @@ export const buttonConfig = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Icon color',
validation: { schema: { type: 'string' } },
accordian: 'button',
@ -219,10 +219,10 @@ export const buttonConfig = {
events: [],
styles: {
textColor: { value: '#FFFFFF' },
borderColor: { value: '#4368E3' },
borderColor: { value: 'var(--primary-brand)' },
loaderColor: { value: '#FFFFFF' },
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#4368E3' },
backgroundColor: { value: 'var(--primary-brand)' },
iconColor: { value: '#FFFFFF' },
direction: { value: 'left' },
padding: { value: 'default' },

View file

@ -68,7 +68,7 @@ export const buttonGroupConfig = {
},
styles: {
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background color',
validation: {
schema: { type: 'string' },
@ -76,7 +76,7 @@ export const buttonGroupConfig = {
},
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -108,7 +108,7 @@ export const buttonGroupConfig = {
},
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Selected text colour',
validation: {
schema: { type: 'string' },
@ -116,17 +116,32 @@ export const buttonGroupConfig = {
},
},
selectedBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Selected background color',
validation: {
schema: { type: 'string' },
defaultValue: '#007bff',
defaultValue: 'var(--primary-brand)',
},
},
alignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'left',
},
},
},
exposedVariables: {
selected: [1],
},
actions: [
{
handle: 'setSelected',
displayName: 'Select option',
params: [{ handle: 'selected', displayName: 'Value' }],
},
],
definition: {
others: {
showOnDesktop: { value: '{{true}}' },
@ -147,7 +162,8 @@ export const buttonGroupConfig = {
borderRadius: { value: '{{4}}' },
disabledState: { value: '{{false}}' },
selectedTextColor: { value: '#FFFFFF' },
selectedBackgroundColor: { value: '#4368E3' },
selectedBackgroundColor: { value: 'var(--primary-brand)' },
alignment: { value: 'left' },
},
},
};

View file

@ -39,13 +39,13 @@ export const chartConfig = {
},
},
markerColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Marker color',
validation: {
schema: {
type: 'string',
},
defaultValue: '#CDE1F8',
defaultValue: 'var(--primary-brand)',
},
},
showAxes: {
@ -134,7 +134,7 @@ export const chartConfig = {
},
styles: {
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background color',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
},
@ -192,7 +192,7 @@ export const chartConfig = {
},
properties: {
title: { value: 'This title can be changed' },
markerColor: { value: '#CDE1F8' },
markerColor: { value: 'var(--primary-brand)' },
showAxes: { value: '{{true}}' },
showGridLines: { value: '{{true}}' },
plotFromJson: { value: '{{false}}' },

View file

@ -70,7 +70,7 @@ export const checkboxConfig = {
},
styles: {
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -78,7 +78,7 @@ export const checkboxConfig = {
accordian: 'label',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border color',
validation: {
schema: { type: 'string' },
@ -86,7 +86,7 @@ export const checkboxConfig = {
accordian: 'switch',
},
checkboxColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Checked color',
validation: {
schema: { type: 'string' },
@ -94,7 +94,7 @@ export const checkboxConfig = {
accordian: 'switch',
},
uncheckedColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Unchecked color',
validation: {
schema: { type: 'string' },
@ -102,7 +102,7 @@ export const checkboxConfig = {
accordian: 'switch',
},
handleColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Handle color',
validation: {
schema: { type: 'string' },
@ -183,7 +183,7 @@ export const checkboxConfig = {
styles: {
disabledState: { value: '{{false}}' },
textColor: { value: '#1B1F24' },
checkboxColor: { value: '#4368E3' },
checkboxColor: { value: 'var(--primary-brand)' },
uncheckedColor: { value: '#E4E7EB' },
borderColor: { value: '#CCD1D5' },
handleColor: { value: '#FFFFFF' },

View file

@ -32,15 +32,15 @@ export const circularProgressbarConfig = {
events: {},
styles: {
color: {
type: 'color',
displayName: 'Color',
type: 'colorSwatches',
displayName: 'colorSwatches',
validation: {
schema: { type: 'string' },
defaultValue: '#375FCF',
defaultValue: 'var(--primary-brand)',
},
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text Color',
validation: {
schema: { type: 'string' },
@ -104,7 +104,7 @@ export const circularProgressbarConfig = {
},
events: [],
styles: {
color: { value: '' },
color: { value: 'var(--primary-brand)' },
textColor: { value: '' },
textSize: { value: '{{16}}' },
strokeWidth: { value: '{{8}}' },

View file

@ -4,7 +4,7 @@ export const colorPickerConfig = {
description: 'Choose colors from a palette',
component: 'ColorPicker',
properties: {
defaultColor: { type: 'color', displayName: 'Default color' },
defaultColor: { type: 'colorSwatches', displayName: 'Default color' },
},
defaultSize: {
width: 9,
@ -14,7 +14,9 @@ export const colorPickerConfig = {
{
displayName: 'Set Color',
handle: 'setColor',
params: [{ handle: 'color', displayName: 'color', defaultValue: '#ffffff', type: 'color' }],
params: [
{ handle: 'colorSwatches', displayName: 'colorSwatches', defaultValue: '#ffffff', type: 'colorSwatches' },
],
},
],
others: {

View file

@ -44,7 +44,7 @@ export const containerConfig = {
displayName: 'Show header',
validation: {
schema: { type: 'boolean' },
defaultValue: true,
defaultValue: false,
},
},
},
@ -58,6 +58,7 @@ export const containerConfig = {
},
displayName: 'ContainerText',
properties: ['text'],
slotName: 'header',
accessorKey: 'text',
styles: ['fontWeight', 'textSize', 'textColor'],
defaultValue: {
@ -71,7 +72,7 @@ export const containerConfig = {
events: {},
styles: {
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: {
schema: { type: 'string' },
@ -80,7 +81,7 @@ export const containerConfig = {
accordian: 'container',
},
headerBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: {
schema: { type: 'string' },
@ -89,7 +90,7 @@ export const containerConfig = {
accordian: 'header',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border color',
validation: {
schema: { type: 'string' },
@ -153,7 +154,7 @@ export const containerConfig = {
showOnMobile: { value: '{{false}}' },
},
properties: {
showHeader: { value: `{{true}}` },
showHeader: { value: `{{false}}` },
loadingState: { value: `{{false}}` },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
@ -163,6 +164,7 @@ export const containerConfig = {
backgroundColor: { value: '#fff' },
headerBackgroundColor: { value: '#fff' },
borderRadius: { value: '4' },
headerHeight: { value: '{{80}}' },
borderColor: { value: '#fff' },
boxShadow: { value: '0px 0px 0px 0px #00000040' },
},

View file

@ -1,32 +1,12 @@
export const timePickerConfig = {
name: 'TimePicker',
displayName: 'Time Picker',
description: 'Choose date and time',
component: 'TimePicker',
export const currencyinputConfig = {
name: 'CurrencyInput',
displayName: 'Currency Input',
description: 'Currency input field',
component: 'CurrencyInput',
defaultSize: {
width: 10,
height: 40,
},
validation: {
minTime: {
type: 'timepicker',
placeholder: 'HH:mm',
displayName: 'Min Time',
},
maxTime: {
type: 'timepicker',
placeholder: 'HH:mm',
displayName: 'Max Time',
},
customRule: {
type: 'code',
displayName: 'Custom validation',
},
mandatory: {
type: 'toggle',
displayName: 'Make this field mandatory',
},
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
@ -35,142 +15,88 @@ export const timePickerConfig = {
label: {
type: 'code',
displayName: 'Label',
validation: { schema: { type: 'string' }, defaultValue: 'Label' },
},
placeholder: {
type: 'code',
displayName: 'Placeholder',
validation: {
schema: { type: 'string' },
defaultValue: 'Label',
defaultValue: 'Enter your number',
},
accordian: 'Data',
},
defaultValue: {
value: {
type: 'code',
displayName: 'Default value',
validation: {
schema: { type: 'string' },
defaultValue: '00:00',
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: 0,
},
},
isTimezoneEnabled: {
decimalPlaces: {
type: 'code',
displayName: 'Decimal places',
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: '2' },
},
isCountryChangeEnabled: {
type: 'toggle',
displayName: 'Manage time zones',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'formatting',
displayName: 'Enable currency change',
validation: { schema: { type: 'boolean' }, defaultValue: true },
},
loadingState: {
type: 'toggle',
displayName: 'Loading state',
validation: { schema: { type: 'boolean' }, defaultValue: true },
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
visibility: {
type: 'toggle',
displayName: 'Visibility',
validation: { schema: { type: 'boolean' }, defaultValue: true },
section: 'additionalActions',
},
disabledState: {
type: 'toggle',
displayName: 'Disable',
validation: { schema: { type: 'boolean' }, defaultValue: true },
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
tooltip: {
type: 'code',
displayName: 'Tooltip',
validation: {
schema: { type: 'string' },
defaultValue: 'Enter tooltip text',
},
validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
section: 'additionalActions',
placeholder: 'Enter tooltip text',
},
},
validation: {
mandatory: { type: 'toggle', displayName: 'Make this field mandatory' },
regex: { type: 'code', displayName: 'Regex', placeholder: '^[a-zA-Z0-9_ -]{3,16}$' },
minValue: { type: 'code', displayName: 'Min value', placeholder: 'Enter min value' },
maxValue: { type: 'code', displayName: 'Max value', placeholder: 'Enter max value' },
customRule: {
type: 'code',
displayName: 'Custom validation',
placeholder: `{{components.text2.text=='yes'&&'valid'}}`,
},
},
events: {
onSelect: { displayName: 'On select' },
onChange: { displayName: 'On change' },
onEnterPressed: { displayName: 'On enter pressed' },
onFocus: { displayName: 'On focus' },
onBlur: { displayName: 'On blur' },
},
actions: [
{
handle: 'setValue',
displayName: 'Set value',
params: [
{ handle: 'value', displayName: 'Value' },
{ handle: 'format', displayName: 'Format' },
],
},
{
handle: 'clearValue',
displayName: 'Clear value',
},
{
handle: 'setTime',
displayName: 'Set time',
params: [
{ handle: 'value', displayName: 'Value' },
{ handle: 'format', displayName: 'Format' },
],
},
{
handle: 'setValueInTimestamp',
displayName: 'Set value in timestamp',
params: [{ handle: 'value', displayName: 'Value' }],
},
{
handle: 'setMinTime',
displayName: 'Set min time',
params: [{ handle: 'value', displayName: 'Value' }],
},
{
handle: 'setMaxTime',
displayName: 'Set max time',
params: [{ handle: 'value', displayName: 'Value' }],
},
{
handle: 'setDisplayTimezone',
displayName: 'Set display timezone',
params: [{ handle: 'value', displayName: 'Value' }],
},
{
handle: 'setStoreTimezone',
displayName: 'Set store timezone',
params: [{ handle: 'value', displayName: 'Value' }],
},
{
handle: 'setVisibility',
displayName: 'Set visibility',
params: [{ handle: 'value', displayName: 'Value', defaultValue: `{{true}}`, type: 'toggle' }],
},
{
handle: 'setLoading',
displayName: 'Set loading',
params: [{ handle: 'value', displayName: 'Value', defaultValue: `{{false}}`, type: 'toggle' }],
},
{
handle: 'setDisable',
displayName: 'Set disable',
params: [{ handle: 'value', displayName: 'Value', defaultValue: `{{false}}`, type: 'toggle' }],
},
{
handle: 'setFocus',
displayName: 'Set focus',
},
{
handle: 'setBlur',
displayName: 'Set blur',
},
],
styles: {
labelColor: {
color: {
type: 'color',
displayName: 'Color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
alignment: {
type: 'switch',
displayName: 'Alignment',
validation: { schema: { type: 'string' }, defaultValue: 'top' },
validation: { schema: { type: 'string' }, defaultValue: 'side' },
options: [
{ displayName: 'Side', value: 'side' },
{ displayName: 'Top', value: 'top' },
@ -179,7 +105,7 @@ export const timePickerConfig = {
},
direction: {
type: 'switch',
displayName: 'Direction',
displayName: '',
validation: { schema: { type: 'string' }, defaultValue: 'left' },
showLabel: false,
isIcon: true,
@ -190,7 +116,7 @@ export const timePickerConfig = {
accordian: 'label',
isFxNotRequired: true,
},
labelWidth: {
width: {
type: 'slider',
displayName: 'Width',
accordian: 'label',
@ -204,7 +130,7 @@ export const timePickerConfig = {
type: 'checkbox',
displayName: 'auto',
showLabel: false,
validation: { schema: { type: 'boolean' } },
validation: { schema: { type: 'boolean' }, defaultValue: true },
accordian: 'label',
conditionallyRender: {
key: 'alignment',
@ -212,13 +138,14 @@ export const timePickerConfig = {
},
isFxNotRequired: true,
},
fieldBackgroundColor: {
backgroundColor: {
type: 'color',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
borderColor: {
type: 'color',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
@ -230,7 +157,7 @@ export const timePickerConfig = {
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
textColor: {
type: 'color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
@ -239,7 +166,7 @@ export const timePickerConfig = {
errTextColor: {
type: 'color',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#E54D2E' },
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
},
icon: {
@ -251,38 +178,24 @@ export const timePickerConfig = {
},
iconColor: {
type: 'color',
displayName: '',
showLabel: false,
validation: {
schema: { type: 'string' },
defaultValue: '#6A727C',
},
displayName: 'Icon color',
validation: { schema: { type: 'string' }, defaultValue: '#CFD3D859' },
accordian: 'field',
},
iconDirection: {
type: 'switch',
displayName: '',
validation: { schema: { type: 'string' } },
visibility: false,
showLabel: false,
isIcon: true,
options: [
{ displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
{ displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
],
accordian: 'field',
},
fieldBorderRadius: {
type: 'input',
borderRadius: {
type: 'numberInput',
displayName: 'Border radius',
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 6 },
accordian: 'field',
},
boxShadow: {
type: 'boxShadow',
displayName: 'Box shadow',
displayName: 'Box Shadow',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: '0px 0px 0px 0px #121212',
defaultValue: '0px 0px 0px 0px #00000040',
},
accordian: 'field',
},
@ -293,6 +206,7 @@ export const timePickerConfig = {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: 'default',
},
isFxNotRequired: true,
options: [
{ displayName: 'Default', value: 'default' },
{ displayName: 'None', value: 'none' },
@ -300,52 +214,92 @@ export const timePickerConfig = {
accordian: 'container',
},
},
exposedVariables: {
value: '',
isMandatory: false,
isVisible: true,
isDisabled: false,
isLoading: false,
},
actions: [
{
handle: 'setValue',
displayName: 'Set Value',
params: [
{ handle: 'value', displayName: 'value', defaultValue: '' },
{ handle: 'country', displayName: 'country', defaultValue: '' },
],
},
{
handle: 'clear',
displayName: 'Clear',
},
{
handle: 'setFocus',
displayName: 'Set focus',
},
{
handle: 'setBlur',
displayName: 'Set blur',
},
{
handle: 'setVisibility',
displayName: 'Set visibility',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setDisable',
displayName: 'Set disable',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setLoading',
displayName: 'Set loading',
params: [{ handle: 'loading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
],
definition: {
validation: {
mandatory: { value: '{{false}}' },
regex: { value: '' },
minValue: { value: '' },
maxValue: { value: '' },
customRule: { value: '' },
},
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
validation: {
minTime: { value: '' },
maxTime: { value: '' },
customRule: { value: '' },
mandatory: { value: '{{false}}' },
},
properties: {
value: { value: '0' },
label: { value: 'Label' },
defaultValue: { value: '00:00' },
timeFormat: { value: 'HH:mm' },
isTimezoneEnabled: { value: '{{false}}' },
displayTimezone: { value: 'UTC' },
storeTimezone: { value: 'UTC' },
loadingState: { value: '{{false}}' },
placeholder: { value: 'Enter amount' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
loadingState: { value: '{{false}}' },
tooltip: { value: '' },
isCountryChangeEnabled: { value: '{{true}}' },
decimalPlaces: { value: '2' },
},
events: [],
styles: {
labelColor: { value: '#1B1F24' },
alignment: { value: 'side' },
direction: { value: 'left' },
labelWidth: { value: '20' },
auto: { value: '{{true}}' },
fieldBackgroundColor: { value: '#fff' },
fieldBorderColor: { value: '#CCD1D5' },
textColor: { value: '#1B1F24' },
borderColor: { value: '#CCD1D5' },
accentColor: { value: '#4368E3' },
selectedTextColor: { value: '#1B1F24' },
errTextColor: { value: '#E54D2E' },
icon: { value: 'IconClock' },
iconVisibility: { value: true },
iconDirection: { value: 'left' },
fieldBorderRadius: { value: '{{6}}' },
boxShadow: { value: '0px 0px 0px 0px #121212' },
errTextColor: { value: '#D72D39' },
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#fff' },
iconColor: { value: '#CFD3D859' },
direction: { value: 'left' },
width: { value: '{{33}}' },
alignment: { value: 'side' },
color: { value: '#1B1F24' },
auto: { value: '{{true}}' },
padding: { value: 'default' },
iconColor: { value: '#6A727C' },
boxShadow: { value: '0px 0px 0px 0px #00000040' },
icon: { value: 'IconHome2' },
iconVisibility: { value: false },
},
},
};

View file

@ -169,8 +169,8 @@ export const datePickerV2Config = {
],
styles: {
labelColor: {
type: 'color',
displayName: 'Color',
type: 'colorSwatches',
displayName: 'colorSwatches',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
@ -220,31 +220,31 @@ export const datePickerV2Config = {
isFxNotRequired: true,
},
fieldBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#E54D2E' },
accordian: 'field',
@ -257,7 +257,7 @@ export const datePickerV2Config = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: '',
showLabel: false,
validation: {

View file

@ -199,8 +199,8 @@ export const daterangepickerConfig = {
],
styles: {
labelColor: {
type: 'color',
displayName: 'Color',
type: 'colorSwatches',
displayName: 'colorSwatches',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
@ -250,31 +250,31 @@ export const daterangepickerConfig = {
isFxNotRequired: true,
},
fieldBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#E54D2E' },
accordian: 'field',
@ -287,7 +287,7 @@ export const daterangepickerConfig = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: '',
showLabel: false,
validation: {

View file

@ -214,8 +214,8 @@ export const datetimePickerV2Config = {
],
styles: {
labelColor: {
type: 'color',
displayName: 'Color',
type: 'colorSwatches',
displayName: 'colorSwatches',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
@ -265,31 +265,31 @@ export const datetimePickerV2Config = {
isFxNotRequired: true,
},
fieldBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#E54D2E' },
accordian: 'field',
@ -302,7 +302,7 @@ export const datetimePickerV2Config = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: '',
showLabel: false,
validation: {

View file

@ -15,7 +15,7 @@ export const dividerConfig = {
events: {},
styles: {
dividerColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Divider color',
validation: {
schema: { type: 'string' },

View file

@ -128,7 +128,7 @@ export const dropdownConfig = {
defaultValue: true,
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Selected text color',
validation: {
schema: {

View file

@ -101,7 +101,7 @@ export const dropdownV2Config = {
},
styles: {
labelColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Color',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
@ -153,31 +153,31 @@ export const dropdownV2Config = {
},
fieldBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
@ -190,7 +190,7 @@ export const dropdownV2Config = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: '',
showLabel: false,
validation: {

View file

@ -0,0 +1,292 @@
export const emailinputConfig = {
name: 'EmailInput',
displayName: 'Email Input',
description: 'Email input field',
component: 'EmailInput',
defaultSize: {
width: 10,
height: 40,
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
properties: {
label: {
type: 'code',
displayName: 'Label',
validation: { schema: { type: 'string' }, defaultValue: 'Label' },
},
placeholder: {
type: 'code',
displayName: 'Placeholder',
validation: {
schema: { type: 'string' },
defaultValue: 'Enter email',
},
},
value: {
type: 'code',
displayName: 'Default value',
validation: {
schema: {
type: 'string',
},
defaultValue: 'Default value',
},
},
loadingState: {
type: 'toggle',
displayName: 'Loading state',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
visibility: {
type: 'toggle',
displayName: 'Visibility',
validation: { schema: { type: 'boolean' }, defaultValue: true },
section: 'additionalActions',
},
disabledState: {
type: 'toggle',
displayName: 'Disable',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
tooltip: {
type: 'code',
displayName: 'Tooltip',
validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
section: 'additionalActions',
placeholder: 'Enter tooltip text',
},
},
validation: {
mandatory: { type: 'toggle', displayName: 'Make this field mandatory' },
regex: { type: 'code', displayName: 'Regex', placeholder: '^[a-zA-Z0-9_ -]{3,16}$' },
minLength: { type: 'code', displayName: 'Min length', placeholder: 'Enter min length' },
maxLength: { type: 'code', displayName: 'Max length', placeholder: 'Enter max length' },
customRule: {
type: 'code',
displayName: 'Custom validation',
placeholder: `{{components.text2.text=='yes'&&'valid'}}`,
},
},
events: {
onChange: { displayName: 'On change' },
onEnterPressed: { displayName: 'On enter pressed' },
onFocus: { displayName: 'On focus' },
onBlur: { displayName: 'On blur' },
},
styles: {
color: {
type: 'color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
alignment: {
type: 'switch',
displayName: 'Alignment',
validation: { schema: { type: 'string' }, defaultValue: 'side' },
options: [
{ displayName: 'Side', value: 'side' },
{ displayName: 'Top', value: 'top' },
],
accordian: 'label',
},
direction: {
type: 'switch',
displayName: '',
validation: { schema: { type: 'string' }, defaultValue: 'left' },
showLabel: false,
isIcon: true,
options: [
{ displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
{ displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
],
accordian: 'label',
isFxNotRequired: true,
},
width: {
type: 'slider',
displayName: 'Width',
accordian: 'label',
conditionallyRender: {
key: 'alignment',
value: 'side',
},
isFxNotRequired: true,
},
auto: {
type: 'checkbox',
displayName: 'auto',
showLabel: false,
validation: { schema: { type: 'boolean' }, defaultValue: true },
accordian: 'label',
conditionallyRender: {
key: 'alignment',
value: 'side',
},
isFxNotRequired: true,
},
backgroundColor: {
type: 'color',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
borderColor: {
type: 'color',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
textColor: {
type: 'color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
},
icon: {
type: 'icon',
displayName: 'Icon',
validation: { schema: { type: 'string' }, defaultValue: 'IconMailFilled' },
accordian: 'field',
visibility: true,
},
iconColor: {
type: 'color',
displayName: 'Icon color',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
visibility: false,
showLabel: false,
},
borderRadius: {
type: 'numberInput',
displayName: 'Border radius',
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 6 },
accordian: 'field',
},
boxShadow: {
type: 'boxShadow',
displayName: 'Box Shadow',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: '0px 0px 0px 0px #00000040',
},
accordian: 'field',
},
padding: {
type: 'switch',
displayName: 'Padding',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: 'default',
},
isFxNotRequired: true,
options: [
{ displayName: 'Default', value: 'default' },
{ displayName: 'None', value: 'none' },
],
accordian: 'container',
},
},
exposedVariables: {
value: '',
isMandatory: false,
isVisible: true,
isDisabled: false,
isLoading: false,
},
actions: [
{
handle: 'setText',
displayName: 'Set text',
params: [{ handle: 'text', displayName: 'text', defaultValue: 'New text' }],
},
{
handle: 'clear',
displayName: 'Clear',
},
{
handle: 'setFocus',
displayName: 'Set focus',
},
{
handle: 'setBlur',
displayName: 'Set blur',
},
{
handle: 'setVisibility',
displayName: 'Set visibility',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setDisable',
displayName: 'Set disable',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setLoading',
displayName: 'Set loading',
params: [{ handle: 'loading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
],
definition: {
validation: {
mandatory: { value: '{{false}}' },
regex: { value: '' },
minLength: { value: '' },
maxLength: { value: '' },
customRule: { value: '' },
},
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
properties: {
value: { value: '' },
label: { value: 'Label' },
placeholder: { value: 'Enter email' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
loadingState: { value: '{{false}}' },
tooltip: { value: '' },
},
events: [],
styles: {
textColor: { value: '#1B1F24' },
borderColor: { value: '#CCD1D5' },
accentColor: { value: '#4368E3' },
errTextColor: { value: '#D72D39' },
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#fff' },
iconColor: { value: '#CCD1D5' },
direction: { value: 'left' },
width: { value: '{{33}}' },
alignment: { value: 'side' },
color: { value: '#1B1F24' },
auto: { value: '{{true}}' },
padding: { value: 'default' },
boxShadow: { value: '0px 0px 0px 0px #00000040' },
icon: { value: 'IconMailFilled' },
iconVisibility: { value: true },
},
},
};

View file

@ -333,7 +333,7 @@ export const formConfig = {
},
},
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background color',
validation: {
schema: { type: 'string' },
@ -351,7 +351,7 @@ export const formConfig = {
},
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border color',
validation: {
schema: { type: 'string' },

View file

@ -61,7 +61,7 @@ export const iconConfig = {
},
styles: {
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Color',
validation: {
schema: { type: 'string' },

View file

@ -143,8 +143,17 @@ export const imageConfig = {
},
accordian: 'Image',
},
alignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'center',
},
accordian: 'Image',
},
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: {
schema: { type: 'string' },
@ -153,7 +162,7 @@ export const imageConfig = {
accordian: 'Container',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: {
schema: { type: 'string' },
@ -179,11 +188,11 @@ export const imageConfig = {
padding: {
type: 'switch',
displayName: 'Padding',
validation: { schema: { type: 'string' }, defaultValue: 'default' },
options: [
{ displayName: 'Default', value: 'default' },
{ displayName: 'Custom', value: 'custom' },
],
validation: { schema: { type: 'string' }, defaultValue: 'default' },
accordian: 'Container',
isFxNotRequired: true,
},
@ -244,7 +253,6 @@ export const imageConfig = {
loadingState: { value: '{{false}}' },
disabledState: { value: '{{false}}' },
visibility: { value: '{{true}}' },
visible: { value: '{{true}}' },
},
events: [],
styles: {
@ -256,6 +264,7 @@ export const imageConfig = {
boxShadow: { value: '0px 0px 0px 0px #00000090' },
padding: { value: 'default' },
customPadding: { value: '{{0}}' },
alignment: { value: 'center' },
},
},
};

View file

@ -58,6 +58,9 @@ import { kanbanBoardConfig } from './kanbanBoard';
import { datetimePickerV2Config } from './datetimepickerV2';
import { datePickerV2Config } from './datepickerV2';
import { timePickerConfig } from './timepicker';
import { emailinputConfig } from './emailinput';
import { phoneinputConfig } from './phoneinput';
import { currencyinputConfig } from './currencyinput';
export {
buttonConfig,
@ -73,6 +76,9 @@ export {
datetimePickerV2Config,
datePickerV2Config,
timePickerConfig,
emailinputConfig,
phoneinputConfig,
currencyinputConfig,
checkboxConfig,
radiobuttonConfig, //!Depreciated
radiobuttonV2Config,

View file

@ -77,7 +77,7 @@ export const kanbanConfig = {
styles: {
disabledState: { type: 'toggle', displayName: 'Disable' },
visibility: { type: 'toggle', displayName: 'Visibility' },
accentColor: { type: 'color', displayName: 'Accent color' },
accentColor: { type: 'colorSwatches', displayName: 'Accent color' },
},
actions: [
{
@ -157,7 +157,7 @@ export const kanbanConfig = {
styles: {
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
accentColor: { value: '#4d72fa' },
accentColor: { value: 'var(--primary-brand)' },
},
},
};

View file

@ -30,7 +30,7 @@ export const kanbanBoardConfig = {
visibility: { type: 'toggle', displayName: 'Visibility' },
width: { type: 'number', displayName: 'Width' },
minWidth: { type: 'number', displayName: 'Min Width' },
accentColor: { type: 'color', displayName: 'Accent color' },
accentColor: { type: 'colorSwatches', displayName: 'Accent color' },
},
exposedVariables: {
columns: {},

View file

@ -12,14 +12,6 @@ export const linkConfig = {
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
properties: {
linkTarget: {
type: 'code',
displayName: 'Link target',
validation: {
schema: { type: 'string' },
defaultValue: 'https://dev.to/',
},
},
linkText: {
type: 'code',
displayName: 'Link text',
@ -28,6 +20,14 @@ export const linkConfig = {
defaultValue: 'Click here',
},
},
linkTarget: {
type: 'code',
displayName: 'Link target',
validation: {
schema: { type: 'string' },
defaultValue: 'https://dev.to/',
},
},
targetType: {
type: 'select',
displayName: 'Target type',
@ -39,6 +39,34 @@ export const linkConfig = {
schema: { type: 'string' },
},
},
loadingState: {
type: 'toggle',
displayName: 'Loading state',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
visibility: {
type: 'toggle',
displayName: 'Visibility',
validation: {
schema: { type: 'boolean' },
defaultValue: true,
},
section: 'additionalActions',
},
disabledState: {
type: 'toggle',
displayName: 'Disable',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
tooltip: {
type: 'code',
displayName: 'Tooltip',
validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
section: 'additionalActions',
placeholder: 'Enter tooltip text',
},
},
events: {
onClick: { displayName: 'On click' },
@ -46,21 +74,54 @@ export const linkConfig = {
},
styles: {
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
defaultValue: '#375FCF',
},
accordian: 'Link text',
},
textSize: {
type: 'number',
type: 'numberInput',
displayName: 'Text size',
validation: {
schema: { type: 'number' },
defaultValue: 14,
},
accordian: 'Link text',
},
horizontalAlignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'left',
},
accordian: 'Link text',
},
verticalAlignment: {
type: 'switch',
displayName: '',
validation: { schema: { type: 'string' }, defaultValue: 'center' },
showLabel: false,
isIcon: true,
options: [
{ displayName: 'alignverticallytop', value: 'top', iconName: 'alignverticallytop' },
{ displayName: 'alignverticallycenter', value: 'center', iconName: 'alignverticallycenter' },
{ displayName: 'alignverticallybottom', value: 'bottom', iconName: 'alignverticallybottom' },
],
accordian: 'Link text',
isFxNotRequired: true,
},
icon: {
type: 'icon',
displayName: 'Icon',
validation: { schema: { type: 'string' }, defaultValue: 'IconHome2' },
accordian: 'Link text',
visibility: false,
},
underline: {
type: 'select',
displayName: 'Underline',
@ -73,13 +134,37 @@ export const linkConfig = {
schema: { type: 'string' },
defaultValue: 'on-hover',
},
accordian: 'Link text',
},
visibility: {
type: 'toggle',
displayName: 'Visibility',
boxShadow: {
type: 'boxShadow',
displayName: 'Box Shadow',
validation: {
schema: { type: 'boolean' },
defaultValue: true,
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: '0px 0px 0px 0px #00000040',
},
accordian: 'Link text',
},
padding: {
type: 'switch',
displayName: 'Padding',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: 'default',
},
isFxNotRequired: true,
options: [
{ displayName: 'Default', value: 'default' },
{ displayName: 'None', value: 'none' },
],
accordian: 'container',
},
alignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'left',
},
},
},
@ -89,6 +174,31 @@ export const linkConfig = {
handle: 'click',
displayName: 'Click',
},
{
handle: 'setLinkTarget',
displayName: 'Set link target',
params: [{ handle: 'setLinkTargetState', displayName: 'Value', defaultValue: '', type: 'code' }],
},
{
handle: 'setLinkText',
displayName: 'Set link text',
params: [{ handle: 'setLinkTextState', displayName: 'Value', defaultValue: '', type: 'code' }],
},
{
handle: 'setVisibility',
displayName: 'Set visibility',
params: [{ handle: 'isVisible', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setDisable',
displayName: 'Set disable',
params: [{ handle: 'isDisabled', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setLoading',
displayName: 'Set loading',
params: [{ handle: 'isLoading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
],
definition: {
others: {
@ -99,13 +209,22 @@ export const linkConfig = {
linkTarget: { value: 'https://dev.to/' },
linkText: { value: 'Click here' },
targetType: { value: 'new' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
tooltip: { value: '' },
loadingState: { value: '{{false}}' },
},
events: [],
styles: {
textColor: { value: '#375FCF' },
textColor: { value: '#4368E3' },
textSize: { value: '{{14}}' },
underline: { value: 'on-hover' },
visibility: { value: '{{true}}' },
verticalAlignment: { value: 'center' },
horizontalAlignment: { value: 'left' },
padding: { value: 'default' },
boxShadow: { value: '0px 0px 0px 0px #00000040' },
icon: { value: 'IconLink' },
iconVisibility: { value: false },
},
},
};

View file

@ -13,6 +13,7 @@ export const listviewConfig = {
top: 15,
left: 3,
height: 100,
width: 7,
},
properties: ['source'],
accessorKey: 'imageURL',
@ -124,7 +125,7 @@ export const listviewConfig = {
},
styles: {
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background color',
validation: {
schema: { type: 'string' },
@ -132,7 +133,7 @@ export const listviewConfig = {
},
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border color',
validation: {
schema: { type: 'string' },

View file

@ -81,7 +81,7 @@ export const modalConfig = {
},
styles: {
headerBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Header background color',
validation: {
schema: { type: 'string' },
@ -89,7 +89,7 @@ export const modalConfig = {
},
},
headerTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Header title color',
validation: {
schema: { type: 'string' },
@ -97,7 +97,7 @@ export const modalConfig = {
},
},
bodyBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Body background color',
validation: {
schema: { type: 'string' },
@ -121,7 +121,7 @@ export const modalConfig = {
},
},
triggerButtonBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Trigger button background color',
validation: {
schema: { type: 'string' },
@ -129,7 +129,7 @@ export const modalConfig = {
},
},
triggerButtonTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Trigger button text color',
validation: {
schema: { type: 'string' },
@ -175,7 +175,7 @@ export const modalConfig = {
bodyBackgroundColor: { value: '#ffffffff' },
disabledState: { value: '{{false}}' },
visibility: { value: '{{true}}' },
triggerButtonBackgroundColor: { value: '#4D72FA' },
triggerButtonBackgroundColor: { value: 'var(--primary-brand)' },
triggerButtonTextColor: { value: '#ffffffff' },
},
},

View file

@ -165,7 +165,7 @@ export const multiselectV2Config = {
styles: {
labelColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Color',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
@ -218,32 +218,32 @@ export const multiselectV2Config = {
},
fieldBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
fieldBorderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
selectedTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error Text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
@ -256,7 +256,7 @@ export const multiselectV2Config = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Icon color',
validation: {
schema: { type: 'string' },
@ -365,7 +365,7 @@ export const multiselectV2Config = {
icon: { value: 'IconHome2' },
iconVisibility: { value: false },
iconColor: { value: '#6A727C' },
accentColor: { value: '#4368E3' },
accentColor: { value: 'var(--primary-brand)' },
},
},
};

View file

@ -72,7 +72,7 @@ export const numberinputConfig = {
},
styles: {
color: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
@ -124,31 +124,31 @@ export const numberinputConfig = {
},
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
validation: { schema: { type: 'string' }, defaultValue: 'var(--primary-brand)' },
accordian: 'field',
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
@ -161,7 +161,7 @@ export const numberinputConfig = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Icon color',
validation: { schema: { type: 'string' }, defaultValue: '#CFD3D859' },
accordian: 'field',
@ -279,7 +279,7 @@ export const numberinputConfig = {
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#fff' },
borderColor: { value: '#CCD1D5' },
accentColor: { value: '#4368E3' },
accentColor: { value: 'var(--primary-brand)' },
errTextColor: { value: '#D72D39' },
textColor: { value: '#1B1F24' },
color: { value: '#1B1F24' },

View file

@ -50,6 +50,14 @@ export const paginationConfig = {
defaultValue: false,
},
},
alignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'left',
},
},
},
exposedVariables: {
totalPages: null,
@ -73,6 +81,7 @@ export const paginationConfig = {
styles: {
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
alignment: { value: 'left' },
},
},
};

View file

@ -84,7 +84,7 @@ export const passinputConfig = {
},
styles: {
color: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
@ -136,31 +136,31 @@ export const passinputConfig = {
},
backgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
accentColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
validation: { schema: { type: 'string' }, defaultValue: 'var(--primary-brand)' },
accordian: 'field',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
@ -173,7 +173,7 @@ export const passinputConfig = {
visibility: false,
},
iconColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Icon color',
validation: { schema: { type: 'string' }, defaultValue: '#CFD3D859' },
accordian: 'field',
@ -278,7 +278,7 @@ export const passinputConfig = {
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#fff' },
borderColor: { value: '#CCD1D5' },
accentColor: { value: '#4368E3' },
accentColor: { value: 'var(--primary-brand)' },
errTextColor: { value: '#D72D39' },
textColor: { value: '#1B1F24' },
iconColor: { value: '#CFD3D859' },

View file

@ -0,0 +1,288 @@
export const phoneinputConfig = {
name: 'PhoneInput',
displayName: 'Phone Input',
description: 'Phone input field',
component: 'PhoneInput',
defaultSize: {
width: 10,
height: 40,
},
others: {
showOnDesktop: { type: 'toggle', displayName: 'Show on desktop' },
showOnMobile: { type: 'toggle', displayName: 'Show on mobile' },
},
properties: {
label: {
type: 'code',
displayName: 'Label',
validation: { schema: { type: 'string' }, defaultValue: 'Label' },
},
placeholder: {
type: 'code',
displayName: 'Placeholder',
validation: {
schema: { type: 'string' },
defaultValue: 'Enter your input',
},
},
value: {
type: 'code',
displayName: 'Default value',
validation: {
schema: {
type: 'string',
},
defaultValue: 'Default value',
},
},
isCountryChangeEnabled: {
type: 'toggle',
displayName: 'Enable country change',
validation: { schema: { type: 'boolean' }, defaultValue: true },
},
loadingState: {
type: 'toggle',
displayName: 'Loading state',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
visibility: {
type: 'toggle',
displayName: 'Visibility',
validation: { schema: { type: 'boolean' }, defaultValue: true },
section: 'additionalActions',
},
disabledState: {
type: 'toggle',
displayName: 'Disable',
validation: { schema: { type: 'boolean' }, defaultValue: false },
section: 'additionalActions',
},
tooltip: {
type: 'code',
displayName: 'Tooltip',
validation: { schema: { type: 'string' }, defaultValue: 'Tooltip text' },
section: 'additionalActions',
placeholder: 'Enter tooltip text',
},
},
validation: {
mandatory: { type: 'toggle', displayName: 'Make this field mandatory' },
regex: { type: 'code', displayName: 'Regex', placeholder: '^[a-zA-Z0-9_ -]{3,16}$' },
minLength: { type: 'code', displayName: 'Min length', placeholder: 'Enter min length' },
maxLength: { type: 'code', displayName: 'Max length', placeholder: 'Enter max length' },
customRule: {
type: 'code',
displayName: 'Custom validation',
placeholder: `{{components.text2.text=='yes'&&'valid'}}`,
},
},
events: {
onChange: { displayName: 'On change' },
onEnterPressed: { displayName: 'On enter pressed' },
onFocus: { displayName: 'On focus' },
onBlur: { displayName: 'On blur' },
},
styles: {
color: {
type: 'color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
},
alignment: {
type: 'switch',
displayName: 'Alignment',
validation: { schema: { type: 'string' }, defaultValue: 'side' },
options: [
{ displayName: 'Side', value: 'side' },
{ displayName: 'Top', value: 'top' },
],
accordian: 'label',
},
direction: {
type: 'switch',
displayName: '',
validation: { schema: { type: 'string' }, defaultValue: 'left' },
showLabel: false,
isIcon: true,
options: [
{ displayName: 'alignleftinspector', value: 'left', iconName: 'alignleftinspector' },
{ displayName: 'alignrightinspector', value: 'right', iconName: 'alignrightinspector' },
],
accordian: 'label',
isFxNotRequired: true,
},
width: {
type: 'slider',
displayName: 'Width',
accordian: 'label',
conditionallyRender: {
key: 'alignment',
value: 'side',
},
isFxNotRequired: true,
},
auto: {
type: 'checkbox',
displayName: 'auto',
showLabel: false,
validation: { schema: { type: 'boolean' }, defaultValue: true },
accordian: 'label',
conditionallyRender: {
key: 'alignment',
value: 'side',
},
isFxNotRequired: true,
},
backgroundColor: {
type: 'color',
displayName: 'Background',
validation: { schema: { type: 'string' }, defaultValue: '#fff' },
accordian: 'field',
},
borderColor: {
type: 'color',
displayName: 'Border',
validation: { schema: { type: 'string' }, defaultValue: '#CCD1D5' },
accordian: 'field',
},
accentColor: {
type: 'color',
displayName: 'Accent',
validation: { schema: { type: 'string' }, defaultValue: '#4368E3' },
accordian: 'field',
},
textColor: {
type: 'color',
displayName: 'Text',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'field',
},
errTextColor: {
type: 'color',
displayName: 'Error text',
validation: { schema: { type: 'string' }, defaultValue: '#D72D39' },
accordian: 'field',
},
borderRadius: {
type: 'numberInput',
displayName: 'Border radius',
validation: { schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] }, defaultValue: 6 },
accordian: 'field',
},
boxShadow: {
type: 'boxShadow',
displayName: 'Box Shadow',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: '0px 0px 0px 0px #00000040',
},
accordian: 'field',
},
padding: {
type: 'switch',
displayName: 'Padding',
validation: {
schema: { type: 'union', schemas: [{ type: 'string' }, { type: 'number' }] },
defaultValue: 'default',
},
isFxNotRequired: true,
options: [
{ displayName: 'Default', value: 'default' },
{ displayName: 'None', value: 'none' },
],
accordian: 'container',
},
},
exposedVariables: {
value: '',
isMandatory: false,
isVisible: true,
isDisabled: false,
isLoading: false,
},
actions: [
{
handle: 'setValue',
displayName: 'Set Value',
params: [
{ handle: 'value', displayName: 'value', defaultValue: '' },
{ handle: 'country', displayName: 'country', defaultValue: '' },
],
},
{
handle: 'setCountryCode',
displayName: 'Set country code',
params: [{ handle: 'countryCode', displayName: 'Country code', defaultValue: '' }],
},
{
handle: 'clear',
displayName: 'Clear',
},
{
handle: 'setFocus',
displayName: 'Set focus',
},
{
handle: 'setBlur',
displayName: 'Set blur',
},
{
handle: 'setVisibility',
displayName: 'Set visibility',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setDisable',
displayName: 'Set disable',
params: [{ handle: 'disable', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
{
handle: 'setLoading',
displayName: 'Set loading',
params: [{ handle: 'loading', displayName: 'Value', defaultValue: '{{false}}', type: 'toggle' }],
},
],
definition: {
validation: {
mandatory: { value: '{{false}}' },
regex: { value: '' },
minLength: { value: '' },
maxLength: { value: '' },
customRule: { value: '' },
},
others: {
showOnDesktop: { value: '{{true}}' },
showOnMobile: { value: '{{false}}' },
},
properties: {
value: { value: '' },
label: { value: 'Label' },
placeholder: { value: 'Enter your phone' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
loadingState: { value: '{{false}}' },
tooltip: { value: '' },
isCountryChangeEnabled: { value: '{{true}}' },
},
events: [],
styles: {
textColor: { value: '#1B1F24' },
borderColor: { value: '#CCD1D5' },
accentColor: { value: '#4368E3' },
errTextColor: { value: '#D72D39' },
borderRadius: { value: '{{6}}' },
backgroundColor: { value: '#fff' },
direction: { value: 'left' },
width: { value: '{{33}}' },
alignment: { value: 'side' },
color: { value: '#1B1F24' },
auto: { value: '{{true}}' },
padding: { value: 'default' },
boxShadow: { value: '0px 0px 0px 0px #00000040' },
},
},
};

View file

@ -89,7 +89,7 @@ export const radiobuttonV2Config = {
},
styles: {
labelColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Color',
validation: { schema: { type: 'string' }, defaultValue: '#1B1F24' },
accordian: 'label',
@ -139,7 +139,7 @@ export const radiobuttonV2Config = {
isFxNotRequired: true,
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: {
schema: { type: 'string' },
@ -147,7 +147,7 @@ export const radiobuttonV2Config = {
accordian: 'switch',
},
switchOnBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Checked background',
validation: {
schema: { type: 'string' },
@ -158,7 +158,7 @@ export const radiobuttonV2Config = {
tooltipPlacement: 'bottom',
},
switchOffBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Unchecked background',
validation: {
schema: { type: 'string' },
@ -169,7 +169,7 @@ export const radiobuttonV2Config = {
tooltipPlacement: 'bottom',
},
handleColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Handle color',
validation: {
schema: { type: 'string' },
@ -177,7 +177,7 @@ export const radiobuttonV2Config = {
accordian: 'switch',
},
optionsTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text',
validation: {
schema: { type: 'string' },

View file

@ -53,7 +53,7 @@ export const radiobuttonConfig = {
},
styles: {
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -61,11 +61,11 @@ export const radiobuttonConfig = {
},
},
activeColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Active color',
validation: {
schema: { type: 'string' },
defaultValue: '#000000',
defaultValue: 'var(--primary-brand)',
},
},
visibility: {
@ -113,7 +113,7 @@ export const radiobuttonConfig = {
events: [],
styles: {
textColor: { value: '' },
activeColor: { value: '' },
activeColor: { value: 'var(--primary-brand)' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
},

View file

@ -53,7 +53,7 @@ export const rangeSliderConfig = {
},
styles: {
lineColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Line color',
validation: {
schema: { type: 'string' },
@ -61,7 +61,7 @@ export const rangeSliderConfig = {
},
},
handleColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Handle color',
validation: {
schema: { type: 'string' },
@ -69,7 +69,7 @@ export const rangeSliderConfig = {
},
},
trackColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Track color',
validation: {
schema: { type: 'string' },
@ -109,7 +109,7 @@ export const rangeSliderConfig = {
styles: {
lineColor: { value: '' },
handleColor: { value: '' },
trackColor: { value: '' },
trackColor: { value: 'var(--primary-brand)' },
visibility: { value: '{{true}}' },
},
},

View file

@ -23,11 +23,11 @@ export const spinnerConfig = {
},
},
colour: {
type: 'color',
type: 'colorSwatches',
displayName: 'Colour',
validation: {
schema: { type: 'string' },
defaultValue: '#0565ff',
defaultValue: 'var(--primary-brand)',
},
},
size: {
@ -54,7 +54,7 @@ export const spinnerConfig = {
styles: {
visibility: { value: '{{true}}' },
size: { value: 'sm' },
colour: { value: '#0565ff' },
colour: { value: 'var(--primary-brand)' },
},
},
};

View file

@ -58,7 +58,7 @@ export const starratingConfig = {
},
styles: {
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Star color',
validation: {
schema: { type: 'string' },
@ -66,7 +66,7 @@ export const starratingConfig = {
},
},
labelColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Label color',
validation: {
schema: { type: 'string' },

View file

@ -55,22 +55,22 @@ export const statisticsConfig = {
events: {},
styles: {
primaryLabelColour: {
type: 'color',
type: 'colorSwatches',
displayName: 'Primary label colour',
validation: { schema: { type: 'string' }, defaultValue: '#8092AB' },
},
primaryTextColour: {
type: 'color',
type: 'colorSwatches',
displayName: 'Primary text colour',
validation: { schema: { type: 'string' }, defaultValue: '#000000' },
},
secondaryLabelColour: {
type: 'color',
type: 'colorSwatches',
displayName: 'Secondary label colour',
validation: { schema: { type: 'string' }, defaultValue: '#8092AB' },
},
secondaryTextColour: {
type: 'color',
type: 'colorSwatches',
displayName: 'Secondary text colour',
validation: { schema: { type: 'string' }, defaultValue: '#36AF8B' },
},

View file

@ -45,15 +45,15 @@ export const stepsConfig = {
},
styles: {
color: {
type: 'color',
displayName: 'Color',
type: 'colorSwatches',
displayName: 'colorSwatches',
validation: {
schema: { type: 'string' },
defaultValue: '#000000',
defaultValue: 'var(--primary-brand)',
},
},
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -101,7 +101,7 @@ export const stepsConfig = {
styles: {
visibility: { value: '{{true}}' },
theme: { value: 'titles' },
color: { value: '' },
color: { value: 'var(--primary-brand)' },
textColor: { value: '' },
},
},

View file

@ -32,6 +32,14 @@ export const svgImageConfig = {
defaultValue: true,
},
},
alignment: {
type: 'alignButtons',
displayName: 'Alignment',
validation: {
schema: { type: 'string' },
defaultValue: 'left',
},
},
},
exposedVariables: {
value: {},
@ -50,6 +58,7 @@ export const svgImageConfig = {
events: [],
styles: {
visibility: { value: '{{true}}' },
alignment: { value: 'left' },
},
},
};

View file

@ -157,7 +157,7 @@ export const tableConfig = {
defaultValue: 'clientSide',
},
actionButtonBackgroundColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Background color',
validation: {
schema: { type: 'string' },
@ -165,7 +165,7 @@ export const tableConfig = {
},
},
actionButtonTextColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text color',
validation: {
schema: { type: 'string' },
@ -293,7 +293,7 @@ export const tableConfig = {
},
styles: {
textColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Text Color',
validation: {
schema: { type: 'string' },
@ -404,7 +404,7 @@ export const tableConfig = {
accordian: 'Container',
},
borderColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Border',
validation: {
schema: { type: 'string' },

View file

@ -13,6 +13,7 @@ export const tabsConfig = {
top: 60,
left: 17,
height: 100,
width: 7,
},
tab: 0,
properties: ['source'],
@ -109,11 +110,11 @@ export const tabsConfig = {
events: { onTabSwitch: { displayName: 'On tab switch' } },
styles: {
highlightColor: {
type: 'color',
type: 'colorSwatches',
displayName: 'Highlight color',
validation: {
schema: { type: 'string' },
defaultValue: '#375FCF',
defaultValue: 'var(--primary-brand)',
},
},
visibility: {
@ -174,7 +175,7 @@ export const tabsConfig = {
},
events: [],
styles: {
highlightColor: { value: '#375FCF' },
highlightColor: { value: 'var(--primary-brand)' },
visibility: { value: '{{true}}' },
disabledState: { value: '{{false}}' },
tabWidth: { value: 'auto' },

Some files were not shown because too many files have changed in this diff Show more