@oneblink/apps-react 4.0.0-beta.5 → 4.0.0-beta.6

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 (107) hide show
  1. package/README.md +2 -8
  2. package/dist/OneBlinkAutoSaveForm.d.ts +24 -5
  3. package/dist/OneBlinkAutoSaveForm.js +11 -0
  4. package/dist/OneBlinkAutoSaveForm.js.map +1 -1
  5. package/dist/OneBlinkForm.d.ts +556 -8
  6. package/dist/OneBlinkForm.js +544 -0
  7. package/dist/OneBlinkForm.js.map +1 -1
  8. package/dist/OneBlinkFormBase.d.ts +51 -6
  9. package/dist/OneBlinkFormBase.js.map +1 -1
  10. package/dist/OneBlinkReadOnlyForm.d.ts +82 -6
  11. package/dist/OneBlinkReadOnlyForm.js +78 -0
  12. package/dist/OneBlinkReadOnlyForm.js.map +1 -1
  13. package/dist/PaymentReceipt.d.ts +55 -0
  14. package/dist/PaymentReceipt.js +45 -0
  15. package/dist/PaymentReceipt.js.map +1 -1
  16. package/dist/components/formStore/FormStoreTableProvider.js +23 -1
  17. package/dist/components/formStore/FormStoreTableProvider.js.map +1 -1
  18. package/dist/components/renderer/LookupNotification.js +11 -2
  19. package/dist/components/renderer/LookupNotification.js.map +1 -1
  20. package/dist/components/renderer/OneBlinkFormElements.d.ts +3 -3
  21. package/dist/components/renderer/OneBlinkFormElements.js.map +1 -1
  22. package/dist/components/renderer/PageFormElements.d.ts +3 -3
  23. package/dist/components/renderer/PageFormElements.js.map +1 -1
  24. package/dist/components/renderer/ProgressBar.d.ts +2 -3
  25. package/dist/components/renderer/ProgressBar.js.map +1 -1
  26. package/dist/form-elements/FormElementCalculation.js.map +1 -1
  27. package/dist/form-elements/FormElementForm.d.ts +4 -4
  28. package/dist/form-elements/FormElementForm.js.map +1 -1
  29. package/dist/form-elements/FormElementRepeatableSet.d.ts +4 -4
  30. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  31. package/dist/form-elements/FormElementSummary.js.map +1 -1
  32. package/dist/hooks/useAuth.d.ts +79 -6
  33. package/dist/hooks/useAuth.js +52 -0
  34. package/dist/hooks/useAuth.js.map +1 -1
  35. package/dist/hooks/useBooleanState.d.ts +41 -5
  36. package/dist/hooks/useBooleanState.js +35 -0
  37. package/dist/hooks/useBooleanState.js.map +1 -1
  38. package/dist/hooks/useClickOutsideElement.d.ts +39 -0
  39. package/dist/hooks/useClickOutsideElement.js +39 -0
  40. package/dist/hooks/useClickOutsideElement.js.map +1 -1
  41. package/dist/hooks/useConditionalLogic.d.ts +2 -3
  42. package/dist/hooks/useConditionalLogic.js.map +1 -1
  43. package/dist/hooks/useDrafts.d.ts +61 -1
  44. package/dist/hooks/useDrafts.js +56 -11
  45. package/dist/hooks/useDrafts.js.map +1 -1
  46. package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +17 -5
  47. package/dist/hooks/useFormSubmissionAutoSaveState.js +9 -0
  48. package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
  49. package/dist/hooks/useFormSubmissionModelContext.d.ts +4 -4
  50. package/dist/hooks/useFormSubmissionModelContext.js.map +1 -1
  51. package/dist/hooks/useFormSubmissionState.d.ts +44 -5
  52. package/dist/hooks/useFormSubmissionState.js +36 -0
  53. package/dist/hooks/useFormSubmissionState.js.map +1 -1
  54. package/dist/hooks/useFormValidation.d.ts +3 -3
  55. package/dist/hooks/useFormValidation.js.map +1 -1
  56. package/dist/hooks/useInjectPages.d.ts +2 -3
  57. package/dist/hooks/useInjectPages.js.map +1 -1
  58. package/dist/hooks/useIsMounted.d.ts +19 -0
  59. package/dist/hooks/useIsMounted.js +18 -0
  60. package/dist/hooks/useIsMounted.js.map +1 -1
  61. package/dist/hooks/useIsOffline.d.ts +49 -0
  62. package/dist/hooks/useIsOffline.js +49 -0
  63. package/dist/hooks/useIsOffline.js.map +1 -1
  64. package/dist/hooks/useLoadDataState.d.ts +44 -3
  65. package/dist/hooks/useLoadDataState.js +39 -0
  66. package/dist/hooks/useLoadDataState.js.map +1 -1
  67. package/dist/hooks/useLogin.d.ts +396 -11
  68. package/dist/hooks/useLogin.js +299 -0
  69. package/dist/hooks/useLogin.js.map +1 -1
  70. package/dist/hooks/useLookups.d.ts +3 -3
  71. package/dist/hooks/useLookups.js.map +1 -1
  72. package/dist/hooks/useNullableState.d.ts +44 -1
  73. package/dist/hooks/useNullableState.js +40 -1
  74. package/dist/hooks/useNullableState.js.map +1 -1
  75. package/dist/hooks/usePendingSubmissions.d.ts +95 -0
  76. package/dist/hooks/usePendingSubmissions.js +192 -0
  77. package/dist/hooks/usePendingSubmissions.js.map +1 -0
  78. package/dist/index.d.ts +5 -3
  79. package/dist/index.js +4 -2
  80. package/dist/index.js.map +1 -1
  81. package/dist/services/checkBsbsAreInvalid.d.ts +2 -3
  82. package/dist/services/checkBsbsAreInvalid.js.map +1 -1
  83. package/dist/services/checkIfAttachmentsExist.d.ts +2 -3
  84. package/dist/services/checkIfAttachmentsExist.js.map +1 -1
  85. package/dist/services/checkIfBsbsAreValidating.d.ts +2 -3
  86. package/dist/services/checkIfBsbsAreValidating.js.map +1 -1
  87. package/dist/services/cleanFormSubmissionModel.d.ts +4 -4
  88. package/dist/services/cleanFormSubmissionModel.js +2 -1
  89. package/dist/services/cleanFormSubmissionModel.js.map +1 -1
  90. package/dist/services/form-validation.d.ts +3 -3
  91. package/dist/services/form-validation.js.map +1 -1
  92. package/dist/services/generate-default-data.d.ts +2 -3
  93. package/dist/services/generate-default-data.js +3 -1
  94. package/dist/services/generate-default-data.js.map +1 -1
  95. package/dist/services/generateFreshdeskDependentFieldElements.js.map +1 -1
  96. package/dist/services/getDateRangeConfiguration.d.ts +2 -3
  97. package/dist/services/getDateRangeConfiguration.js.map +1 -1
  98. package/dist/services/getRepeatableSetEntriesConfiguration.d.ts +2 -3
  99. package/dist/services/getRepeatableSetEntriesConfiguration.js.map +1 -1
  100. package/dist/styles/receipt.scss +1 -1
  101. package/dist/styles/repeatable-set.scss +2 -2
  102. package/dist/typedoc.d.ts +2 -0
  103. package/dist/typedoc.js +3 -0
  104. package/dist/typedoc.js.map +1 -0
  105. package/dist/types/form.d.ts +5 -6
  106. package/dist/types/form.js.map +1 -1
  107. package/package.json +9 -3
