@bpmn-io/form-js-viewer 1.7.0 → 1.7.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/LICENSE +22 -22
- package/README.md +189 -189
- package/dist/index.cjs +270 -163
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +271 -164
- package/dist/index.es.js.map +1 -1
- package/dist/types/render/components/Label.d.ts +4 -2
- package/dist/types/render/components/index.d.ts +1 -1
- package/dist/types/render/components/util/optionsUtil.d.ts +24 -8
- package/dist/types/render/hooks/index.d.ts +1 -1
- package/dist/types/render/hooks/useDeepCompareMemoize.d.ts +8 -0
- package/dist/types/types.d.ts +35 -35
- package/package.json +2 -2
- package/dist/types/render/hooks/useDeepCompareState.d.ts +0 -8
package/dist/index.cjs
CHANGED
|
@@ -792,20 +792,59 @@ function useCondition(condition) {
|
|
|
792
792
|
}, [conditionChecker, condition, expressionContextInfo]);
|
|
793
793
|
}
|
|
794
794
|
|
|
795
|
-
|
|
796
|
-
|
|
795
|
+
/**
|
|
796
|
+
* Returns the options data for the provided if they can be simply determined, ignoring expression defined options.
|
|
797
|
+
*
|
|
798
|
+
* @param {object} formField
|
|
799
|
+
* @param {object} formData
|
|
800
|
+
*/
|
|
801
|
+
function getSimpleOptionsData(formField, formData) {
|
|
797
802
|
const {
|
|
803
|
+
valuesExpression: optionsExpression,
|
|
798
804
|
valuesKey: optionsKey,
|
|
799
805
|
values: staticOptions
|
|
800
806
|
} = formField;
|
|
807
|
+
if (optionsExpression) {
|
|
808
|
+
return null;
|
|
809
|
+
}
|
|
801
810
|
return optionsKey ? minDash.get(formData, [optionsKey]) : staticOptions;
|
|
802
811
|
}
|
|
803
812
|
|
|
804
|
-
|
|
813
|
+
/**
|
|
814
|
+
* Normalizes the provided options data to a format that can be used by the select components.
|
|
815
|
+
* If the options data is not valid, it is filtered out.
|
|
816
|
+
*
|
|
817
|
+
* @param {any[]} optionsData
|
|
818
|
+
*
|
|
819
|
+
* @returns {object[]}
|
|
820
|
+
*/
|
|
805
821
|
function normalizeOptionsData(optionsData) {
|
|
806
822
|
return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !minDash.isNil(o));
|
|
807
823
|
}
|
|
808
824
|
|
|
825
|
+
/**
|
|
826
|
+
* Creates an options object with default values if no options are provided.
|
|
827
|
+
*
|
|
828
|
+
* @param {object} options
|
|
829
|
+
*
|
|
830
|
+
* @returns {object}
|
|
831
|
+
*/
|
|
832
|
+
function createEmptyOptions(options = {}) {
|
|
833
|
+
const defaults = {};
|
|
834
|
+
|
|
835
|
+
// provide default options if valuesKey and valuesExpression are not set
|
|
836
|
+
if (!options.valuesKey && !options.valuesExpression) {
|
|
837
|
+
defaults.values = [{
|
|
838
|
+
label: 'Value',
|
|
839
|
+
value: 'value'
|
|
840
|
+
}];
|
|
841
|
+
}
|
|
842
|
+
return {
|
|
843
|
+
...defaults,
|
|
844
|
+
...options
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
|
|
809
848
|
/**
|
|
810
849
|
* Converts the provided option to a normalized format.
|
|
811
850
|
* If the option is not valid, null is returned.
|
|
@@ -856,21 +895,6 @@ function _isAllowedValue(value) {
|
|
|
856
895
|
}
|
|
857
896
|
return _isAllowedPrimitive(value);
|
|
858
897
|
}
|
|
859
|
-
function createEmptyOptions(options = {}) {
|
|
860
|
-
const defaults = {};
|
|
861
|
-
|
|
862
|
-
// provide default options if valuesKey and valuesExpression are not set
|
|
863
|
-
if (!options.valuesKey && !options.valuesExpression) {
|
|
864
|
-
defaults.values = [{
|
|
865
|
-
label: 'Value',
|
|
866
|
-
value: 'value'
|
|
867
|
-
}];
|
|
868
|
-
}
|
|
869
|
-
return {
|
|
870
|
-
...defaults,
|
|
871
|
-
...options
|
|
872
|
-
};
|
|
873
|
-
}
|
|
874
898
|
|
|
875
899
|
/**
|
|
876
900
|
* Evaluate a string reactively based on the expressionLanguage and form data.
|
|
@@ -891,29 +915,19 @@ function useExpressionEvaluation(value) {
|
|
|
891
915
|
}, [expressionLanguage, expressionContextInfo, value]);
|
|
892
916
|
}
|
|
893
917
|
|
|
894
|
-
function usePrevious(value, defaultValue = null) {
|
|
895
|
-
const ref = hooks.useRef(defaultValue);
|
|
896
|
-
hooks.useEffect(() => ref.current = value, [value]);
|
|
897
|
-
return ref.current;
|
|
898
|
-
}
|
|
899
|
-
|
|
900
918
|
/**
|
|
901
919
|
* A custom hook to manage state changes with deep comparison.
|
|
902
920
|
*
|
|
903
|
-
* @
|
|
904
|
-
* @param {
|
|
905
|
-
* @returns {
|
|
921
|
+
* @template T
|
|
922
|
+
* @param {T} value - The current value to manage.
|
|
923
|
+
* @returns {T} - Returns the current state.
|
|
906
924
|
*/
|
|
907
|
-
function
|
|
908
|
-
const
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
setState(value);
|
|
914
|
-
}
|
|
915
|
-
}, [changed, value]);
|
|
916
|
-
return state;
|
|
925
|
+
function useDeepCompareMemoize(value) {
|
|
926
|
+
const ref = hooks.useRef();
|
|
927
|
+
if (!isEqual(value, ref.current)) {
|
|
928
|
+
ref.current = value;
|
|
929
|
+
}
|
|
930
|
+
return ref.current;
|
|
917
931
|
}
|
|
918
932
|
|
|
919
933
|
/**
|
|
@@ -943,15 +957,10 @@ function useOptionsAsync(field) {
|
|
|
943
957
|
valuesKey: optionsKey,
|
|
944
958
|
values: staticOptions
|
|
945
959
|
} = field;
|
|
946
|
-
const [optionsGetter, setOptionsGetter] = hooks.useState({
|
|
947
|
-
options: [],
|
|
948
|
-
error: undefined,
|
|
949
|
-
loadState: LOAD_STATES.LOADING
|
|
950
|
-
});
|
|
951
960
|
const initialData = useService('form')._getState().initialData;
|
|
952
961
|
const expressionEvaluation = useExpressionEvaluation(optionsExpression);
|
|
953
|
-
const evaluatedOptions =
|
|
954
|
-
hooks.
|
|
962
|
+
const evaluatedOptions = useDeepCompareMemoize(expressionEvaluation || []);
|
|
963
|
+
const optionsGetter = hooks.useMemo(() => {
|
|
955
964
|
let options = [];
|
|
956
965
|
|
|
957
966
|
// dynamic options
|
|
@@ -966,18 +975,16 @@ function useOptionsAsync(field) {
|
|
|
966
975
|
options = Array.isArray(staticOptions) ? staticOptions : [];
|
|
967
976
|
|
|
968
977
|
// expression
|
|
969
|
-
} else if (optionsExpression) {
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
978
|
+
} else if (optionsExpression && evaluatedOptions && Array.isArray(evaluatedOptions)) {
|
|
979
|
+
options = evaluatedOptions;
|
|
980
|
+
|
|
981
|
+
// error case
|
|
973
982
|
} else {
|
|
974
|
-
|
|
975
|
-
return;
|
|
983
|
+
return buildErrorState('No options source defined in the form definition');
|
|
976
984
|
}
|
|
977
985
|
|
|
978
986
|
// normalize data to support primitives and partially defined objects
|
|
979
|
-
|
|
980
|
-
setOptionsGetter(buildLoadedState(options));
|
|
987
|
+
return buildLoadedState(normalizeOptionsData(options));
|
|
981
988
|
}, [optionsKey, staticOptions, initialData, optionsExpression, evaluatedOptions]);
|
|
982
989
|
return optionsGetter;
|
|
983
990
|
}
|
|
@@ -1022,14 +1029,14 @@ const getDOMPurifyConfig = sanitizeStyleTags => {
|
|
|
1022
1029
|
};
|
|
1023
1030
|
};
|
|
1024
1031
|
|
|
1025
|
-
/**
|
|
1026
|
-
* A custom hook to build up security attributes from form configuration.
|
|
1027
|
-
*
|
|
1028
|
-
* @param {Object} security - The security configuration.
|
|
1029
|
-
* @returns {Array} - Returns a tuple with sandbox and allow attributes.
|
|
1032
|
+
/**
|
|
1033
|
+
* A custom hook to build up security attributes from form configuration.
|
|
1034
|
+
*
|
|
1035
|
+
* @param {Object} security - The security configuration.
|
|
1036
|
+
* @returns {Array} - Returns a tuple with sandbox and allow attributes.
|
|
1030
1037
|
*/
|
|
1031
1038
|
function useSecurityAttributesMap(security) {
|
|
1032
|
-
const securityMemoized =
|
|
1039
|
+
const securityMemoized = useDeepCompareMemoize(security);
|
|
1033
1040
|
const sandbox = hooks.useMemo(() => SECURITY_ATTRIBUTES_DEFINITIONS.filter(({
|
|
1034
1041
|
attribute
|
|
1035
1042
|
}) => attribute === SANDBOX_ATTRIBUTE).filter(({
|
|
@@ -1201,6 +1208,12 @@ function useReadonly(formField, properties = {}) {
|
|
|
1201
1208
|
return readonly || false;
|
|
1202
1209
|
}
|
|
1203
1210
|
|
|
1211
|
+
function usePrevious(value, defaultValue = null) {
|
|
1212
|
+
const ref = hooks.useRef(defaultValue);
|
|
1213
|
+
hooks.useEffect(() => ref.current = value, [value]);
|
|
1214
|
+
return ref.current;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1204
1217
|
function useFlushDebounce(func) {
|
|
1205
1218
|
const timeoutRef = hooks.useRef(null);
|
|
1206
1219
|
const lastArgsRef = hooks.useRef(null);
|
|
@@ -1465,8 +1478,16 @@ function sanitizeSingleSelectValue(options) {
|
|
|
1465
1478
|
data,
|
|
1466
1479
|
value
|
|
1467
1480
|
} = options;
|
|
1481
|
+
const {
|
|
1482
|
+
valuesExpression: optionsExpression
|
|
1483
|
+
} = formField;
|
|
1468
1484
|
try {
|
|
1469
|
-
|
|
1485
|
+
// if options are expression evaluated, we don't need to sanitize the value against the options
|
|
1486
|
+
// and defer to the field's internal validation
|
|
1487
|
+
if (optionsExpression) {
|
|
1488
|
+
return value;
|
|
1489
|
+
}
|
|
1490
|
+
const validValues = normalizeOptionsData(getSimpleOptionsData(formField, data)).map(v => v.value);
|
|
1470
1491
|
return hasEqualValue(value, validValues) ? value : null;
|
|
1471
1492
|
} catch (error) {
|
|
1472
1493
|
// use default value in case of formatting error
|
|
@@ -1480,8 +1501,16 @@ function sanitizeMultiSelectValue(options) {
|
|
|
1480
1501
|
data,
|
|
1481
1502
|
value
|
|
1482
1503
|
} = options;
|
|
1504
|
+
const {
|
|
1505
|
+
valuesExpression: optionsExpression
|
|
1506
|
+
} = formField;
|
|
1483
1507
|
try {
|
|
1484
|
-
|
|
1508
|
+
// if options are expression evaluated, we don't need to sanitize the values against the options
|
|
1509
|
+
// and defer to the field's internal validation
|
|
1510
|
+
if (optionsExpression) {
|
|
1511
|
+
return value;
|
|
1512
|
+
}
|
|
1513
|
+
const validValues = normalizeOptionsData(getSimpleOptionsData(formField, data)).map(v => v.value);
|
|
1485
1514
|
return value.filter(v => hasEqualValue(v, validValues));
|
|
1486
1515
|
} catch (error) {
|
|
1487
1516
|
// use default value in case of formatting error
|
|
@@ -1569,7 +1598,7 @@ function useCleanupMultiSelectValue(props) {
|
|
|
1569
1598
|
onChange,
|
|
1570
1599
|
values
|
|
1571
1600
|
} = props;
|
|
1572
|
-
const memoizedValues =
|
|
1601
|
+
const memoizedValues = useDeepCompareMemoize(values || []);
|
|
1573
1602
|
|
|
1574
1603
|
// ensures that the values are always a subset of the possible options
|
|
1575
1604
|
hooks.useEffect(() => {
|
|
@@ -1589,7 +1618,8 @@ function useCleanupMultiSelectValue(props) {
|
|
|
1589
1618
|
|
|
1590
1619
|
function Description(props) {
|
|
1591
1620
|
const {
|
|
1592
|
-
description
|
|
1621
|
+
description,
|
|
1622
|
+
id
|
|
1593
1623
|
} = props;
|
|
1594
1624
|
const evaluatedDescription = useSingleLineTemplateEvaluation(description || '', {
|
|
1595
1625
|
debug: true
|
|
@@ -1598,6 +1628,7 @@ function Description(props) {
|
|
|
1598
1628
|
return null;
|
|
1599
1629
|
}
|
|
1600
1630
|
return jsxRuntime.jsx("div", {
|
|
1631
|
+
id: id,
|
|
1601
1632
|
class: "fjs-form-field-description",
|
|
1602
1633
|
children: evaluatedDescription
|
|
1603
1634
|
});
|
|
@@ -1628,6 +1659,7 @@ function Errors(props) {
|
|
|
1628
1659
|
function Label(props) {
|
|
1629
1660
|
const {
|
|
1630
1661
|
id,
|
|
1662
|
+
htmlFor,
|
|
1631
1663
|
label,
|
|
1632
1664
|
collapseOnEmpty = true,
|
|
1633
1665
|
required = false
|
|
@@ -1636,12 +1668,14 @@ function Label(props) {
|
|
|
1636
1668
|
debug: true
|
|
1637
1669
|
});
|
|
1638
1670
|
return jsxRuntime.jsxs("label", {
|
|
1639
|
-
|
|
1671
|
+
id: id,
|
|
1672
|
+
for: htmlFor,
|
|
1640
1673
|
class: classNames('fjs-form-field-label', {
|
|
1641
1674
|
'fjs-incollapsible-label': !collapseOnEmpty
|
|
1642
1675
|
}, props['class']),
|
|
1643
1676
|
children: [props.children, evaluatedLabel, required && jsxRuntime.jsx("span", {
|
|
1644
1677
|
class: "fjs-asterix",
|
|
1678
|
+
"aria-hidden": true,
|
|
1645
1679
|
children: "*"
|
|
1646
1680
|
})]
|
|
1647
1681
|
});
|
|
@@ -1652,7 +1686,6 @@ function Checkbox(props) {
|
|
|
1652
1686
|
const {
|
|
1653
1687
|
disabled,
|
|
1654
1688
|
errors = [],
|
|
1655
|
-
errorMessageId,
|
|
1656
1689
|
domId,
|
|
1657
1690
|
onBlur,
|
|
1658
1691
|
onFocus,
|
|
@@ -1676,6 +1709,8 @@ function Checkbox(props) {
|
|
|
1676
1709
|
value: target.checked
|
|
1677
1710
|
});
|
|
1678
1711
|
};
|
|
1712
|
+
const descriptionId = `${domId}-description`;
|
|
1713
|
+
const errorMessageId = `${domId}-error-message`;
|
|
1679
1714
|
return jsxRuntime.jsxs("div", {
|
|
1680
1715
|
class: classNames(formFieldClasses(type$f, {
|
|
1681
1716
|
errors,
|
|
@@ -1685,7 +1720,7 @@ function Checkbox(props) {
|
|
|
1685
1720
|
'fjs-checked': value
|
|
1686
1721
|
}),
|
|
1687
1722
|
children: [jsxRuntime.jsx(Label, {
|
|
1688
|
-
|
|
1723
|
+
htmlFor: domId,
|
|
1689
1724
|
label: label,
|
|
1690
1725
|
required: required,
|
|
1691
1726
|
children: jsxRuntime.jsx("input", {
|
|
@@ -1698,13 +1733,16 @@ function Checkbox(props) {
|
|
|
1698
1733
|
onChange: onChange,
|
|
1699
1734
|
onBlur: () => onBlur && onBlur(),
|
|
1700
1735
|
onFocus: () => onFocus && onFocus(),
|
|
1701
|
-
|
|
1736
|
+
required: required,
|
|
1737
|
+
"aria-invalid": errors.length > 0,
|
|
1738
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' ')
|
|
1702
1739
|
})
|
|
1703
1740
|
}), jsxRuntime.jsx(Description, {
|
|
1741
|
+
id: descriptionId,
|
|
1704
1742
|
description: description
|
|
1705
1743
|
}), jsxRuntime.jsx(Errors, {
|
|
1706
|
-
|
|
1707
|
-
|
|
1744
|
+
id: errorMessageId,
|
|
1745
|
+
errors: errors
|
|
1708
1746
|
})]
|
|
1709
1747
|
});
|
|
1710
1748
|
}
|
|
@@ -1727,7 +1765,6 @@ function Checklist(props) {
|
|
|
1727
1765
|
const {
|
|
1728
1766
|
disabled,
|
|
1729
1767
|
errors = [],
|
|
1730
|
-
errorMessageId,
|
|
1731
1768
|
domId,
|
|
1732
1769
|
onBlur,
|
|
1733
1770
|
onFocus,
|
|
@@ -1774,6 +1811,8 @@ function Checklist(props) {
|
|
|
1774
1811
|
values,
|
|
1775
1812
|
onChange: props.onChange
|
|
1776
1813
|
});
|
|
1814
|
+
const descriptionId = `${domId}-description`;
|
|
1815
|
+
const errorMessageId = `${domId}-error-message`;
|
|
1777
1816
|
return jsxRuntime.jsxs("div", {
|
|
1778
1817
|
class: classNames(formFieldClasses(type$e, {
|
|
1779
1818
|
errors,
|
|
@@ -1788,7 +1827,7 @@ function Checklist(props) {
|
|
|
1788
1827
|
const itemDomId = `${domId}-${index}`;
|
|
1789
1828
|
const isChecked = hasEqualValue(o.value, values);
|
|
1790
1829
|
return jsxRuntime.jsx(Label, {
|
|
1791
|
-
|
|
1830
|
+
htmlFor: itemDomId,
|
|
1792
1831
|
label: o.label,
|
|
1793
1832
|
class: classNames({
|
|
1794
1833
|
'fjs-checked': isChecked
|
|
@@ -1804,14 +1843,17 @@ function Checklist(props) {
|
|
|
1804
1843
|
onClick: () => toggleCheckbox(o.value),
|
|
1805
1844
|
onBlur: onCheckboxBlur,
|
|
1806
1845
|
onFocus: onCheckboxFocus,
|
|
1807
|
-
|
|
1846
|
+
required: required,
|
|
1847
|
+
"aria-invalid": errors.length > 0,
|
|
1848
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' ')
|
|
1808
1849
|
})
|
|
1809
1850
|
});
|
|
1810
1851
|
}), jsxRuntime.jsx(Description, {
|
|
1852
|
+
id: descriptionId,
|
|
1811
1853
|
description: description
|
|
1812
1854
|
}), jsxRuntime.jsx(Errors, {
|
|
1813
|
-
|
|
1814
|
-
|
|
1855
|
+
id: errorMessageId,
|
|
1856
|
+
errors: errors
|
|
1815
1857
|
})]
|
|
1816
1858
|
});
|
|
1817
1859
|
}
|
|
@@ -1891,6 +1933,7 @@ function FormField(props) {
|
|
|
1891
1933
|
}
|
|
1892
1934
|
}, [viewerCommands, field, initialValue, initialValidationTrigger, indexes]);
|
|
1893
1935
|
const onBlur = hooks.useCallback(() => {
|
|
1936
|
+
const value = minDash.get(data, valuePath);
|
|
1894
1937
|
if (initialValidationTrigger) {
|
|
1895
1938
|
setInitialValidationTrigger(false);
|
|
1896
1939
|
viewerCommands.updateFieldValidation(field, value, indexes);
|
|
@@ -1898,7 +1941,7 @@ function FormField(props) {
|
|
|
1898
1941
|
eventBus.fire('formField.blur', {
|
|
1899
1942
|
formField: field
|
|
1900
1943
|
});
|
|
1901
|
-
}, [eventBus, field, indexes,
|
|
1944
|
+
}, [eventBus, field, indexes, viewerCommands, initialValidationTrigger, data, valuePath]);
|
|
1902
1945
|
const onFocus = hooks.useCallback(() => {
|
|
1903
1946
|
eventBus.fire('formField.focus', {
|
|
1904
1947
|
formField: field
|
|
@@ -1922,7 +1965,6 @@ function FormField(props) {
|
|
|
1922
1965
|
}
|
|
1923
1966
|
const domId = `${prefixId(field.id, formId, indexes)}`;
|
|
1924
1967
|
const fieldErrors = minDash.get(errors, [field.id, ...Object.values(indexes || {})]) || [];
|
|
1925
|
-
const errorMessageId = errors.length === 0 ? undefined : `${domId}-error-message`;
|
|
1926
1968
|
return jsxRuntime.jsx(Column, {
|
|
1927
1969
|
field: field,
|
|
1928
1970
|
class: gridColumnClasses(field),
|
|
@@ -1933,7 +1975,6 @@ function FormField(props) {
|
|
|
1933
1975
|
...props,
|
|
1934
1976
|
disabled: disabled,
|
|
1935
1977
|
errors: fieldErrors,
|
|
1936
|
-
errorMessageId: errorMessageId,
|
|
1937
1978
|
domId: domId,
|
|
1938
1979
|
onChange: disabled || readonly ? noop$1 : onChangeIndexed,
|
|
1939
1980
|
onBlur: disabled || readonly ? noop$1 : onBlur,
|
|
@@ -2245,7 +2286,7 @@ function Datepicker(props) {
|
|
|
2245
2286
|
const [forceFocusCalendar, setForceFocusCalendar] = hooks.useState(false);
|
|
2246
2287
|
|
|
2247
2288
|
// ensures we render based on date value instead of reference
|
|
2248
|
-
const date =
|
|
2289
|
+
const date = useDeepCompareMemoize(dateObject);
|
|
2249
2290
|
|
|
2250
2291
|
// shorts the date value back to the source
|
|
2251
2292
|
hooks.useEffect(() => {
|
|
@@ -2336,7 +2377,7 @@ function Datepicker(props) {
|
|
|
2336
2377
|
return jsxRuntime.jsxs("div", {
|
|
2337
2378
|
class: "fjs-datetime-subsection",
|
|
2338
2379
|
children: [jsxRuntime.jsx(Label, {
|
|
2339
|
-
|
|
2380
|
+
htmlFor: domId,
|
|
2340
2381
|
label: label,
|
|
2341
2382
|
collapseOnEmpty: collapseLabelOnEmpty,
|
|
2342
2383
|
required: required
|
|
@@ -2608,7 +2649,7 @@ function Timepicker(props) {
|
|
|
2608
2649
|
return jsxRuntime.jsxs("div", {
|
|
2609
2650
|
class: "fjs-datetime-subsection",
|
|
2610
2651
|
children: [jsxRuntime.jsx(Label, {
|
|
2611
|
-
|
|
2652
|
+
htmlFor: domId,
|
|
2612
2653
|
label: label,
|
|
2613
2654
|
collapseOnEmpty: collapseLabelOnEmpty,
|
|
2614
2655
|
required: required
|
|
@@ -2795,6 +2836,7 @@ function Datetime(props) {
|
|
|
2795
2836
|
});
|
|
2796
2837
|
}, []);
|
|
2797
2838
|
const errorMessageId = allErrors.length === 0 ? undefined : `${prefixId(id, formId)}-error-message`;
|
|
2839
|
+
const descriptionId = `${prefixId(id, formId)}-description`;
|
|
2798
2840
|
const datePickerProps = {
|
|
2799
2841
|
label: dateLabel,
|
|
2800
2842
|
collapseLabelOnEmpty: !timeLabel,
|
|
@@ -2807,7 +2849,7 @@ function Datetime(props) {
|
|
|
2807
2849
|
date: dateTime.date,
|
|
2808
2850
|
readonly,
|
|
2809
2851
|
setDate,
|
|
2810
|
-
'aria-describedby': errorMessageId
|
|
2852
|
+
'aria-describedby': [descriptionId, errorMessageId].join(' ')
|
|
2811
2853
|
};
|
|
2812
2854
|
const timePickerProps = {
|
|
2813
2855
|
label: timeLabel,
|
|
@@ -2822,7 +2864,7 @@ function Datetime(props) {
|
|
|
2822
2864
|
timeInterval,
|
|
2823
2865
|
time: dateTime.time,
|
|
2824
2866
|
setTime,
|
|
2825
|
-
'aria-describedby': errorMessageId
|
|
2867
|
+
'aria-describedby': [descriptionId, errorMessageId].join(' ')
|
|
2826
2868
|
};
|
|
2827
2869
|
return jsxRuntime.jsxs("div", {
|
|
2828
2870
|
class: formFieldClasses(type$d, {
|
|
@@ -2841,6 +2883,7 @@ function Datetime(props) {
|
|
|
2841
2883
|
...timePickerProps
|
|
2842
2884
|
})]
|
|
2843
2885
|
}), jsxRuntime.jsx(Description, {
|
|
2886
|
+
id: descriptionId,
|
|
2844
2887
|
description: description
|
|
2845
2888
|
}), jsxRuntime.jsx(Errors, {
|
|
2846
2889
|
errors: allErrors,
|
|
@@ -2944,7 +2987,7 @@ function IFrame(props) {
|
|
|
2944
2987
|
readonly
|
|
2945
2988
|
}),
|
|
2946
2989
|
children: [jsxRuntime.jsx(Label, {
|
|
2947
|
-
|
|
2990
|
+
htmlFor: domId,
|
|
2948
2991
|
label: evaluatedLabel
|
|
2949
2992
|
}), !evaluatedUrl && jsxRuntime.jsx(IFramePlaceholder, {
|
|
2950
2993
|
text: "No content to show."
|
|
@@ -3490,7 +3533,6 @@ function Numberfield(props) {
|
|
|
3490
3533
|
const {
|
|
3491
3534
|
disabled,
|
|
3492
3535
|
errors = [],
|
|
3493
|
-
errorMessageId,
|
|
3494
3536
|
domId,
|
|
3495
3537
|
onBlur,
|
|
3496
3538
|
onFocus,
|
|
@@ -3628,6 +3670,8 @@ function Numberfield(props) {
|
|
|
3628
3670
|
e.preventDefault();
|
|
3629
3671
|
}
|
|
3630
3672
|
};
|
|
3673
|
+
const descriptionId = `${domId}-description`;
|
|
3674
|
+
const errorMessageId = `${domId}-error-message`;
|
|
3631
3675
|
return jsxRuntime.jsxs("div", {
|
|
3632
3676
|
class: formFieldClasses(type$a, {
|
|
3633
3677
|
errors,
|
|
@@ -3635,7 +3679,7 @@ function Numberfield(props) {
|
|
|
3635
3679
|
readonly
|
|
3636
3680
|
}),
|
|
3637
3681
|
children: [jsxRuntime.jsx(Label, {
|
|
3638
|
-
|
|
3682
|
+
htmlFor: domId,
|
|
3639
3683
|
label: label,
|
|
3640
3684
|
required: required
|
|
3641
3685
|
}), jsxRuntime.jsx(TemplatedInputAdorner, {
|
|
@@ -3669,15 +3713,17 @@ function Numberfield(props) {
|
|
|
3669
3713
|
autoComplete: "off",
|
|
3670
3714
|
step: incrementAmount,
|
|
3671
3715
|
value: displayValue,
|
|
3672
|
-
"aria-describedby": errorMessageId
|
|
3716
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' '),
|
|
3717
|
+
required: required,
|
|
3718
|
+
"aria-invalid": errors.length > 0
|
|
3673
3719
|
}), jsxRuntime.jsxs("div", {
|
|
3674
3720
|
class: classNames('fjs-number-arrow-container', {
|
|
3675
3721
|
'fjs-disabled': disabled,
|
|
3676
3722
|
'fjs-readonly': readonly
|
|
3677
3723
|
}),
|
|
3678
3724
|
children: [jsxRuntime.jsx("button", {
|
|
3679
|
-
class: "fjs-number-arrow-up",
|
|
3680
3725
|
type: "button",
|
|
3726
|
+
class: "fjs-number-arrow-up",
|
|
3681
3727
|
"aria-label": "Increment",
|
|
3682
3728
|
onClick: () => increment(),
|
|
3683
3729
|
tabIndex: -1,
|
|
@@ -3685,8 +3731,8 @@ function Numberfield(props) {
|
|
|
3685
3731
|
}), jsxRuntime.jsx("div", {
|
|
3686
3732
|
class: "fjs-number-arrow-separator"
|
|
3687
3733
|
}), jsxRuntime.jsx("button", {
|
|
3688
|
-
class: "fjs-number-arrow-down",
|
|
3689
3734
|
type: "button",
|
|
3735
|
+
class: "fjs-number-arrow-down",
|
|
3690
3736
|
"aria-label": "Decrement",
|
|
3691
3737
|
onClick: () => decrement(),
|
|
3692
3738
|
tabIndex: -1,
|
|
@@ -3695,10 +3741,11 @@ function Numberfield(props) {
|
|
|
3695
3741
|
})]
|
|
3696
3742
|
})
|
|
3697
3743
|
}), jsxRuntime.jsx(Description, {
|
|
3744
|
+
id: descriptionId,
|
|
3698
3745
|
description: description
|
|
3699
3746
|
}), jsxRuntime.jsx(Errors, {
|
|
3700
|
-
|
|
3701
|
-
|
|
3747
|
+
id: errorMessageId,
|
|
3748
|
+
errors: errors
|
|
3702
3749
|
})]
|
|
3703
3750
|
});
|
|
3704
3751
|
}
|
|
@@ -3728,7 +3775,6 @@ function Radio(props) {
|
|
|
3728
3775
|
const {
|
|
3729
3776
|
disabled,
|
|
3730
3777
|
errors = [],
|
|
3731
|
-
errorMessageId,
|
|
3732
3778
|
domId,
|
|
3733
3779
|
onBlur,
|
|
3734
3780
|
onFocus,
|
|
@@ -3774,6 +3820,8 @@ function Radio(props) {
|
|
|
3774
3820
|
value,
|
|
3775
3821
|
onChange: props.onChange
|
|
3776
3822
|
});
|
|
3823
|
+
const descriptionId = `${domId}-description`;
|
|
3824
|
+
const errorMessageId = `${domId}-error-message`;
|
|
3777
3825
|
return jsxRuntime.jsxs("div", {
|
|
3778
3826
|
class: formFieldClasses(type$9, {
|
|
3779
3827
|
errors,
|
|
@@ -3788,7 +3836,7 @@ function Radio(props) {
|
|
|
3788
3836
|
const itemDomId = `${domId}-${index}`;
|
|
3789
3837
|
const isChecked = isEqual(option.value, value);
|
|
3790
3838
|
return jsxRuntime.jsx(Label, {
|
|
3791
|
-
|
|
3839
|
+
htmlFor: itemDomId,
|
|
3792
3840
|
label: option.label,
|
|
3793
3841
|
class: classNames({
|
|
3794
3842
|
'fjs-checked': isChecked
|
|
@@ -3804,14 +3852,17 @@ function Radio(props) {
|
|
|
3804
3852
|
onClick: () => onChange(option.value),
|
|
3805
3853
|
onBlur: onRadioBlur,
|
|
3806
3854
|
onFocus: onRadioFocus,
|
|
3807
|
-
"aria-describedby": errorMessageId
|
|
3855
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' '),
|
|
3856
|
+
required: required,
|
|
3857
|
+
"aria-invalid": errors.length > 0
|
|
3808
3858
|
})
|
|
3809
3859
|
}, index);
|
|
3810
3860
|
}), jsxRuntime.jsx(Description, {
|
|
3861
|
+
id: descriptionId,
|
|
3811
3862
|
description: description
|
|
3812
3863
|
}), jsxRuntime.jsx(Errors, {
|
|
3813
|
-
|
|
3814
|
-
|
|
3864
|
+
id: errorMessageId,
|
|
3865
|
+
errors: errors
|
|
3815
3866
|
})]
|
|
3816
3867
|
});
|
|
3817
3868
|
}
|
|
@@ -3876,7 +3927,7 @@ function SearchableSelect(props) {
|
|
|
3876
3927
|
|
|
3877
3928
|
// whenever we change the underlying value, set the label to it
|
|
3878
3929
|
hooks.useEffect(() => {
|
|
3879
|
-
setFilter(label);
|
|
3930
|
+
setFilter(label || '');
|
|
3880
3931
|
}, [label]);
|
|
3881
3932
|
const filteredOptions = hooks.useMemo(() => {
|
|
3882
3933
|
if (loadState !== LOAD_STATES.LOADED) {
|
|
@@ -3956,7 +4007,7 @@ function SearchableSelect(props) {
|
|
|
3956
4007
|
}, [onFocus]);
|
|
3957
4008
|
const onInputBlur = hooks.useCallback(() => {
|
|
3958
4009
|
setIsDropdownExpanded(false);
|
|
3959
|
-
setFilter(label);
|
|
4010
|
+
setFilter(label || '');
|
|
3960
4011
|
onBlur && onBlur();
|
|
3961
4012
|
}, [onBlur, label]);
|
|
3962
4013
|
return jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
@@ -4052,6 +4103,9 @@ function SimpleSelect(props) {
|
|
|
4052
4103
|
}, [disabled, isDropdownExpanded, loadState, readonly, value]);
|
|
4053
4104
|
const onMouseDown = hooks.useCallback(e => {
|
|
4054
4105
|
const input = inputRef.current;
|
|
4106
|
+
if (disabled || !input) {
|
|
4107
|
+
return;
|
|
4108
|
+
}
|
|
4055
4109
|
setIsDropdownExpanded(!isDropdownExpanded);
|
|
4056
4110
|
if (isDropdownExpanded) {
|
|
4057
4111
|
input.blur();
|
|
@@ -4059,7 +4113,7 @@ function SimpleSelect(props) {
|
|
|
4059
4113
|
input.focus();
|
|
4060
4114
|
}
|
|
4061
4115
|
e.preventDefault();
|
|
4062
|
-
}, [isDropdownExpanded]);
|
|
4116
|
+
}, [disabled, isDropdownExpanded]);
|
|
4063
4117
|
const initialFocusIndex = hooks.useMemo(() => value && minDash.findIndex(options, o => o.value === value) || 0, [options, value]);
|
|
4064
4118
|
const onInputFocus = hooks.useCallback(() => {
|
|
4065
4119
|
if (!readonly) {
|
|
@@ -4131,7 +4185,6 @@ function Select(props) {
|
|
|
4131
4185
|
const {
|
|
4132
4186
|
disabled,
|
|
4133
4187
|
errors = [],
|
|
4134
|
-
errorMessageId,
|
|
4135
4188
|
domId,
|
|
4136
4189
|
onBlur,
|
|
4137
4190
|
onFocus,
|
|
@@ -4149,6 +4202,8 @@ function Select(props) {
|
|
|
4149
4202
|
const {
|
|
4150
4203
|
required
|
|
4151
4204
|
} = validate;
|
|
4205
|
+
const descriptionId = `${domId}-description`;
|
|
4206
|
+
const errorMessageId = `${domId}-error-message`;
|
|
4152
4207
|
const selectProps = {
|
|
4153
4208
|
domId,
|
|
4154
4209
|
disabled,
|
|
@@ -4159,7 +4214,9 @@ function Select(props) {
|
|
|
4159
4214
|
value,
|
|
4160
4215
|
onChange,
|
|
4161
4216
|
readonly,
|
|
4162
|
-
|
|
4217
|
+
required,
|
|
4218
|
+
'aria-invalid': errors.length > 0,
|
|
4219
|
+
'aria-describedby': [descriptionId, errorMessageId].join(' ')
|
|
4163
4220
|
};
|
|
4164
4221
|
return jsxRuntime.jsxs("div", {
|
|
4165
4222
|
class: formFieldClasses(type$8, {
|
|
@@ -4174,7 +4231,7 @@ function Select(props) {
|
|
|
4174
4231
|
}
|
|
4175
4232
|
},
|
|
4176
4233
|
children: [jsxRuntime.jsx(Label, {
|
|
4177
|
-
|
|
4234
|
+
htmlFor: domId,
|
|
4178
4235
|
label: label,
|
|
4179
4236
|
required: required
|
|
4180
4237
|
}), searchable ? jsxRuntime.jsx(SearchableSelect, {
|
|
@@ -4182,10 +4239,11 @@ function Select(props) {
|
|
|
4182
4239
|
}) : jsxRuntime.jsx(SimpleSelect, {
|
|
4183
4240
|
...selectProps
|
|
4184
4241
|
}), jsxRuntime.jsx(Description, {
|
|
4242
|
+
id: descriptionId,
|
|
4185
4243
|
description: description
|
|
4186
4244
|
}), jsxRuntime.jsx(Errors, {
|
|
4187
|
-
|
|
4188
|
-
|
|
4245
|
+
id: errorMessageId,
|
|
4246
|
+
errors: errors
|
|
4189
4247
|
})]
|
|
4190
4248
|
});
|
|
4191
4249
|
}
|
|
@@ -4318,7 +4376,6 @@ function Taglist(props) {
|
|
|
4318
4376
|
const {
|
|
4319
4377
|
disabled,
|
|
4320
4378
|
errors = [],
|
|
4321
|
-
errorMessageId,
|
|
4322
4379
|
onFocus,
|
|
4323
4380
|
domId,
|
|
4324
4381
|
onBlur,
|
|
@@ -4346,7 +4403,7 @@ function Taglist(props) {
|
|
|
4346
4403
|
} = useOptionsAsync(field);
|
|
4347
4404
|
|
|
4348
4405
|
// ensures we render based on array content instead of reference
|
|
4349
|
-
const values =
|
|
4406
|
+
const values = useDeepCompareMemoize(value || []);
|
|
4350
4407
|
useCleanupMultiSelectValue({
|
|
4351
4408
|
field,
|
|
4352
4409
|
loadState,
|
|
@@ -4454,6 +4511,8 @@ function Taglist(props) {
|
|
|
4454
4511
|
inputRef.current.focus();
|
|
4455
4512
|
};
|
|
4456
4513
|
const shouldDisplayDropdown = hooks.useMemo(() => !disabled && loadState === LOAD_STATES.LOADED && isDropdownExpanded && !isEscapeClosed, [disabled, isDropdownExpanded, isEscapeClosed, loadState]);
|
|
4514
|
+
const descriptionId = `${domId}-description`;
|
|
4515
|
+
const errorMessageId = `${domId}-error-message`;
|
|
4457
4516
|
return jsxRuntime.jsxs("div", {
|
|
4458
4517
|
ref: focusScopeRef,
|
|
4459
4518
|
class: formFieldClasses(type$5, {
|
|
@@ -4470,7 +4529,7 @@ function Taglist(props) {
|
|
|
4470
4529
|
children: [jsxRuntime.jsx(Label, {
|
|
4471
4530
|
label: label,
|
|
4472
4531
|
required: required,
|
|
4473
|
-
|
|
4532
|
+
htmlFor: domId
|
|
4474
4533
|
}), !disabled && !readonly && !!values.length && jsxRuntime.jsx(SkipLink, {
|
|
4475
4534
|
className: "fjs-taglist-skip-link",
|
|
4476
4535
|
label: "Skip to search",
|
|
@@ -4518,7 +4577,9 @@ function Taglist(props) {
|
|
|
4518
4577
|
onMouseDown: () => setIsEscapeClose(false),
|
|
4519
4578
|
onFocus: onInputFocus,
|
|
4520
4579
|
onBlur: onInputBlur,
|
|
4521
|
-
"aria-describedby": errorMessageId
|
|
4580
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' '),
|
|
4581
|
+
required: required,
|
|
4582
|
+
"aria-invalid": errors.length > 0
|
|
4522
4583
|
})]
|
|
4523
4584
|
}), jsxRuntime.jsx("div", {
|
|
4524
4585
|
class: "fjs-taglist-anchor",
|
|
@@ -4530,10 +4591,11 @@ function Taglist(props) {
|
|
|
4530
4591
|
listenerElement: inputRef.current
|
|
4531
4592
|
})
|
|
4532
4593
|
}), jsxRuntime.jsx(Description, {
|
|
4594
|
+
id: descriptionId,
|
|
4533
4595
|
description: description
|
|
4534
4596
|
}), jsxRuntime.jsx(Errors, {
|
|
4535
|
-
|
|
4536
|
-
|
|
4597
|
+
id: errorMessageId,
|
|
4598
|
+
errors: errors
|
|
4537
4599
|
})]
|
|
4538
4600
|
});
|
|
4539
4601
|
}
|
|
@@ -4850,7 +4912,6 @@ function Textfield(props) {
|
|
|
4850
4912
|
const {
|
|
4851
4913
|
disabled,
|
|
4852
4914
|
errors = [],
|
|
4853
|
-
errorMessageId,
|
|
4854
4915
|
domId,
|
|
4855
4916
|
onBlur,
|
|
4856
4917
|
onFocus,
|
|
@@ -4886,6 +4947,8 @@ function Textfield(props) {
|
|
|
4886
4947
|
const onInputFocus = () => {
|
|
4887
4948
|
onFocus && onFocus();
|
|
4888
4949
|
};
|
|
4950
|
+
const descriptionId = `${domId}-description`;
|
|
4951
|
+
const errorMessageId = `${domId}-error-message`;
|
|
4889
4952
|
return jsxRuntime.jsxs("div", {
|
|
4890
4953
|
class: formFieldClasses(type$2, {
|
|
4891
4954
|
errors,
|
|
@@ -4893,7 +4956,7 @@ function Textfield(props) {
|
|
|
4893
4956
|
readonly
|
|
4894
4957
|
}),
|
|
4895
4958
|
children: [jsxRuntime.jsx(Label, {
|
|
4896
|
-
|
|
4959
|
+
htmlFor: domId,
|
|
4897
4960
|
label: label,
|
|
4898
4961
|
required: required
|
|
4899
4962
|
}), jsxRuntime.jsx(TemplatedInputAdorner, {
|
|
@@ -4911,13 +4974,16 @@ function Textfield(props) {
|
|
|
4911
4974
|
onFocus: onInputFocus,
|
|
4912
4975
|
type: "text",
|
|
4913
4976
|
value: value,
|
|
4914
|
-
"aria-describedby": errorMessageId
|
|
4977
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' '),
|
|
4978
|
+
required: required,
|
|
4979
|
+
"aria-invalid": errors.length > 0
|
|
4915
4980
|
})
|
|
4916
4981
|
}), jsxRuntime.jsx(Description, {
|
|
4982
|
+
id: descriptionId,
|
|
4917
4983
|
description: description
|
|
4918
4984
|
}), jsxRuntime.jsx(Errors, {
|
|
4919
|
-
|
|
4920
|
-
|
|
4985
|
+
id: errorMessageId,
|
|
4986
|
+
errors: errors
|
|
4921
4987
|
})]
|
|
4922
4988
|
});
|
|
4923
4989
|
}
|
|
@@ -4950,7 +5016,6 @@ function Textarea(props) {
|
|
|
4950
5016
|
const {
|
|
4951
5017
|
disabled,
|
|
4952
5018
|
errors = [],
|
|
4953
|
-
errorMessageId,
|
|
4954
5019
|
domId,
|
|
4955
5020
|
onBlur,
|
|
4956
5021
|
onFocus,
|
|
@@ -4994,6 +5059,8 @@ function Textarea(props) {
|
|
|
4994
5059
|
hooks.useEffect(() => {
|
|
4995
5060
|
autoSizeTextarea(textareaRef.current);
|
|
4996
5061
|
}, []);
|
|
5062
|
+
const descriptionId = `${domId}-description`;
|
|
5063
|
+
const errorMessageId = `${domId}-error-message`;
|
|
4997
5064
|
return jsxRuntime.jsxs("div", {
|
|
4998
5065
|
class: formFieldClasses(type$1, {
|
|
4999
5066
|
errors,
|
|
@@ -5001,7 +5068,7 @@ function Textarea(props) {
|
|
|
5001
5068
|
readonly
|
|
5002
5069
|
}),
|
|
5003
5070
|
children: [jsxRuntime.jsx(Label, {
|
|
5004
|
-
|
|
5071
|
+
htmlFor: domId,
|
|
5005
5072
|
label: label,
|
|
5006
5073
|
required: required
|
|
5007
5074
|
}), jsxRuntime.jsx("textarea", {
|
|
@@ -5014,12 +5081,15 @@ function Textarea(props) {
|
|
|
5014
5081
|
onFocus: onInputFocus,
|
|
5015
5082
|
value: value,
|
|
5016
5083
|
ref: textareaRef,
|
|
5017
|
-
"aria-describedby": errorMessageId
|
|
5084
|
+
"aria-describedby": [descriptionId, errorMessageId].join(' '),
|
|
5085
|
+
required: required,
|
|
5086
|
+
"aria-invalid": errors.length > 0
|
|
5018
5087
|
}), jsxRuntime.jsx(Description, {
|
|
5088
|
+
id: descriptionId,
|
|
5019
5089
|
description: description
|
|
5020
5090
|
}), jsxRuntime.jsx(Errors, {
|
|
5021
|
-
|
|
5022
|
-
|
|
5091
|
+
id: errorMessageId,
|
|
5092
|
+
errors: errors
|
|
5023
5093
|
})]
|
|
5024
5094
|
});
|
|
5025
5095
|
}
|
|
@@ -5188,7 +5258,7 @@ function Table(props) {
|
|
|
5188
5258
|
return jsxRuntime.jsxs("div", {
|
|
5189
5259
|
class: formFieldClasses(type),
|
|
5190
5260
|
children: [jsxRuntime.jsx(Label, {
|
|
5191
|
-
|
|
5261
|
+
htmlFor: prefixId(id),
|
|
5192
5262
|
label: label
|
|
5193
5263
|
}), jsxRuntime.jsxs("div", {
|
|
5194
5264
|
class: classNames('fjs-table-middle-container', {
|
|
@@ -5588,7 +5658,7 @@ class FormFields {
|
|
|
5588
5658
|
}
|
|
5589
5659
|
|
|
5590
5660
|
const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression', 'url', 'dataSource', 'columnsExpression'];
|
|
5591
|
-
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text', 'url'];
|
|
5661
|
+
const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text', 'content', 'url'];
|
|
5592
5662
|
|
|
5593
5663
|
/**
|
|
5594
5664
|
* @typedef { import('../types').Schema } Schema
|
|
@@ -6574,47 +6644,17 @@ class RepeatRenderManager {
|
|
|
6574
6644
|
};
|
|
6575
6645
|
const parentExpressionContextInfo = hooks.useContext(LocalExpressionContext);
|
|
6576
6646
|
return jsxRuntime.jsx(jsxRuntime.Fragment, {
|
|
6577
|
-
children: displayValues.map((value, index) => {
|
|
6578
|
-
|
|
6579
|
-
|
|
6580
|
-
|
|
6581
|
-
|
|
6582
|
-
|
|
6583
|
-
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
|
|
6588
|
-
parent: buildExpressionContext(parentExpressionContextInfo),
|
|
6589
|
-
i: [...parentExpressionContextInfo.i, index + 1]
|
|
6590
|
-
}), [index, value]);
|
|
6591
|
-
return !showRemove ? jsxRuntime.jsx(LocalExpressionContext.Provider, {
|
|
6592
|
-
value: localExpressionContextInfo,
|
|
6593
|
-
children: jsxRuntime.jsx(RowsRenderer, {
|
|
6594
|
-
...elementProps
|
|
6595
|
-
})
|
|
6596
|
-
}) : jsxRuntime.jsxs("div", {
|
|
6597
|
-
class: "fjs-repeat-row-container",
|
|
6598
|
-
children: [jsxRuntime.jsx("div", {
|
|
6599
|
-
class: "fjs-repeat-row-rows",
|
|
6600
|
-
children: jsxRuntime.jsx(LocalExpressionContext.Provider, {
|
|
6601
|
-
value: localExpressionContextInfo,
|
|
6602
|
-
children: jsxRuntime.jsx(RowsRenderer, {
|
|
6603
|
-
...elementProps
|
|
6604
|
-
})
|
|
6605
|
-
})
|
|
6606
|
-
}), jsxRuntime.jsx("button", {
|
|
6607
|
-
class: "fjs-repeat-row-remove",
|
|
6608
|
-
type: "button",
|
|
6609
|
-
"aria-label": `Remove list item ${index + 1}`,
|
|
6610
|
-
onClick: () => onDeleteItem(index),
|
|
6611
|
-
children: jsxRuntime.jsx("div", {
|
|
6612
|
-
class: "fjs-repeat-row-remove-icon-container",
|
|
6613
|
-
children: jsxRuntime.jsx(DeleteSvg, {})
|
|
6614
|
-
})
|
|
6615
|
-
})]
|
|
6616
|
-
});
|
|
6617
|
-
})
|
|
6647
|
+
children: displayValues.map((value, index) => jsxRuntime.jsx(RepetitionScaffold, {
|
|
6648
|
+
index: index,
|
|
6649
|
+
value: value,
|
|
6650
|
+
parentExpressionContextInfo: parentExpressionContextInfo,
|
|
6651
|
+
repeaterField: repeaterField,
|
|
6652
|
+
RowsRenderer: RowsRenderer,
|
|
6653
|
+
indexes: indexes,
|
|
6654
|
+
onDeleteItem: onDeleteItem,
|
|
6655
|
+
showRemove: showRemove,
|
|
6656
|
+
...restProps
|
|
6657
|
+
}, index))
|
|
6618
6658
|
});
|
|
6619
6659
|
}
|
|
6620
6660
|
RepeatFooter(props) {
|
|
@@ -6677,18 +6717,18 @@ class RepeatRenderManager {
|
|
|
6677
6717
|
'fjs-remove-allowed': repeaterField.allowAddRemove
|
|
6678
6718
|
}),
|
|
6679
6719
|
children: [showAdd ? jsxRuntime.jsx("button", {
|
|
6720
|
+
type: "button",
|
|
6680
6721
|
readOnly: readonly,
|
|
6681
6722
|
disabled: disabled || readonly,
|
|
6682
6723
|
class: "fjs-repeat-render-add",
|
|
6683
|
-
type: "button",
|
|
6684
6724
|
ref: addButtonRef,
|
|
6685
6725
|
onClick: onAddItem,
|
|
6686
6726
|
children: jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
6687
6727
|
children: [jsxRuntime.jsx(AddSvg, {}), " ", 'Add new']
|
|
6688
6728
|
})
|
|
6689
6729
|
}) : null, collapseEnabled ? jsxRuntime.jsx("button", {
|
|
6690
|
-
class: "fjs-repeat-render-collapse",
|
|
6691
6730
|
type: "button",
|
|
6731
|
+
class: "fjs-repeat-render-collapse",
|
|
6692
6732
|
onClick: toggle,
|
|
6693
6733
|
children: isCollapsed ? jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
6694
6734
|
children: [jsxRuntime.jsx(ExpandSvg, {}), " ", `Expand all (${values.length})`]
|
|
@@ -6706,6 +6746,73 @@ class RepeatRenderManager {
|
|
|
6706
6746
|
return nonCollapsedItems ? nonCollapsedItems : DEFAULT_NON_COLLAPSED_ITEMS;
|
|
6707
6747
|
}
|
|
6708
6748
|
}
|
|
6749
|
+
|
|
6750
|
+
/**
|
|
6751
|
+
* Individual repetition of a repeated field and context scaffolding.
|
|
6752
|
+
*
|
|
6753
|
+
* @param {Object} props
|
|
6754
|
+
* @param {number} props.index
|
|
6755
|
+
* @param {Object} props.value
|
|
6756
|
+
* @param {Object} props.parentExpressionContextInfo
|
|
6757
|
+
* @param {Object} props.repeaterField
|
|
6758
|
+
* @param {Function} props.RowsRenderer
|
|
6759
|
+
* @param {Object} props.indexes
|
|
6760
|
+
* @param {Function} props.onDeleteItem
|
|
6761
|
+
* @param {boolean} props.showRemove
|
|
6762
|
+
*/
|
|
6763
|
+
|
|
6764
|
+
const RepetitionScaffold = props => {
|
|
6765
|
+
const {
|
|
6766
|
+
index,
|
|
6767
|
+
value,
|
|
6768
|
+
parentExpressionContextInfo,
|
|
6769
|
+
repeaterField,
|
|
6770
|
+
RowsRenderer,
|
|
6771
|
+
indexes,
|
|
6772
|
+
onDeleteItem,
|
|
6773
|
+
showRemove,
|
|
6774
|
+
...restProps
|
|
6775
|
+
} = props;
|
|
6776
|
+
const elementProps = hooks.useMemo(() => ({
|
|
6777
|
+
...restProps,
|
|
6778
|
+
indexes: {
|
|
6779
|
+
...(indexes || {}),
|
|
6780
|
+
[repeaterField.id]: index
|
|
6781
|
+
}
|
|
6782
|
+
}), [index, indexes, repeaterField.id, restProps]);
|
|
6783
|
+
const localExpressionContextInfo = hooks.useMemo(() => ({
|
|
6784
|
+
data: parentExpressionContextInfo.data,
|
|
6785
|
+
this: value,
|
|
6786
|
+
parent: buildExpressionContext(parentExpressionContextInfo),
|
|
6787
|
+
i: [...parentExpressionContextInfo.i, index + 1]
|
|
6788
|
+
}), [index, parentExpressionContextInfo, value]);
|
|
6789
|
+
return !showRemove ? jsxRuntime.jsx(LocalExpressionContext.Provider, {
|
|
6790
|
+
value: localExpressionContextInfo,
|
|
6791
|
+
children: jsxRuntime.jsx(RowsRenderer, {
|
|
6792
|
+
...elementProps
|
|
6793
|
+
})
|
|
6794
|
+
}) : jsxRuntime.jsxs("div", {
|
|
6795
|
+
class: "fjs-repeat-row-container",
|
|
6796
|
+
children: [jsxRuntime.jsx("div", {
|
|
6797
|
+
class: "fjs-repeat-row-rows",
|
|
6798
|
+
children: jsxRuntime.jsx(LocalExpressionContext.Provider, {
|
|
6799
|
+
value: localExpressionContextInfo,
|
|
6800
|
+
children: jsxRuntime.jsx(RowsRenderer, {
|
|
6801
|
+
...elementProps
|
|
6802
|
+
})
|
|
6803
|
+
})
|
|
6804
|
+
}), jsxRuntime.jsx("button", {
|
|
6805
|
+
type: "button",
|
|
6806
|
+
class: "fjs-repeat-row-remove",
|
|
6807
|
+
"aria-label": `Remove list item ${index + 1}`,
|
|
6808
|
+
onClick: () => onDeleteItem(index),
|
|
6809
|
+
children: jsxRuntime.jsx("div", {
|
|
6810
|
+
class: "fjs-repeat-row-remove-icon-container",
|
|
6811
|
+
children: jsxRuntime.jsx(DeleteSvg, {})
|
|
6812
|
+
})
|
|
6813
|
+
})]
|
|
6814
|
+
});
|
|
6815
|
+
};
|
|
6709
6816
|
RepeatRenderManager.$inject = ['form', 'formFields', 'formFieldRegistry', 'pathRegistry'];
|
|
6710
6817
|
|
|
6711
6818
|
const RepeatRenderModule = {
|