@vaadin/hilla-react-crud 24.7.0-alpha8 → 24.7.0-beta1

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 (151) hide show
  1. package/autocrud-dialog.d.ts +0 -1
  2. package/autocrud-dialog.js +9 -23
  3. package/autocrud-dialog.js.map +1 -7
  4. package/autocrud-feature.d.ts +0 -1
  5. package/autocrud-feature.js +5 -8
  6. package/autocrud-feature.js.map +1 -7
  7. package/autocrud.d.ts +2 -64
  8. package/autocrud.js +43 -92
  9. package/autocrud.js.map +1 -7
  10. package/autocrud.obj.js +1 -6
  11. package/autoform-feature.d.ts +0 -1
  12. package/autoform-feature.js +5 -8
  13. package/autoform-feature.js.map +1 -7
  14. package/autoform-field.d.ts +0 -90
  15. package/autoform-field.js +87 -95
  16. package/autoform-field.js.map +1 -7
  17. package/autoform.d.ts +0 -190
  18. package/autoform.js +126 -184
  19. package/autoform.js.map +1 -7
  20. package/autoform.obj.js +1 -6
  21. package/autogrid-column-context.d.ts +1 -2
  22. package/autogrid-column-context.js +4 -8
  23. package/autogrid-column-context.js.map +1 -7
  24. package/autogrid-columns.d.ts +0 -1
  25. package/autogrid-columns.js +83 -99
  26. package/autogrid-columns.js.map +1 -7
  27. package/autogrid-feature.d.ts +0 -1
  28. package/autogrid-feature.js +5 -8
  29. package/autogrid-feature.js.map +1 -7
  30. package/autogrid-renderers.d.ts +0 -1
  31. package/autogrid-renderers.js +71 -80
  32. package/autogrid-renderers.js.map +1 -7
  33. package/autogrid.d.ts +1 -103
  34. package/autogrid.js +176 -234
  35. package/autogrid.js.map +1 -7
  36. package/autogrid.obj.js +1 -6
  37. package/crud.d.ts +7 -10
  38. package/data-provider.d.ts +37 -6
  39. package/data-provider.js +186 -121
  40. package/data-provider.js.map +1 -7
  41. package/header-filter.d.ts +1 -30
  42. package/header-filter.js +137 -244
  43. package/header-filter.js.map +1 -7
  44. package/header-sorter.d.ts +0 -1
  45. package/header-sorter.js +16 -27
  46. package/header-sorter.js.map +1 -7
  47. package/i18n.d.ts +0 -1
  48. package/i18n.js +2 -5
  49. package/i18n.js.map +1 -7
  50. package/index.d.ts +1 -2
  51. package/index.js +12 -16
  52. package/index.js.map +1 -7
  53. package/locale.d.ts +0 -1
  54. package/locale.js +100 -107
  55. package/locale.js.map +1 -7
  56. package/media-query.d.ts +0 -1
  57. package/media-query.js +12 -15
  58. package/media-query.js.map +1 -7
  59. package/model-info.d.ts +0 -1
  60. package/model-info.js +126 -127
  61. package/model-info.js.map +1 -7
  62. package/package.json +9 -33
  63. package/types/com/vaadin/hilla/crud/filter/AndFilter.d.ts +3 -4
  64. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts +0 -1
  65. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js +6 -9
  66. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js.map +1 -7
  67. package/types/com/vaadin/hilla/crud/filter/Filter.d.ts +1 -2
  68. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts +0 -1
  69. package/types/com/vaadin/hilla/crud/filter/FilterModel.js +3 -6
  70. package/types/com/vaadin/hilla/crud/filter/FilterModel.js.map +1 -7
  71. package/types/com/vaadin/hilla/crud/filter/FilterUnion.d.ts +4 -2
  72. package/types/com/vaadin/hilla/crud/filter/OrFilter.d.ts +3 -4
  73. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts +0 -1
  74. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js +6 -9
  75. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js.map +1 -7
  76. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts +0 -1
  77. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js +9 -12
  78. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js.map +1 -7
  79. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts +0 -1
  80. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js +4 -7
  81. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js.map +1 -7
  82. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter.d.ts +4 -5
  83. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts +0 -1
  84. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js +12 -15
  85. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js.map +1 -7
  86. package/types/com/vaadin/hilla/mappedtypes/Order.d.ts +3 -4
  87. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts +0 -1
  88. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js +15 -18
  89. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js.map +1 -7
  90. package/types/com/vaadin/hilla/mappedtypes/Pageable.d.ts +1 -2
  91. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts +0 -1
  92. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js +12 -15
  93. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js.map +1 -7
  94. package/types/com/vaadin/hilla/mappedtypes/Sort.d.ts +1 -2
  95. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts +0 -1
  96. package/types/com/vaadin/hilla/mappedtypes/SortModel.js +6 -9
  97. package/types/com/vaadin/hilla/mappedtypes/SortModel.js.map +1 -7
  98. package/types/org/springframework/data/domain/Sort/Direction.d.ts +0 -1
  99. package/types/org/springframework/data/domain/Sort/Direction.js +7 -10
  100. package/types/org/springframework/data/domain/Sort/Direction.js.map +1 -7
  101. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts +0 -1
  102. package/types/org/springframework/data/domain/Sort/DirectionModel.js +4 -7
  103. package/types/org/springframework/data/domain/Sort/DirectionModel.js.map +1 -7
  104. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts +0 -1
  105. package/types/org/springframework/data/domain/Sort/NullHandling.js +8 -11
  106. package/types/org/springframework/data/domain/Sort/NullHandling.js.map +1 -7
  107. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts +0 -1
  108. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js +4 -7
  109. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js.map +1 -7
  110. package/types.d.ts +6 -9
  111. package/types.js +2 -0
  112. package/types.js.map +1 -0
  113. package/util.d.ts +1 -2
  114. package/util.js +42 -47
  115. package/util.js.map +1 -7
  116. package/autocrud-dialog.d.ts.map +0 -1
  117. package/autocrud-feature.d.ts.map +0 -1
  118. package/autocrud.d.ts.map +0 -1
  119. package/autocrud.obj.js.map +0 -7
  120. package/autoform-feature.d.ts.map +0 -1
  121. package/autoform-field.d.ts.map +0 -1
  122. package/autoform.d.ts.map +0 -1
  123. package/autoform.obj.js.map +0 -7
  124. package/autogrid-column-context.d.ts.map +0 -1
  125. package/autogrid-columns.d.ts.map +0 -1
  126. package/autogrid-feature.d.ts.map +0 -1
  127. package/autogrid-renderers.d.ts.map +0 -1
  128. package/autogrid.d.ts.map +0 -1
  129. package/autogrid.obj.js.map +0 -7
  130. package/data-provider.d.ts.map +0 -1
  131. package/header-filter.d.ts.map +0 -1
  132. package/header-sorter.d.ts.map +0 -1
  133. package/i18n.d.ts.map +0 -1
  134. package/index.d.ts.map +0 -1
  135. package/locale.d.ts.map +0 -1
  136. package/media-query.d.ts.map +0 -1
  137. package/model-info.d.ts.map +0 -1
  138. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts.map +0 -1
  139. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts.map +0 -1
  140. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts.map +0 -1
  141. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts.map +0 -1
  142. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts.map +0 -1
  143. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts.map +0 -1
  144. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts.map +0 -1
  145. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts.map +0 -1
  146. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts.map +0 -1
  147. package/types/org/springframework/data/domain/Sort/Direction.d.ts.map +0 -1
  148. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts.map +0 -1
  149. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts.map +0 -1
  150. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts.map +0 -1
  151. package/util.d.ts.map +0 -1