@@ -1,6 +1,42 @@
1
1
  import * as React from 'react';
2
2
  import _cloneDeep from 'lodash.clonedeep';
3
3
  import generateDefaultData from '../services/generate-default-data';
4
+ /**
5
+ * This function is a simple wrapper around the react hook `useState()`. The
6
+ * results can be passed to the [`<OneBlinkForm
7
+ * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link
8
+ * component.
9
+ *
10
+ * ## Example
11
+ *
12
+ * ```js
13
+ * import {
14
+ * useFormSubmissionState,
15
+ * OneBlinkFormControlled,
16
+ * } from '@oneblink/apps-react'
17
+ *
18
+ * function Uncontrolled({ form, initialSubmission, ...props }) {
19
+ * const [{ definition, submission }, setFormSubmission] =
20
+ * useFormSubmissionState(form, initialSubmission)
21
+ *
22
+ * return (
23
+ * <OneBlinkFormControlled
24
+ * {...props}
25
+ * definition={definition}
26
+ * submission={submission}
27
+ * setFormSubmission={setFormSubmission}
28
+ * lastElementUpdated={lastElementUpdated}
29
+ * />
30
+ * )
31
+ * }
32
+ * ```
33
+ *
34
+ * @param form The OneBlink Form to render
35
+ * @param initialSubmission The initial submission data to populate the form
36
+ * with
37
+ * @param lastElementUpdated
38
+ * @returns
39
+ */
4
40
  export default function useFormSubmissionState(form, initialSubmission, lastElementUpdated) {
5
41
  return React.useState(() => {
6
42
  const definition = _cloneDeep(form);
@@ -1 +1 @@
1
- {"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AAGnE,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,IAAoB,EACpB,iBAAuC,EACvC,kBAA0C;IAE1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,WAAW,GAAG,mBAAmB,CACrC,UAAU,CAAC,QAAQ,EACnB,iBAAiB,IAAI,EAAE,CACxB,CAAA;QACD,OAAO;YACL,UAAU;YACV,UAAU,EAAE,WAAW;YACvB,kBAAkB;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { FormTypes } from '@oneblink/types'\nimport generateDefaultData from '../services/generate-default-data'\nimport { FormSubmissionModel } from '../types/form'\n\nexport default function useFormSubmissionState(\n form: FormTypes.Form,\n initialSubmission?: FormSubmissionModel,\n lastElementUpdated?: FormTypes.FormElement,\n) {\n return React.useState(() => {\n const definition = _cloneDeep(form)\n const defaultData = generateDefaultData(\n definition.elements,\n initialSubmission || {},\n )\n return {\n definition,\n submission: defaultData,\n lastElementUpdated,\n }\n })\n}\n"]}
1
+ {"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,IAAoB,EACpB,iBAAkE,EAClE,kBAA0C;IAE1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,WAAW,GAAG,mBAAmB,CACrC,UAAU,CAAC,QAAQ,EACnB,iBAAiB,IAAI,EAAE,CACxB,CAAA;QACD,OAAO;YACL,UAAU;YACV,UAAU,EAAE,WAAW;YACvB,kBAAkB;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport generateDefaultData from '../services/generate-default-data'\n/**\n * This function is a simple wrapper around the react hook `useState()`. The\n * results can be passed to the [`<OneBlinkForm\n * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link\n * component.\n *\n * ## Example\n *\n * ```js\n * import {\n * useFormSubmissionState,\n * OneBlinkFormControlled,\n * } from '@oneblink/apps-react'\n *\n * function Uncontrolled({ form, initialSubmission, ...props }) {\n * const [{ definition, submission }, setFormSubmission] =\n * useFormSubmissionState(form, initialSubmission)\n *\n * return (\n * <OneBlinkFormControlled\n * {...props}\n * definition={definition}\n * submission={submission}\n * setFormSubmission={setFormSubmission}\n * lastElementUpdated={lastElementUpdated}\n * />\n * )\n * }\n * ```\n *\n * @param form The OneBlink Form to render\n * @param initialSubmission The initial submission data to populate the form\n * with\n * @param lastElementUpdated\n * @returns\n */\nexport default function useFormSubmissionState(\n form: FormTypes.Form,\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormTypes.FormElement,\n) {\n return React.useState(() => {\n const definition = _cloneDeep(form)\n const defaultData = generateDefaultData(\n definition.elements,\n initialSubmission || {},\n )\n return {\n definition,\n submission: defaultData,\n lastElementUpdated,\n }\n })\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { FormTypes } from '@oneblink/types';
2
- import { FormElementsConditionallyShown, FormSubmissionModel } from '../types/form';
1
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
+ import { FormElementsConditionallyShown } from '../types/form';
3
3
  export default function useFormValidation(pages: FormTypes.PageElement[]): {
4
4
  executedLookup: (element: FormTypes.LookupFormElement) => void;
5
5
  executeLookupFailed: (element: FormTypes.LookupFormElement) => void;
6
- validate: (submission: FormSubmissionModel, formElementsConditionallyShown: FormElementsConditionallyShown) => import("../types/form").FormElementsValidation | undefined;
6
+ validate: (submission: SubmissionTypes.S3SubmissionData['submission'], formElementsConditionallyShown: FormElementsConditionallyShown) => import("../types/form").FormElementsValidation | undefined;
7
7
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useFormValidation.js","sourceRoot":"","sources":["../../src/hooks/useFormValidation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,6BAA6B,CAAA;AAMpC,SAAS,4BAA4B,CACnC,YAAqC;IAErC,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC;gBACd,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,CAAC;iBACtD,CAAA;aACF;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC;gBACpB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,CAC3B;qBACF;iBACF,CAAA;aACF;YACD,OAAO,CAAC,CAAC;gBACP,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;aAC9B;SACF;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,CAAC,6BAA6B,EAAE,gCAAgC,CAAC,GACrE,KAAK,CAAC,QAAQ,CAAW,EAAE,CAAC,CAAA;IAE9B,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAA8C,EAAE,EAAE;YACjD,IAAI,oCAAoC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBAC7D,OAAO,oCAAoC,CAAA;aAC5C;YACD,OAAO,CAAC,GAAG,oCAAoC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;QAC9D,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IACD,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAAoC,EAAE,EAAE;YACvC,OAAO,oCAAoC,CAAC,MAAM,CAChD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CACxC,CAAA;QACH,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IAED,MAAM,uBAAuB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjD,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1C,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,6BAA6B,CAC9B,CAAA;IACH,CAAC,EAAE,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAC,CAAA;IAE5D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA+B,EAC/B,8BAA8D,EAC9D,EAAE;QACF,OAAO,kBAAkB,CACvB,gBAAgB,EAChB,UAAU,EACV,8BAA8B,CAC/B,CAAA;IACH,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAA;IAED,OAAO;QACL,cAAc;QACd,mBAAmB;QACnB,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport {\n validateSubmission,\n generateValidationSchema,\n} from '../services/form-validation'\nimport {\n FormElementsConditionallyShown,\n FormSubmissionModel,\n} from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements),\n ]\n }\n case 'infoPage':\n case 'form':\n case 'repeatableSet': {\n return [\n ...memo,\n {\n ...formElement,\n elements: stripFormElementsWithoutName(\n formElement.elements || [],\n ),\n },\n ]\n }\n default: {\n return [...memo, formElement]\n }\n }\n },\n [],\n )\n}\n\nexport default function useFormValidation(pages: FormTypes.PageElement[]) {\n const [elementIdsWithLookupsExecuted, setElementIdsWithLookupsExecuted] =\n React.useState<string[]>([])\n\n const executedLookup = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted: string[]) => {\n if (currentElementIdsWithLookupsExecuted.includes(element.id)) {\n return currentElementIdsWithLookupsExecuted\n }\n return [...currentElementIdsWithLookupsExecuted, element.id]\n },\n )\n },\n [],\n )\n const executeLookupFailed = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted) => {\n return currentElementIdsWithLookupsExecuted.filter(\n (elementId) => elementId !== element.id,\n )\n },\n )\n },\n [],\n )\n\n const formElementsWithoutName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages)\n }, [pages])\n\n const validationSchema = React.useMemo(() => {\n return generateValidationSchema(\n formElementsWithoutName,\n elementIdsWithLookupsExecuted,\n )\n }, [formElementsWithoutName, elementIdsWithLookupsExecuted])\n\n const handleValidate = React.useCallback(\n (\n submission: FormSubmissionModel,\n formElementsConditionallyShown: FormElementsConditionallyShown,\n ) => {\n return validateSubmission(\n validationSchema,\n submission,\n formElementsConditionallyShown,\n )\n },\n [validationSchema],\n )\n\n return {\n executedLookup,\n executeLookupFailed,\n validate: handleValidate,\n }\n}\n"]}
1
+ {"version":3,"file":"useFormValidation.js","sourceRoot":"","sources":["../../src/hooks/useFormValidation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,6BAA6B,CAAA;AAGpC,SAAS,4BAA4B,CACnC,YAAqC;IAErC,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC;gBACd,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,CAAC;iBACtD,CAAA;aACF;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC;gBACpB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,CAC3B;qBACF;iBACF,CAAA;aACF;YACD,OAAO,CAAC,CAAC;gBACP,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;aAC9B;SACF;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,CAAC,6BAA6B,EAAE,gCAAgC,CAAC,GACrE,KAAK,CAAC,QAAQ,CAAW,EAAE,CAAC,CAAA;IAE9B,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAA8C,EAAE,EAAE;YACjD,IAAI,oCAAoC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBAC7D,OAAO,oCAAoC,CAAA;aAC5C;YACD,OAAO,CAAC,GAAG,oCAAoC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;QAC9D,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IACD,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAAoC,EAAE,EAAE;YACvC,OAAO,oCAAoC,CAAC,MAAM,CAChD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CACxC,CAAA;QACH,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IAED,MAAM,uBAAuB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjD,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1C,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,6BAA6B,CAC9B,CAAA;IACH,CAAC,EAAE,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAC,CAAA;IAE5D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA0D,EAC1D,8BAA8D,EAC9D,EAAE;QACF,OAAO,kBAAkB,CACvB,gBAAgB,EAChB,UAAU,EACV,8BAA8B,CAC/B,CAAA;IACH,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAA;IAED,OAAO;QACL,cAAc;QACd,mBAAmB;QACnB,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport {\n validateSubmission,\n generateValidationSchema,\n} from '../services/form-validation'\nimport { FormElementsConditionallyShown } from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements),\n ]\n }\n case 'infoPage':\n case 'form':\n case 'repeatableSet': {\n return [\n ...memo,\n {\n ...formElement,\n elements: stripFormElementsWithoutName(\n formElement.elements || [],\n ),\n },\n ]\n }\n default: {\n return [...memo, formElement]\n }\n }\n },\n [],\n )\n}\n\nexport default function useFormValidation(pages: FormTypes.PageElement[]) {\n const [elementIdsWithLookupsExecuted, setElementIdsWithLookupsExecuted] =\n React.useState<string[]>([])\n\n const executedLookup = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted: string[]) => {\n if (currentElementIdsWithLookupsExecuted.includes(element.id)) {\n return currentElementIdsWithLookupsExecuted\n }\n return [...currentElementIdsWithLookupsExecuted, element.id]\n },\n )\n },\n [],\n )\n const executeLookupFailed = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted) => {\n return currentElementIdsWithLookupsExecuted.filter(\n (elementId) => elementId !== element.id,\n )\n },\n )\n },\n [],\n )\n\n const formElementsWithoutName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages)\n }, [pages])\n\n const validationSchema = React.useMemo(() => {\n return generateValidationSchema(\n formElementsWithoutName,\n elementIdsWithLookupsExecuted,\n )\n }, [formElementsWithoutName, elementIdsWithLookupsExecuted])\n\n const handleValidate = React.useCallback(\n (\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown: FormElementsConditionallyShown,\n ) => {\n return validateSubmission(\n validationSchema,\n submission,\n formElementsConditionallyShown,\n )\n },\n [validationSchema],\n )\n\n return {\n executedLookup,\n executeLookupFailed,\n validate: handleValidate,\n }\n}\n"]}
@@ -1,7 +1,6 @@
1
- import { FormTypes } from '@oneblink/types';
1
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import * as React from 'react';
3
- import { FormSubmissionModel } from '../types/form';
4
- type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data?: FormSubmissionModel) => void;
3
+ type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data?: SubmissionTypes.S3SubmissionData['submission']) => void;
5
4
  export declare const InjectPagesContext: React.Context<InjectPagesContextValue>;
