labellife-design-tool 2.2.7 → 2.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useState, useEffect, useCallback, useRef, memo, Fragment as Fragment$1 } from 'react';
2
- import { ButtonBase, Box, Typography, Button, IconButton, TextField, InputAdornment, ClickAwayListener, Paper, ListItem, ListItemIcon, ListItemText, List, Switch, Slider, CircularProgress, FormControlLabel, Checkbox, FormControl, InputLabel, Select, MenuItem, Divider, Alert, Chip, Autocomplete, Tooltip, ToggleButtonGroup, ToggleButton, Menu, Popover } from '@mui/material';
2
+ import { ButtonBase, Box, Typography, Button, IconButton, TextField, InputAdornment, ClickAwayListener, Paper, ListItem, ListItemIcon, ListItemText, List, Switch, Slider, CircularProgress, FormControlLabel, Checkbox, FormControl, InputLabel, Select, MenuItem, Divider, Alert, Chip, Autocomplete, Tooltip, ToggleButtonGroup, ToggleButton, Menu, Popover, FormGroup, RadioGroup, Radio } from '@mui/material';
3
3
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
4
  import { types, getParent, getRoot, getSnapshot, applySnapshot, destroy } from 'mobx-state-tree';
5
5
  import { v4 } from 'uuid';
@@ -28,6 +28,9 @@ import CloseIcon from '@mui/icons-material/Close';
28
28
  import InputIcon from '@mui/icons-material/Input';
29
29
  import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
30
30
  import NumbersIcon from '@mui/icons-material/Numbers';
31
+ import RadioButtonCheckedIcon from '@mui/icons-material/RadioButtonChecked';
32
+ import FormatListBulletedIcon from '@mui/icons-material/FormatListBulleted';
33
+ import AddIcon from '@mui/icons-material/Add';
31
34
  import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown';
32
35
  import FileUploadIcon from '@mui/icons-material/FileUpload';
33
36
  import UndoIcon from '@mui/icons-material/Undo';
@@ -6897,7 +6900,7 @@ function ImagesGrid(_ref) {
6897
6900
  });
6898
6901
  }
6899
6902
 
6900
- var _excluded$2 = ["inputField", "promptText", "inputType", "required", "placeholder"];
6903
+ var _excluded$2 = ["inputField", "promptText", "inputType", "required", "placeholder", "options", "minSelections", "maxSelections"];
6901
6904
  var IMAGE_PLACEHOLDER_SRC = "data:image/svg+xml;charset=utf-8,".concat(encodeURIComponent("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"400\" height=\"400\" viewBox=\"0 0 400 400\">\n <rect width=\"400\" height=\"400\" fill=\"#f0f2f5\" rx=\"12\"/>\n <rect x=\"110\" y=\"90\" width=\"180\" height=\"145\" rx=\"10\" fill=\"#dde1e7\"/>\n <circle cx=\"158\" cy=\"135\" r=\"22\" fill=\"#f0f2f5\"/>\n <polygon points=\"110,235 168,163 210,205 250,163 290,235\" fill=\"#c8cdd6\"/>\n <rect x=\"140\" y=\"268\" width=\"120\" height=\"14\" rx=\"7\" fill=\"#c8cdd6\"/>\n <rect x=\"160\" y=\"292\" width=\"80\" height=\"10\" rx=\"5\" fill=\"#dde1e7\"/>\n </svg>"));
6902
6905
 
6903
6906
  // ── Date formatting helpers ──────────────────────────────────────────
@@ -6939,12 +6942,84 @@ function formatDate$1(date, format) {
6939
6942
  }
6940
6943
  }
6941
6944
 
