hooks.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { useEffect } from 'react';
  2. import { useRefresh } from '@flowgram.ai/utils';
  3. import { FlowNodeFormData } from '@flowgram.ai/form-core';
  4. import { Errors, Warnings } from '@flowgram.ai/form/src/types';
  5. import { FormState, useFormErrors, useFormState, useFormWarnings } from '@flowgram.ai/form';
  6. import { FlowNodeEntity } from '@flowgram.ai/document';
  7. import { FormModelV2 } from './form-model-v2';
  8. /**
  9. * Listen to Form's values and refresh the React component.
  10. * By providing related node, you can use this hook outside the Form Component.
  11. * @param node
  12. */
  13. export function useWatchFormValues<T = any>(node: FlowNodeEntity): T | undefined {
  14. const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
  15. const refresh = useRefresh();
  16. useEffect(() => {
  17. const disposable = formModel.nativeFormModel?.onFormValuesChange(() => {
  18. refresh();
  19. });
  20. return () => disposable?.dispose();
  21. }, [formModel.nativeFormModel]);
  22. return formModel.getValues<T>();
  23. }
  24. /**
  25. * Listen to Form's value in a certain path and refresh the React component.
  26. * By providing related node, you can use this hook outside the Form Component.
  27. * @param node
  28. */
  29. export function useWatchFormValueIn<T = any>(node: FlowNodeEntity, name: string): T | undefined {
  30. const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
  31. const refresh = useRefresh();
  32. useEffect(() => {
  33. const disposable = formModel.nativeFormModel?.onFormValuesChange(({ name: changedName }) => {
  34. if (name === changedName) {
  35. refresh();
  36. }
  37. });
  38. return () => disposable?.dispose();
  39. }, []);
  40. return formModel.getValueIn<T>(name);
  41. }
  42. /**
  43. * Listen to FormModel's initialization and refresh React component.
  44. * By providing related node, you can use this hook outside the Form Component.
  45. * @param node
  46. */
  47. export function useInitializedFormModel(node: FlowNodeEntity) {
  48. const formModel = node.getData(FlowNodeFormData).getFormModel<FormModelV2>();
  49. const refresh = useRefresh();
  50. useEffect(() => {
  51. const disposable = formModel.onInitialized(() => {
  52. refresh();
  53. });
  54. return () => disposable.dispose();
  55. }, [formModel]);
  56. return formModel;
  57. }
  58. /**
  59. * Get Form's state, Form State is a proxy, it will refresh the React component when the value you accessed changed
  60. * By providing related node, you can use this hook outside the Form Component.
  61. * @param node
  62. */
  63. export function useWatchFormState(node: FlowNodeEntity): FormState | undefined {
  64. const formModel = useInitializedFormModel(node);
  65. return useFormState(formModel.formControl);
  66. }
  67. /**
  68. * Get Form's errors, Form errors is a proxy, it will refresh the React component when the value you accessed changed
  69. * By providing related node, you can use this hook outside the Form Component.
  70. * @param node
  71. */
  72. export function useWatchFormErrors(node: FlowNodeEntity): Errors | undefined {
  73. const formModel = useInitializedFormModel(node);
  74. return useFormErrors(formModel.formControl);
  75. }
  76. /**
  77. * Get Form's warnings, Form warnings is a proxy, it will refresh the React component when the value you accessed changed
  78. * By providing related node, you can use this hook outside the Form Component.
  79. * @param node
  80. */
  81. export function useWatchFormWarnings(node: FlowNodeEntity): Warnings | undefined {
  82. const formModel = useInitializedFormModel(node);
  83. return useFormWarnings(formModel.formControl);
  84. }