@dhis2/ui-forms 9.11.0 → 9.11.1-beta.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 (192) hide show
  1. package/build/cjs/CheckboxFieldFF/{CheckboxFieldFF.stories.e2e.js → CheckboxFieldFF.e2e.stories.js} +22 -15
  2. package/build/cjs/CheckboxFieldFF/CheckboxFieldFF.js +2 -12
  3. package/build/cjs/CheckboxFieldFF/{CheckboxFieldFF.stories.js → CheckboxFieldFF.prod.stories.js} +29 -24
  4. package/build/cjs/CheckboxFieldFF/features/can_toggle_a_boolean/index.js +0 -1
  5. package/build/cjs/CheckboxFieldFF/features/can_toggle_a_value/index.js +0 -1
  6. package/build/cjs/CheckboxFieldFF/features/common/index.js +0 -1
  7. package/build/cjs/CheckboxFieldFF/features/displays_error/index.js +0 -2
  8. package/build/cjs/FieldGroupFF/FieldGroupFF.js +1 -10
  9. package/build/cjs/FieldGroupFF/{FieldGroupFF.stories.js → FieldGroupFF.prod.stories.js} +11 -12
  10. package/build/cjs/FileInputFieldFF/{FileInputFieldFF.stories.e2e.js → FileInputFieldFF.e2e.stories.js} +45 -56
  11. package/build/cjs/FileInputFieldFF/FileInputFieldFF.js +2 -19
  12. package/build/cjs/FileInputFieldFF/{FileInputFieldFF.stories.js → FileInputFieldFF.prod.stories.js} +29 -22
  13. package/build/cjs/FileInputFieldFF/features/accepts_file/index.js +0 -1
  14. package/build/cjs/FileInputFieldFF/features/common/index.js +0 -1
  15. package/build/cjs/FileInputFieldFF/features/displays_error/index.js +0 -1
  16. package/build/cjs/InputFieldFF/InputFieldFF.e2e.stories.js +30 -0
  17. package/build/cjs/InputFieldFF/InputFieldFF.js +2 -12
  18. package/build/cjs/InputFieldFF/{InputFieldFF.stories.js → InputFieldFF.prod.stories.js} +29 -22
  19. package/build/cjs/InputFieldFF/features/can_set_a_value/index.js +0 -1
  20. package/build/cjs/InputFieldFF/features/displays_error/index.js +0 -2
  21. package/build/cjs/MultiSelectFieldFF/{MultiSelectFieldFF.stories.e2e.js → MultiSelectFieldFF.e2e.stories.js} +15 -17
  22. package/build/cjs/MultiSelectFieldFF/MultiSelectFieldFF.js +3 -15
  23. package/build/cjs/MultiSelectFieldFF/MultiSelectFieldFF.prod.stories.js +107 -0
  24. package/build/cjs/MultiSelectFieldFF/features/can_set_a_value/index.js +0 -1
  25. package/build/cjs/MultiSelectFieldFF/features/common/index.js +1 -2
  26. package/build/cjs/MultiSelectFieldFF/features/displays_error/index.js +0 -2
  27. package/build/cjs/RadioFieldFF/RadioFieldFF.e2e.stories.js +45 -0
  28. package/build/cjs/RadioFieldFF/RadioFieldFF.js +2 -12
  29. package/build/cjs/RadioFieldFF/{RadioFieldFF.stories.js → RadioFieldFF.prod.stories.js} +29 -16
  30. package/build/cjs/RadioFieldFF/features/can_set_a_value/index.js +0 -1
  31. package/build/cjs/RadioFieldFF/features/common/index.js +0 -1
  32. package/build/cjs/RadioFieldFF/features/displays_error/index.js +0 -2
  33. package/build/cjs/SingleSelectFieldFF/SingleSelectFieldFF.e2e.stories.js +39 -0
  34. package/build/cjs/SingleSelectFieldFF/SingleSelectFieldFF.js +2 -12
  35. package/build/cjs/SingleSelectFieldFF/SingleSelectFieldFF.prod.stories.js +106 -0
  36. package/build/cjs/SingleSelectFieldFF/features/can_set_a_value/index.js +0 -1
  37. package/build/cjs/SingleSelectFieldFF/features/common/index.js +0 -1
  38. package/build/cjs/SingleSelectFieldFF/features/displays_error/index.js +0 -2
  39. package/build/cjs/SwitchFieldFF/SwitchFieldFF.e2e.stories.js +56 -0
  40. package/build/cjs/SwitchFieldFF/SwitchFieldFF.js +2 -12
  41. package/build/cjs/SwitchFieldFF/{SwitchFieldFF.stories.js → SwitchFieldFF.prod.stories.js} +29 -24
  42. package/build/cjs/SwitchFieldFF/features/can_toggle_a_boolean/index.js +0 -1
  43. package/build/cjs/SwitchFieldFF/features/can_toggle_a_value/index.js +0 -1
  44. package/build/cjs/SwitchFieldFF/features/common/index.js +0 -1
  45. package/build/cjs/SwitchFieldFF/features/displays_error/index.js +0 -2
  46. package/build/cjs/TextAreaFieldFF/TextAreaFieldFF.e2e.stories.js +30 -0
  47. package/build/cjs/TextAreaFieldFF/TextAreaFieldFF.js +2 -12
  48. package/build/cjs/TextAreaFieldFF/{TextAreaFieldFF.stories.js → TextAreaFieldFF.prod.stories.js} +29 -24
  49. package/build/cjs/TextAreaFieldFF/features/can_set_a_value/index.js +0 -1
  50. package/build/cjs/TextAreaFieldFF/features/displays_error/index.js +0 -2
  51. package/build/cjs/__tests__/__snapshots__/index.test.js.snap +3 -0
  52. package/build/cjs/__tests__/index.test.js +1 -1
  53. package/build/cjs/formDecorator.js +6 -21
  54. package/build/cjs/index.js +2 -21
  55. package/build/cjs/locales/index.js +3 -75
  56. package/build/cjs/shared/helpers/createBlurHandler.js +0 -3
  57. package/build/cjs/shared/helpers/createChangeHandler.js +0 -2
  58. package/build/cjs/shared/helpers/createFocusHandler.js +0 -3
  59. package/build/cjs/shared/helpers/createSelectChangeHandler.js +0 -2
  60. package/build/cjs/shared/helpers/createToggleChangeHandler.js +0 -3
  61. package/build/cjs/shared/helpers/getValidationText.js +0 -6
  62. package/build/cjs/shared/helpers/hasError.js +0 -2
  63. package/build/cjs/shared/helpers/isLoading.js +0 -2
  64. package/build/cjs/shared/helpers/isValid.js +0 -2
  65. package/build/cjs/shared/helpers.js +0 -9
  66. package/build/cjs/shared/propTypes.js +7 -20
  67. package/build/cjs/transformers/arrayWithIdObjects.js +2 -6
  68. package/build/cjs/transformers/index.js +0 -1
  69. package/build/cjs/validators/__tests__/alphaNumeric.test.js +0 -2
  70. package/build/cjs/validators/__tests__/boolean.test.js +0 -2
  71. package/build/cjs/validators/__tests__/composeValidators.test.js +0 -3
  72. package/build/cjs/validators/__tests__/createCharacterLengthRange.test.js +6 -6
  73. package/build/cjs/validators/__tests__/createEqualTo.test.js +0 -3
  74. package/build/cjs/validators/__tests__/createMaxCharacterLength.test.js +1 -2
  75. package/build/cjs/validators/__tests__/createMaxNumber.test.js +1 -2
  76. package/build/cjs/validators/__tests__/createMinCharacterLength.test.js +1 -2
  77. package/build/cjs/validators/__tests__/createMinNumber.test.js +1 -2
  78. package/build/cjs/validators/__tests__/createNumberRange.test.js +0 -3
  79. package/build/cjs/validators/__tests__/createPattern.test.js +1 -3
  80. package/build/cjs/validators/__tests__/dhis2Password.test.js +0 -2
  81. package/build/cjs/validators/__tests__/dhis2Username.test.js +0 -2
  82. package/build/cjs/validators/__tests__/email.test.js +7 -6
  83. package/build/cjs/validators/__tests__/hasValue.test.js +0 -2
  84. package/build/cjs/validators/__tests__/integer.test.js +0 -2
  85. package/build/cjs/validators/__tests__/internationalPhoneNumber.test.js +6 -5
  86. package/build/cjs/validators/__tests__/number.test.js +0 -2
  87. package/build/cjs/validators/__tests__/string.test.js +0 -2
  88. package/build/cjs/validators/__tests__/url.test.js +1 -2
  89. package/build/cjs/validators/alphaNumeric.js +2 -11
  90. package/build/cjs/validators/boolean.js +2 -10
  91. package/build/cjs/validators/composeValidators.js +0 -4
  92. package/build/cjs/validators/createCharacterLengthRange.js +1 -8
  93. package/build/cjs/validators/createEqualTo.js +1 -8
  94. package/build/cjs/validators/createMaxCharacterLength.js +1 -6
  95. package/build/cjs/validators/createMaxNumber.js +1 -6
  96. package/build/cjs/validators/createMinCharacterLength.js +1 -6
  97. package/build/cjs/validators/createMinNumber.js +1 -6
  98. package/build/cjs/validators/createNumberRange.js +1 -8
  99. package/build/cjs/validators/createPattern.js +2 -10
  100. package/build/cjs/validators/dhis2Password.js +6 -28
  101. package/build/cjs/validators/dhis2Username.js +2 -11
  102. package/build/cjs/validators/email.js +3 -11
  103. package/build/cjs/validators/hasValue.js +2 -10
  104. package/build/cjs/validators/helpers/index.js +1 -16
  105. package/build/cjs/validators/index.js +0 -20
  106. package/build/cjs/validators/integer.js +3 -10
  107. package/build/cjs/validators/internationalPhoneNumber.js +8 -14
  108. package/build/cjs/validators/number.js +2 -10
  109. package/build/cjs/validators/string.js +2 -10
  110. package/build/cjs/validators/test-helpers/index.js +1 -6
  111. package/build/cjs/validators/url.js +2 -11
  112. package/build/es/CheckboxFieldFF/{CheckboxFieldFF.stories.e2e.js → CheckboxFieldFF.e2e.stories.js} +14 -7
  113. package/build/es/CheckboxFieldFF/CheckboxFieldFF.js +1 -3
  114. package/build/es/CheckboxFieldFF/{CheckboxFieldFF.stories.js → CheckboxFieldFF.prod.stories.js} +29 -3
  115. package/build/es/FieldGroupFF/FieldGroupFF.js +0 -2
  116. package/build/es/FieldGroupFF/{FieldGroupFF.stories.js → FieldGroupFF.prod.stories.js} +11 -1
  117. package/build/es/FileInputFieldFF/{FileInputFieldFF.stories.e2e.js → FileInputFieldFF.e2e.stories.js} +14 -16
  118. package/build/es/FileInputFieldFF/FileInputFieldFF.js +1 -8
  119. package/build/es/FileInputFieldFF/{FileInputFieldFF.stories.js → FileInputFieldFF.prod.stories.js} +29 -3
  120. package/build/es/InputFieldFF/{InputFieldFF.stories.e2e.js → InputFieldFF.e2e.stories.js} +8 -4
  121. package/build/es/InputFieldFF/InputFieldFF.js +1 -3
  122. package/build/es/InputFieldFF/{InputFieldFF.stories.js → InputFieldFF.prod.stories.js} +29 -3
  123. package/build/es/MultiSelectFieldFF/{MultiSelectFieldFF.stories.e2e.js → MultiSelectFieldFF.e2e.stories.js} +7 -7
  124. package/build/es/MultiSelectFieldFF/MultiSelectFieldFF.js +2 -6
  125. package/build/es/MultiSelectFieldFF/MultiSelectFieldFF.prod.stories.js +98 -0
  126. package/build/es/MultiSelectFieldFF/features/common/index.js +1 -1
  127. package/build/es/RadioFieldFF/{RadioFieldFF.stories.e2e.js → RadioFieldFF.e2e.stories.js} +6 -3
  128. package/build/es/RadioFieldFF/RadioFieldFF.js +1 -3
  129. package/build/es/RadioFieldFF/{RadioFieldFF.stories.js → RadioFieldFF.prod.stories.js} +29 -3
  130. package/build/es/SingleSelectFieldFF/{SingleSelectFieldFF.stories.e2e.js → SingleSelectFieldFF.e2e.stories.js} +10 -6
  131. package/build/es/SingleSelectFieldFF/SingleSelectFieldFF.js +1 -3
  132. package/build/es/SingleSelectFieldFF/SingleSelectFieldFF.prod.stories.js +97 -0
  133. package/build/es/SwitchFieldFF/{SwitchFieldFF.stories.e2e.js → SwitchFieldFF.e2e.stories.js} +14 -7
  134. package/build/es/SwitchFieldFF/SwitchFieldFF.js +1 -3
  135. package/build/es/SwitchFieldFF/{SwitchFieldFF.stories.js → SwitchFieldFF.prod.stories.js} +29 -3
  136. package/build/es/TextAreaFieldFF/{TextAreaFieldFF.stories.e2e.js → TextAreaFieldFF.e2e.stories.js} +8 -4
  137. package/build/es/TextAreaFieldFF/TextAreaFieldFF.js +1 -3
  138. package/build/es/TextAreaFieldFF/{TextAreaFieldFF.stories.js → TextAreaFieldFF.prod.stories.js} +29 -3
  139. package/build/es/__tests__/__snapshots__/index.test.js.snap +3 -0
  140. package/build/es/__tests__/index.test.js +1 -0
  141. package/build/es/formDecorator.js +5 -12
  142. package/build/es/index.js +2 -2
  143. package/build/es/shared/helpers/createBlurHandler.js +0 -2
  144. package/build/es/shared/helpers/createChangeHandler.js +0 -2
  145. package/build/es/shared/helpers/createFocusHandler.js +0 -2
  146. package/build/es/shared/helpers/createSelectChangeHandler.js +0 -1
  147. package/build/es/shared/helpers/createToggleChangeHandler.js +0 -2
  148. package/build/es/shared/helpers/getValidationText.js +0 -5
  149. package/build/es/shared/helpers/hasError.js +0 -1
  150. package/build/es/shared/helpers/isLoading.js +0 -1
  151. package/build/es/shared/helpers/isValid.js +0 -1
  152. package/build/es/transformers/arrayWithIdObjects.js +0 -2
  153. package/build/es/validators/__tests__/createCharacterLengthRange.test.js +6 -3
  154. package/build/es/validators/__tests__/createMaxCharacterLength.test.js +1 -0
  155. package/build/es/validators/__tests__/createMaxNumber.test.js +1 -0
  156. package/build/es/validators/__tests__/createMinCharacterLength.test.js +1 -0
  157. package/build/es/validators/__tests__/createMinNumber.test.js +1 -0
  158. package/build/es/validators/__tests__/createPattern.test.js +1 -1
  159. package/build/es/validators/__tests__/email.test.js +7 -4
  160. package/build/es/validators/__tests__/internationalPhoneNumber.test.js +6 -3
  161. package/build/es/validators/__tests__/url.test.js +1 -0
  162. package/build/es/validators/alphaNumeric.js +0 -2
  163. package/build/es/validators/boolean.js +0 -2
  164. package/build/es/validators/composeValidators.js +0 -2
  165. package/build/es/validators/createCharacterLengthRange.js +0 -2
  166. package/build/es/validators/createEqualTo.js +0 -2
  167. package/build/es/validators/createMaxCharacterLength.js +0 -2
  168. package/build/es/validators/createMaxNumber.js +0 -2
  169. package/build/es/validators/createMinCharacterLength.js +0 -2
  170. package/build/es/validators/createMinNumber.js +0 -2
  171. package/build/es/validators/createNumberRange.js +0 -2
  172. package/build/es/validators/createPattern.js +0 -3
  173. package/build/es/validators/dhis2Password.js +3 -12
  174. package/build/es/validators/dhis2Username.js +0 -2
  175. package/build/es/validators/email.js +1 -2
  176. package/build/es/validators/hasValue.js +0 -2
  177. package/build/es/validators/integer.js +3 -4
  178. package/build/es/validators/internationalPhoneNumber.js +7 -7
  179. package/build/es/validators/number.js +0 -2
  180. package/build/es/validators/string.js +0 -2
  181. package/build/es/validators/test-helpers/index.js +1 -4
  182. package/build/es/validators/url.js +2 -3
  183. package/package.json +13 -13
  184. package/build/cjs/InputFieldFF/InputFieldFF.stories.e2e.js +0 -27
  185. package/build/cjs/MultiSelectFieldFF/MultiSelectFieldFF.stories.js +0 -91
  186. package/build/cjs/RadioFieldFF/RadioFieldFF.stories.e2e.js +0 -45
  187. package/build/cjs/SingleSelectFieldFF/SingleSelectFieldFF.stories.e2e.js +0 -37
  188. package/build/cjs/SingleSelectFieldFF/SingleSelectFieldFF.stories.js +0 -90
  189. package/build/cjs/SwitchFieldFF/SwitchFieldFF.stories.e2e.js +0 -49
  190. package/build/cjs/TextAreaFieldFF/TextAreaFieldFF.stories.e2e.js +0 -27
  191. package/build/es/MultiSelectFieldFF/MultiSelectFieldFF.stories.js +0 -70
  192. package/build/es/SingleSelectFieldFF/SingleSelectFieldFF.stories.js +0 -69