6
5
  export default function useInjectPages(): InjectPagesContextValue;
7
6
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useInjectPages.js","sourceRoot":"","sources":["../../src/hooks/useInjectPages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAS9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CACnD,GAAG,EAAE,GAAE,CAAC,CACT,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,OAAO,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AAC7C,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport { FormSubmissionModel } from '../types/form'\n\ntype InjectPagesContextValue = (\n lookupFormElement: FormTypes.LookupFormElement,\n pageElements: FormTypes.PageElement[],\n data?: FormSubmissionModel,\n) => void\n\nexport const InjectPagesContext = React.createContext<InjectPagesContextValue>(\n () => {},\n)\n\nexport default function useInjectPages() {\n return React.useContext(InjectPagesContext)\n}\n"]}
1
+ {"version":3,"file":"useInjectPages.js","sourceRoot":"","sources":["../../src/hooks/useInjectPages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CACnD,GAAG,EAAE,GAAE,CAAC,CACT,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,OAAO,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AAC7C,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\ntype InjectPagesContextValue = (\n lookupFormElement: FormTypes.LookupFormElement,\n pageElements: FormTypes.PageElement[],\n data?: SubmissionTypes.S3SubmissionData['submission'],\n) => void\n\nexport const InjectPagesContext = React.createContext<InjectPagesContextValue>(\n () => {},\n)\n\nexport default function useInjectPages() {\n return React.useContext(InjectPagesContext)\n}\n"]}
@@ -1,3 +1,22 @@
1
+ /**
2
+ * This function is a react hook for determining whether the consuming component
3
+ * is currently mounted on the DOM.
4
+ *
5
+ * ## Example
6
+ *
7
+ * ```js
8
+ * import { useIsMounted } from '@oneblink/apps-react'
9
+ *
10
+ * const isMounted = useIsMounted()
11
+ *
12
+ * if (isMounted.current) {
13
+ * // DO SOMETHING HERE
14
+ * }
15
+ * ```
16
+ *
17
+ * @returns
18
+ */
1
19
  export default function useIsMounted(): {
20
+ /** Whether the current component is mounted. */
2
21
  current: boolean;
3
22
  };