package/autoform-field.js CHANGED
@@ -1,118 +1,110 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { _enum } from "@vaadin/hilla-lit-form";
3
- import { useFormPart } from "@vaadin/hilla-react-form";
4
- import { Checkbox } from "@vaadin/react-components/Checkbox.js";
5
- import { DatePicker } from "@vaadin/react-components/DatePicker.js";
6
- import { DateTimePicker } from "@vaadin/react-components/DateTimePicker.js";
7
- import { IntegerField } from "@vaadin/react-components/IntegerField.js";
8
- import { NumberField } from "@vaadin/react-components/NumberField.js";
9
- import { Select } from "@vaadin/react-components/Select.js";
10
- import { TextArea } from "@vaadin/react-components/TextArea.js";
11
- import { TextField } from "@vaadin/react-components/TextField.js";
12
- import { TimePicker } from "@vaadin/react-components/TimePicker.js";
13
- import {
14
- cloneElement,
15
- createElement,
16
- useEffect,
17
- useMemo
18
- } from "react";
19
- import { useDatePickerI18n, useDateTimePickerI18n } from "./locale.js";
20
- import { convertToTitleCase } from "./util.js";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { _enum } from '@vaadin/hilla-lit-form';
3
+ import { useFormPart } from '@vaadin/hilla-react-form';
4
+ import { Checkbox } from '@vaadin/react-components/Checkbox.js';
5
+ import { DatePicker } from '@vaadin/react-components/DatePicker.js';
6
+ import { DateTimePicker } from '@vaadin/react-components/DateTimePicker.js';
7
+ import { IntegerField } from '@vaadin/react-components/IntegerField.js';
8
+ import { NumberField } from '@vaadin/react-components/NumberField.js';
9
+ import { Select } from '@vaadin/react-components/Select.js';
10
+ import { TextArea } from '@vaadin/react-components/TextArea.js';
11
+ import { TextField } from '@vaadin/react-components/TextField.js';
12
+ import { TimePicker } from '@vaadin/react-components/TimePicker.js';
13
+ import { cloneElement, createElement, useEffect, useMemo, } from 'react';
14
+ import { useDatePickerI18n, useDateTimePickerI18n } from './locale.js';
15
+ import { convertToTitleCase } from './util.js';
21
16
  function getPropertyModel(form, propertyInfo) {
22
- const pathParts = propertyInfo.name.split(".");
23
- return pathParts.reduce((model, property) => model ? model[property] : void 0, form.model);
17
+ const pathParts = propertyInfo.name.split('.');
18
+ return pathParts.reduce((model, property) => (model ? model[property] : undefined), form.model);
24
19
  }
25
20
  function renderFieldElement(defaultComponentType, { element, field, fieldProps }, additionalProps = {}) {
26
- const fieldElement = element ?? createElement(defaultComponentType);
27
- return cloneElement(fieldElement, { ...fieldProps, ...additionalProps, ...fieldElement.props, ...field });
21
+ const fieldElement = element ?? createElement(defaultComponentType);
22
+ return cloneElement(fieldElement, { ...fieldProps, ...additionalProps, ...fieldElement.props, ...field });
28
23
  }
29
24
  function AutoFormTextField(props) {
30
- return renderFieldElement(TextField, props);
25
+ return renderFieldElement(TextField, props);
31
26
  }
32
27
  function AutoFormIntegerField(props) {
33
- return renderFieldElement(IntegerField, props);
28
+ return renderFieldElement(IntegerField, props);
34
29
  }
35
30
  function AutoFormDecimalField(props) {
36
- return renderFieldElement(NumberField, props);
31
+ return renderFieldElement(NumberField, props);
37
32
  }
38
33
  function AutoFormDateField(props) {
39
- const i18n = useDatePickerI18n();
40
- return renderFieldElement(DatePicker, props, { i18n });
34
+ const i18n = useDatePickerI18n();
35
+ return renderFieldElement(DatePicker, props, { i18n });
41
36
  }
