@bpmn-io/form-js-viewer 1.21.0 → 1.21.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.
package/dist/index.es.js CHANGED
@@ -620,6 +620,110 @@ function prefixId(id, formId, indexes) {
620
620
  return result;
621
621
  }
622
622
 
623
+ /**
624
+ * Returns the options data for the provided if they can be simply determined, ignoring expression defined options.
625
+ *
626
+ * @param {object} formField
627
+ * @param {object} formData
628
+ */
629
+ function getSimpleOptionsData(formField, formData) {
630
+ const {
631
+ valuesExpression: optionsExpression,
632
+ valuesKey: optionsKey,
633
+ values: staticOptions
634
+ } = formField;
635
+ if (optionsExpression) {
636
+ return null;
637
+ }
638
+ return optionsKey ? get(formData, [optionsKey]) : staticOptions;
639
+ }
640
+
641
+ /**
642
+ * Normalizes the provided options data to a format that can be used by the select components.
643
+ * If the options data is not valid, it is filtered out.
644
+ *
645
+ * @param {any[]} optionsData
646
+ *
647
+ * @returns {object[]}
648
+ */
649
+ function normalizeOptionsData(optionsData) {
650
+ return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !isNil(o));
651
+ }
652
+
653
+ /**
654
+ * Creates an options object with default values if no options are provided.
655
+ *
656
+ * @param {object} options
657
+ *
658
+ * @returns {object}
659
+ */
660
+ function createEmptyOptions(options = {}) {
661
+ const defaults = {};
662
+
663
+ // provide default options if valuesKey and valuesExpression are not set
664
+ if (!options.valuesKey && !options.valuesExpression) {
665
+ defaults.values = [{
666
+ label: 'Value',
667
+ value: 'value'
668
+ }];
669
+ }
670
+ return {
671
+ ...defaults,
672
+ ...options
673
+ };
674
+ }
675
+
676
+ /**
677
+ * Converts the provided option to a normalized format.
678
+ * If the option is not valid, null is returned.
679
+ *
680
+ * @param {object} option
681
+ * @param {string} option.label
682
+ * @param {*} option.value
683
+ *
684
+ * @returns
685
+ */
686
+ function _normalizeOption(option) {
687
+ // (1) simple primitive case, use it as both label and value
688
+ if (_isAllowedPrimitive(option)) {
689
+ return {
690
+ value: option,
691
+ label: `${option}`
692
+ };
693
+ }
694
+ if (isObject(option)) {
695
+ const isValidLabel = _isValidLabel(option.label);
696
+
697
+ // (2) no label provided, but value is a simple primitive, use it as label and value
698
+ if (!isValidLabel && _isAllowedPrimitive(option.value)) {
699
+ return {
700
+ value: option.value,
701
+ label: `${option.value}`
702
+ };
703
+ }
704
+
705
+ // (3) both label and value are provided, use them as is
706
+ if (isValidLabel && _isAllowedValue(option.value)) {
707
+ return option;
708
+ }
709
+ }
710
+ return null;
711
+ }
712
+ function _isAllowedPrimitive(value) {
713
+ const isAllowedPrimitiveType = ['number', 'string', 'boolean'].includes(typeof value);
714
+ const isValid = value || value === 0 || value === false;
715
+ return isAllowedPrimitiveType && isValid;
716
+ }
717
+ function _isValidLabel(label) {
718
+ return label && isString(label);
719
+ }
720
+ function _isAllowedValue(value) {
721
+ if (isObject(value)) {
722
+ return Object.keys(value).length > 0;
723
+ }
724
+ return _isAllowedPrimitive(value);
725
+ }
726
+
623
727
  const FormRenderContext = createContext({
624
728
  Empty: props => {
625
729
  return null;
@@ -660,7 +764,8 @@ const FormRenderContext = createContext({
660
764
  },
661
765
  hoverInfo: {
662
766
  cleanup: () => {}
663
- }
767
+ },
768
+ applyVisibilityConditions: true
664
769
  });
665
770
 
666
771
  const LocalExpressionContext = createContext({
@@ -793,134 +898,6 @@ function runUnaryTestEvaluation(expressionLanguage, value, expressionContextInfo
793
898
  return expressionLanguage.evaluateUnaryTest(value, buildExpressionContext(expressionContextInfo));
794
899
  }
795
900
 
796
- /**
797
- * Evaluate a unary test expression reactively. Returns null for invalid/missing expressions.
798
- * The function is memoized to minimize re-renders.
799
- *
800
- * @param {string | undefined} value - A unary test expression to evaluate.
801
- * @returns {boolean | null} - Evaluated result, or null if expression is invalid/missing.
802
- */
803
- function useUnaryTestEvaluation(value) {
804
- const expressionLanguage = useService('expressionLanguage');
805
- const expressionContextInfo = useContext(LocalExpressionContext);
806
- return useMemo(() => runUnaryTestEvaluation(expressionLanguage, value, expressionContextInfo), [expressionLanguage, expressionContextInfo, value]);
807
- }
808
-
809
- /**
810
- * Evaluate if condition is met reactively based on the expression language and form data.
811
- *
812
- * @param {string | undefined} condition
813
- *
814
- * @returns {boolean | null} true if condition is met, false if not, null if no condition or expression language
815
- */
816
- function useCondition(condition) {
817
- return useUnaryTestEvaluation(condition);
818
- }
819
-
820
- /**
821
- * Returns the options data for the provided if they can be simply determined, ignoring expression defined options.
822
- *
823
- * @param {object} formField
824
- * @param {object} formData
825
- */
826
- function getSimpleOptionsData(formField, formData) {
827
- const {
828
- valuesExpression: optionsExpression,
829
- valuesKey: optionsKey,
830
- values: staticOptions
831
- } = formField;
832
- if (optionsExpression) {
833
- return null;
834
- }
835
- return optionsKey ? get(formData, [optionsKey]) : staticOptions;
836
- }
837
-
838
- /**
839
- * Normalizes the provided options data to a format that can be used by the select components.
840
- * If the options data is not valid, it is filtered out.
841
- *
842
- * @param {any[]} optionsData
843
- *
844
- * @returns {object[]}
845
- */
846
- function normalizeOptionsData(optionsData) {
847
- return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !isNil(o));
848
- }
849
-
850
- /**
851
- * Creates an options object with default values if no options are provided.
852
- *
853
- * @param {object} options
854
- *
855
- * @returns {object}
856
- */
857
- function createEmptyOptions(options = {}) {
858
- const defaults = {};
859
-
860
- // provide default options if valuesKey and valuesExpression are not set
861
- if (!options.valuesKey && !options.valuesExpression) {
862
- defaults.values = [{
863
- label: 'Value',
864
- value: 'value'
865
- }];
866
- }
867
- return {
868
- ...defaults,
869
- ...options
870
- };
871
- }
872
-
873
- /**
874
- * Converts the provided option to a normalized format.
875
- * If the option is not valid, null is returned.
876
- *
877
- * @param {object} option
878
- * @param {string} option.label
879
- * @param {*} option.value
880
- *
881
- * @returns
882
- */
883
- function _normalizeOption(option) {
884
- // (1) simple primitive case, use it as both label and value
885
- if (_isAllowedPrimitive(option)) {
886
- return {
887
- value: option,
888
- label: `${option}`
889
- };
890
- }
891
- if (isObject(option)) {
892
- const isValidLabel = _isValidLabel(option.label);
893
-
894
- // (2) no label provided, but value is a simple primitive, use it as label and value
895
- if (!isValidLabel && _isAllowedPrimitive(option.value)) {
896
- return {
897
- value: option.value,
898
- label: `${option.value}`
899
- };
900
- }
901
-
902
- // (3) both label and value are provided, use them as is
903
- if (isValidLabel && _isAllowedValue(option.value)) {
904
- return option;
905
- }
906
- }
907
- return null;
908
- }
909
- function _isAllowedPrimitive(value) {
910
- const isAllowedPrimitiveType = ['number', 'string', 'boolean'].includes(typeof value);
911
- const isValid = value || value === 0 || value === false;
912
- return isAllowedPrimitiveType && isValid;
913
- }
914
- function _isValidLabel(label) {
915
- return label && isString(label);
916
- }
917
- function _isAllowedValue(value) {
918
- if (isObject(value)) {
919
- return Object.keys(value).length > 0;
920
- }
921
- return _isAllowedPrimitive(value);
922
- }
923
-
924
901
  /**
925
902
  * If the value is a valid expression, it is evaluated and returned. Otherwise, it is returned as-is.
926
903
  * The function is memoized to minimize re-renders.
@@ -1252,6 +1229,19 @@ function useBooleanExpressionEvaluation(value) {
1252
1229
  }, [expressionLanguage, expressionContextInfo, value]);
1253
1230
  }
1254
1231
 
1232
+ /**
1233
+ * Evaluate a unary test expression reactively. Returns null for invalid/missing expressions.
1234
+ * The function is memoized to minimize re-renders.
1235
+ *
1236
+ * @param {string | undefined} value - A unary test expression to evaluate.
1237
+ * @returns {boolean | null} - Evaluated result, or null if expression is invalid/missing.
1238
+ */
1239
+ function useUnaryTestEvaluation(value) {
1240
+ const expressionLanguage = useService('expressionLanguage');
1241
+ const expressionContextInfo = useContext(LocalExpressionContext);
1242
+ return useMemo(() => runUnaryTestEvaluation(expressionLanguage, value, expressionContextInfo), [expressionLanguage, expressionContextInfo, value]);
1243
+ }
1244
+
1255
1245
  /**
1256
1246
  * Returns the conditionally filtered data of a form reactively.
1257
1247
  * Memoised to minimize re-renders
@@ -2063,7 +2053,8 @@ function FormField(props) {
2063
2053
  const {
2064
2054
  Element,
2065
2055
  Hidden,
2066
- Column
2056
+ Column,
2057
+ applyVisibilityConditions
2067
2058
  } = useContext(FormRenderContext);
2068
2059
  const {
2069
2060
  formId
@@ -2087,7 +2078,8 @@ function FormField(props) {
2087
2078
 
2088
2079
  // add precedence: global readonly > form field disabled
2089
2080
  const disabled = !properties.readOnly && (properties.disabled || field.disabled || false);
2090
- const hidden = useCondition(field.conditional && field.conditional.hide || null);
2081
+ const conditionResult = useUnaryTestEvaluation(field.conditional && field.conditional.hide || null);
2082
+ const hidden = applyVisibilityConditions ? conditionResult : null;
2091
2083
  const instanceId = useMemo(() => {
2092
2084
  if (!formFieldInstanceRegistry) {
2093
2085
  return null;
@@ -8487,11 +8479,23 @@ function runPresetValidation(field, validation, value) {
8487
8479
  errors.push('Field is required.');
8488
8480
  }
8489
8481
  }
8490
- if ('min' in validation && (value || value === 0) && value < validation.min) {
8491
- errors.push(`Field must have minimum value of ${validation.min}.`);
8482
+ if ('min' in validation && (value || value === 0)) {
8483
+ try {
8484
+ if (Big(value).lt(Big(validation.min))) {
8485
+ errors.push(`Field must have minimum value of ${validation.min}.`);
8486
+ }
8487
+ } catch {
8488
+ errors.push('Min validation value is not a valid number.');
8489
+ }
8492
8490
  }
8493
- if ('max' in validation && (value || value === 0) && value > validation.max) {
8494
- errors.push(`Field must have maximum value of ${validation.max}.`);
8491
+ if ('max' in validation && (value || value === 0)) {
8492
+ try {
8493
+ if (Big(value).gt(Big(validation.max))) {
8494
+ errors.push(`Field must have maximum value of ${validation.max}.`);
8495
+ }
8496
+ } catch {
8497
+ errors.push('Max validation value is not a valid number.');
8498
+ }
8495
8499
  }
8496
8500
  if ('minLength' in validation && value && value.trim().length < validation.minLength) {
8497
8501
  errors.push(`Field must have minimum length of ${validation.minLength}.`);