createInput.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. import { createSection } from '@formkit/inputs'
  3. import { cloneAny } from '@formkit/utils'
  4. import { markRaw } from 'vue'
  5. import initializeFieldDefinition from './initializeFieldDefinition.ts'
  6. import type { FieldsCustomOptions } from './initializeFieldDefinition.ts'
  7. import type { FormKitSchemaNode, FormKitTypeDefinition } from '@formkit/core'
  8. import type { FormKitSchemaExtendableSection } from '@formkit/inputs'
  9. import type { Component } from 'vue'
  10. let totalCreated = 0
  11. const isComponent = (obj: unknown): obj is Component => {
  12. if (!obj) return false
  13. return Boolean(
  14. (typeof obj === 'function' && obj.length === 2) ||
  15. (typeof obj === 'object' &&
  16. !Array.isArray(obj) &&
  17. !('$el' in obj) &&
  18. !('$cmp' in obj) &&
  19. !('if' in obj)),
  20. )
  21. }
  22. /**
  23. * Wrapper around the formkit createInput function. This function adds the default initilization of the
  24. * field definition.
  25. *
  26. * @param schemaOrComponent - The actual input schema or component.
  27. * @param props - The additional props for the field.
  28. * @param customDefinition - Additional formkit type definition options.
  29. * @param options - Add some field custom options.
  30. * @public
  31. */
  32. const createInput = (
  33. schemaOrComponent: FormKitSchemaNode | Component,
  34. props?: string[],
  35. customDefinition: Partial<FormKitTypeDefinition> = {},
  36. options: FieldsCustomOptions = {},
  37. ): FormKitTypeDefinition => {
  38. customDefinition.props = props
  39. const definition = {
  40. type: 'input' as const,
  41. ...customDefinition,
  42. }
  43. let schema: () => FormKitSchemaExtendableSection
  44. if (isComponent(schemaOrComponent)) {
  45. // eslint-disable-next-line no-plusplus
  46. const cmpName = `CustomSchemaComponent${totalCreated++}`
  47. schema = createSection('input', () => ({
  48. $cmp: cmpName,
  49. props: {
  50. context: '$node.context',
  51. },
  52. }))
  53. definition.library = { [cmpName]: markRaw(schemaOrComponent) }
  54. } else {
  55. schema = createSection('input', () => cloneAny(schemaOrComponent))
  56. }
  57. initializeFieldDefinition(definition, {}, { ...options, schema })
  58. if (!definition.schemaMemoKey) {
  59. definition.schemaMemoKey = `${Math.random()}`
  60. }
  61. return definition
  62. }
  63. export default createInput