42
37
  function AutoFormTimeField(props) {
43
- return renderFieldElement(TimePicker, props);
38
+ return renderFieldElement(TimePicker, props);
44
39
  }
45
40
  function AutoFormDateTimeField(props) {
46
- const i18n = useDateTimePickerI18n();
47
- return renderFieldElement(DateTimePicker, props, { i18n });
41
+ const i18n = useDateTimePickerI18n();
42
+ return renderFieldElement(DateTimePicker, props, { i18n });
48
43
  }
49
44
  function AutoFormEnumField(props) {
50
- const enumModel = props.model;
51
- const items = Object.keys(enumModel[_enum]).map((value) => ({
52
- label: convertToTitleCase(value),
53
- value
54
- }));
55
- return renderFieldElement(Select, props, { items });
45
+ const enumModel = props.model;
46
+ const items = Object.keys(enumModel[_enum]).map((value) => ({
47
+ label: convertToTitleCase(value),
48
+ value,
49
+ }));
50
+ return renderFieldElement(Select, props, { items });
56
51
  }
57
52
  function AutoFormBooleanField(props) {
58
- return renderFieldElement(Checkbox, props);
53
+ return renderFieldElement(Checkbox, props);
59
54
  }
60
55
  function AutoFormObjectField({ model, fieldProps }) {
61
- const part = useFormPart(model);
62
- const jsonString = part.value ? JSON.stringify(part.value) : "";
63
- return /* @__PURE__ */ jsx(TextArea, { ...fieldProps, value: jsonString, readonly: true });
56
+ const part = useFormPart(model);
57
+ const jsonString = part.value ? JSON.stringify(part.value) : '';
58
+ return _jsx(TextArea, { ...fieldProps, value: jsonString, readonly: true });
64
59
  }