@@ -1,4 +1,22 @@
1
1
  import * as React from 'react';
2
+ /**
3
+ * This function is a react hook for determining whether the consuming component
4
+ * is currently mounted on the DOM.
5
+ *
6
+ * ## Example
7
+ *
8
+ * ```js
9
+ * import { useIsMounted } from '@oneblink/apps-react'
10
+ *
11
+ * const isMounted = useIsMounted()
12
+ *
13
+ * if (isMounted.current) {
14
+ * // DO SOMETHING HERE
15
+ * }
16
+ * ```
17
+ *
18
+ * @returns
19
+ */
2
20
  export default function useIsMounted() {
3
21
  const isMounted = React.useRef(false);
4
22
  React.useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as React from 'react'\n\nexport default function useIsMounted(): { current: boolean } {\n const isMounted = React.useRef(false)\n React.useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n return isMounted\n}\n"]}
1
+ {"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY;IAIlC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as React from 'react'\n\n/**\n * This function is a react hook for determining whether the consuming component\n * is currently mounted on the DOM.\n *\n * ## Example\n *\n * ```js\n * import { useIsMounted } from '@oneblink/apps-react'\n *\n * const isMounted = useIsMounted()\n *\n * if (isMounted.current) {\n * // DO SOMETHING HERE\n * }\n * ```\n *\n * @returns\n */\nexport default function useIsMounted(): {\n /** Whether the current component is mounted. */\n current: boolean\n} {\n const isMounted = React.useRef(false)\n React.useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n return isMounted\n}\n"]}
@@ -1,6 +1,55 @@
1
1
  import * as React from 'react';
