@formio/js 5.3.1-refb-rc.0 → 5.3.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.
Files changed (66) hide show
  1. package/dist/formio.embed.js +1 -1
  2. package/dist/formio.embed.min.js +1 -1
  3. package/dist/formio.embed.min.js.LICENSE.txt +1 -1
  4. package/dist/formio.form.js +53 -44
  5. package/dist/formio.form.min.js +1 -1
  6. package/dist/formio.form.min.js.LICENSE.txt +2 -4
  7. package/dist/formio.full.js +55 -46
  8. package/dist/formio.full.min.js +1 -1
  9. package/dist/formio.full.min.js.LICENSE.txt +2 -4
  10. package/dist/formio.js +32 -12
  11. package/dist/formio.min.js +1 -1
  12. package/dist/formio.min.js.LICENSE.txt +2 -2
  13. package/dist/formio.utils.js +32 -23
  14. package/dist/formio.utils.min.js +1 -1
  15. package/dist/formio.utils.min.js.LICENSE.txt +2 -4
  16. package/lib/cjs/Embed.js +29 -1
  17. package/lib/cjs/Formio.js +1 -1
  18. package/lib/cjs/PDF.js +9 -1
  19. package/lib/cjs/Webform.js +27 -1
  20. package/lib/cjs/components/_classes/component/Component.d.ts +1 -0
  21. package/lib/cjs/components/_classes/component/Component.js +14 -1
  22. package/lib/cjs/components/_classes/input/Input.js +17 -2
  23. package/lib/cjs/components/address/Address.js +2 -1
  24. package/lib/cjs/components/datagrid/DataGrid.js +12 -1
  25. package/lib/cjs/components/datetime/editForm/DateTime.edit.date.d.ts +18 -1
  26. package/lib/cjs/components/datetime/editForm/DateTime.edit.date.js +3 -0
  27. package/lib/cjs/components/datetime/editForm/DateTime.edit.time.d.ts +13 -2
  28. package/lib/cjs/components/datetime/editForm/DateTime.edit.time.js +3 -0
  29. package/lib/cjs/components/fieldset/Fieldset.d.ts +1 -0
  30. package/lib/cjs/components/fieldset/Fieldset.js +7 -0
  31. package/lib/cjs/components/select/Select.js +13 -8
  32. package/lib/cjs/components/tags/Tags.js +2 -1
  33. package/lib/cjs/package.json +1 -1
  34. package/lib/cjs/utils/conditionOperators/IsEqualTo.d.ts +1 -3
  35. package/lib/cjs/utils/conditionOperators/IsEqualTo.js +6 -12
  36. package/lib/cjs/utils/conditionOperators/index.d.ts +2 -1
  37. package/lib/cjs/utils/index.d.ts +2 -1
  38. package/lib/cjs/utils/utils.d.ts +9 -0
  39. package/lib/cjs/utils/utils.js +132 -2
  40. package/lib/cjs/widgets/CalendarWidget.js +2 -1
  41. package/lib/mjs/Embed.js +29 -1
  42. package/lib/mjs/Formio.js +1 -1
  43. package/lib/mjs/PDF.js +9 -1
  44. package/lib/mjs/Webform.js +27 -1
  45. package/lib/mjs/components/_classes/component/Component.d.ts +1 -0
  46. package/lib/mjs/components/_classes/component/Component.js +12 -1
  47. package/lib/mjs/components/_classes/input/Input.js +16 -3
  48. package/lib/mjs/components/address/Address.js +1 -1
  49. package/lib/mjs/components/datagrid/DataGrid.js +11 -1
  50. package/lib/mjs/components/datetime/editForm/DateTime.edit.date.d.ts +18 -1
  51. package/lib/mjs/components/datetime/editForm/DateTime.edit.date.js +3 -0
  52. package/lib/mjs/components/datetime/editForm/DateTime.edit.time.d.ts +13 -2
  53. package/lib/mjs/components/datetime/editForm/DateTime.edit.time.js +3 -0
  54. package/lib/mjs/components/fieldset/Fieldset.d.ts +1 -0
  55. package/lib/mjs/components/fieldset/Fieldset.js +7 -0
  56. package/lib/mjs/components/select/Select.js +11 -8
  57. package/lib/mjs/components/tags/Tags.js +1 -1
  58. package/lib/mjs/package.json +1 -1
  59. package/lib/mjs/utils/conditionOperators/IsEqualTo.d.ts +1 -3
  60. package/lib/mjs/utils/conditionOperators/IsEqualTo.js +6 -11
  61. package/lib/mjs/utils/conditionOperators/index.d.ts +2 -1
  62. package/lib/mjs/utils/index.d.ts +2 -1
  63. package/lib/mjs/utils/utils.d.ts +9 -0
  64. package/lib/mjs/utils/utils.js +130 -1
  65. package/lib/mjs/widgets/CalendarWidget.js +1 -1
  66. package/package.json +4 -4