65
- function AutoFormField(props) {
66
- const { form, propertyInfo, options } = props;
67
- const label = options.label ?? propertyInfo.humanReadableName;
68
- const model = getPropertyModel(form, propertyInfo);
69
- const field = form.field(model);
70
- const formPart = useFormPart(model);
71
- const defaultValidators = useMemo(() => formPart.validators, []);
72
- const { validators } = options;
73
- useEffect(() => {
74
- formPart.setValidators([...defaultValidators, ...validators ?? []]);
75
- }, [validators]);
76
- if (options.renderer) {
77
- const customFieldProps = { ...field, disabled: props.disabled, label };
78
- return options.renderer({ field: customFieldProps });
79
- }
80
- const fieldProps = {
81
- id: options.id,
82
- className: options.className,
83
- style: options.style,
84
- label,
85
- placeholder: options.placeholder,
86
- helperText: options.helperText,
87
- colspan: options.colspan,
88
- disabled: options.disabled ?? props.disabled,
89
- readonly: options.readonly
90
- };
91
- const rendererProps = { model, field, element: options.element, fieldProps };
92
- switch (props.propertyInfo.type) {
93
- case "string":
94
- return /* @__PURE__ */ jsx(AutoFormTextField, { ...rendererProps });
95
- case "integer":
96
- return /* @__PURE__ */ jsx(AutoFormIntegerField, { ...rendererProps });
97
- case "decimal":
98
- return /* @__PURE__ */ jsx(AutoFormDecimalField, { ...rendererProps });
99
- case "date":
100
- return /* @__PURE__ */ jsx(AutoFormDateField, { ...rendererProps });
101
- case "time":
102
- return /* @__PURE__ */ jsx(AutoFormTimeField, { ...rendererProps });
103
- case "datetime":
104
- return /* @__PURE__ */ jsx(AutoFormDateTimeField, { ...rendererProps });
105
- case "enum":
106
- return /* @__PURE__ */ jsx(AutoFormEnumField, { ...rendererProps });
107
- case "boolean":
108
- return /* @__PURE__ */ jsx(AutoFormBooleanField, { ...rendererProps });
109
- case "object":
110
- return /* @__PURE__ */ jsx(AutoFormObjectField, { ...rendererProps });
111
- default:
112
- return null;
113
- }
60
+ export function AutoFormField(props) {
61
+ const { form, propertyInfo, options } = props;
62
+ const label = options.label ?? propertyInfo.humanReadableName;
63
+ const model = getPropertyModel(form, propertyInfo);
64
+ const field = form.field(model);
65
+ const formPart = useFormPart(model);
66
+ const defaultValidators = useMemo(() => formPart.validators, []);
67
+ const { validators } = options;
68
+ useEffect(() => {
69
+ formPart.setValidators([...defaultValidators, ...(validators ?? [])]);
70
+ }, [validators]);
71
+ if (options.renderer) {
72
+ const customFieldProps = { ...field, disabled: props.disabled, label };
73
+ return options.renderer({ field: customFieldProps });
74
+ }
75
+ const fieldProps = {
76
+ id: options.id,
77
+ className: options.className,
78
+ style: options.style,
79
+ label,
80
+ placeholder: options.placeholder,
81
+ helperText: options.helperText,
82
+ colspan: options.colspan,
83
+ disabled: options.disabled ?? props.disabled,
84
+ readonly: options.readonly,
85
+ };
86
+ const rendererProps = { model, field, element: options.element, fieldProps };
87
+ switch (props.propertyInfo.type) {
88
+ case 'string':
89
+ return _jsx(AutoFormTextField, { ...rendererProps });
90
+ case 'integer':
91
+ return _jsx(AutoFormIntegerField, { ...rendererProps });
92
+ case 'decimal':
93
+ return _jsx(AutoFormDecimalField, { ...rendererProps });
94
+ case 'date':
95
+ return _jsx(AutoFormDateField, { ...rendererProps });
96
+ case 'time':
97
+ return _jsx(AutoFormTimeField, { ...rendererProps });
98
+ case 'datetime':
99
+ return _jsx(AutoFormDateTimeField, { ...rendererProps });
100
+ case 'enum':
101
+ return _jsx(AutoFormEnumField, { ...rendererProps });
102
+ case 'boolean':
103
+ return _jsx(AutoFormBooleanField, { ...rendererProps });
104
+ case 'object':
105
+ return _jsx(AutoFormObjectField, { ...rendererProps });
106
+ default:
107
+ return null;
108
+ }
114
109
  }
115
- export {
116
- AutoFormField
117
- };
118
- //# sourceMappingURL=autoform-field.js.map
110
+ //# sourceMappingURL=autoform-field.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/autoform-field.tsx"],
4
- "sourcesContent": ["import { _enum, type AbstractModel, type EnumModel, type Validator } from '@vaadin/hilla-lit-form';\nimport type { FieldDirectiveResult, UseFormResult } from '@vaadin/hilla-react-form';\nimport { useFormPart } from '@vaadin/hilla-react-form';\nimport { Checkbox } from '@vaadin/react-components/Checkbox.js';\nimport { DatePicker } from '@vaadin/react-components/DatePicker.js';\nimport { DateTimePicker } from '@vaadin/react-components/DateTimePicker.js';\nimport { IntegerField } from '@vaadin/react-components/IntegerField.js';\nimport { NumberField } from '@vaadin/react-components/NumberField.js';\nimport { Select } from '@vaadin/react-components/Select.js';\nimport { TextArea } from '@vaadin/react-components/TextArea.js';\nimport { TextField } from '@vaadin/react-components/TextField.js';\nimport { TimePicker } from '@vaadin/react-components/TimePicker.js';\nimport {\n cloneElement,\n type ComponentType,\n createElement,\n type CSSProperties,\n type JSX,\n useEffect,\n useMemo,\n} from 'react';\nimport { useDatePickerI18n, useDateTimePickerI18n } from './locale.js';\nimport type { PropertyInfo } from './model-info.js';\nimport { convertToTitleCase } from './util.js';\n\nexport type AutoFormFieldProps = Readonly<{\n propertyInfo: PropertyInfo;\n form: UseFormResult<any>;\n options: FieldOptions;\n disabled?: boolean;\n}>;\n\ntype CustomFormFieldProps = FieldDirectiveResult & Readonly<{ label?: string; disabled?: boolean }>;\n\nexport type FieldOptions = Readonly<{\n /**\n * The id to apply to the field.\n */\n id?: string;\n /**\n * The class names to add to the field.\n */\n className?: string;\n /**\n * The style to apply to the field.\n */\n style?: CSSProperties;\n /**\n * The label to show for the field. If not specified, a human-readable label\n * is generated from the property name.\n */\n label?: string;\n /**\n * The placeholder to when the field is empty.\n *\n * Note that some field types, such as checkbox, do not support a placeholder.\n */\n placeholder?: string;\n /**\n * The helper text to display below the field.\n *\n * Note that some field types, such as checkbox, do not support a helper text.\n */\n helperText?: string;\n /**\n * The number of columns to span. This value is passed to the underlying\n * FormLayout, unless a custom layout is used. In that case, the value is\n * ignored.\n */\n colspan?: number;\n /**\n * Whether the field should be disabled.\n */\n disabled?: boolean;\n /**\n * Whether the field should be readonly.\n */\n readonly?: boolean;\n /**\n * The element to render for the field. This allows customizing field props\n * that are not supported by the field options, or to render a different field\n * component. Other field options are automatically applied to the element,\n * and the element is automatically bound to the form. If not specified, a\n * default field element is rendered based on the property type.\n *\n * The element must be a field component, such as TextField, TextArea,\n * NumberField, etc., otherwise form binding will not work. For more\n * sophisticated customizations, use the `renderer` option.\n *\n * If the field options also specify a renderer function, then the element is\n * ignored.\n *\n * Example enabling the clear button for a text field:\n * ```tsx\n * {\n * element: <TextField clearButtonVisible />\n * }\n * ```\n *\n * Example rendering a text area instead of a text field:\n * ```tsx\n * {\n * element: <TextArea />\n * }\n * ```\n */\n element?: JSX.Element;\n /**\n * Allows to specify a custom renderer for the field, for example to render a\n * custom type of field or apply an additional layout around the field. The\n * renderer receives field props that must be applied to the custom field\n * component in order to connect it to the form.\n *\n * In order to customize one of the default fields, or render a different type\n * of field, consider using the `element` option instead.\n *\n * Example:\n * ```tsx\n * {\n * renderer: ({ field }) => (\n * <div>\n * <TextArea {...field} />\n * <p>Number of words: {calculateNumberOfWords()}</p>\n * </div>\n * )\n * }\n * ```\n */\n renderer?(props: { field: CustomFormFieldProps }): JSX.Element;\n /**\n * Validators to apply to the field. The validators are added to the form\n * when the field is rendered.\n * UseMemo is recommended for the validators, so that they are not recreated\n * on every render.\n */\n validators?: Validator[];\n}>;\n\ntype CommonFieldProps = Pick<\n FieldOptions,\n 'className' | 'colspan' | 'disabled' | 'helperText' | 'id' | 'label' | 'placeholder' | 'readonly' | 'style'\n>;\n\ntype FieldRendererProps = Readonly<{\n model: AbstractModel;\n field: FieldDirectiveResult;\n element?: JSX.Element;\n fieldProps: CommonFieldProps;\n}>;\n\nfunction getPropertyModel(form: UseFormResult<any>, propertyInfo: PropertyInfo) {\n const pathParts = propertyInfo.name.split('.');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return pathParts.reduce<any>((model, property) => (model ? model[property] : undefined), form.model);\n}\n\nfunction renderFieldElement(\n defaultComponentType: ComponentType,\n { element, field, fieldProps }: FieldRendererProps,\n additionalProps: any = {},\n) {\n const fieldElement = element ?? createElement(defaultComponentType);\n return cloneElement(fieldElement, { ...fieldProps, ...additionalProps, ...fieldElement.props, ...field });\n}\n\nfunction AutoFormTextField(props: FieldRendererProps) {\n return renderFieldElement(TextField, props);\n}\n\nfunction AutoFormIntegerField(props: FieldRendererProps) {\n return renderFieldElement(IntegerField, props);\n}\n\nfunction AutoFormDecimalField(props: FieldRendererProps) {\n return renderFieldElement(NumberField, props);\n}\n\nfunction AutoFormDateField(props: FieldRendererProps) {\n const i18n = useDatePickerI18n();\n return renderFieldElement(DatePicker, props, { i18n });\n}\n\nfunction AutoFormTimeField(props: FieldRendererProps) {\n return renderFieldElement(TimePicker, props);\n}\n\nfunction AutoFormDateTimeField(props: FieldRendererProps) {\n const i18n = useDateTimePickerI18n();\n return renderFieldElement(DateTimePicker, props, { i18n });\n}\n\nfunction AutoFormEnumField(props: FieldRendererProps) {\n const enumModel = props.model as EnumModel;\n const items = Object.keys(enumModel[_enum]).map((value) => ({\n label: convertToTitleCase(value),\n value,\n }));\n return renderFieldElement(Select, props, { items });\n}\n\nfunction AutoFormBooleanField(props: FieldRendererProps) {\n return renderFieldElement(Checkbox, props);\n}\n\nfunction AutoFormObjectField({ model, fieldProps }: FieldRendererProps) {\n const part = useFormPart(model);\n const jsonString = part.value ? JSON.stringify(part.value) : '';\n return <TextArea {...fieldProps} value={jsonString} readonly />;\n}\n\nexport function AutoFormField(props: AutoFormFieldProps): JSX.Element | null {\n const { form, propertyInfo, options } = props;\n const label = options.label ?? propertyInfo.humanReadableName;\n const model = getPropertyModel(form, propertyInfo);\n const field = form.field(model);\n\n const formPart = useFormPart(model);\n const defaultValidators = useMemo(() => formPart.validators, []);\n const { validators } = options;\n useEffect(() => {\n formPart.setValidators([...defaultValidators, ...(validators ?? [])]);\n }, [validators]);\n\n if (options.renderer) {\n const customFieldProps = { ...field, disabled: props.disabled, label };\n return options.renderer({ field: customFieldProps });\n }\n\n const fieldProps: CommonFieldProps = {\n id: options.id,\n className: options.className,\n style: options.style,\n label,\n placeholder: options.placeholder,\n helperText: options.helperText,\n colspan: options.colspan,\n disabled: options.disabled ?? props.disabled,\n readonly: options.readonly,\n };\n\n const rendererProps: FieldRendererProps = { model, field, element: options.element, fieldProps };\n\n switch (props.propertyInfo.type) {\n case 'string':\n return <AutoFormTextField {...rendererProps}></AutoFormTextField>;\n case 'integer':\n return <AutoFormIntegerField {...rendererProps}></AutoFormIntegerField>;\n case 'decimal':\n return <AutoFormDecimalField {...rendererProps}></AutoFormDecimalField>;\n case 'date':\n return <AutoFormDateField {...rendererProps}></AutoFormDateField>;\n case 'time':\n return <AutoFormTimeField {...rendererProps}></AutoFormTimeField>;\n case 'datetime':\n return <AutoFormDateTimeField {...rendererProps}></AutoFormDateTimeField>;\n case 'enum':\n return <AutoFormEnumField {...rendererProps}></AutoFormEnumField>;\n case 'boolean':\n return <AutoFormBooleanField {...rendererProps}></AutoFormBooleanField>;\n case 'object':\n return <AutoFormObjectField {...rendererProps}></AutoFormObjectField>;\n default:\n return null;\n }\n}\n"],
5
- "mappings": "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",
6
- "names": []
7
- }
1
+ {"version":3,"file":"autoform-field.js","sourceRoot":"","sources":["src/autoform-field.tsx"],"names":[],"mappings":"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","sourcesContent":["import { _enum, type AbstractModel, type EnumModel, type Validator } from '@vaadin/hilla-lit-form';\nimport type { FieldDirectiveResult, UseFormResult } from '@vaadin/hilla-react-form';\nimport { useFormPart } from '@vaadin/hilla-react-form';\nimport { Checkbox } from '@vaadin/react-components/Checkbox.js';\nimport { DatePicker } from '@vaadin/react-components/DatePicker.js';\nimport { DateTimePicker } from '@vaadin/react-components/DateTimePicker.js';\nimport { IntegerField } from '@vaadin/react-components/IntegerField.js';\nimport { NumberField } from '@vaadin/react-components/NumberField.js';\nimport { Select } from '@vaadin/react-components/Select.js';\nimport { TextArea } from '@vaadin/react-components/TextArea.js';\nimport { TextField } from '@vaadin/react-components/TextField.js';\nimport { TimePicker } from '@vaadin/react-components/TimePicker.js';\nimport {\n cloneElement,\n type ComponentType,\n createElement,\n type CSSProperties,\n type JSX,\n useEffect,\n useMemo,\n} from 'react';\nimport { useDatePickerI18n, useDateTimePickerI18n } from './locale.js';\nimport type { PropertyInfo } from './model-info.js';\nimport { convertToTitleCase } from './util.js';\n\nexport type AutoFormFieldProps = Readonly<{\n propertyInfo: PropertyInfo;\n form: UseFormResult<any>;\n options: FieldOptions;\n disabled?: boolean;\n}>;\n\ntype CustomFormFieldProps = FieldDirectiveResult & Readonly<{ label?: string; disabled?: boolean }>;\n\nexport type FieldOptions = Readonly<{\n /**\n * The id to apply to the field.\n */\n id?: string;\n /**\n * The class names to add to the field.\n */\n className?: string;\n /**\n * The style to apply to the field.\n */\n style?: CSSProperties;\n /**\n * The label to show for the field. If not specified, a human-readable label\n * is generated from the property name.\n */\n label?: string;\n /**\n * The placeholder to when the field is empty.\n *\n * Note that some field types, such as checkbox, do not support a placeholder.\n */\n placeholder?: string;\n /**\n * The helper text to display below the field.\n *\n * Note that some field types, such as checkbox, do not support a helper text.\n */\n helperText?: string;\n /**\n * The number of columns to span. This value is passed to the underlying\n * FormLayout, unless a custom layout is used. In that case, the value is\n * ignored.\n */\n colspan?: number;\n /**\n * Whether the field should be disabled.\n */\n disabled?: boolean;\n /**\n * Whether the field should be readonly.\n */\n readonly?: boolean;\n /**\n * The element to render for the field. This allows customizing field props\n * that are not supported by the field options, or to render a different field\n * component. Other field options are automatically applied to the element,\n * and the element is automatically bound to the form. If not specified, a\n * default field element is rendered based on the property type.\n *\n * The element must be a field component, such as TextField, TextArea,\n * NumberField, etc., otherwise form binding will not work. For more\n * sophisticated customizations, use the `renderer` option.\n *\n * If the field options also specify a renderer function, then the element is\n * ignored.\n *\n * Example enabling the clear button for a text field:\n * ```tsx\n * {\n * element: <TextField clearButtonVisible />\n * }\n * ```\n *\n * Example rendering a text area instead of a text field:\n * ```tsx\n * {\n * element: <TextArea />\n * }\n * ```\n */\n element?: JSX.Element;\n /**\n * Allows to specify a custom renderer for the field, for example to render a\n * custom type of field or apply an additional layout around the field. The\n * renderer receives field props that must be applied to the custom field\n * component in order to connect it to the form.\n *\n * In order to customize one of the default fields, or render a different type\n * of field, consider using the `element` option instead.\n *\n * Example:\n * ```tsx\n * {\n * renderer: ({ field }) => (\n * <div>\n * <TextArea {...field} />\n * <p>Number of words: {calculateNumberOfWords()}</p>\n * </div>\n * )\n * }\n * ```\n */\n renderer?(props: { field: CustomFormFieldProps }): JSX.Element;\n /**\n * Validators to apply to the field. The validators are added to the form\n * when the field is rendered.\n * UseMemo is recommended for the validators, so that they are not recreated\n * on every render.\n */\n validators?: Validator[];\n}>;\n\ntype CommonFieldProps = Pick<\n FieldOptions,\n 'className' | 'colspan' | 'disabled' | 'helperText' | 'id' | 'label' | 'placeholder' | 'readonly' | 'style'\n>;\n\ntype FieldRendererProps = Readonly<{\n model: AbstractModel;\n field: FieldDirectiveResult;\n element?: JSX.Element;\n fieldProps: CommonFieldProps;\n}>;\n\nfunction getPropertyModel(form: UseFormResult<any>, propertyInfo: PropertyInfo) {\n const pathParts = propertyInfo.name.split('.');\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return pathParts.reduce<any>((model, property) => (model ? model[property] : undefined), form.model);\n}\n\nfunction renderFieldElement(\n defaultComponentType: ComponentType,\n { element, field, fieldProps }: FieldRendererProps,\n additionalProps: any = {},\n) {\n const fieldElement = element ?? createElement(defaultComponentType);\n return cloneElement(fieldElement, { ...fieldProps, ...additionalProps, ...fieldElement.props, ...field });\n}\n\nfunction AutoFormTextField(props: FieldRendererProps) {\n return renderFieldElement(TextField, props);\n}\n\nfunction AutoFormIntegerField(props: FieldRendererProps) {\n return renderFieldElement(IntegerField, props);\n}\n\nfunction AutoFormDecimalField(props: FieldRendererProps) {\n return renderFieldElement(NumberField, props);\n}\n\nfunction AutoFormDateField(props: FieldRendererProps) {\n const i18n = useDatePickerI18n();\n return renderFieldElement(DatePicker, props, { i18n });\n}\n\nfunction AutoFormTimeField(props: FieldRendererProps) {\n return renderFieldElement(TimePicker, props);\n}\n\nfunction AutoFormDateTimeField(props: FieldRendererProps) {\n const i18n = useDateTimePickerI18n();\n return renderFieldElement(DateTimePicker, props, { i18n });\n}\n\nfunction AutoFormEnumField(props: FieldRendererProps) {\n const enumModel = props.model as EnumModel;\n const items = Object.keys(enumModel[_enum]).map((value) => ({\n label: convertToTitleCase(value),\n value,\n }));\n return renderFieldElement(Select, props, { items });\n}\n\nfunction AutoFormBooleanField(props: FieldRendererProps) {\n return renderFieldElement(Checkbox, props);\n}\n\nfunction AutoFormObjectField({ model, fieldProps }: FieldRendererProps) {\n const part = useFormPart(model);\n const jsonString = part.value ? JSON.stringify(part.value) : '';\n return <TextArea {...fieldProps} value={jsonString} readonly />;\n}\n\nexport function AutoFormField(props: AutoFormFieldProps): JSX.Element | null {\n const { form, propertyInfo, options } = props;\n const label = options.label ?? propertyInfo.humanReadableName;\n const model = getPropertyModel(form, propertyInfo);\n const field = form.field(model);\n\n const formPart = useFormPart(model);\n const defaultValidators = useMemo(() => formPart.validators, []);\n const { validators } = options;\n useEffect(() => {\n formPart.setValidators([...defaultValidators, ...(validators ?? [])]);\n }, [validators]);\n\n if (options.renderer) {\n const customFieldProps = { ...field, disabled: props.disabled, label };\n return options.renderer({ field: customFieldProps });\n }\n\n const fieldProps: CommonFieldProps = {\n id: options.id,\n className: options.className,\n style: options.style,\n label,\n placeholder: options.placeholder,\n helperText: options.helperText,\n colspan: options.colspan,\n disabled: options.disabled ?? props.disabled,\n readonly: options.readonly,\n };\n\n const rendererProps: FieldRendererProps = { model, field, element: options.element, fieldProps };\n\n switch (props.propertyInfo.type) {\n case 'string':\n return <AutoFormTextField {...rendererProps}></AutoFormTextField>;\n case 'integer':\n return <AutoFormIntegerField {...rendererProps}></AutoFormIntegerField>;\n case 'decimal':\n return <AutoFormDecimalField {...rendererProps}></AutoFormDecimalField>;\n case 'date':\n return <AutoFormDateField {...rendererProps}></AutoFormDateField>;\n case 'time':\n return <AutoFormTimeField {...rendererProps}></AutoFormTimeField>;\n case 'datetime':\n return <AutoFormDateTimeField {...rendererProps}></AutoFormDateTimeField>;\n case 'enum':\n return <AutoFormEnumField {...rendererProps}></AutoFormEnumField>;\n case 'boolean':\n return <AutoFormBooleanField {...rendererProps}></AutoFormBooleanField>;\n case 'object':\n return <AutoFormObjectField {...rendererProps}></AutoFormObjectField>;\n default:\n return null;\n }\n}\n"]}
package/autoform.d.ts CHANGED
@@ -7,54 +7,18 @@ import { type AutoFormFieldProps, type FieldOptions } from './autoform-field.js'
7
7
  import type { FormService } from './crud.js';