2
+ /**
3
+ * @param type
4
+ * @param listener
5
+ */
2
6
  export declare const useNetworkChangeEffect: (type: 'online' | 'offline', listener: () => unknown) => void;
7
+ /**
8
+ * IsOfflineContextProvider is a React Component that provides the `isOffline`
9
+ * state for components further down your component tree to consume. It should
10
+ * be used to wrap the components requiring the state.
11
+ *
12
+ * - **This component is required in your component tree to be able to consume the
13
+ * [`useIsOffline`](./useIsOffline.html) hook.**
14
+ *
15
+ * ### Usage
16
+ *
17
+ * ```jsx
18
+ * import { IsOfflineContextProvider } from '@oneblink/apps-react'
19
+ *
20
+ * const TopLevelComponent = () => {
21
+ * return (
22
+ * <IsOfflineContextProvider>
23
+ * <div>
24
+ * <ComponentThatRequiresOfflineState />
25
+ * </div>
26
+ * </IsOfflineContextProvider>
27
+ * )
28
+ * }
29
+ *
30
+ * export default TopLevelComponent
31
+ * ```
32
+ *
33
+ * @param props
34
+ * @returns
35
+ */
3
36
  export declare function IsOfflineContextProvider({ children, }: {
4
37
  children: React.ReactNode;
5
38
  }): JSX.Element;
39
+ /**
40
+ * This function is a react hook for determining whether an application is in an
41
+ * offline state.
42
+ *
43
+ * - **This component requires
44
+ * [`<IsOfflineContextProvider/>`](./IsOfflineContextProvider.html) to be
45
+ * present in your component tree.**
46
+ *
47
+ * ## Example
48
+ *
49
+ * ```js
50
+ * import { useIsOffline } from '@oneblink/apps-react'
51
+ *
52
+ * const isOffline = useIsOffline()
53
+ * ```
54
+ */
6
55
  export default function useIsOffline(): boolean;
@@ -3,6 +3,10 @@ import { offlineService } from '@oneblink/apps';
3
3
  import useBooleanState from '../hooks/useBooleanState';
4
4
  const defaultValue = offlineService.isOffline();
5
5
  const IsOfflineContext = React.createContext(defaultValue);
6
+ /**
7
+ * @param type
8
+ * @param listener
9
+ */
6
10
  export const useNetworkChangeEffect = (type, listener) => {
7
11
  React.useEffect(() => {
8
12
  // Stupid cordova seems to require that offline/online
@@ -15,12 +19,57 @@ export const useNetworkChangeEffect = (type, listener) => {
15
19
  };
16
20
  }, [type, listener]);
17
21
  };
22
+ /**
23
+ * IsOfflineContextProvider is a React Component that provides the `isOffline`
24
+ * state for components further down your component tree to consume. It should
25
+ * be used to wrap the components requiring the state.
26
+ *
27
+ * - **This component is required in your component tree to be able to consume the
28
+ * [`useIsOffline`](./useIsOffline.html) hook.**
29
+ *
30
+ * ### Usage
31
+ *
32
+ * ```jsx
33
+ * import { IsOfflineContextProvider } from '@oneblink/apps-react'
34
+ *
35
+ * const TopLevelComponent = () => {
36
+ * return (
37
+ * <IsOfflineContextProvider>
38
+ * <div>
39
+ * <ComponentThatRequiresOfflineState />
40
+ * </div>
41
+ * </IsOfflineContextProvider>
42
+ * )
43
+ * }
44
+ *
45
+ * export default TopLevelComponent
46
+ * ```
47
+ *
48
+ * @param props
49
+ * @returns
50
+ */
18
51
  export function IsOfflineContextProvider({ children, }) {
19
52
  const [isOffline, goOffline, goOnline] = useBooleanState(defaultValue);
20
53
  useNetworkChangeEffect('online', goOnline);
21
54
  useNetworkChangeEffect('offline', goOffline);
22
55
  return (React.createElement(IsOfflineContext.Provider, { value: isOffline }, children));
23
56
  }
