@bpmn-io/properties-panel 1.7.0 → 1.8.1

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.js CHANGED
@@ -403,6 +403,10 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
403
403
  if (ref.current) {
404
404
  const scrollContainer = minDom.query(scrollContainerSelector);
405
405
  observer = new Observer(entries => {
406
+ // The ScrollContainer is unmounted, do not update sticky state
407
+ if (scrollContainer.scrollHeight === 0) {
408
+ return;
409
+ }
406
410
  entries.forEach(entry => {
407
411
  if (entry.intersectionRatio < 1) {
408
412
  setSticky(true);
@@ -649,7 +653,7 @@ function PropertiesPanel(props) {
649
653
  const [layout, setLayout] = hooks.useState(createLayout(layoutConfig));
650
654
 
651
655
  // react to external changes in the layout config
652
- useUpdateEffect(() => {
656
+ useUpdateLayoutEffect(() => {
653
657
  const newLayout = createLayout(layoutConfig);
654
658
  setLayout(newLayout);
655
659
  }, [layoutConfig]);
@@ -770,14 +774,14 @@ function createDescriptionContext(overrides = {}) {
770
774
  // hooks //////////////////
771
775
 
772
776
  /**
773
- * This hook behaves like useEffect, but does not trigger on the first render.
777
+ * This hook behaves like useLayoutEffect, but does not trigger on the first render.
774
778
  *
775
779
  * @param {Function} effect
776
780
  * @param {Array} deps
777
781
  */
778
- function useUpdateEffect(effect, deps) {
782
+ function useUpdateLayoutEffect(effect, deps) {
779
783
  const isMounted = hooks.useRef(false);
780
- hooks.useEffect(() => {
784
+ hooks.useLayoutEffect(() => {
781
785
  if (isMounted.current) {
782
786
  return effect();
783
787
  } else {
@@ -2750,6 +2754,7 @@ function TextArea(props) {
2750
2754
  * @param {Function} props.onBlur
2751
2755
  * @param {number} props.rows
2752
2756
  * @param {boolean} props.monospace
2757
+ * @param {Function} [props.validate]
2753
2758
  * @param {boolean} [props.disabled]
2754
2759
  */
2755
2760
  function TextAreaEntry(props) {
@@ -2764,12 +2769,38 @@ function TextAreaEntry(props) {
2764
2769
  rows,
2765
2770
  monospace,
2766
2771
  disabled,
2772
+ validate,
2767
2773
  onFocus,
2768
2774
  onBlur,
2769
2775
  autoResize
2770
2776
  } = props;
2771
- const value = getValue(element);
2772
- const error = useError(id);
2777
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
2778
+ const globalError = useError(id);
2779
+ const [localError, setLocalError] = hooks.useState(null);
2780
+ let value = getValue(element);
2781
+ const previousValue = usePrevious(value);
2782
+ hooks.useEffect(() => {
2783
+ if (minDash.isFunction(validate)) {
2784
+ const newValidationError = validate(value) || null;
2785
+ setLocalError(newValidationError);
2786
+ }
2787
+ }, [value]);
2788
+ const onInput = newValue => {
2789
+ let newValidationError = null;
2790
+ if (minDash.isFunction(validate)) {
2791
+ newValidationError = validate(newValue) || null;
2792
+ }
2793
+ if (newValidationError) {
2794
+ setCachedInvalidValue(newValue);
2795
+ } else {
2796
+ setValue(newValue);
2797
+ }
2798
+ setLocalError(newValidationError);
2799
+ };
2800
+ if (previousValue === value && localError) {
2801
+ value = cachedInvalidValue;
2802
+ }
2803
+ const error = globalError || localError;
2773
2804
  return jsxRuntime.jsxs("div", {
2774
2805
  class: classnames__default["default"]('bio-properties-panel-entry', error ? 'has-error' : ''),
2775
2806
  "data-entry-id": id,
@@ -2777,7 +2808,7 @@ function TextAreaEntry(props) {
2777
2808
  id: id,
2778
2809
  label: label,
2779
2810
  value: value,
2780
- onInput: setValue,
2811
+ onInput: onInput,
2781
2812
  onFocus: onFocus,
2782
2813
  onBlur: onBlur,
2783
2814
  rows: rows,