8
8
  import { type ComponentStyleProps } from './util.js';
9
9
  export declare const emptyItem: unique symbol;
10
- /**
11
- * An event that is fired when an error occurs while submitting the form.
12
- */
13
10
  export type SubmitErrorEvent = {
14
- /**
15
- * The error that occurred.
16
- */
17
11
  error: EndpointError;
18
- /**
19
- * A function that can be used to set a custom error message. This will be
20
- * shown in the form at the same position as the default error message.
21
- * You are not required to call this function if you want to handle the
22
- * error differently.
23
- */
24
12
  setMessage(message: string): void;
25
13
  };
26
- /**
27
- * An event that is fired when the form has been successfully submitted.
28
- */
29
14
  export type SubmitEvent<TItem> = {
30
- /**
31
- * The item that was submitted, as returned by the service.
32
- */
33
15
  item: TItem;
34
16
  };
35
- /**
36
- * An event that is fired when an error occurs while deleting an item.
37
- */
38
17
  export type DeleteErrorEvent = {
39
- /**
40
- * The error that occurred.
41
- */
42
18
  error: EndpointError;
43
- /**
44
- * A function that can be used to set a custom error message. This will be
45
- * shown in the form at the same position as the default error message.
46
- * You are not required to call this function if you want to handle the
47
- * error differently.
48
- */
49
19
  setMessage(message: string): void;
50
20
  };