57
+ /**
58
+ * This function is a react hook for determining whether an application is in an
59
+ * offline state.
60
+ *
61
+ * - **This component requires
62
+ * [`<IsOfflineContextProvider/>`](./IsOfflineContextProvider.html) to be
63
+ * present in your component tree.**
64
+ *
65
+ * ## Example
66
+ *
67
+ * ```js
68
+ * import { useIsOffline } from '@oneblink/apps-react'
69
+ *
70
+ * const isOffline = useIsOffline()
71
+ * ```
72
+ */
24
73
  export default function useIsOffline() {
25
74
  return React.useContext(IsOfflineContext);
26
75
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useIsOffline.js","sourceRoot":"","sources":["../../src/hooks/useIsOffline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,eAAe,MAAM,0BAA0B,CAAA;AAEtD,MAAM,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,CAAA;AAE/C,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAU,YAAY,CAAC,CAAA;AAEnE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,IAA0B,EAC1B,QAAuB,EACvB,EAAE;IACF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,sDAAsD;QACtD,sDAAsD;QACtD,qBAAqB;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;QAClD,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAExC,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC7C,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,UAAU,wBAAwB,CAAC,EACvC,QAAQ,GAGT;IACC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;IAEtE,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC1C,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAE5C,OAAO,CACL,oBAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,IACxC,QAAQ,CACiB,CAC7B,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,OAAO,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AAC3C,CAAC","sourcesContent":["import * as React from 'react'\n\nimport { offlineService } from '@oneblink/apps'\nimport useBooleanState from '../hooks/useBooleanState'\n\nconst defaultValue = offlineService.isOffline()\n\nconst IsOfflineContext = React.createContext<boolean>(defaultValue)\n\nexport const useNetworkChangeEffect = (\n type: 'online' | 'offline',\n listener: () => unknown,\n) => {\n React.useEffect(() => {\n // Stupid cordova seems to require that offline/online\n // listeners are set on the document and browsers seem\n // to require window.\n const element = window.cordova ? document : window\n element.addEventListener(type, listener)\n\n return () => {\n element.removeEventListener(type, listener)\n }\n }, [type, listener])\n}\n\nexport function IsOfflineContextProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n const [isOffline, goOffline, goOnline] = useBooleanState(defaultValue)\n\n useNetworkChangeEffect('online', goOnline)\n useNetworkChangeEffect('offline', goOffline)\n\n return (\n <IsOfflineContext.Provider value={isOffline}>\n {children}\n </IsOfflineContext.Provider>\n )\n}\n\nexport default function useIsOffline() {\n return React.useContext(IsOfflineContext)\n}\n"]}
1
+ {"version":3,"file":"useIsOffline.js","sourceRoot":"","sources":["../../src/hooks/useIsOffline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,eAAe,MAAM,0BAA0B,CAAA;AAEtD,MAAM,YAAY,GAAG,cAAc,CAAC,SAAS,EAAE,CAAA;AAE/C,MAAM,gBAAgB,GAAG,KAAK,CAAC,aAAa,CAAU,YAAY,CAAC,CAAA;AAEnE;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,IAA0B,EAC1B,QAAuB,EACvB,EAAE;IACF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,sDAAsD;QACtD,sDAAsD;QACtD,qBAAqB;QACrB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAA;QAClD,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAExC,OAAO,GAAG,EAAE;YACV,OAAO,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC7C,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;AACtB,CAAC,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,wBAAwB,CAAC,EACvC,QAAQ,GAGT;IACC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,eAAe,CAAC,YAAY,CAAC,CAAA;IAEtE,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAC1C,sBAAsB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IAE5C,OAAO,CACL,oBAAC,gBAAgB,CAAC,QAAQ,IAAC,KAAK,EAAE,SAAS,IACxC,QAAQ,CACiB,CAC7B,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,OAAO,KAAK,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAA;AAC3C,CAAC","sourcesContent":["import * as React from 'react'\n\nimport { offlineService } from '@oneblink/apps'\nimport useBooleanState from '../hooks/useBooleanState'\n\nconst defaultValue = offlineService.isOffline()\n\nconst IsOfflineContext = React.createContext<boolean>(defaultValue)\n\n/**\n * @param type\n * @param listener\n */\nexport const useNetworkChangeEffect = (\n type: 'online' | 'offline',\n listener: () => unknown,\n) => {\n React.useEffect(() => {\n // Stupid cordova seems to require that offline/online\n // listeners are set on the document and browsers seem\n // to require window.\n const element = window.cordova ? document : window\n element.addEventListener(type, listener)\n\n return () => {\n element.removeEventListener(type, listener)\n }\n }, [type, listener])\n}\n\n/**\n * IsOfflineContextProvider is a React Component that provides the `isOffline`\n * state for components further down your component tree to consume. It should\n * be used to wrap the components requiring the state.\n *\n * - **This component is required in your component tree to be able to consume the\n * [`useIsOffline`](./useIsOffline.html) hook.**\n *\n * ### Usage\n *\n * ```jsx\n * import { IsOfflineContextProvider } from '@oneblink/apps-react'\n *\n * const TopLevelComponent = () => {\n * return (\n * <IsOfflineContextProvider>\n * <div>\n * <ComponentThatRequiresOfflineState />\n * </div>\n * </IsOfflineContextProvider>\n * )\n * }\n *\n * export default TopLevelComponent\n * ```\n *\n * @param props\n * @returns\n */\nexport function IsOfflineContextProvider({\n children,\n}: {\n children: React.ReactNode\n}) {\n const [isOffline, goOffline, goOnline] = useBooleanState(defaultValue)\n\n useNetworkChangeEffect('online', goOnline)\n useNetworkChangeEffect('offline', goOffline)\n\n return (\n <IsOfflineContext.Provider value={isOffline}>\n {children}\n </IsOfflineContext.Provider>\n )\n}\n\n/**\n * This function is a react hook for determining whether an application is in an\n * offline state.\n *\n * - **This component requires\n * [`<IsOfflineContextProvider/>`](./IsOfflineContextProvider.html) to be\n * present in your component tree.**\n *\n * ## Example\n *\n * ```js\n * import { useIsOffline } from '@oneblink/apps-react'\n *\n * const isOffline = useIsOffline()\n * ```\n */\nexport default function useIsOffline() {\n return React.useContext(IsOfflineContext)\n}\n"]}
@@ -1,15 +1,56 @@
1
1
  import * as React from 'react';
2
2
  export type LoadDataState<T> = {
3
3
  status: 'SUCCESS';
4
+ /** Your data. */
4
5
  result: T;
5
6
  } | {
6
7
  status: 'ERROR';
8
+ /** A JavaScript `Error` object. */
7
9
  error: Error;
8
10
  } | {
9
11
  status: 'LOADING';
10
12
  };
13
+ /**
14
+ * This function is a react hook for managing the state involved with loading
15
+ * data.
16
+ *
17
+ * ## Example
18
+ *
19
+ * ```js
20
+ * import { useLoadDataState } from '@oneblink/apps-react'
21
+ * const fetchData = async () => {
22
+ * const response = await fetch(`https://some-website.com/api?data=data`)
23
+ *
24
+ * if (!response.ok) {
25
+ * const text = await response.text()
26
+ * throw new Error(text)
27
+ * }
28
+ *
29
+ * return await response.json()
30
+ * }
31
+ *
32
+ * const MyComponent = () => {
33
+ * const [state, refresh, setResult] = useLoadDataState(fetchData)
34
+ *
35
+ * switch (state.status) {
36
+ * case 'LOADING':
37
+ * return <Loading />
38
+ * case 'ERROR':
39
+ * return <Error message={state.error} />
40
+ * case 'SUCCESS':
41
+ * // RENDER UI
42
+ * }
43
+ * }
44
+ *
45
+ * export default MyComponent
46
+ * ```
47
+ *
48
+ * @param onLoad The function that fetches your data. Should be a Promise that
49
+ * returns your data
50
+ * @returns
51
+ */
11
52
  export default function useLoadDataState<T>(onLoad: (abortSignal?: AbortSignal) => Promise<T>): [
12
- LoadDataState<T>,
13
- (abortSignal?: AbortSignal) => void,
14
- React.Dispatch<React.SetStateAction<T>>
53
+ state: LoadDataState<T>,
54
+ handleLoad: (abortSignal?: AbortSignal) => void,
55
+ setResult: React.Dispatch<React.SetStateAction<T>>
15
56
  ];
@@ -1,5 +1,44 @@
1
1
  import * as React from 'react';
2
2
  import useIsMounted from './useIsMounted';
3
+ /**
4
+ * This function is a react hook for managing the state involved with loading
5
+ * data.
6
+ *
7
+ * ## Example
8
+ *
9
+ * ```js
10
+ * import { useLoadDataState } from '@oneblink/apps-react'
11
+ * const fetchData = async () => {
12
+ * const response = await fetch(`https://some-website.com/api?data=data`)
13
+ *
14
+ * if (!response.ok) {
15
+ * const text = await response.text()
16
+ * throw new Error(text)
17
+ * }
18
+ *
19
+ * return await response.json()
20
+ * }
21
+ *
22
+ * const MyComponent = () => {
23
+ * const [state, refresh, setResult] = useLoadDataState(fetchData)
24
+ *
25
+ * switch (state.status) {
26
+ * case 'LOADING':
27
+ * return <Loading />
28
+ * case 'ERROR':
29
+ * return <Error message={state.error} />
30
+ * case 'SUCCESS':
31
+ * // RENDER UI
32
+ * }
33
+ * }
34
+ *
35
+ * export default MyComponent
36
+ * ```
37
+ *
38
+ * @param onLoad The function that fetches your data. Should be a Promise that
39
+ * returns your data
40
+ * @returns
41
+ */
3
42
  export default function useLoadDataState(onLoad) {
4
43
  const isMounted = useIsMounted();
5
44
  const [state, setState] = React.useState({
@@ -1 +1 @@
1
- {"version":3,"file":"useLoadDataState.js","sourceRoot":"","sources":["../../src/hooks/useLoadDataState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,gBAAgB,CAAA;AAezC,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,MAAiD;IAMjD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAmB;QACzD,MAAM,EAAE,SAAS;KAClB,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAClC,KAAK,EAAE,WAAyB,EAAE,EAAE;QAClC,QAAQ,CAAC;YACP,MAAM,EAAE,SAAS;SAClB,CAAC,CAAA;QACF,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;YACxC,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAA,EAAE;gBAC9C,QAAQ,CAAC;oBACP,MAAM,EAAE,SAAS;oBACjB,MAAM;iBACP,CAAC,CAAA;aACH;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAA,EAAE;gBAC9C,QAAQ,CAAC;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,GAAY;iBACpB,CAAC,CAAA;aACH;SACF;IACH,CAAC,EACD,CAAC,SAAS,EAAE,MAAM,CAAC,CACpB,CAAA;IAED,MAAM,SAAS,GAA4C,KAAK,CAAC,WAAW,CAC1E,CAAC,MAAM,EAAE,EAAE;QACT,QAAQ,CAAC,CAAC,YAA8B,EAAE,EAAE;YAC1C,IAAI,YAAY,CAAC,MAAM,KAAK,SAAS,EAAE;gBACrC,OAAO;oBACL,GAAG,YAAY;oBACf,MAAM,EACJ,OAAO,MAAM,KAAK,UAAU;wBAC1B,CAAC,CAAC,oFAAoF;4BACpF,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;wBAC7B,CAAC,CAAC,MAAM;iBACb,CAAA;aACF;iBAAM;gBACL,OAAO,YAAY,CAAA;aACpB;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,EAAE,CACH,CAAA;IAED,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC7C,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;QAClC,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;AACvC,CAAC","sourcesContent":["import * as React from 'react'\nimport useIsMounted from './useIsMounted'\n\nexport type LoadDataState<T> =\n | {\n status: 'SUCCESS'\n result: T\n }\n | {\n status: 'ERROR'\n error: Error\n }\n | {\n status: 'LOADING'\n }\n\nexport default function useLoadDataState<T>(\n onLoad: (abortSignal?: AbortSignal) => Promise<T>,\n): [\n LoadDataState<T>,\n (abortSignal?: AbortSignal) => void,\n React.Dispatch<React.SetStateAction<T>>,\n] {\n const isMounted = useIsMounted()\n const [state, setState] = React.useState<LoadDataState<T>>({\n status: 'LOADING',\n })\n\n const handleLoad = React.useCallback(\n async (abortSignal?: AbortSignal) => {\n setState({\n status: 'LOADING',\n })\n try {\n const result = await onLoad(abortSignal)\n if (isMounted.current && !abortSignal?.aborted) {\n setState({\n status: 'SUCCESS',\n result,\n })\n }\n } catch (err) {\n if (isMounted.current && !abortSignal?.aborted) {\n setState({\n status: 'ERROR',\n error: err as Error,\n })\n }\n }\n },\n [isMounted, onLoad],\n )\n\n const setResult: React.Dispatch<React.SetStateAction<T>> = React.useCallback(\n (setter) => {\n setState((currentState: LoadDataState<T>) => {\n if (currentState.status === 'SUCCESS') {\n return {\n ...currentState,\n result:\n typeof setter === 'function'\n ? // @ts-expect-error Typescript cannot tell between a generic type (T) and a function\n setter(currentState.result)\n : setter,\n }\n } else {\n return currentState\n }\n })\n },\n [],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n handleLoad(abortController.signal)\n return () => {\n abortController.abort()\n }\n }, [handleLoad])\n\n return [state, handleLoad, setResult]\n}\n"]}
1
+ {"version":3,"file":"useLoadDataState.js","sourceRoot":"","sources":["../../src/hooks/useLoadDataState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,YAAY,MAAM,gBAAgB,CAAA;AAiBzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,CAAC,OAAO,UAAU,gBAAgB,CACtC,MAAiD;IAMjD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAmB;QACzD,MAAM,EAAE,SAAS;KAClB,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAClC,KAAK,EAAE,WAAyB,EAAE,EAAE;QAClC,QAAQ,CAAC;YACP,MAAM,EAAE,SAAS;SAClB,CAAC,CAAA;QACF,IAAI;YACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAA;YACxC,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAA,EAAE;gBAC9C,QAAQ,CAAC;oBACP,MAAM,EAAE,SAAS;oBACjB,MAAM;iBACP,CAAC,CAAA;aACH;SACF;QAAC,OAAO,GAAG,EAAE;YACZ,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,CAAA,WAAW,aAAX,WAAW,uBAAX,WAAW,CAAE,OAAO,CAAA,EAAE;gBAC9C,QAAQ,CAAC;oBACP,MAAM,EAAE,OAAO;oBACf,KAAK,EAAE,GAAY;iBACpB,CAAC,CAAA;aACH;SACF;IACH,CAAC,EACD,CAAC,SAAS,EAAE,MAAM,CAAC,CACpB,CAAA;IAED,MAAM,SAAS,GAA4C,KAAK,CAAC,WAAW,CAC1E,CAAC,MAAM,EAAE,EAAE;QACT,QAAQ,CAAC,CAAC,YAA8B,EAAE,EAAE;YAC1C,IAAI,YAAY,CAAC,MAAM,KAAK,SAAS,EAAE;gBACrC,OAAO;oBACL,GAAG,YAAY;oBACf,MAAM,EACJ,OAAO,MAAM,KAAK,UAAU;wBAC1B,CAAC,CAAC,oFAAoF;4BACpF,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC;wBAC7B,CAAC,CAAC,MAAM;iBACb,CAAA;aACF;iBAAM;gBACL,OAAO,YAAY,CAAA;aACpB;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,EAAE,CACH,CAAA;IAED,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC7C,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;QAClC,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,KAAK,EAAE,CAAA;QACzB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,CAAA;AACvC,CAAC","sourcesContent":["import * as React from 'react'\nimport useIsMounted from './useIsMounted'\n\nexport type LoadDataState<T> =\n | {\n status: 'SUCCESS'\n /** Your data. */\n result: T\n }\n | {\n status: 'ERROR'\n /** A JavaScript `Error` object. */\n error: Error\n }\n | {\n status: 'LOADING'\n }\n\n/**\n * This function is a react hook for managing the state involved with loading\n * data.\n *\n * ## Example\n *\n * ```js\n * import { useLoadDataState } from '@oneblink/apps-react'\n * const fetchData = async () => {\n * const response = await fetch(`https://some-website.com/api?data=data`)\n *\n * if (!response.ok) {\n * const text = await response.text()\n * throw new Error(text)\n * }\n *\n * return await response.json()\n * }\n *\n * const MyComponent = () => {\n * const [state, refresh, setResult] = useLoadDataState(fetchData)\n *\n * switch (state.status) {\n * case 'LOADING':\n * return <Loading />\n * case 'ERROR':\n * return <Error message={state.error} />\n * case 'SUCCESS':\n * // RENDER UI\n * }\n * }\n *\n * export default MyComponent\n * ```\n *\n * @param onLoad The function that fetches your data. Should be a Promise that\n * returns your data\n * @returns\n */\nexport default function useLoadDataState<T>(\n onLoad: (abortSignal?: AbortSignal) => Promise<T>,\n): [\n state: LoadDataState<T>,\n handleLoad: (abortSignal?: AbortSignal) => void,\n setResult: React.Dispatch<React.SetStateAction<T>>,\n] {\n const isMounted = useIsMounted()\n const [state, setState] = React.useState<LoadDataState<T>>({\n status: 'LOADING',\n })\n\n const handleLoad = React.useCallback(\n async (abortSignal?: AbortSignal) => {\n setState({\n status: 'LOADING',\n })\n try {\n const result = await onLoad(abortSignal)\n if (isMounted.current && !abortSignal?.aborted) {\n setState({\n status: 'SUCCESS',\n result,\n })\n }\n } catch (err) {\n if (isMounted.current && !abortSignal?.aborted) {\n setState({\n status: 'ERROR',\n error: err as Error,\n })\n }\n }\n },\n [isMounted, onLoad],\n )\n\n const setResult: React.Dispatch<React.SetStateAction<T>> = React.useCallback(\n (setter) => {\n setState((currentState: LoadDataState<T>) => {\n if (currentState.status === 'SUCCESS') {\n return {\n ...currentState,\n result:\n typeof setter === 'function'\n ? // @ts-expect-error Typescript cannot tell between a generic type (T) and a function\n setter(currentState.result)\n : setter,\n }\n } else {\n return currentState\n }\n })\n },\n [],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n handleLoad(abortController.signal)\n return () => {\n abortController.abort()\n }\n }, [handleLoad])\n\n return [state, handleLoad, setResult]\n}\n"]}