6945
+ // ── Options list editor ──────────────────────────────────────────────
6946
+ var OptionsEditor = function OptionsEditor(_ref) {
6947
+ var options = _ref.options,
6948
+ _onChange = _ref.onChange;
6949
+ return /*#__PURE__*/jsxs(Box, {
6950
+ sx: {
6951
+ ml: 6.5,
6952
+ mr: 1,
6953
+ display: 'flex',
6954
+ flexDirection: 'column',
6955
+ gap: 0.75
6956
+ },
6957
+ children: [options.map(function (opt, i) {
6958
+ return /*#__PURE__*/jsxs(Box, {
6959
+ sx: {
6960
+ display: 'flex',
6961
+ gap: 0.5,
6962
+ alignItems: 'center'
6963
+ },
6964
+ children: [/*#__PURE__*/jsx(TextField, {
6965
+ size: "small",
6966
+ value: opt,
6967
+ onChange: function onChange(e) {
6968
+ var next = _toConsumableArray(options);
6969
+ next[i] = e.target.value;
6970
+ _onChange(next);
6971
+ },
6972
+ placeholder: "Option ".concat(i + 1),
6973
+ sx: {
6974
+ flex: 1,
6975
+ '& .MuiInputBase-input': {
6976
+ fontSize: 12,
6977
+ py: 0.75
6978
+ }
6979
+ }
6980
+ }), /*#__PURE__*/jsx(IconButton, {
6981
+ size: "small",
6982
+ onClick: function onClick() {
6983
+ return _onChange(options.filter(function (_, j) {
6984
+ return j !== i;
6985
+ }));
6986
+ },
6987
+ disabled: options.length <= 1,
6988
+ sx: {
6989
+ color: '#bbb',
6990
+ '&:hover': {
6991
+ color: '#e57373'
6992
+ }
6993
+ },
6994
+ children: /*#__PURE__*/jsx(DeleteIcon, {
6995
+ fontSize: "small"
6996
+ })
6997
+ })]
6998
+ }, i);
6999
+ }), /*#__PURE__*/jsx(Button, {
7000
+ size: "small",
7001
+ startIcon: /*#__PURE__*/jsx(AddIcon, {}),
7002
+ onClick: function onClick() {
7003
+ return _onChange([].concat(_toConsumableArray(options), ['']));
7004
+ },
7005
+ sx: {
7006
+ alignSelf: 'flex-start',
7007
+ fontSize: 11,
7008
+ textTransform: 'none',
7009
+ color: '#0d83cd',
7010
+ p: 0.5
7011
+ },
7012
+ children: "Add option"
7013
+ })]
7014
+ });
7015
+ };
7016
+
6942
7017
  // ── Card component ───────────────────────────────────────────────────