51
- /**
52
- * An event that is fired when the form has been successfully deleted.
53
- */
54
21
  export type DeleteEvent<TItem> = {
55
- /**
56
- * The item that was deleted, as returned by the service.
57
- */
58
22
  item: TItem;
59
23
  };
60
24
  export type AutoFormLayoutRendererProps<M extends AbstractModel> = Readonly<{
@@ -62,174 +26,20 @@ export type AutoFormLayoutRendererProps<M extends AbstractModel> = Readonly<{
62
26
  children: ReadonlyArray<ReactElement<AutoFormFieldProps>>;
63
27
  }>;
64
28
  export type AutoFormProps<M extends AbstractModel = AbstractModel> = ComponentStyleProps & Readonly<{
65
- /**
66
- * The service to use for saving and deleting items. This must be a
67
- * TypeScript service that has been generated by Hilla from a backend Java
68
- * service that implements the `com.vaadin.hilla.crud.FormService` interface.
69
- */
70
29
  service: FormService<Value<M>>;
71
- /**
72
- * The entity model to use, which determines which fields to show in the
73
- * form. This must be a Typescript model class that has been generated by
74
- * Hilla from a backend Java class. The model must match with the type of
75
- * the items handled by the service. For example, a `PersonModel` can be
76
- * used with a service that handles `Person` instances.
77
- *
78
- * By default, the form shows fields for all properties of the model which
79
- * have a type that is supported. Use the `visibleFields` option to customize
80
- * which fields to show and in which order.
81
- */
82
30
  model: DetachedModelConstructor<M>;
83
- /**
84
- * The property to use to detect an item's ID. The item ID is required for
85
- * deleting items via the `FormService.delete` method. The delete button
86
- * will not be shown if no item ID can be found.
87
- *
88
- * By default, the component uses the property annotated with
89
- * `jakarta.persistence.Id`, or a property named `id`, in that order.
90
- * This option can be used to override the default behavior, or define the ID
91
- * property in case a class doesn't have a property matching the defaults.
92
- */
93
31
  itemIdProperty?: string;
94
- /**
95
- * The item to edit in the form. The form fields are automatically populated
96
- * with values from the item's properties. In order to create a new item,
97
- * either pass `null`, or leave this prop as undefined.
98
- *
99
- * Use the `onSubmitSuccess` callback to get notified when the item has been
100
- * saved.
101
- *
102
- * When submitting a new item (i.e. when `item` is null or undefined), the
103
- * form will be automatically cleared, allowing to submit another new item.
104
- * In order to keep editing the same item after submitting, set the `item`
105
- * prop to the new item.
106
- */
107
32
  item?: Value<M> | typeof emptyItem | null;
108
- /**
109
- * Whether the form should be disabled. This disables all form fields and
110
- * all buttons.
111
- */
112
33
  disabled?: boolean;
113
- /**
114
- * Allows to customize the layout of the form by providing a custom
115
- * renderer. The renderer receives the form instance and the pre-rendered
116
- * fields as props. The renderer can either reuse the pre-rendered fields in
117
- * the custom layout, or render custom fields and connect them to the form
118
- * manually.
119
- *
120
- * Check the component documentation for details and examples.
121
- *
122
- * Example using pre-rendered fields:
123
- * ```tsx
124
- * <AutoForm layoutRenderer={({ children }) =>
125
- * <VerticalLayout>
126
- * {children}
127
- * <p>All data is collected anonymously.</p>
128
- * </VerticalLayout>
129
- * } />
130
- * ```
131
- *
132
- * Example rendering custom fields:
133
- * ```tsx
134
- * <AutoForm layoutRenderer={({ form }) =>
135
- * <VerticalLayout>
136
- * <TextField {...form.field(form.model.name)} />
137
- * ...
138
- * </VerticalLayout>
139
- * } />
140
- * ```
141
- */
142
34
  layoutRenderer?: ComponentType<AutoFormLayoutRendererProps<M>>;
143
- /**
144
- * Defines the fields to show in the form, and in which order. This takes
145
- * an array of property names. Properties that are not included in this
146
- * array will not be shown in the form, and properties that are included,
147
- * but don't exist in the model, will be ignored.
148
- */
149
35
  visibleFields?: string[];
150
- /**
151
- * Defines the fields to hide in the form, keeping the default order. This takes
152
- * an array of property names. Properties that are not included in this
153
- * array will not be hidden in the form, and properties that are included,
154
- * but don't exist in the model, will be ignored.
155
- */
156
36
  hiddenFields?: string[];
157
- /**
158
- * Allows to customize the FormLayout used by default. This is especially useful
159
- * to define the `responsiveSteps`. See the
160
- * {@link https://hilla.dev/docs/react/components/form-layout | FormLayout documentation}
161
- * for details.
162
- */
163
37
  formLayoutProps?: ComponentStyleProps & Pick<Parameters<typeof FormLayout>[0], 'responsiveSteps'>;
164
- /**
165
- * Allows to customize individual fields of the form. This takes an object
166
- * where the keys are property names, and the values are options for the
167
- * respective field for editing that property.
168
- */
169
38
  fieldOptions?: Record<string, FieldOptions>;
170
- /**
171
- * Whether to show the delete button in the form. This is disabled by
172
- * default. If enabled, the delete button will only be shown when editing
173
- * an existing item, which means that `item` is not null. The delete button
174
- * will also only be shown if an item has a discernible ID. See the
175
- * `itemIdProperty` prop for details how the item ID is detected.
176
- *
177
- * Use the `onDeleteSuccess` callback to get notified when the item has been
178
- * deleted.
179
- *
180
- * NOTE: This only hides the button, it does not prevent from calling the
181
- * delete method on the service. To completely disable deleting, you must
182
- * override the `delete` method in the backend Java service to either throw
183
- * an exception or annotate it with `@DenyAll` to prevent access.
184
- */
185
39
  deleteButtonVisible?: boolean;
186
- /**
187
- * A callback that will be called if an unexpected error occurs while
188
- * submitting the form.
189
- *
190
- * Note that this will not be called for validation errors, which are
191
- * handled automatically.
192
- */
193
40
  onSubmitError?({ error }: SubmitErrorEvent): void;
194
- /**
195
- * A callback that will be called after the form has been successfully
196
- * submitted and the item has been saved.
197
- *
198
- * When submitting a new item (i.e. when `item` is null or undefined), the
199
- * form will be automatically cleared, allowing to submit another new item.
200
- * In order to keep editing the same item after submitting, set the `item`
201
- * prop to the new item.
202
- */
203
41
  onSubmitSuccess?({ item }: SubmitEvent<Value<M>>): void;
204
- /**
205
- * A callback that will be called if an unexpected error occurs while
206
- * deleting an item.
207
- */
208
42
  onDeleteError?({ error }: DeleteErrorEvent): void;
209
- /**
210
- * A callback that will be called after the form has been successfully
211
- * deleted.
212
- */
213
43
  onDeleteSuccess?({ item }: DeleteEvent<Value<M>>): void;
214
44
  }>;
215
- /**
216
- * Auto Form is a component that automatically generates a form for editing,
217
- * updating and deleting items from a backend service.
218
- *
219
- * Example usage:
220
- * ```tsx
221
- * import { AutoForm } from '@vaadin/hilla-react-crud';
222
- * import PersonService from 'Frontend/generated/endpoints';
223
- * import PersonModel from 'Frontend/generated/com/example/application/Person';
224
- *
225
- * <AutoForm
226
- * service={PersonService}
227
- * model={PersonModel}
228
- * onSubmitSuccess={({ item }) => {
229
- * console.log('Submitted item:', item);
230
- * }}
231
- * />
232
- * ```
233
- */
234
45
  export declare function AutoForm<M extends AbstractModel>({ service, model, itemIdProperty, item, onSubmitError, onSubmitSuccess, disabled, layoutRenderer: LayoutRenderer, visibleFields, hiddenFields, formLayoutProps, fieldOptions, style, id, className, deleteButtonVisible, onDeleteSuccess, onDeleteError, }: AutoFormProps<M>): JSX.Element;
235
- //# sourceMappingURL=autoform.d.ts.map