@@ -1,12 +1,16 @@
1
- import { storiesOf } from '@storybook/react';
2
1
  import React from 'react';
3
2
  import { Field } from 'react-final-form';
4
3
  import { formDecorator } from '../formDecorator.js';
5
4
  import { hasValue } from '../validators/index.js';
6
- import { SwitchFieldFF } from './SwitchFieldFF.js'; // https://github.com/final-form/react-final-form-arrays/issues/111
5
+ import { SwitchFieldFF } from './SwitchFieldFF.js';
7
6
 
7
+ // https://github.com/final-form/react-final-form-arrays/issues/111
8
8
  const initialValue = ['yes'];
9
- storiesOf('Testing:SwitchFieldFF', module).addDecorator(formDecorator).add('Unchecked', () => /*#__PURE__*/React.createElement(Field, {
9
+ export default {
10
+ title: 'Testing:SwitchFieldFF',
11
+ decorators: [formDecorator]
12
+ };
13
+ export const Unchecked = () => /*#__PURE__*/React.createElement(Field, {
10
14
  component: SwitchFieldFF,
11
15
  className: "switch",
12
16
  name: "switch",
@@ -14,21 +18,24 @@ storiesOf('Testing:SwitchFieldFF', module).addDecorator(formDecorator).add('Unch
14
18
  validate: hasValue,
15
19
  required: true,
16
20
  type: "checkbox"
17
- })).add('Checked ', () => /*#__PURE__*/React.createElement(Field, {
21
+ });
22
+ export const Checked = () => /*#__PURE__*/React.createElement(Field, {
18
23
  component: SwitchFieldFF,
19
24
  className: "switch",
20
25
  name: "switch",
21
26
  label: "Label text",
22
27
  initialValue: true,
23
28
  type: "checkbox"
24
- })).add('Unchecked with value', () => /*#__PURE__*/React.createElement(Field, {
29
+ });
30
+ export const UncheckedWithValue = () => /*#__PURE__*/React.createElement(Field, {
25
31
  component: SwitchFieldFF,
26
32
  className: "switch",
27
33
  name: "switch",
28
34
  label: "Label text",
29
35
  value: "yes",
30
36
  type: "checkbox"
31
- })).add('Checked with value', () => /*#__PURE__*/React.createElement(Field, {
37
+ });
38
+ export const CheckedWithValue = () => /*#__PURE__*/React.createElement(Field, {
32
39
  component: SwitchFieldFF,
33
40
  className: "switch",
34
41
  name: "switch",
@@ -36,4 +43,4 @@ storiesOf('Testing:SwitchFieldFF', module).addDecorator(formDecorator).add('Unch
36
43
  value: "yes",
37
44
  initialValue: initialValue,
38
45
  type: "checkbox"
39
- }));
46
+ });
@@ -1,5 +1,4 @@
1
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
-
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
2
  import { SwitchField } from '@dhis2-ui/switch';
4
3
  import PropTypes from 'prop-types';
5
4
  import React from 'react';
@@ -32,7 +31,6 @@ export const SwitchFieldFF = _ref => {
32
31
  SwitchFieldFF.propTypes = {
33
32
  /** `input` props received from Final Form `Field` */
34
33
  input: inputPropType.isRequired,
35
-
36
34
  /** `meta` props received from Final Form `Field` */
37
35
  meta: metaPropType.isRequired,
38
36
  error: PropTypes.bool,
@@ -4,7 +4,31 @@ import { formDecorator } from '../formDecorator.js';
4
4
  import { inputArgType, metaArgType } from '../shared/propTypes.js';
5
5
  import { hasValue } from '../validators/index.js';
6
6
  import { SwitchFieldFF } from './SwitchFieldFF.js';
7
- const description = "\nThe `SwitchFieldFF` is a wrapper around a `SwitchField` that enables it to work with Final Form, the preferred library for form validation and utilities in DHIS 2 apps.\n\n#### Final Form\n\nSee how to use Final Form at [Final Form - Getting Started](https://final-form.org/docs/react-final-form/getting-started).\n\nInside a Final Form `<Form>` component, these 'FF' UI components are intended to be used in the `component` prop of the [Final Form `<Field>` components](https://final-form.org/docs/react-final-form/api/Field) where they will receive some props from the Field, e.g. `<Field component={SwitchFieldFF} />`. See the code samples below for examples.\n\n#### Props\n\nThe props shown in the table below are generally provided to the `SwitchFieldFF` wrapper by the Final Form `Field`.\n\nNote that any props beyond the API of the `Field` component will be spread to the `SwitchFieldFF`, which passes any extra props to the underlying `SwitchField` using `{...rest}`.\n\nTherefore, to add any props to the `SwitchFieldFF` or `SwitchField`, add those props to the parent Final Form `Field` component.\n\nAlso see `Switch` and `SwitchField` for notes about props and implementation.\n\n```js\nimport { SwitchFieldFF } from '@dhis2/ui'\n```\n\nPress **Submit** to see the form values logged to the console.\n";
7
+ const description = `
8
+ The \`SwitchFieldFF\` is a wrapper around a \`SwitchField\` that enables it to work with Final Form, the preferred library for form validation and utilities in DHIS 2 apps.
9
+
10
+ #### Final Form
11
+
12
+ See how to use Final Form at [Final Form - Getting Started](https://final-form.org/docs/react-final-form/getting-started).
13
+
14
+ Inside a Final Form \`<Form>\` component, these 'FF' UI components are intended to be used in the \`component\` prop of the [Final Form \`<Field>\` components](https://final-form.org/docs/react-final-form/api/Field) where they will receive some props from the Field, e.g. \`<Field component={SwitchFieldFF} />\`. See the code samples below for examples.
15
+
16
+ #### Props
17
+
18
+ The props shown in the table below are generally provided to the \`SwitchFieldFF\` wrapper by the Final Form \`Field\`.
19
+
20
+ Note that any props beyond the API of the \`Field\` component will be spread to the \`SwitchFieldFF\`, which passes any extra props to the underlying \`SwitchField\` using \`{...rest}\`.
21
+
22
+ Therefore, to add any props to the \`SwitchFieldFF\` or \`SwitchField\`, add those props to the parent Final Form \`Field\` component.
23
+
24
+ Also see \`Switch\` and \`SwitchField\` for notes about props and implementation.
25
+
26
+ \`\`\`js
27
+ import { SwitchFieldFF } from '@dhis2/ui'
28
+ \`\`\`
29
+
30
+ Press **Submit** to see the form values logged to the console.
31
+ `;
8
32
  export default {
9
33
  title: 'Switch Field (Final Form)',
10
34
  component: SwitchFieldFF,
@@ -17,9 +41,11 @@ export default {
17
41
  }
18
42
  },
19
43
  argTypes: {
20
- input: { ...inputArgType
44
+ input: {
45
+ ...inputArgType
21
46
  },
22
- meta: { ...metaArgType
47
+ meta: {
48
+ ...metaArgType
23
49
  }
24
50
  }
25
51
  };
@@ -1,17 +1,21 @@
1
- import { storiesOf } from '@storybook/react';
2
1
  import React from 'react';
3
2
  import { Field } from 'react-final-form';
4
3
  import { formDecorator } from '../formDecorator.js';
5
4
  import { hasValue } from '../validators/index.js';
6
5
  import { TextAreaFieldFF } from './TextAreaFieldFF.js';
7
- storiesOf('TextArea', module).addDecorator(formDecorator).add('Default', () => /*#__PURE__*/React.createElement(Field, {
6
+ export default {
7
+ title: 'TextArea',
8
+ decorators: [formDecorator]
9
+ };
10
+ export const Default = () => /*#__PURE__*/React.createElement(Field, {
8
11
  component: TextAreaFieldFF,
9
12
  name: "comment",
10
13
  label: "Do you have any comments?"
11
- })).add('Required', () => /*#__PURE__*/React.createElement(Field, {
14
+ });
15
+ export const Required = () => /*#__PURE__*/React.createElement(Field, {
12
16
  required: true,
13
17
  name: "comment",
14
18
  component: TextAreaFieldFF,
15
19
  validate: hasValue,
16
20
  label: "Do you have any comments?"
17
- }));
21
+ });
@@ -1,5 +1,4 @@
1
- function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
2
-
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
2
  import { TextAreaField } from '@dhis2-ui/text-area';
4
3
  import PropTypes from 'prop-types';
5
4
  import React from 'react';
@@ -34,7 +33,6 @@ export const TextAreaFieldFF = _ref => {
34
33
  TextAreaFieldFF.propTypes = {
35
34
  /** `input` props received from Final Form `Field` */
36
35
  input: inputPropType.isRequired,
37
-
38
36
  /** `meta` props received from Final Form `Field` */
39
37
  meta: metaPropType.isRequired,
40
38
  error: PropTypes.bool,
@@ -4,7 +4,31 @@ import { formDecorator } from '../formDecorator.js';
4
4
  import { inputArgType, metaArgType } from '../shared/propTypes.js';
5
5
  import { hasValue } from '../validators/index.js';
6
6
  import { TextAreaFieldFF } from './TextAreaFieldFF.js';
7
- const description = "\nThe `TextAreaFieldFF` is a wrapper around a `TextAreaField` that enables it to work with Final Form, the preferred library for form validation and utilities in DHIS 2 apps.\n\n#### Final Form\n\nSee how to use Final Form at [Final Form - Getting Started](https://final-form.org/docs/react-final-form/getting-started).\n\nInside a Final Form `<Form>` component, these 'FF' UI components are intended to be used in the `component` prop of the [Final Form `<Field>` components](https://final-form.org/docs/react-final-form/api/Field) where they will receive some props from the Field, e.g. `<Field component={TextAreaFieldFF} />`. See the code samples below for examples.\n\n#### Props\n\nThe props shown in the table below are generally provided to the `TextAreaFieldFF` wrapper by the Final Form `Field`.\n\nNote that any props beyond the API of the `Field` component will be spread to the `TextAreaFieldFF`, which passes any extra props to the underlying `TextAreaField` using `{...rest}`.\n\nTherefore, to add any props to the `TextAreaFieldFF` or `TextAreaField`, add those props to the parent Final Form `Field` component.\n\nAlso see `TextArea` and `TextAreaField` for notes about props and implementation.\n\n```js\nimport { TextAreaFieldFF } from '@dhis2/ui'\n```\n\nPress **Submit** to see the form values logged to the console.\n";
7
+ const description = `
8
+ The \`TextAreaFieldFF\` is a wrapper around a \`TextAreaField\` that enables it to work with Final Form, the preferred library for form validation and utilities in DHIS 2 apps.
9
+
10
+ #### Final Form
11
+
12
+ See how to use Final Form at [Final Form - Getting Started](https://final-form.org/docs/react-final-form/getting-started).
13
+
14
+ Inside a Final Form \`<Form>\` component, these 'FF' UI components are intended to be used in the \`component\` prop of the [Final Form \`<Field>\` components](https://final-form.org/docs/react-final-form/api/Field) where they will receive some props from the Field, e.g. \`<Field component={TextAreaFieldFF} />\`. See the code samples below for examples.
15
+
16
+ #### Props
17
+
18
+ The props shown in the table below are generally provided to the \`TextAreaFieldFF\` wrapper by the Final Form \`Field\`.
19
+
20
+ Note that any props beyond the API of the \`Field\` component will be spread to the \`TextAreaFieldFF\`, which passes any extra props to the underlying \`TextAreaField\` using \`{...rest}\`.
21
+
22
+ Therefore, to add any props to the \`TextAreaFieldFF\` or \`TextAreaField\`, add those props to the parent Final Form \`Field\` component.
23
+
24
+ Also see \`TextArea\` and \`TextAreaField\` for notes about props and implementation.
25
+
26
+ \`\`\`js
27
+ import { TextAreaFieldFF } from '@dhis2/ui'
28
+ \`\`\`
29
+
30
+ Press **Submit** to see the form values logged to the console.
31
+ `;
8
32
  export default {
9
33
  title: 'Text Area Field (Final Form)',
10
34
  component: TextAreaFieldFF,
@@ -17,9 +41,11 @@ export default {
17
41
  }
18
42
  },
19
43
  argTypes: {
20
- input: { ...inputArgType
44
+ input: {
45
+ ...inputArgType
21
46
  },
22
- meta: { ...metaArgType
47
+ meta: {
48
+ ...metaArgType
23
49
  }
24
50
  }
25
51
  };
@@ -11,6 +11,7 @@ Array [
11
11
  "getIn",
12
12
  "setIn",
13
13
  "version",
14
+ "default",
14
15
  ]
15
16
  `;
16
17
 
@@ -22,6 +23,8 @@ exports[`final-form named export should re-export the expected type for configOp
22
23
 
23
24
  exports[`final-form named export should re-export the expected type for createForm 1`] = `"function"`;
24
25
 
26
+ exports[`final-form named export should re-export the expected type for default 1`] = `"object"`;
27
+
25
28
  exports[`final-form named export should re-export the expected type for fieldSubscriptionItems 1`] = `"object"`;
26
29
 
27
30
  exports[`final-form named export should re-export the expected type for formSubscriptionItems 1`] = `"object"`;
@@ -1,4 +1,5 @@
1
1
  /* eslint-disable import/namespace */
2
+
2
3
  import { FinalForm, ReactFinalForm } from '../index.js';
3
4
  describe('final-form named export', () => {
4
5
  it('should re-export the expected exports', () => {
@@ -1,5 +1,6 @@
1
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
-
1
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
2
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
3
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
3
4
  import { Button } from '@dhis2-ui/button';
4
5
  import PropTypes from 'prop-types';
5
6
  import React from 'react';
@@ -10,42 +11,36 @@ const formProps = {
10
11
  },
11
12
  mutators: {}
12
13
  };
13
-
14
14
  class FormWithSpyAndSubmit extends React.Component {
15
15
  constructor() {
16
16
  super(...arguments);
17
-
18
17
  _defineProperty(this, "state", {
19
18
  cypressProps: {}
20
19
  });
21
-
22
20
  _defineProperty(this, "updateCypressProps", updateObj => {
23
- const cypressProps = { ...this.state.cypressProps,
21
+ const cypressProps = {
22
+ ...this.state.cypressProps,
24
23
  ...updateObj
25
24
  };
26
25
  this.setState({
27
26
  cypressProps
28
27
  });
29
28
  });
30
-
31
29
  _defineProperty(this, "clearCypressProps", () => {
32
30
  this.setState({
33
31
  cypressProps: {}
34
32
  });
35
33
  });
36
34
  }
37
-
38
35
  componentDidMount() {
39
36
  window.updateCypressProps = this.updateCypressProps;
40
37
  window.clearCypressProps = this.clearCypressProps;
41
38
  this.forceUpdate();
42
39
  }
43
-
44
40
  componentWillUnmount() {
45
41
  delete window.updateCypressProps;
46
42
  delete window.clearCypressProps;
47
43
  }
48
-
49
44
  render() {
50
45
  return /*#__PURE__*/React.createElement(Form, formProps, formRenderProps => /*#__PURE__*/React.createElement("form", {
51
46
  onSubmit: formRenderProps.handleSubmit
@@ -65,9 +60,7 @@ class FormWithSpyAndSubmit extends React.Component {
65
60
  });
66
61
  })));
67
62
  }
68
-
69
63
  }
70
-
71
64
  FormWithSpyAndSubmit.propTypes = {
72
65
  renderChildren: PropTypes.func.isRequired
73
66
  };
package/build/es/index.js CHANGED
@@ -11,16 +11,16 @@ export { TextAreaFieldFF } from './TextAreaFieldFF/TextAreaFieldFF.js';
11
11
  export { FieldGroupFF } from './FieldGroupFF/FieldGroupFF.js';
12
12
  export * from './transformers/index.js';
13
13
  export * from './validators/index.js';
14
+
14
15
  /**
15
16
  * Allows direct access to the FinalForm library. Please note that this is considered advanced
16
17
  * usage and that you need to stay up to date with breaking changes in the FinalForm library.
17
18
  */
18
-
19
19
  export { FinalForm };
20
+
20
21
  /**
21
22
  * Allows direct access to the ReactFinalForm library. Please note that this is considered
22
23
  * advanced usage and that you need to stay up to date with breaking changes in the FinalForm
23
24
  * library.
24
25
  */
25
-
26
26
  export { ReactFinalForm };
@@ -1,9 +1,7 @@
1
1
  const createBlurHandler = (input, onBlur) => (payload, event) => {
2
2
  input.onBlur(event);
3
-
4
3
  if (onBlur && typeof onBlur === 'function') {
5
4
  onBlur(payload, event);
6
5
  }
7
6
  };
8
-
9
7
  export { createBlurHandler };
@@ -1,5 +1,4 @@
1
1
  const PRIMITIVE_TYPES = new Set(['string', 'number', 'boolean']);
2
-
3
2
  const createChangeHandler = _ref => {
4
3
  let {
5
4
  onChange
@@ -20,5 +19,4 @@ const createChangeHandler = _ref => {
20
19
  }
21
20
  };
22
21
  };
23
-
24
22
  export { createChangeHandler };
@@ -1,9 +1,7 @@
1
1
  const createFocusHandler = (input, onFocus) => (payload, event) => {
2
2
  input.onFocus(event);
3
-
4
3
  if (onFocus && typeof onFocus === 'function') {
5
4
  onFocus(payload, event);
6
5
  }
7
6
  };
8
-
9
7
  export { createFocusHandler };
@@ -9,5 +9,4 @@ const createSelectChangeHandler = _ref => {
9
9
  onChange(selected);
10
10
  };
11
11
  };
12
-
13
12
  export { createSelectChangeHandler };
@@ -1,9 +1,7 @@
1
1
  const createToggleChangeHandler = (input, onChange) => (payload, event) => {
2
2
  input.onChange(event);
3
-
4
3
  if (onChange && typeof onChange === 'function') {
5
4
  onChange(payload, event);
6
5
  }
7
6
  };
8
-
9
7
  export { createToggleChangeHandler };
@@ -1,21 +1,16 @@
1
1
  import { hasError } from './hasError.js';
2
-
3
2
  const getValidationText = (meta, validationText, error) => {
4
3
  if (validationText) {
5
4
  return validationText;
6
5
  }
7
-
8
6
  if (hasError(meta, error)) {
9
7
  if (meta.error) {
10
8
  return meta.error;
11
9
  }
12
-
13
10
  if (meta.submitError) {
14
11
  return meta.submitError;
15
12
  }
16
13
  }
17
-
18
14
  return '';
19
15
  };
20
-
21
16
  export { getValidationText };
@@ -1,3 +1,2 @@
1
1
  const hasError = (meta, error) => error || meta.touched && meta.invalid;
2
-
3
2
  export { hasError };
@@ -1,3 +1,2 @@
1
1
  const isLoading = (meta, loading, showLoadingStatus) => loading || showLoadingStatus && meta.validating;
2
-
3
2
  export { isLoading };
@@ -1,3 +1,2 @@
1
1
  const isValid = (meta, valid, showValidStatus) => valid || showValidStatus && meta.touched && meta.valid;
2
-
3
2
  export { isValid };
@@ -4,11 +4,9 @@ const format = value => !value ? [] : value.map(_ref => {
4
4
  } = _ref;
5
5
  return id;
6
6
  });
7
-
8
7
  const parse = value => !value || Array.isArray(value) && value.length === 0 ? undefined : value.map(id => ({
9
8
  id
10
9
  }));
11
-
12
10
  export const arrayWithIdObjects = {
13
11
  format,
14
12
  parse
@@ -23,7 +23,8 @@ describe('validator: createCharacterLengthRange', () => {
23
23
  });
24
24
  allowsEmptyValues(betweenSixAndTenChars);
25
25
  describe('allows within-range strings', () => {
26
- testValidatorValues(betweenSixAndTenChars, undefined, ['abcdef', // 6
26
+ testValidatorValues(betweenSixAndTenChars, undefined, ['abcdef',
27
+ // 6
27
28
  'abcdefgh', 'abcdefghij' // 10
28
29
  ]);
29
30
  });
@@ -31,8 +32,10 @@ describe('validator: createCharacterLengthRange', () => {
31
32
  testValidatorValues(betweenSixAndTenChars, inValidMsg, [true, 3, {}, [], () => {}]);
32
33
  });
33
34
  describe('rejects out-of-range strings', () => {
34
- testValidatorValues(betweenSixAndTenChars, inValidMsg, ['a', 'abcde', // 5
35
- 'abcdefghijk', // 11
35
+ testValidatorValues(betweenSixAndTenChars, inValidMsg, ['a', 'abcde',
36
+ // 5
37
+ 'abcdefghijk',
38
+ // 11
36
39
  'abcdefghijklmnopqrstuvw']);
37
40
  });
38
41
  });
@@ -3,6 +3,7 @@ import { testValidatorValues } from '../test-helpers/index.js';
3
3
  describe('validator: createMaxCharacterLength', () => {
4
4
  const maxSixChars = createMaxCharacterLength(6);
5
5
  const errorMessage = 'Please enter a maximum of 6 characters';
6
+
6
7
  /*
7
8
  * Since createMaxCharacterLength calls createNumberRange internally
8
9
  * a lot of things have been tested there and here we focus
@@ -3,6 +3,7 @@ import { testValidatorValues } from '../test-helpers/index.js';
3
3
  describe('validator: createMaxNumber', () => {
4
4
  const maxSix = createMaxNumber(6);
5
5
  const errorMessage = 'Please enter a number with a maximum of 6';
6
+
6
7
  /*
7
8
  * Since createMaxNumber calls createNumberRange internally
8
9
  * a lot of things have been tested there and here we focus
@@ -3,6 +3,7 @@ import { testValidatorValues } from '../test-helpers/index.js';
3
3
  describe('validator: createMinCharacterLength', () => {
4
4
  const atLeastSixChars = createMinCharacterLength(6);
5
5
  const errorMessage = 'Please enter at least 6 characters';
6
+
6
7
  /*
7
8
  * Since createMinCharacterLength calls createCharacterLengthRange internally
8
9
  * a lot of things have been tested there and here we focus
@@ -3,6 +3,7 @@ import { testValidatorValues } from '../test-helpers/index.js';
3
3
  describe('validator: createMinNumber', () => {
4
4
  const atLeastSix = createMinNumber(6);
5
5
  const errorMessage = 'Please enter a number of at least 6';
6
+
6
7
  /*
7
8
  * Since createMinNumber calls createNumberRange internally
8
9
  * a lot of things have been tested there and here we focus
@@ -20,7 +20,7 @@ describe('validator: createPattern', () => {
20
20
  });
21
21
  it('should return an error string when input does not match the pattern', () => {
22
22
  const escapedRegexString = '&#x2F;^test$&#x2F;';
23
- const invalidMsg = "Please make sure the value of this input matches the pattern ".concat(escapedRegexString, ".");
23
+ const invalidMsg = `Please make sure the value of this input matches the pattern ${escapedRegexString}.`;
24
24
  expect(equalToTestPattern('bad input')).toEqual(invalidMsg);
25
25
  });
26
26
  it('should return an custon error string when one was provided and input does not match the pattern', () => {
@@ -1,5 +1,6 @@
1
1
  import { email, invalidEmailMessage } from '../email.js';
2
2
  import { testValidatorValues, allowsEmptyValues } from '../test-helpers/index.js';
3
+
3
4
  /*
4
5
  * A comprehensive list technically valid and invalid email addresses was
5
6
  * taken from:
@@ -19,8 +20,10 @@ describe('validator: email', () => {
19
20
  /*
20
21
  * Items that have been commented out below are FALSELY REJECTED by the chosen regex
21
22
  */
22
- testValidatorValues(email, undefined, ['email@example.com', 'firstname.lastname@example.com', 'email@subdomain.example.com', 'firstname+lastname@example.com', // 'email@123.123.123.123',
23
+ testValidatorValues(email, undefined, ['email@example.com', 'firstname.lastname@example.com', 'email@subdomain.example.com', 'firstname+lastname@example.com',
24
+ // 'email@123.123.123.123',
23
25
  'email@[123.123.123.123]', '"email"@example.com', '1234567890@example.com', 'email@example-one.com', '_______@example.com', 'email@example.name', 'email@example.museum', 'email@example.co.jp', 'firstname-lastname@example.com'
26
+
24
27
  /* very strange but technically valid addresses */
25
28
  // 'much."more unusual"@example.com',
26
29
  // 'very.unusual."@".unusual.com@example.com',
@@ -37,10 +40,10 @@ describe('validator: email', () => {
37
40
  * see https://en.wikipedia.org/wiki/International_email)
38
41
  */
39
42
  // 'あいうえお@example.com'
40
- 'email@example.com (Joe Smith)', 'email@example', // 'email@-example.com',
43
+ 'email@example.com (Joe Smith)', 'email@example',
44
+ // 'email@-example.com',
41
45
  // 'email@example.web',
42
- 'email@111.222.333.44444', 'email@example..com', 'Abc..123@example.com',
43
- /* very strange invalid addresses */
46
+ 'email@111.222.333.44444', 'email@example..com', 'Abc..123@example.com', /* very strange invalid addresses */
44
47
  '"(),:;<>[]@example.com', 'just"not"right@example.com', 'this is"really"not\\\\allowed@example.com']);
45
48
  });
46
49
  });
@@ -9,9 +9,12 @@ describe('validator: internationalPhoneNumber', () => {
9
9
  testValidatorValues(internationalPhoneNumber, invalidInternationalPhoneNumberMessage, [true, 3, {}, [], () => {}]);
10
10
  });
11
11
  describe('rejects invalid phone numbers', () => {
12
- testValidatorValues(internationalPhoneNumber, invalidInternationalPhoneNumberMessage, ['sometext123', // text
13
- '+3172%^$#%*182838485868', // special characters
14
- '+31725111889101112131415', // too long
12
+ testValidatorValues(internationalPhoneNumber, invalidInternationalPhoneNumberMessage, ['sometext123',
13
+ // text
14
+ '+3172%^$#%*182838485868',
15
+ // special characters
16
+ '+31725111889101112131415',
17
+ // too long
15
18
  '0031_72_5111889' // bad separators
16
19
  ]);
17
20
  });
@@ -1,5 +1,6 @@
1
1
  import { testValidatorValues, allowsEmptyValues } from '../test-helpers/index.js';
2
2
  import { url, invalidUrlMessage } from '../url.js';
3
+
3
4
  /**
4
5
  * List of valid and invalid URIs was sourced from
5
6
  * https://formvalidation.io/guide/validators/uri
@@ -2,7 +2,5 @@ import i18n from '../locales/index.js';
2
2
  import { isEmpty, isString } from './helpers/index.js';
3
3
  const ALPHA_NUMERIC_PATTERN = /^[a-z0-9 ]*$/i;
4
4
  const invalidAlphaNumericMessage = i18n.t('Please provide an alpha-numeric value');
5
-
6
5
  const alphaNumeric = value => isEmpty(value) || isString(value) && ALPHA_NUMERIC_PATTERN.test(value) ? undefined : invalidAlphaNumericMessage;
7
-
8
6
  export { alphaNumeric, invalidAlphaNumericMessage };
@@ -1,7 +1,5 @@
1
1
  import i18n from '../locales/index.js';
2
2
  import { isEmpty } from './helpers/index.js';
3
3
  const invalidBooleanMessage = i18n.t('Please provide a boolean value');
4
-
5
4
  const boolean = value => isEmpty(value) || typeof value === 'boolean' ? undefined : invalidBooleanMessage;
6
-
7
5
  export { boolean, invalidBooleanMessage };
@@ -2,12 +2,10 @@ export const composeValidators = function () {
2
2
  for (var _len = arguments.length, validators = new Array(_len), _key = 0; _key < _len; _key++) {
3
3
  validators[_key] = arguments[_key];
4
4
  }
5
-
6
5
  return function () {
7
6
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
8
7
  args[_key2] = arguments[_key2];
9
8
  }
10
-
11
9
  return validators.reduce((error, validator) => error || validator(...args), undefined);
12
10
  };
13
11
  };
@@ -1,6 +1,5 @@
1
1
  import i18n from '../locales/index.js';
2
2
  import { isEmpty, isString, isInRange, requireArgument } from './helpers/index.js';
3
-
4
3
  const createCharacterLengthRange = (lowerBound, upperBound, customMessage) => {
5
4
  requireArgument(lowerBound, 'number');
6
5
  requireArgument(upperBound, 'number');
@@ -10,5 +9,4 @@ const createCharacterLengthRange = (lowerBound, upperBound, customMessage) => {
10
9
  });
11
10
  return value => isEmpty(value) || isString(value) && isInRange(lowerBound, upperBound, value.length) ? undefined : errorMessage;
12
11
  };
13
-
14
12
  export { createCharacterLengthRange };
@@ -1,6 +1,5 @@
1
1
  import i18n from '../locales/index.js';
2
2
  import { isEmpty, requireArgument } from './helpers/index.js';
3
-
4
3
  const createEqualTo = (key, description) => {
5
4
  requireArgument(key, 'string');
6
5
  const errorMessage = i18n.t('Please make sure the value of this input matches the value in "{{otherField}}".', {
@@ -8,5 +7,4 @@ const createEqualTo = (key, description) => {
8
7
  });
9
8
  return (value, allValues) => isEmpty(value) || value === allValues[key] ? undefined : errorMessage;
10
9
  };
11
-
12
10
  export { createEqualTo };
@@ -1,8 +1,6 @@
1
1
  import i18n from '../locales/index.js';
2
2
  import { createCharacterLengthRange } from './createCharacterLengthRange.js';
3
-
4
3
  const createMaxCharacterLength = upperBound => createCharacterLengthRange(0, upperBound, i18n.t('Please enter a maximum of {{upperBound}} characters', {
5
4
  upperBound
6
5
  }));
7
-
8
6
  export { createMaxCharacterLength };
@@ -1,8 +1,6 @@
1
1
  import i18n from '../locales/index.js';
2
2
  import { createNumberRange } from './createNumberRange.js';
3
-
4
3
  const createMaxNumber = upperBound => createNumberRange(-Infinity, upperBound, i18n.t('Please enter a number with a maximum of {{upperBound}}', {
5
4
  upperBound
6
5
  }));
7
-
8
6
  export { createMaxNumber };