@@ -1,6 +1,7 @@
1
1
  export default ConditionOperators;
2
2
  declare const ConditionOperators: {
3
- [x: string]: typeof IsEqualTo | typeof DateGreaterThan;
3
+ [x: string]: typeof IsEqualTo | typeof IsEmptyValue | typeof DateGreaterThan;
4
4
  };
5
5
  import IsEqualTo from './IsEqualTo';
6
+ import IsEmptyValue from './IsEmptyValue';
6
7
  import DateGreaterThan from './DateGreaterThan';
@@ -5,7 +5,7 @@ declare const FormioUtils: {
5
5
  Evaluator: DefaultEvaluator;
6
6
  interpolate: typeof interpolate;
7
7
  ConditionOperators: {
8
- [x: string]: typeof import("./conditionOperators/IsEqualTo").default | typeof import("./conditionOperators/DateGreaterThan").default;
8
+ [x: string]: typeof import("./conditionOperators/IsEqualTo").default | typeof import("./conditionOperators/IsEmptyValue").default | typeof import("./conditionOperators/DateGreaterThan").default;
9
9
  };
10
10
  _: any;
11
11
  moment: typeof moment;
@@ -150,6 +150,7 @@ declare const FormioUtils: {
150
150
  getFocusableElements(element: HTMLElement): NodeList<HTMLElement>;
151
151
  getComponentSavedTypes(fullSchema: import("@formio/core").Component): string[] | null;
152
152
  hasEncodedTimezone(value: string): boolean;
153
+ announceScreenReaderMessage(component: any, value: any, index?: any, forFocus?: any): undefined;
153
154
  screenReaderSpeech(text: string): void;
154
155
  firstNonNil: any;
155
156
  componentValueTypes: {
@@ -499,6 +499,15 @@ export function getComponentSavedTypes(fullSchema: import('@formio/core').Compon
499
499
  * @returns {boolean} if value has encoded timezone
500
500
  */
501
501
  export function hasEncodedTimezone(value: string): boolean;
502
+ /**
503
+ * The function for announcing messages via a screen reader
504
+ * @param {component} component - The component instance
505
+ * @param {value} value - The current component value
506
+ * @param {index} index - The component index
507
+ * @param {forFocus} forFocus - Whether the component is focused or not
508
+ * @returns {undefined}
509
+ */
510
+ export function announceScreenReaderMessage(component: any, value: any, index?: any, forFocus?: any): undefined;
502
511
  /**
503
512
  * Outputs text to screen reader
504
513
  * @param {string} text The text to output to screen readers
@@ -135,7 +135,7 @@ function getConditionalPathsRecursive(conditionPaths, data) {
135
135
  if (currentData.some((element) => typeof element !== 'object')) {
136
136
  return;
137
137
  }
138
- const hasInnerDataArray = currentData.find((x) => Array.isArray(x[conditionPaths[currentLocalIndex]]));
138
+ const hasInnerDataArray = currentData.find((x) => x && conditionPaths && Array.isArray(x[conditionPaths[currentLocalIndex]]));
139
139
  if (hasInnerDataArray) {
140
140
  currentData.forEach((_, indexOutside) => {
141
141
  const innerCompDataPath = `${currentPath}[${indexOutside}].${conditionPaths[currentLocalIndex]}`;
@@ -1619,6 +1619,135 @@ export function hasEncodedTimezone(value) {
1619
1619
  value.substring(value.length - 1) === 'Z' ||
1620
1620
  value.match(/[+|-][0-9]{2}:[0-9]{2}$/));
1621
1621
  }
1622
+ // Types for min max validation if value = string
1623
+ const TYPES = new Map([["char", "Length"], ["word", "Words"]]);
1624
+ // The number from which the remaining character(words) count message starts being read
1625
+ const REMAIN_COUNT = new Map([["char", 10], ["word", 5]]);
1626
+ function getWordOrCharacterLabel(isWordType, count) {
1627
+ const base = isWordType ? "word" : "character";
1628
+ return Math.abs(count) === 1 ? base : `${base}s`;
1629
+ }
1630
+ /**
1631
+ * The function calculates the message values depending on the type and the current component settings.
1632
+ * @param {component} component - The component instance
1633
+ * @param {type} type - The type of validation max and min
1634
+ * @param {value} value - The current component value
1635
+ * @param {forFocus} forFocus - Whether the component is focused or not
1636
+ * @returns {string} - The messsage string
1637
+ */
1638
+ function getScreenReaderMessage(component, type, value) {
1639
+ const isWordType = type === "word";
1640
+ const maxKey = typeof value === "string" && (type === "char" || isWordType)
1641
+ ? `validate.max${TYPES.get(type)}`
1642
+ : "validate.max";
1643
+ const minKey = typeof value === "string" && (type === "char" || isWordType)
1644
+ ? `validate.min${TYPES.get(type)}`
1645
+ : "validate.min";
1646
+ const max = _.parseInt(_.get(component.component, maxKey), 10);
1647
+ const min = _.parseInt(_.get(component.component, minKey), 10);
1648
+ let message = "";
1649
+ if (typeof value === "string") {
1650
+ const currentLength = isWordType ? component.getWordCount(value) : value.length;
1651
+ if (!isNaN(max)) {
1652
+ const remains = max - currentLength;
1653
+ if (value) {
1654
+ const threshold = REMAIN_COUNT.get(type) || max;
1655
+ if (remains > 0 && remains < threshold) {
1656
+ message += `${remains} ${getWordOrCharacterLabel(isWordType, remains)} remaining. `;
1657
+ }
1658
+ else if (remains < 0) {
1659
+ const removeCount = Math.abs(remains);
1660
+ message += `${removeCount} ${getWordOrCharacterLabel(isWordType, removeCount)} should be removed. `;
1661
+ }
1662
+ else if (remains === 0) {
1663
+ message += `No ${getWordOrCharacterLabel(isWordType, 0)} remaining.`;
1664
+ }
1665
+ }
1666
+ else {
1667
+ message += `Maximum ${max} ${getWordOrCharacterLabel(isWordType, max)}. `;
1668
+ }
1669
+ }
1670
+ if (!isNaN(min)) {
1671
+ if (value) {
1672
+ const remains = min - currentLength;
1673
+ if (remains > 0) {
1674
+ message += `${remains} ${getWordOrCharacterLabel(isWordType, remains)} should be added.`;
1675
+ }
1676
+ if (remains === 0) {
1677
+ message += ``;
1678
+ }
1679
+ }
1680
+ else {
1681
+ message += `Minimum ${min} ${getWordOrCharacterLabel(isWordType, min)}. `;
1682
+ }
1683
+ }
1684
+ }
1685
+ else if (typeof value === "number" || value === null) {
1686
+ if (value != null && value !== "") {
1687
+ if (!isNaN(max) && value > max) {
1688
+ message += `Number cannot be greater than ${max}. `;
1689
+ }
1690
+ if (!isNaN(min) && value < min) {
1691
+ message += `Number cannot be less than ${min}.`;
1692
+ }
1693
+ }
1694
+ else {
1695
+ if (!isNaN(min))
1696
+ message += `Minimum value ${min}. `;
1697
+ if (!isNaN(max))
1698
+ message += `Maximum value ${max}. `;
1699
+ }
1700
+ }
1701
+ return message.trim();
1702
+ }
1703
+ /**
1704
+ * The function for announcing messages via a screen reader
1705
+ * @param {component} component - The component instance
1706
+ * @param {value} value - The current component value
1707
+ * @param {index} index - The component index
1708
+ * @param {forFocus} forFocus - Whether the component is focused or not
1709
+ * @returns {undefined}
1710
+ */
1711
+ export function announceScreenReaderMessage(component, value, index = 0, forFocus = false) {
1712
+ if (typeof value !== "string" && typeof value !== "number" && value !== null) {
1713
+ return;
1714
+ }
1715
+ // The ref for announcing messages
1716
+ const messageSpan = "announceMessage";
1717
+ if (!component.refs[messageSpan])
1718
+ return;
1719
+ const el = component.refs[messageSpan][index];
1720
+ if (!el)
1721
+ return;
1722
+ // Define types for validation
1723
+ const typesToCheck = [];
1724
+ if (typeof value === "string")
1725
+ typesToCheck.push("char", "word");
1726
+ if (typeof value === "number" || value === null)
1727
+ typesToCheck.push("number");
1728
+ // Construct the combined message
1729
+ const combinedMessage = typesToCheck
1730
+ .map(type => getScreenReaderMessage(component, type, value))
1731
+ .filter(msg => msg)
1732
+ .join(" ")
1733
+ .trim();
1734
+ if (forFocus) {
1735
+ setTimeout(() => {
1736
+ el.textContent = "";
1737
+ requestAnimationFrame(() => {
1738
+ el.textContent = combinedMessage;
1739
+ });
1740
+ }, 150);
1741
+ return;
1742
+ }
1743
+ clearTimeout(el._announceTimer);
1744
+ el._announceTimer = setTimeout(() => {
1745
+ el.textContent = "";
1746
+ requestAnimationFrame(() => {
1747
+ el.textContent = combinedMessage;
1748
+ });
1749
+ }, 500);
1750
+ }
1622
1751
  /**
1623
1752
  * Outputs text to screen reader
1624
1753
  * @param {string} text The text to output to screen readers
@@ -442,7 +442,7 @@ export default class CalendarWidget extends InputWidget {
442
442
  // If other fields are used to calculate disabled dates, we need to redraw calendar to refresh disabled dates
443
443
  if (this.settings.disableFunction && this.componentInstance && this.componentInstance.root) {
444
444
  this.changeHandler = (e) => {
445
- if (e.changed && this.calendar) {
445
+ if (e.changed && this.calendar?.config) {
446
446
  this.calendar.redraw();
447
447
  }
448
448
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formio/js",
3
- "version": "5.3.1-refb-rc.0",
3
+ "version": "5.3.2",
4
4
  "description": "JavaScript powered Forms with JSON Form Builder",
5
5
  "main": "lib/cjs/index.js",
6
6
  "exports": {
@@ -67,7 +67,7 @@
67
67
  "core-js": "^3.37.1",
68
68
  "dialog-polyfill": "^0.5.6",
69
69
  "dom-autoscroller": "^2.3.4",
70
- "dompurify": "^3.2.4",
70
+ "dompurify": "^3.3.3",
71
71
  "downloadjs": "^1.4.7",
72
72
  "dragula": "^3.7.3",
73
73
  "eventemitter3": "^5.0.1",
@@ -88,8 +88,8 @@
88
88
  "tippy.js": "^6.3.7",
89
89
  "uuid": "^9.0.0",
90
90
  "vanilla-picker": "^2.12.3",
91
- "@formio/bootstrap": "^3.2.0",
92
- "@formio/core": "^2.6.0"
91
+ "@formio/bootstrap": "^3.2.2",
92
+ "@formio/core": "^2.6.2"
93
93
  },
94
94
  "devDependencies": {
95
95
  "@types/node": "^22.15.19",