use-create-form.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /**
  2. * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
  3. * SPDX-License-Identifier: MIT
  4. */
  5. import { useEffect, useMemo } from 'react';
  6. import type { OnFormValuesChangePayload } from '@flowgram.ai/form-core';
  7. import { createForm, ValidateTrigger, type IForm } from '@flowgram.ai/form';
  8. import { createValidate } from '../utils';
  9. import { FormSchema, FormSchemaValidate } from '../types';
  10. import { FormSchemaModel } from '../model';
  11. export interface FormInstance {
  12. model: FormSchemaModel;
  13. form: IForm;
  14. }
  15. export interface UseCreateFormOptions {
  16. defaultValues?: any;
  17. validate?: Record<string, FormSchemaValidate>;
  18. validateTrigger?: ValidateTrigger;
  19. onMounted?: (form: FormInstance) => void;
  20. onFormValuesChange?: (payload: OnFormValuesChangePayload) => void;
  21. onUnmounted?: () => void;
  22. }
  23. export const useCreateForm = (schema: FormSchema, options: UseCreateFormOptions = {}) => {
  24. const { form, control } = useMemo(
  25. () =>
  26. createForm({
  27. validate: {
  28. ...createValidate(schema),
  29. ...options.validate,
  30. },
  31. validateTrigger: options.validateTrigger ?? ValidateTrigger.onBlur,
  32. }),
  33. [schema]
  34. );
  35. const model = useMemo(
  36. () => new FormSchemaModel({ type: 'object', ...schema, defaultValue: options.defaultValues }),
  37. [schema]
  38. );
  39. /** Lifecycle and event binding */
  40. useEffect(() => {
  41. if (options.onMounted) {
  42. options.onMounted({ model, form });
  43. }
  44. const disposable = control._formModel.onFormValuesChange((payload) => {
  45. if (options.onFormValuesChange) {
  46. options.onFormValuesChange(payload);
  47. }
  48. });
  49. return () => {
  50. disposable.dispose();
  51. if (options.onUnmounted) {
  52. options.onUnmounted();
  53. }
  54. };
  55. }, [control]);
  56. return {
  57. form,
  58. control,
  59. model,
  60. };
  61. };