6943
- var InputFieldCard = function InputFieldCard(_ref) {
6944
- var icon = _ref.icon,
6945
- label = _ref.label,
6946
- description = _ref.description,
6947
- onClick = _ref.onClick;
7018
+ var InputFieldCard = function InputFieldCard(_ref2) {
7019
+ var icon = _ref2.icon,
7020
+ label = _ref2.label,
7021
+ description = _ref2.description,
7022
+ onClick = _ref2.onClick;
6948
7023
  return /*#__PURE__*/jsxs(Box, {
6949
7024
  onClick: onClick,
6950
7025
  sx: {
@@ -7000,8 +7075,8 @@ var InputFieldCard = function InputFieldCard(_ref) {
7000
7075
  };
7001
7076
 
7002
7077
  // ── Panel content ────────────────────────────────────────────────────
7003
- var InputFieldsPanelContent = observer(function (_ref2) {
7004
- var store = _ref2.store;
7078
+ var InputFieldsPanelContent = observer(function (_ref3) {
7079
+ var store = _ref3.store;
7005
7080
  var _useState = useState('MM-DD-YYYY'),
7006
7081
  _useState2 = _slicedToArray(_useState, 2),
7007
7082
  dateFormat = _useState2[0],
@@ -7038,6 +7113,34 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7038
7113
  _useState16 = _slicedToArray(_useState15, 2),
7039
7114
  imageRequired = _useState16[0],
7040
7115
  setImageRequired = _useState16[1];
7116
+ var _useState17 = useState(''),
7117
+ _useState18 = _slicedToArray(_useState17, 2),
7118
+ radioPrompt = _useState18[0],
7119
+ setRadioPrompt = _useState18[1];
7120
+ var _useState19 = useState(false),
7121
+ _useState20 = _slicedToArray(_useState19, 2),
7122
+ radioRequired = _useState20[0],
7123
+ setRadioRequired = _useState20[1];
7124
+ var _useState21 = useState(['Option 1', 'Option 2']),
7125
+ _useState22 = _slicedToArray(_useState21, 2),
7126
+ radioOptions = _useState22[0],
7127
+ setRadioOptions = _useState22[1];
7128
+ var _useState23 = useState(''),
7129
+ _useState24 = _slicedToArray(_useState23, 2),
7130
+ listPrompt = _useState24[0],
7131
+ setListPrompt = _useState24[1];
7132
+ var _useState25 = useState(0),
7133
+ _useState26 = _slicedToArray(_useState25, 2),
7134
+ listMinSelections = _useState26[0],
7135
+ setListMinSelections = _useState26[1];
7136
+ var _useState27 = useState(2),
7137
+ _useState28 = _slicedToArray(_useState27, 2),
7138
+ listMaxSelections = _useState28[0],
7139
+ setListMaxSelections = _useState28[1];
7140
+ var _useState29 = useState(['Option 1', 'Option 2']),
7141
+ _useState30 = _slicedToArray(_useState29, 2),
7142
+ listOptions = _useState30[0],
7143
+ setListOptions = _useState30[1];
7041
7144
  var addInputElement = function addInputElement(inputType) {
7042
7145
  var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
7043
7146
  var page = store.activePage;
@@ -7080,6 +7183,16 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7080
7183
  placeholder = t('sidePanel.inputFields.integerPlaceholder', 'Enter number');
7081
7184
  defaultPrompt = t('sidePanel.inputFields.defaultIntegerPrompt', 'Please enter a number');
7082
7185
  break;
7186
+ case 'radio':
7187
+ dummyText = (extra.options || []).filter(Boolean)[0] || 'Option 1';
7188
+ placeholder = t('sidePanel.inputFields.radioPlaceholder', 'Select an option');
7189
+ defaultPrompt = t('sidePanel.inputFields.defaultRadioPrompt', 'Please select an option');
7190
+ break;
7191
+ case 'list':
7192
+ dummyText = (extra.options || []).filter(Boolean).slice(0, 2).join(', ') || 'Option 1, Option 2';
7193
+ placeholder = t('sidePanel.inputFields.listPlaceholder', 'Select options');
7194
+ defaultPrompt = t('sidePanel.inputFields.defaultListPrompt', 'Please select options');
7195
+ break;
7083
7196
  default:
7084
7197
  dummyText = 'Input';
7085
7198
  placeholder = 'Input';
@@ -7098,7 +7211,7 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7098
7211
  fontFamily: 'Roboto',
7099
7212
  align: 'center',
7100
7213
  fill: '#333333',
7101
- custom: _objectSpread2({
7214
+ custom: _objectSpread2(_objectSpread2(_objectSpread2({
7102
7215
  inputField: true,
7103
7216
  inputType: inputType,
7104
7217
  placeholder: placeholder,
@@ -7106,6 +7219,11 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7106
7219
  required: extra.required || false
7107
7220
  }, inputType === 'date' ? {
7108
7221
  dateFormat: extra.dateFormat || 'MM-DD-YYYY'
7222
+ } : {}), ['radio', 'list'].includes(inputType) ? {
7223
+ options: (extra.options || []).filter(Boolean)
7224
+ } : {}), inputType === 'list' ? {
7225
+ minSelections: extra.minSelections || 0,
7226
+ maxSelections: extra.maxSelections || 0
7109
7227
  } : {})
7110
7228
  });
7111
7229
  }
@@ -7347,6 +7465,138 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7347
7465
  sx: {
7348
7466
  ml: 5.5
7349
7467
  }
7468
+ }), /*#__PURE__*/jsx(InputFieldCard, {
7469
+ icon: /*#__PURE__*/jsx(RadioButtonCheckedIcon, {
7470
+ fontSize: "small"
7471
+ }),
7472
+ label: t('sidePanel.inputFields.radioInput', 'Radio Input'),
7473
+ description: t('sidePanel.inputFields.radioInputDesc', 'Single option selection'),
7474
+ onClick: function onClick() {
7475
+ return addInputElement('radio', {
7476
+ promptText: radioPrompt,
7477
+ required: radioRequired,
7478
+ options: radioOptions
7479
+ });
7480
+ }
7481
+ }), /*#__PURE__*/jsx(TextField, {
7482
+ size: "small",
7483
+ placeholder: t('sidePanel.inputFields.promptTextHint', 'Prompt text shown to user...'),
7484
+ value: radioPrompt,
7485
+ onChange: function onChange(e) {
7486
+ return setRadioPrompt(e.target.value);
7487
+ },
7488
+ sx: {
7489
+ ml: 6.5,
7490
+ mr: 1,
7491
+ '& .MuiInputBase-input': {
7492
+ fontSize: 12,
7493
+ py: 0.75
7494
+ }
7495
+ }
7496
+ }), /*#__PURE__*/jsx(FormControlLabel, {
7497
+ control: /*#__PURE__*/jsx(Checkbox, {
7498
+ size: "small",
7499
+ checked: radioRequired,
7500
+ onChange: function onChange(e) {
7501
+ return setRadioRequired(e.target.checked);
7502
+ }
7503
+ }),
7504
+ label: /*#__PURE__*/jsx(Typography, {
7505
+ sx: {
7506
+ fontSize: 12
7507
+ },
7508
+ children: t('sidePanel.inputFields.required', 'Required')
7509
+ }),
7510
+ sx: {
7511
+ ml: 5.5
7512
+ }
7513
+ }), /*#__PURE__*/jsx(OptionsEditor, {
7514
+ options: radioOptions,
7515
+ onChange: setRadioOptions
7516
+ }), /*#__PURE__*/jsx(InputFieldCard, {
7517
+ icon: /*#__PURE__*/jsx(FormatListBulletedIcon, {
7518
+ fontSize: "small"
7519
+ }),
7520
+ label: t('sidePanel.inputFields.listInput', 'List Input'),
7521
+ description: t('sidePanel.inputFields.listInputDesc', 'Multiple option selection'),
7522
+ onClick: function onClick() {
7523
+ return addInputElement('list', {
7524
+ promptText: listPrompt,
7525
+ minSelections: listMinSelections,
7526
+ maxSelections: listMaxSelections,
7527
+ options: listOptions
7528
+ });
7529
+ }
7530
+ }), /*#__PURE__*/jsx(TextField, {
7531
+ size: "small",
7532
+ placeholder: t('sidePanel.inputFields.promptTextHint', 'Prompt text shown to user...'),
7533
+ value: listPrompt,
7534
+ onChange: function onChange(e) {
7535
+ return setListPrompt(e.target.value);
7536
+ },
7537
+ sx: {
7538
+ ml: 6.5,
7539
+ mr: 1,
7540
+ '& .MuiInputBase-input': {
7541
+ fontSize: 12,
7542
+ py: 0.75
7543
+ }
7544
+ }
7545
+ }), /*#__PURE__*/jsx(OptionsEditor, {
7546
+ options: listOptions,
7547
+ onChange: setListOptions
7548
+ }), /*#__PURE__*/jsxs(Box, {
7549
+ sx: {
7550
+ display: 'flex',
7551
+ gap: 1,
7552
+ ml: 6.5,
7553
+ mr: 1
7554
+ },
7555
+ children: [/*#__PURE__*/jsx(TextField, {
7556
+ size: "small",
7557
+ type: "number",
7558
+ label: t('sidePanel.inputFields.minSelections', 'Min select'),
7559
+ value: listMinSelections,
7560
+ onChange: function onChange(e) {
7561
+ return setListMinSelections(Math.max(0, parseInt(e.target.value) || 0));
7562
+ },
7563
+ inputProps: {
7564
+ min: 0
7565
+ },
7566
+ sx: {
7567
+ flex: 1,
7568
+ '& .MuiInputBase-input': {
7569
+ fontSize: 12,
7570
+ py: 0.75
7571
+ }
7572
+ }
7573
+ }), /*#__PURE__*/jsx(TextField, {
7574
+ size: "small",
7575
+ type: "number",
7576
+ label: t('sidePanel.inputFields.maxSelections', 'Max select'),
7577
+ value: listMaxSelections,
7578
+ onChange: function onChange(e) {
7579
+ return setListMaxSelections(Math.max(0, parseInt(e.target.value) || 0));
7580
+ },
7581
+ inputProps: {
7582
+ min: 0
7583
+ },
7584
+ sx: {
7585
+ flex: 1,
7586
+ '& .MuiInputBase-input': {
7587
+ fontSize: 12,
7588
+ py: 0.75
7589
+ }
7590
+ }
7591
+ })]
7592
+ }), /*#__PURE__*/jsx(Typography, {
7593
+ variant: "caption",
7594
+ sx: {
7595
+ ml: 6.5,
7596
+ color: '#999',
7597
+ fontSize: 10
7598
+ },
7599
+ children: listMinSelections > 0 ? "Required \xB7 min ".concat(listMinSelections).concat(listMaxSelections > 0 ? ", max ".concat(listMaxSelections) : ', no max') : "Optional \xB7 max ".concat(listMaxSelections > 0 ? listMaxSelections : '∞')
7350
7600
  })]
7351
7601
  }), /*#__PURE__*/jsx(Divider, {
7352
7602
  sx: {
@@ -7376,21 +7626,33 @@ var InputFieldsPanelContent = observer(function (_ref2) {
7376
7626
  });
7377
7627
 
7378
7628
  // ── Mark-as-variable sub-form ─────────────────────────────────────────
7379
- var MarkAsVariableForm = observer(function (_ref3) {
7629
+ var MarkAsVariableForm = observer(function (_ref4) {
7380
7630
  var _selectedElement$cust;
7381
- var store = _ref3.store;
7382
- var _useState17 = useState(''),
7383
- _useState18 = _slicedToArray(_useState17, 2),
7384
- markLabel = _useState18[0],
7385
- setMarkLabel = _useState18[1];
7386
- var _useState19 = useState(false),
7387
- _useState20 = _slicedToArray(_useState19, 2),
7388
- markRequired = _useState20[0],
7389
- setMarkRequired = _useState20[1];
7390
- var _useState21 = useState('text'),
7391
- _useState22 = _slicedToArray(_useState21, 2),
7392
- markInputType = _useState22[0],
7393
- setMarkInputType = _useState22[1];
7631
+ var store = _ref4.store;
7632
+ var _useState31 = useState(''),
7633
+ _useState32 = _slicedToArray(_useState31, 2),
7634
+ markLabel = _useState32[0],
7635
+ setMarkLabel = _useState32[1];
7636
+ var _useState33 = useState(false),
7637
+ _useState34 = _slicedToArray(_useState33, 2),
7638
+ markRequired = _useState34[0],
7639
+ setMarkRequired = _useState34[1];
7640
+ var _useState35 = useState('text'),
7641
+ _useState36 = _slicedToArray(_useState35, 2),
7642
+ markInputType = _useState36[0],
7643
+ setMarkInputType = _useState36[1];
7644
+ var _useState37 = useState(['Option 1', 'Option 2']),
7645
+ _useState38 = _slicedToArray(_useState37, 2),
7646
+ markOptions = _useState38[0],
7647
+ setMarkOptions = _useState38[1];
7648
+ var _useState39 = useState(0),
7649
+ _useState40 = _slicedToArray(_useState39, 2),
7650
+ markMinSelections = _useState40[0],
7651
+ setMarkMinSelections = _useState40[1];
7652
+ var _useState41 = useState(2),
7653
+ _useState42 = _slicedToArray(_useState41, 2),
7654
+ markMaxSelections = _useState42[0],
7655
+ setMarkMaxSelections = _useState42[1];
7394
7656
  var selectedIds = store.selectedElementsIds || [];
7395
7657
  var selectedElement = selectedIds.length === 1 ? store.getElementById(selectedIds[0]) : null;
7396
7658
  var isImageElement = (selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.type) === 'image';
@@ -7399,37 +7661,52 @@ var MarkAsVariableForm = observer(function (_ref3) {
7399
7661
  var isAlreadyVariable = !!(selectedElement !== null && selectedElement !== void 0 && (_selectedElement$cust = selectedElement.custom) !== null && _selectedElement$cust !== void 0 && _selectedElement$cust.inputField);
7400
7662
  useEffect(function () {
7401
7663
  if (selectedElement && isSupportedElement) {
7402
- var _selectedElement$cust2, _selectedElement$cust3, _selectedElement$cust4;
7664
+ var _selectedElement$cust2, _selectedElement$cust3, _selectedElement$cust4, _selectedElement$cust5, _selectedElement$cust6, _selectedElement$cust7;
7403
7665
  setMarkLabel(((_selectedElement$cust2 = selectedElement.custom) === null || _selectedElement$cust2 === void 0 ? void 0 : _selectedElement$cust2.promptText) || '');
7404
7666
  setMarkRequired(!!((_selectedElement$cust3 = selectedElement.custom) !== null && _selectedElement$cust3 !== void 0 && _selectedElement$cust3.required));
7405
7667
  setMarkInputType(isImageElement ? 'image' : ((_selectedElement$cust4 = selectedElement.custom) === null || _selectedElement$cust4 === void 0 ? void 0 : _selectedElement$cust4.inputType) || 'text');
7668
+ setMarkOptions(((_selectedElement$cust5 = selectedElement.custom) === null || _selectedElement$cust5 === void 0 ? void 0 : _selectedElement$cust5.options) || ['Option 1', 'Option 2']);
7669
+ setMarkMinSelections(((_selectedElement$cust6 = selectedElement.custom) === null || _selectedElement$cust6 === void 0 ? void 0 : _selectedElement$cust6.minSelections) || 0);
7670
+ setMarkMaxSelections(((_selectedElement$cust7 = selectedElement.custom) === null || _selectedElement$cust7 === void 0 ? void 0 : _selectedElement$cust7.maxSelections) || 2);
7406
7671
  } else {
7407
7672
  setMarkLabel('');
7408
7673
  setMarkRequired(false);
7409
7674
  setMarkInputType('text');
7675
+ setMarkOptions(['Option 1', 'Option 2']);
7676
+ setMarkMinSelections(0);
7677
+ setMarkMaxSelections(2);
7410
7678
  }
7411
7679
  }, [selectedElement === null || selectedElement === void 0 ? void 0 : selectedElement.id]);
7412
7680
  var handleMark = function handleMark() {
7413
7681
  if (!selectedElement || !markLabel.trim()) return;
7682
+ var effectiveType = isImageElement ? 'image' : markInputType;
7414
7683
  selectedElement.set({
7415
- custom: _objectSpread2(_objectSpread2({}, selectedElement.custom), {}, {
7684
+ custom: _objectSpread2(_objectSpread2(_objectSpread2({}, selectedElement.custom), {}, {
7416
7685
  inputField: true,
7417
7686
  promptText: markLabel.trim(),
7418
- inputType: isImageElement ? 'image' : markInputType,
7687
+ inputType: effectiveType,
7419
7688
  required: markRequired
7420
- })
7689
+ }, ['radio', 'list'].includes(effectiveType) ? {
7690
+ options: markOptions.filter(Boolean)
7691
+ } : {}), effectiveType === 'list' ? {
7692
+ minSelections: markMinSelections,
7693
+ maxSelections: markMaxSelections
7694
+ } : {})
7421
7695
  });
7422
7696
  store.history.addUndoState();
7423
7697
  };
7424
7698
  var handleUnmark = function handleUnmark() {
7425
7699
  if (!selectedElement) return;
7426
- var _ref4 = selectedElement.custom || {};
7427
- _ref4.inputField;
7428
- _ref4.promptText;
7429
- _ref4.inputType;
7430
- _ref4.required;
7431
- _ref4.placeholder;
7432
- var rest = _objectWithoutProperties(_ref4, _excluded$2);
7700
+ var _ref5 = selectedElement.custom || {};
7701
+ _ref5.inputField;
7702
+ _ref5.promptText;
7703
+ _ref5.inputType;
7704
+ _ref5.required;
7705
+ _ref5.placeholder;
7706
+ _ref5.options;
7707
+ _ref5.minSelections;
7708
+ _ref5.maxSelections;
7709
+ var rest = _objectWithoutProperties(_ref5, _excluded$2);
7433
7710
  selectedElement.set({
7434
7711
  custom: rest
7435
7712
  });
@@ -7554,9 +7831,84 @@ var MarkAsVariableForm = observer(function (_ref3) {
7554
7831
  fontSize: 12
7555
7832
  },
7556
7833
  children: t('sidePanel.inputFields.dateInput', 'Date Input')
7834
+ }), /*#__PURE__*/jsx(MenuItem, {
7835
+ value: "radio",
7836
+ sx: {
7837
+ fontSize: 12
7838
+ },
7839
+ children: t('sidePanel.inputFields.radioInput', 'Radio Input')
7840
+ }), /*#__PURE__*/jsx(MenuItem, {
7841
+ value: "list",
7842
+ sx: {
7843
+ fontSize: 12
7844
+ },
7845
+ children: t('sidePanel.inputFields.listInput', 'List Input')
7557
7846
  })]
7558
7847
  })]
7559
- }), /*#__PURE__*/jsx(FormControlLabel, {
7848
+ }), isTextElement && (markInputType === 'radio' || markInputType === 'list') && /*#__PURE__*/jsxs(Fragment, {
7849
+ children: [/*#__PURE__*/jsx(Typography, {
7850
+ variant: "caption",
7851
+ sx: {
7852
+ color: '#888',
7853
+ fontSize: 11
7854
+ },
7855
+ children: "Options"
7856
+ }), /*#__PURE__*/jsx(OptionsEditor, {
7857
+ options: markOptions,
7858
+ onChange: setMarkOptions
7859
+ })]
7860
+ }), isTextElement && markInputType === 'list' && /*#__PURE__*/jsxs(Fragment, {
7861
+ children: [/*#__PURE__*/jsxs(Box, {
7862
+ sx: {
7863
+ display: 'flex',
7864
+ gap: 1
7865
+ },
7866
+ children: [/*#__PURE__*/jsx(TextField, {
7867
+ size: "small",
7868
+ type: "number",
7869
+ label: t('sidePanel.inputFields.minSelections', 'Min select'),
7870
+ value: markMinSelections,
7871
+ onChange: function onChange(e) {
7872
+ return setMarkMinSelections(Math.max(0, parseInt(e.target.value) || 0));
7873
+ },
7874
+ inputProps: {
7875
+ min: 0
7876
+ },
7877
+ sx: {
7878
+ flex: 1,
7879
+ '& .MuiInputBase-input': {
7880
+ fontSize: 12,
7881
+ py: 0.75
7882
+ }
7883
+ }
7884
+ }), /*#__PURE__*/jsx(TextField, {
7885
+ size: "small",
7886
+ type: "number",
7887
+ label: t('sidePanel.inputFields.maxSelections', 'Max select'),
7888
+ value: markMaxSelections,
7889
+ onChange: function onChange(e) {
7890
+ return setMarkMaxSelections(Math.max(0, parseInt(e.target.value) || 0));
7891
+ },
7892
+ inputProps: {
7893
+ min: 0
7894
+ },
7895
+ sx: {
7896
+ flex: 1,
7897
+ '& .MuiInputBase-input': {
7898
+ fontSize: 12,
7899
+ py: 0.75
7900
+ }
7901
+ }
7902
+ })]
7903
+ }), /*#__PURE__*/jsx(Typography, {
7904
+ variant: "caption",
7905
+ sx: {
7906
+ color: '#999',
7907
+ fontSize: 10
7908
+ },
7909
+ children: markMinSelections > 0 ? "Required \xB7 min ".concat(markMinSelections).concat(markMaxSelections > 0 ? ", max ".concat(markMaxSelections) : ', no max') : "Optional \xB7 max ".concat(markMaxSelections > 0 ? markMaxSelections : '∞')
7910
+ })]
7911
+ }), (!isTextElement || markInputType !== 'list') && /*#__PURE__*/jsx(FormControlLabel, {
7560
7912
  control: /*#__PURE__*/jsx(Checkbox, {
7561
7913
  size: "small",
7562
7914
  checked: markRequired,
@@ -10310,12 +10662,20 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10310
10662
  imagePreview = _useState4[0],
10311
10663
  setImagePreview = _useState4[1];
10312
10664
  var fileInputRef = useRef(null);
10665
+ var _useState5 = useState([]),
10666
+ _useState6 = _slicedToArray(_useState5, 2),
10667
+ selectedItems = _useState6[0],
10668
+ setSelectedItems = _useState6[1];
10313
10669
  var config = getInputFieldsConfig();
10314
10670
  var custom = field.custom || {};
10315
10671
  var inputType = custom.inputType || 'text';
10316
10672
  var promptText = custom.promptText || custom.placeholder || 'Please provide input';
10317
10673
  var dateFormat = custom.dateFormat || 'MM-DD-YYYY';
10318
10674
  var isRequired = custom.required === true;
10675
+ var options = custom.options || [];
10676
+ var minSelections = custom.minSelections || 0;
10677
+ var maxSelections = custom.maxSelections || options.length;
10678
+ var isSubmitDisabled = inputType === 'list' ? selectedItems.length < minSelections : isRequired && !value;
10319
10679
  var logoUrl = config.logoUrl || null;
10320
10680
  var headerText = config.headerText || null;
10321
10681
  var accentColor = config.accentColor || '#0d83cd';
@@ -10323,6 +10683,7 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10323
10683
  useEffect(function () {
10324
10684
  setValue('');
10325
10685
  setImagePreview(null);
10686
+ setSelectedItems([]);
10326
10687
  }, [field.id]);
10327
10688
  var handleImageSelect = function handleImageSelect(e) {
10328
10689
  var _e$target$files;
@@ -10342,12 +10703,14 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10342
10703
  var dateObj = parseDateFromFormat(value);
10343
10704
  var formatted = formatDate(dateObj, dateFormat);
10344
10705
  onSubmit(field.id, formatted);
10706
+ } else if (inputType === 'list') {
10707
+ onSubmit(field.id, selectedItems.join(', '));
10345
10708
  } else {
10346
10709
  onSubmit(field.id, value);
10347
10710
  }
10348
10711
  };
10349
10712
  var handleKeyDown = function handleKeyDown(e) {
10350
- if (e.key === 'Enter' && inputType !== 'image') handleSubmit();
10713
+ if (e.key === 'Enter' && inputType !== 'image' && inputType !== 'list' && inputType !== 'radio') handleSubmit();
10351
10714
  };
10352
10715
  var renderInput = function renderInput() {
10353
10716
  var sharedSx = _objectSpread2({
@@ -10487,6 +10850,119 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10487
10850
  })]
10488
10851
  })]
10489
10852
  });
10853
+ case 'radio':
10854
+ return /*#__PURE__*/jsx(RadioGroup, {
10855
+ value: value,
10856
+ onChange: function onChange(e) {
10857
+ return setValue(e.target.value);
10858
+ },
10859
+ sx: {
10860
+ mt: 1,
10861
+ gap: 1
10862
+ },
10863
+ children: options.map(function (opt) {
10864
+ return /*#__PURE__*/jsx(FormControlLabel, {
10865
+ value: opt,
10866
+ control: /*#__PURE__*/jsx(Radio, {
10867
+ sx: {
10868
+ color: '#d0d5dd',
10869
+ '&.Mui-checked': {
10870
+ color: accentColor
10871
+ }
10872
+ }
10873
+ }),
10874
+ label: /*#__PURE__*/jsx(Typography, {
10875
+ sx: {
10876
+ fontSize: 18
10877
+ },
10878
+ children: opt
10879
+ }),
10880
+ sx: {
10881
+ m: 0,
10882
+ border: '1px solid',
10883
+ borderColor: value === opt ? accentColor : '#d0d5dd',
10884
+ borderRadius: '8px',
10885
+ px: 2,
10886
+ py: 0.75,
10887
+ transition: 'all 0.15s ease',
10888
+ backgroundColor: value === opt ? 'rgba(13,131,205,0.04)' : 'transparent',
10889
+ '&:hover': {
10890
+ borderColor: accentColor,
10891
+ backgroundColor: 'rgba(13,131,205,0.03)'
10892
+ }
10893
+ }
10894
+ }, opt);
10895
+ })
10896
+ });
10897
+ case 'list':
10898
+ {
10899
+ var isAtMax = maxSelections > 0 && selectedItems.length >= maxSelections;
10900
+ return /*#__PURE__*/jsxs(Box, {
10901
+ sx: {
10902
+ mt: 1
10903
+ },
10904
+ children: [/*#__PURE__*/jsx(FormGroup, {
10905
+ sx: {
10906
+ gap: 1
10907
+ },
10908
+ children: options.map(function (opt) {
10909
+ var checked = selectedItems.includes(opt);
10910
+ var disabled = !checked && isAtMax;
10911
+ return /*#__PURE__*/jsx(FormControlLabel, {
10912
+ control: /*#__PURE__*/jsx(Checkbox, {
10913
+ checked: checked,
10914
+ disabled: disabled,
10915
+ onChange: function onChange(e) {
10916
+ if (e.target.checked) {
10917
+ setSelectedItems(function (prev) {
10918
+ return [].concat(_toConsumableArray(prev), [opt]);
10919
+ });
10920
+ } else {
10921
+ setSelectedItems(function (prev) {
10922
+ return prev.filter(function (i) {
10923
+ return i !== opt;
10924
+ });
10925
+ });
10926
+ }
10927
+ },
10928
+ sx: {
10929
+ color: '#d0d5dd',
10930
+ '&.Mui-checked': {
10931
+ color: accentColor
10932
+ }
10933
+ }
10934
+ }),
10935
+ label: /*#__PURE__*/jsx(Typography, {
10936
+ sx: {
10937
+ fontSize: 18,
10938
+ opacity: disabled ? 0.45 : 1
10939
+ },
10940
+ children: opt
10941
+ }),
10942
+ sx: {
10943
+ m: 0,
10944
+ border: '1px solid',
10945
+ borderColor: checked ? accentColor : '#d0d5dd',
10946
+ borderRadius: '8px',
10947
+ px: 2,
10948
+ py: 0.75,
10949
+ opacity: disabled ? 0.6 : 1,
10950
+ transition: 'all 0.15s ease',
10951
+ backgroundColor: checked ? 'rgba(13,131,205,0.04)' : 'transparent'
10952
+ }
10953
+ }, opt);
10954
+ })
10955
+ }), /*#__PURE__*/jsxs(Typography, {
10956
+ variant: "caption",
10957
+ sx: {
10958
+ color: '#999',
10959
+ display: 'block',
10960
+ mt: 1.5
10961
+ },
10962
+ children: [selectedItems.length, maxSelections > 0 ? "/".concat(maxSelections) : '', " selected", minSelections > 0 && " \xB7 min ".concat(minSelections, " required")]
10963
+ })]
10964
+ });
10965
+ }
10490
10966
  case 'text':
10491
10967
  default:
10492
10968
  return /*#__PURE__*/jsx(TextField, {
@@ -10629,7 +11105,7 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10629
11105
  }), /*#__PURE__*/jsx(Button, {
10630
11106
  variant: "contained",
10631
11107
  onClick: handleSubmit,
10632
- disabled: isRequired && !value,
11108
+ disabled: isSubmitDisabled,
10633
11109
  sx: _objectSpread2({
10634
11110
  textTransform: 'none',
10635
11111
  fontWeight: 600,
@@ -10645,7 +11121,7 @@ var SingleFieldDialog = function SingleFieldDialog(_ref) {
10645
11121
  }
10646
11122
  }, config.submitButtonStyle),
10647
11123
  children: config.submitButtonText || t('inputFieldsDialog.submit', 'Continue')
10648
- }), !isRequired && /*#__PURE__*/jsx(Button, {
11124
+ }), (inputType === 'list' ? minSelections === 0 : !isRequired) && /*#__PURE__*/jsx(Button, {
10649
11125
  variant: "outlined",
10650
11126
  onClick: function onClick() {
10651
11127
  return onSkip(field.id);
@@ -10682,10 +11158,10 @@ var InputFieldsDialog = observer(function (_ref2) {
10682
11158
  backTrigger = _ref2$backTrigger === void 0 ? 0 : _ref2$backTrigger;
10683
11159
  // displayIndex counts how many fields have been answered (for step indicator only).
10684
11160
  // Navigation always uses fields[0] — the first remaining pending field.
10685
- var _useState5 = useState(0),
10686
- _useState6 = _slicedToArray(_useState5, 2),
10687
- displayIndex = _useState6[0],
10688
- setDisplayIndex = _useState6[1];
11161
+ var _useState7 = useState(0),
11162
+ _useState8 = _slicedToArray(_useState7, 2),
11163
+ displayIndex = _useState8[0],
11164
+ setDisplayIndex = _useState8[1];
10689
11165
  var initialTotalRef = useRef(0);
10690
11166
  var completedHistoryRef = useRef([]);
10691
11167
  var isGoingBackRef = useRef(false);
@@ -10830,7 +11306,9 @@ var InputFieldsDialog = observer(function (_ref2) {
10830
11306
  text: config.CustomTextDialog,
10831
11307
  date: config.CustomDateDialog,
10832
11308
  integer: config.CustomIntegerDialog,
10833
- image: config.CustomImageDialog
11309
+ image: config.CustomImageDialog,
11310
+ radio: config.CustomRadioDialog,
11311
+ list: config.CustomListDialog
10834
11312
  };
10835
11313
  var fieldType = currentField.custom && currentField.custom.inputType || 'text';
10836
11314
  var PerTypeDialog = TYPE_DIALOG_MAP[fieldType];