@evoke-platform/ui-components 1.5.1-dev.0 → 1.5.1-dev.2

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.
@@ -11,6 +11,7 @@ type FormFieldComponentProps = Omit<BaseFormComponentProps, 'property'> & {
11
11
  isAddressLine1?: boolean;
12
12
  initialValue?: string;
13
13
  displayOption?: 'radioButton' | 'dropdown';
14
+ strictlyTrue?: boolean;
14
15
  };
15
16
  export declare class FormFieldComponent extends ReactComponent {
16
17
  [x: string]: any;
@@ -27,7 +28,7 @@ export declare class FormFieldComponent extends ReactComponent {
27
28
  constructor(component: FormFieldComponentProps, options: any, data: any);
28
29
  init(): void;
29
30
  clearErrors(): void;
30
- handleValidation(value: string): void;
31
+ handleValidation(value: any): void;
31
32
  hasErrors(): boolean;
32
33
  errorMessages(): string;
33
34
  /**
@@ -136,13 +136,18 @@ export class FormFieldComponent extends ReactComponent {
136
136
  }
137
137
  }
138
138
  };
139
- if (component.type === 'Boolean' && typeof component.initialValue === 'boolean') {
140
- // For Boolean components, FormIO treats false values as null/undefined
141
- // We need to explicitly set the default value to ensure the correct Boolean state is preserved
142
- const defaultValue = component.defaultValue === null || component.defaultValue === undefined
143
- ? component.initialValue
144
- : component.defaultValue;
145
- this.setValue(defaultValue);
139
+ if (component.type === 'Boolean') {
140
+ if (typeof component.initialValue === 'boolean') {
141
+ // For Boolean components, FormIO treats false values as null/undefined
142
+ // We need to explicitly set the default value to ensure the correct Boolean state is preserved
143
+ const defaultValue = component.defaultValue === null || component.defaultValue === undefined
144
+ ? component.initialValue
145
+ : component.defaultValue;
146
+ this.setValue(defaultValue);
147
+ }
148
+ else if (!component.initialValue) {
149
+ this.setValue(component.defaultValue || false);
150
+ }
146
151
  }
147
152
  this.errorDetails = {};
148
153
  this.handleChange = this.handleChange.bind(this);
@@ -255,7 +260,9 @@ export class FormFieldComponent extends ReactComponent {
255
260
  if (groups?.relatedObjectProperty && groups?.nestedProperty) {
256
261
  this.on(`changed-${groups.relatedObjectProperty}`, (value) => {
257
262
  if (value) {
258
- const newValue = value[groups.nestedProperty];
263
+ const newValue = this.component.type === 'Boolean'
264
+ ? value[groups.nestedProperty] || false
265
+ : value[groups.nestedProperty];
259
266
  this.setValue(newValue);
260
267
  this.updateValue(newValue, { modified: true });
261
268
  this.attach(this.element);
@@ -293,6 +300,14 @@ export class FormFieldComponent extends ReactComponent {
293
300
  delete this.errorDetails['rootError'];
294
301
  return;
295
302
  }
303
+ if (this.component.type === 'Boolean') {
304
+ if (this.component.strictlyTrue && !value) {
305
+ this.errorDetails[`${this.component.key}-required`] = this.component.label + ' is required';
306
+ }
307
+ else {
308
+ delete this.errorDetails[`${this.component.key}-required`];
309
+ }
310
+ }
296
311
  if (this.component.type == 'Date' && value && typeof value === 'object' && value['invalid']) {
297
312
  this.errorDetails['invalidDate'] = 'Invalid Date';
298
313
  }
@@ -470,6 +485,6 @@ export class FormFieldComponent extends ReactComponent {
470
485
  falsePositiveMaskError &&
471
486
  isEmpty(this.errorDetails) &&
472
487
  this.emit('changed-' + this.component.key, e.target.value);
473
- }, ...this.component, id: inputId, defaultValue: this.dataValue, mask: this.component.inputMask, error: this.hasErrors(), size: this.component.fieldHeight ?? 'medium', required: this.component.property.type === 'boolean' ? this.component.validate?.required : undefined }))), root);
488
+ }, ...this.component, id: inputId, defaultValue: this.dataValue, mask: this.component.inputMask, error: this.hasErrors(), size: this.component.fieldHeight ?? 'medium', required: this.component.property.type === 'boolean' ? this.component.strictlyTrue : undefined }))), root);
474
489
  }
475
490
  }
@@ -199,7 +199,7 @@ export function convertFormToComponents(entries, parameters, object) {
199
199
  showCharCount: displayOptions?.charCount,
200
200
  objectId: object.id,
201
201
  validate: {
202
- required: displayOptions?.required,
202
+ required: displayOptions?.required || parameter.required,
203
203
  criteria: ['collection', 'object'].includes(parameter.type ?? '')
204
204
  ? parameter.validation?.criteria
205
205
  : undefined,
@@ -246,6 +246,7 @@ export function convertFormToComponents(entries, parameters, object) {
246
246
  : undefined,
247
247
  conditional: convertVisibilityToConditional(displayOptions?.visibility),
248
248
  viewLayout: displayOptions?.viewLayout,
249
+ strictlyTrue: parameter.type === 'boolean' && parameter.strictlyTrue,
249
250
  };
250
251
  }
251
252
  })
@@ -1,6 +1,7 @@
1
1
  import parse from 'html-react-parser';
2
2
  import React, { useEffect, useState } from 'react';
3
- import { Help } from '../../../../icons';
3
+ import { CheckBox as CheckBoxIcon, CheckBoxOutlineBlank, Help, ToggleOff, ToggleOn } from '../../../../icons';
4
+ import { defaultTheme } from '../../../../theme/defaultTheme';
4
5
  import { Autocomplete, Checkbox, FormControl, FormControlLabel, FormHelperText, IconButton, Switch, TextField, Tooltip, Typography, } from '../../../core';
5
6
  import InputFieldComponent from '../InputFieldComponent/InputFieldComponent';
6
7
  const descriptionStyles = {
@@ -10,7 +11,7 @@ const descriptionStyles = {
10
11
  marginX: 0,
11
12
  };
12
13
  const BooleanSelect = (props) => {
13
- const { id, property, defaultValue, error, errorMessage, readOnly, size, displayOption, label, required, tooltip, description, placeholder, onBlur, additionalProps, } = props;
14
+ const { id, property, defaultValue, error, errorMessage, readOnly, size, displayOption, label, strictlyTrue, tooltip, description, placeholder, onBlur, additionalProps, } = props;
14
15
  const [value, setValue] = useState(defaultValue);
15
16
  useEffect(() => {
16
17
  setValue(defaultValue);
@@ -29,14 +30,39 @@ const BooleanSelect = (props) => {
29
30
  value: false,
30
31
  },
31
32
  ];
32
- return displayOption === 'dropdown' ? (readOnly ? (React.createElement(InputFieldComponent, { ...props })) : (React.createElement(Autocomplete, { renderInput: (params) => (React.createElement(TextField, { ...params, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, sx: { background: 'white' }, placeholder: placeholder, size: size ?? 'medium' })), value: booleanOptions.find((opt) => opt.value === value) ?? '', onChange: (e, selectedValue) => handleChange(selectedValue.value), isOptionEqualToValue: (option, val) => option?.value === val?.value, options: booleanOptions, disableClearable: true, sx: { background: 'white', borderRadius: '8px' }, ...(additionalProps ?? {}), sortBy: "NONE" }))) : (React.createElement(FormControl, { error: error, fullWidth: true },
33
- React.createElement(FormControlLabel, { labelPlacement: "end", label: React.createElement(Typography, { variant: "body2", sx: { wordWrap: 'break-word', fontFamily: 'Public Sans' } },
34
- label,
35
- tooltip && (React.createElement(Tooltip, { placement: "right", title: tooltip },
36
- React.createElement(IconButton, null,
37
- React.createElement(Help, { sx: { fontSize: '14px' } })))),
38
- required && (React.createElement(Typography, { variant: "body2", component: "span", color: "error", sx: { marginLeft: '4px', fontSize: '18px' } }, "*"))), control: displayOption === 'switch' ? (React.createElement(Switch, { id: id, "aria-required": required, "aria-invalid": error, size: size ?? 'medium', name: property.id, checked: value, onChange: (e) => handleChange(e.target.checked), disabled: readOnly, sx: { alignSelf: 'start' } })) : (React.createElement(Checkbox, { id: id, "aria-required": required, "aria-invalid": error, size: size ?? 'medium', checked: value, name: property.id, onChange: (e) => handleChange(e.target.checked), disabled: readOnly, sx: { alignSelf: 'start', padding: '4px 9px 9px 9px' } })) }),
39
- error && React.createElement(FormHelperText, { sx: { marginX: 0 } }, errorMessage),
40
- description && (React.createElement(FormHelperText, { sx: descriptionStyles, component: Typography }, parse(description)))));
33
+ const descriptionComponent = () => {
34
+ return (description && (React.createElement(FormHelperText, { sx: descriptionStyles, component: Typography }, parse(description))));
35
+ };
36
+ const labelComponent = () => {
37
+ return (React.createElement(Typography, { component: "span", variant: "body2", sx: { wordWrap: 'break-word', ...defaultTheme.typography.body2 } },
38
+ label,
39
+ strictlyTrue && (React.createElement(Typography, { component: "span", sx: { color: 'red', fontSize: '12px', marginLeft: '4px' } }, "*")),
40
+ tooltip && (React.createElement(Tooltip, { placement: "right", title: tooltip },
41
+ React.createElement(IconButton, null,
42
+ React.createElement(Help, { sx: { fontSize: '14px' } }))))));
43
+ };
44
+ const readOnlyComponent = () => {
45
+ if (displayOption === 'dropdown') {
46
+ return React.createElement(InputFieldComponent, { ...props });
47
+ }
48
+ else {
49
+ const iconColor = 'rgb(160, 160, 160)';
50
+ return (React.createElement(FormControl, { disabled: true, required: strictlyTrue, fullWidth: true },
51
+ React.createElement(FormControlLabel, { labelPlacement: "end", label: labelComponent(), sx: { gap: 1, marginLeft: 0 }, control: value ? (displayOption === 'checkbox' ? (React.createElement(CheckBoxIcon, { fontSize: size ?? 'medium', "aria-label": "Checked", htmlColor: iconColor })) : (React.createElement(ToggleOn, { fontSize: size ?? 'medium', "aria-label": "Checked", htmlColor: iconColor }))) : displayOption === 'checkbox' ? (React.createElement(CheckBoxOutlineBlank, { fontSize: size ?? 'medium', "aria-label": "Unchecked", htmlColor: iconColor })) : (React.createElement(ToggleOff, { fontSize: size ?? 'medium', "aria-label": "Unchecked", htmlColor: iconColor })) }),
52
+ descriptionComponent()));
53
+ }
54
+ };
55
+ if (readOnly) {
56
+ return readOnlyComponent();
57
+ }
58
+ return displayOption === 'dropdown' ? (React.createElement(Autocomplete, { renderInput: (params) => (React.createElement(TextField, { ...params, error: error, errorMessage: errorMessage, onBlur: onBlur, fullWidth: true, sx: { background: 'white' }, placeholder: placeholder, size: size ?? 'medium' })), value: booleanOptions.find((opt) => opt.value === value) ?? '', onChange: (e, selectedValue) => handleChange(selectedValue.value), isOptionEqualToValue: (option, val) => option?.value === val?.value, options: booleanOptions, disableClearable: true, sx: { background: 'white', borderRadius: '8px' }, ...(additionalProps ?? {}), sortBy: "NONE", required: strictlyTrue })) : (React.createElement(FormControl, { required: strictlyTrue, error: error, fullWidth: true },
59
+ React.createElement(FormControlLabel, { labelPlacement: "end", label: labelComponent(), control: displayOption === 'switch' ? (React.createElement(Switch, { id: id, "aria-required": strictlyTrue, "aria-invalid": error, size: size ?? 'medium', name: property.id, checked: value, onChange: (e) => handleChange(e.target.checked), sx: {
60
+ alignSelf: 'start',
61
+ } })) : (React.createElement(Checkbox, { id: id, "aria-required": strictlyTrue, "aria-invalid": error, size: size ?? 'medium', checked: value, name: property.id, onChange: (e) => handleChange(e.target.checked), sx: {
62
+ alignSelf: 'start',
63
+ padding: '4px 9px 9px 9px',
64
+ } })) }),
65
+ error && errorMessage?.length && React.createElement(FormHelperText, { sx: { marginX: 0 } }, errorMessage),
66
+ descriptionComponent()));
41
67
  };
42
68
  export default BooleanSelect;
@@ -12,6 +12,7 @@ export type FormFieldProps = {
12
12
  error?: boolean;
13
13
  errorMessage?: string;
14
14
  required?: boolean;
15
+ strictlyTrue?: boolean;
15
16
  readOnly?: boolean;
16
17
  min?: number;
17
18
  max?: number;
@@ -8,7 +8,7 @@ import InputFieldComponent from './InputFieldComponent/InputFieldComponent';
8
8
  import Select from './Select/Select';
9
9
  import TimePickerSelect from './TimePickerSelect/TimePickerSelect';
10
10
  const FormField = (props) => {
11
- const { id, defaultValue, error, onChange, property, readOnly, selectOptions, required, size, placeholder, errorMessage, onBlur, mask, max, min, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, isOptionEqualToValue, renderOption, disableCloseOnSelect, getOptionLabel, additionalProps, displayOption, sortBy, label, description, tooltip, } = props;
11
+ const { id, defaultValue, error, onChange, property, readOnly, selectOptions, required, strictlyTrue, size, placeholder, errorMessage, onBlur, mask, max, min, isMultiLineText, rows, inputMaskPlaceholderChar, queryAddresses, isOptionEqualToValue, renderOption, disableCloseOnSelect, getOptionLabel, additionalProps, displayOption, sortBy, label, description, tooltip, } = props;
12
12
  let control;
13
13
  const commonProps = {
14
14
  id: id ?? property.id,
@@ -20,7 +20,8 @@ const FormField = (props) => {
20
20
  readOnly,
21
21
  defaultValue,
22
22
  selectOptions,
23
- required: required,
23
+ required,
24
+ strictlyTrue,
24
25
  size,
25
26
  placeholder,
26
27
  min,
@@ -133,7 +133,8 @@ BooleanField.args = {
133
133
  readOnly: false,
134
134
  size: 'small',
135
135
  displayOption: 'checkbox',
136
- label: "<a href='#'>Label</a>",
136
+ label: 'Label',
137
+ description: "Description <a href='#'>link</a>",
137
138
  };
138
139
  export const FileUploadField = FormFieldTemplate.bind({});
139
140
  FileUploadField.args = {
@@ -23,7 +23,6 @@ const rows = [
23
23
  const TableTemplate = (args) => {
24
24
  const [page, setPage] = useState(0);
25
25
  const [rowsPerPage, setRowsPerPage] = useState(5);
26
- console.log('🚀 ~ file: Table.stories.tsx ~ line 40 ~ rowsPerPage', rowsPerPage);
27
26
  const handleChangePage = (event, newPage) => {
28
27
  setPage(newPage);
29
28
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evoke-platform/ui-components",
3
- "version": "1.5.1-dev.0",
3
+ "version": "1.5.1-dev.2",
4
4
  "description": "",
5
5
  "main": "dist/published/index.js",
6
6
  "module": "dist/published/index.js",
@@ -86,7 +86,7 @@
86
86
  "yalc": "^1.0.0-pre.53"
87
87
  },
88
88
  "peerDependencies": {
89
- "@evoke-platform/context": "^1.2.0-0",
89
+ "@evoke-platform/context": "^1.3.0-0",
90
90
  "react": "^18.1.0",
91
91
  "react-dom": "^18.1.0"
92
92
  },