@vaadin/hilla-react-crud 24.7.0-alpha9 → 24.7.0-beta3

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 +46 -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 +10 -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
@@ -8,4 +8,3 @@ interface AutoCrudDialogProps {
8
8
  }
9
9
  export declare function AutoCrudDialog(props: AutoCrudDialogProps): JSX.Element;
10
10
  export {};
11
- //# sourceMappingURL=autocrud-dialog.d.ts.map
@@ -1,24 +1,10 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Button } from "@vaadin/react-components/Button";
3
- import { Dialog } from "@vaadin/react-components/Dialog";
4
- import { Icon } from "@vaadin/react-components/Icon";
5
- import "@vaadin/vaadin-lumo-styles/vaadin-iconset.js";
6
- function AutoCrudDialog(props) {
7
- const { header, children, opened, onClose } = props;
8
- return /* @__PURE__ */ jsx(
9
- Dialog,
10
- {
11
- overlayClass: "auto-crud-dialog",
12
- opened,
13
- headerRenderer: () => /* @__PURE__ */ jsxs("div", { className: "auto-crud-dialog-header", children: [
14
- header,
15
- /* @__PURE__ */ jsx(Button, { theme: "tertiary", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(Icon, { icon: "lumo:cross", style: { height: "var(--lumo-icon-size-l)", width: "var(--lumo-icon-size-l)" } }) })
16
- ] }),
17
- children
18
- }
19
- );
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@vaadin/react-components/Button';
3
+ import { Dialog } from '@vaadin/react-components/Dialog';
4
+ import { Icon } from '@vaadin/react-components/Icon';
5
+ import '@vaadin/vaadin-lumo-styles/vaadin-iconset.js';
6
+ export function AutoCrudDialog(props) {
7
+ const { header, children, opened, onClose } = props;
8
+ return (_jsx(Dialog, { overlayClass: "auto-crud-dialog", opened: opened, headerRenderer: () => (_jsxs("div", { className: "auto-crud-dialog-header", children: [header, _jsx(Button, { theme: "tertiary", onClick: onClose, "aria-label": "Close", children: _jsx(Icon, { icon: "lumo:cross", style: { height: 'var(--lumo-icon-size-l)', width: 'var(--lumo-icon-size-l)' } }) })] })), children: children }));
20
9
  }
21
- export {
22
- AutoCrudDialog
23
- };
24
- //# sourceMappingURL=autocrud-dialog.js.map
10
+ //# sourceMappingURL=autocrud-dialog.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/autocrud-dialog.tsx"],
4
- "sourcesContent": ["import { Button } from '@vaadin/react-components/Button';\nimport { Dialog } from '@vaadin/react-components/Dialog';\nimport { Icon } from '@vaadin/react-components/Icon';\nimport type { JSX } from 'react';\n\n// eslint-disable-next-line\nimport '@vaadin/vaadin-lumo-styles/vaadin-iconset.js';\n\ninterface AutoCrudDialogProps {\n header: JSX.Element | null | undefined;\n children: React.ReactElement;\n opened: boolean;\n // eslint-disable-next-line @typescript-eslint/method-signature-style\n onClose: () => void;\n}\n\nexport function AutoCrudDialog(props: AutoCrudDialogProps): JSX.Element {\n const { header, children, opened, onClose } = props;\n return (\n <Dialog\n overlayClass=\"auto-crud-dialog\"\n opened={opened}\n headerRenderer={() => (\n <div className=\"auto-crud-dialog-header\">\n {header}\n <Button theme=\"tertiary\" onClick={onClose} aria-label=\"Close\">\n <Icon icon=\"lumo:cross\" style={{ height: 'var(--lumo-icon-size-l)', width: 'var(--lumo-icon-size-l)' }} />\n </Button>\n </div>\n )}\n >\n {children}\n </Dialog>\n );\n}\n"],
5
- "mappings": "AAuBQ,SAGI,KAHJ;AAvBR,SAAS,cAAc;AACvB,SAAS,cAAc;AACvB,SAAS,YAAY;AAIrB,OAAO;AAUA,SAAS,eAAe,OAAyC;AACtE,QAAM,EAAE,QAAQ,UAAU,QAAQ,QAAQ,IAAI;AAC9C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,cAAa;AAAA,MACb;AAAA,MACA,gBAAgB,MACd,qBAAC,SAAI,WAAU,2BACZ;AAAA;AAAA,QACD,oBAAC,UAAO,OAAM,YAAW,SAAS,SAAS,cAAW,SACpD,8BAAC,QAAK,MAAK,cAAa,OAAO,EAAE,QAAQ,2BAA2B,OAAO,0BAA0B,GAAG,GAC1G;AAAA,SACF;AAAA,MAGD;AAAA;AAAA,EACH;AAEJ;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"autocrud-dialog.js","sourceRoot":"","sources":["src/autocrud-dialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AAIrD,OAAO,8CAA8C,CAAC;AAUtD,MAAM,UAAU,cAAc,CAAC,KAA0B;IACvD,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACpD,OAAO,CACL,KAAC,MAAM,IACL,YAAY,EAAC,kBAAkB,EAC/B,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,GAAG,EAAE,CAAC,CACpB,eAAK,SAAS,EAAC,yBAAyB,aACrC,MAAM,EACP,KAAC,MAAM,IAAC,KAAK,EAAC,UAAU,EAAC,OAAO,EAAE,OAAO,gBAAa,OAAO,YAC3D,KAAC,IAAI,IAAC,IAAI,EAAC,YAAY,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,yBAAyB,EAAE,KAAK,EAAE,yBAAyB,EAAE,GAAI,GACnG,IACL,CACP,YAEA,QAAQ,GACF,CACV,CAAC;AACJ,CAAC","sourcesContent":["import { Button } from '@vaadin/react-components/Button';\nimport { Dialog } from '@vaadin/react-components/Dialog';\nimport { Icon } from '@vaadin/react-components/Icon';\nimport type { JSX } from 'react';\n\n// eslint-disable-next-line\nimport '@vaadin/vaadin-lumo-styles/vaadin-iconset.js';\n\ninterface AutoCrudDialogProps {\n header: JSX.Element | null | undefined;\n children: React.ReactElement;\n opened: boolean;\n // eslint-disable-next-line @typescript-eslint/method-signature-style\n onClose: () => void;\n}\n\nexport function AutoCrudDialog(props: AutoCrudDialogProps): JSX.Element {\n const { header, children, opened, onClose } = props;\n return (\n <Dialog\n overlayClass=\"auto-crud-dialog\"\n opened={opened}\n headerRenderer={() => (\n <div className=\"auto-crud-dialog-header\">\n {header}\n <Button theme=\"tertiary\" onClick={onClose} aria-label=\"Close\">\n <Icon icon=\"lumo:cross\" style={{ height: 'var(--lumo-icon-size-l)', width: 'var(--lumo-icon-size-l)' }} />\n </Button>\n </div>\n )}\n >\n {children}\n </Dialog>\n );\n}\n"]}
@@ -1,4 +1,3 @@
1
1
  import { AutoCrud as _AutoCrud } from './autocrud.js';
2
2
  export * from './autocrud.js';
3
3
  export declare const AutoCrud: typeof _AutoCrud;
4
- //# sourceMappingURL=autocrud-feature.d.ts.map
@@ -1,8 +1,5 @@
1
- import { AutoCrud as _AutoCrud } from "./autocrud.js";
2
- import { featureRegistration } from "./util";
3
- export * from "./autocrud.js";
4
- const AutoCrud = featureRegistration(_AutoCrud, "AutoCrud");
5
- export {
6
- AutoCrud
7
- };
8
- //# sourceMappingURL=autocrud-feature.js.map
1
+ import { AutoCrud as _AutoCrud } from './autocrud.js';
2
+ import { featureRegistration } from './util.js';
3
+ export * from './autocrud.js';
4
+ export const AutoCrud = featureRegistration(_AutoCrud, 'AutoCrud');
5
+ //# sourceMappingURL=autocrud-feature.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/autocrud-feature.ts"],
4
- "sourcesContent": ["/* eslint-disable import/export */\nimport { AutoCrud as _AutoCrud } from './autocrud.js';\nimport { featureRegistration } from './util';\n\nexport * from './autocrud.js';\n\nexport const AutoCrud: typeof _AutoCrud = featureRegistration(_AutoCrud, 'AutoCrud');\n"],
5
- "mappings": "AACA,SAAS,YAAY,iBAAiB;AACtC,SAAS,2BAA2B;AAEpC,cAAc;AAEP,MAAM,WAA6B,oBAAoB,WAAW,UAAU;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"autocrud-feature.js","sourceRoot":"","sources":["src/autocrud-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,cAAc,eAAe,CAAC;AAE9B,MAAM,CAAC,MAAM,QAAQ,GAAqB,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC","sourcesContent":["/* eslint-disable import/export */\nimport { AutoCrud as _AutoCrud } from './autocrud.js';\nimport { featureRegistration } from './util.js';\n\nexport * from './autocrud.js';\n\nexport const AutoCrud: typeof _AutoCrud = featureRegistration(_AutoCrud, 'AutoCrud');\n"]}
package/autocrud.d.ts CHANGED
@@ -6,77 +6,15 @@ import type { CrudService } from './crud.js';
6
6
  import { type ComponentStyleProps } from './util.js';
7
7
  export type AutoCrudFormHeaderRenderer<TItem> = (editedItem: TItem | null, disabled: boolean) => JSX.Element | null | undefined;
8
8
  export type AutoCrudFormProps<TModel extends AbstractModel> = Omit<Partial<AutoFormProps<TModel>>, 'disabled' | 'item' | 'model' | 'onDeleteSuccess' | 'onSubmitSuccess' | 'service'> & Readonly<{
9
- /**
10
- * A custom renderer function to create the header for the form. The
11
- * function receives the edited item as the first parameter, and a boolean
12
- * indicating whether the form is disabled as the second parameter. The
13
- * edited item is `null` when creating a new item.
14
- *
15
- * By default, the header shows "New item" when creating a new item, and
16
- * "Edit item" when editing an existing item.
17
- */
18
9
  headerRenderer?: AutoCrudFormHeaderRenderer<Value<TModel>>;
19
10
  }>;
20
11
  export type AutoCrudGridProps<TItem> = Omit<Partial<AutoGridProps<TItem>>, 'model' | 'onActiveItemChanged' | 'selectedItems' | 'service'>;
21
12
  export type AutoCrudProps<TModel extends AbstractModel = AbstractModel> = ComponentStyleProps & Readonly<{
22
- /**
23
- * The service to use for fetching the data, as well saving and deleting
24
- * items. This must be a TypeScript service that has been generated by Hilla
25
- * from a backend Java service that implements the
26
- * `com.vaadin.hilla.crud.CrudService` interface.
27
- */
28
13
  service: CrudService<Value<TModel>>;
29
- /**
30
- * The entity model to use for the CRUD. This determines which columns to
31
- * show in the grid, and which fields to show in the form. This must be a
32
- * Typescript model class that has been generated by Hilla from a backend
33
- * Java class. The model must match with the type of the items returned by
34
- * the service. For example, a `PersonModel` can be used with a service that
35
- * returns `Person` instances.
36
- *
37
- * By default, the grid shows columns for all properties of the model which
38
- * have a type that is supported. Use the `gridProps.visibleColumns` option
39
- * to customize which columns to show and in which order.
40
- *
41
- * By default, the form shows fields for all properties of the model which
42
- * have a type that is supported. Use the `formProps.visibleFields`
43
- * option to customize which fields to show and in which order.
44
- */
45
14
  model: DetachedModelConstructor<TModel>;
46
- /**
47
- * The property to use to detect an item's ID. The item ID is required for
48
- * deleting items via the `CrudService.delete` method as well as keeping the
49
- * selection state after reloading the grid.
50
- *
51
- * By default, the component uses the property annotated with
52
- * `jakarta.persistence.Id`, or a property named `id`, in that order.
53
- * This option can be used to override the default behavior, or define the ID
54
- * property in case a class doesn't have a property matching the defaults.
55
- */
56
15
  itemIdProperty?: string;
57
- /**
58
- * Props to pass to the form. See the `AutoForm` component for details.
59
- */
16
+ noNewButton?: boolean;
60
17
  formProps?: AutoCrudFormProps<TModel>;
61
- /**
62
- * Props to pass to the grid. See the `AutoGrid` component for details.
63
- */
64
18
  gridProps?: AutoCrudGridProps<Value<TModel>>;
65
19
  }>;
66
- /**
67
- * Auto CRUD is a component that provides CRUD (create, read, update, delete)
68
- * functionality based on a Java backend service. It automatically generates a
69
- * grid that shows data from the service, and a form for creating, updating and
70
- * deleting items.
71
- *
72
- * Example usage:
73
- * ```tsx
74
- * import { AutoCrud } from '@hilla/react-crud';
75
- * import PersonService from 'Frontend/generated/endpoints';
76
- * import PersonModel from 'Frontend/generated/com/example/application/Person';
77
- *
78
- * <AutoCrud service={PersonService} model={PersonModel} />
79
- * ```
80
- */
81
- export declare function AutoCrud<TModel extends AbstractModel>({ service, model, itemIdProperty, formProps, gridProps, style, id, className, }: AutoCrudProps<TModel>): JSX.Element;
82
- //# sourceMappingURL=autocrud.d.ts.map
20
+ export declare function AutoCrud<TModel extends AbstractModel>({ service, model, itemIdProperty, noNewButton, formProps, gridProps, style, id, className, }: AutoCrudProps<TModel>): JSX.Element;
package/autocrud.js CHANGED
@@ -1,97 +1,51 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { Button } from "@vaadin/react-components/Button.js";
3
- import { SplitLayout } from "@vaadin/react-components/SplitLayout.js";
4
- import { useId, useRef, useState } from "react";
5
- import { AutoCrudDialog } from "./autocrud-dialog.js";
6
- import css from "./autocrud.obj.js";
7
- import { emptyItem, AutoForm } from "./autoform.js";
8
- import { AutoGrid } from "./autogrid.js";
9
- import { useMediaQuery } from "./media-query.js";
10
- import { registerStylesheet } from "./util.js";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Button } from '@vaadin/react-components/Button.js';
3
+ import { SplitLayout } from '@vaadin/react-components/SplitLayout.js';
4
+ import { useId, useRef, useState } from 'react';
5
+ import { AutoCrudDialog } from './autocrud-dialog.js';
6
+ import css from './autocrud.obj.js';
7
+ import { emptyItem, AutoForm } from './autoform.js';
8
+ import { AutoGrid } from './autogrid.js';
9
+ import { useMediaQuery } from './media-query.js';
10
+ import { registerStylesheet } from './util.js';
11
11
  registerStylesheet(css);
12
12
  function defaultFormHeaderRenderer(editedItem, disabled) {
13
- const style = { color: disabled ? "var(--lumo-disabled-text-color)" : "var(--lumo-text-color)" };
14
- return editedItem ? /* @__PURE__ */ jsx("h3", { style, children: "Edit item" }) : /* @__PURE__ */ jsx("h3", { style, children: "New item" });
13
+ const style = { color: disabled ? 'var(--lumo-disabled-text-color)' : 'var(--lumo-text-color)' };
14
+ return editedItem ? _jsx("h3", { style: style, children: "Edit item" }) : _jsx("h3", { style: style, children: "New item" });
15
15
  }
16
- function AutoCrud({
17
- service,
18
- model,
19
- itemIdProperty,
20
- formProps,
21
- gridProps,
22
- style,
23
- id,
24
- className
25
- }) {
26
- const [item, setItem] = useState(void 0);
27
- const fullScreen = useMediaQuery("(max-width: 600px), (max-height: 600px)");
28
- const autoGridRef = useRef(null);
29
- const { headerRenderer: customFormHeaderRenderer, ...autoFormProps } = formProps ?? {};
30
- const formHeaderRenderer = customFormHeaderRenderer ?? defaultFormHeaderRenderer;
31
- const autoCrudId = useId();
32
- function refreshGrid() {
33
- autoGridRef.current?.refresh();
34
- }
35
- function handleCancel() {
36
- setItem(void 0);
37
- }
38
- const formHeader = item && item !== emptyItem ? formHeaderRenderer(item, !item) : formHeaderRenderer(null, !item);
39
- const mainSection = /* @__PURE__ */ jsxs("div", { className: "auto-crud-main", children: [
40
- /* @__PURE__ */ jsx(
41
- AutoGrid,
42
- {
43
- ...gridProps,
44
- service,
45
- model,
46
- itemIdProperty,
47
- selectedItems: item && item !== emptyItem ? [item] : [],
48
- onActiveItemChanged: (e) => {
49
- const activeItem = e.detail.value;
50
- setItem(activeItem ?? void 0);
51
- },
52
- ref: autoGridRef,
53
- "aria-controls": autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`
54
- }
55
- ),
56
- /* @__PURE__ */ jsx("div", { className: "auto-crud-toolbar", children: /* @__PURE__ */ jsx(Button, { theme: "primary", onClick: () => setItem(emptyItem), children: "+ New" }) })
57
- ] });
58
- const autoForm = /* @__PURE__ */ jsx(
59
- AutoForm,
60
- {
61
- id: autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`,
62
- deleteButtonVisible: true,
63
- ...autoFormProps,
64
- disabled: !item,
65
- service,
66
- model,
67
- itemIdProperty,
68
- item,
69
- onSubmitSuccess: ({ item: submittedItem }) => {
70
- if (fullScreen) {
71
- setItem(void 0);
72
- } else {
73
- setItem(submittedItem);
74
- }
75
- refreshGrid();
76
- },
77
- onDeleteSuccess: () => {
78
- setItem(void 0);
79
- refreshGrid();
80
- }
16
+ export function AutoCrud({ service, model, itemIdProperty, noNewButton, formProps, gridProps, style, id, className, }) {
17
+ const [item, setItem] = useState(undefined);
18
+ const fullScreen = useMediaQuery('(max-width: 600px), (max-height: 600px)');
19
+ const autoGridRef = useRef(null);
20
+ const { headerRenderer: customFormHeaderRenderer, ...autoFormProps } = formProps ?? {};
21
+ const formHeaderRenderer = customFormHeaderRenderer ?? defaultFormHeaderRenderer;
22
+ const autoCrudId = useId();
23
+ function refreshGrid() {
24
+ autoGridRef.current?.refresh();
81
25
  }
82
- );
83
- return /* @__PURE__ */ jsx("div", { className: `auto-crud ${className ?? ""}`, id, style, children: fullScreen ? /* @__PURE__ */ jsxs(Fragment, { children: [
84
- mainSection,
85
- /* @__PURE__ */ jsx(AutoCrudDialog, { opened: !!item, header: formHeader, onClose: handleCancel, children: autoForm })
86
- ] }) : /* @__PURE__ */ jsxs(SplitLayout, { theme: "small", children: [
87
- mainSection,
88
- /* @__PURE__ */ jsxs("div", { className: "auto-crud-form", children: [
89
- /* @__PURE__ */ jsx("div", { className: "auto-crud-form-header", children: formHeader }),
90
- autoForm
91
- ] })
92
- ] }) });
26
+ function handleCancel() {
27
+ setItem(undefined);
28
+ }
29
+ const formHeader = item && item !== emptyItem ? formHeaderRenderer(item, !item) : formHeaderRenderer(null, !item);
30
+ const mainSection = (_jsxs("div", { className: "auto-crud-main", children: [_jsx(AutoGrid, { ...gridProps, service: service, model: model, itemIdProperty: itemIdProperty, selectedItems: item && item !== emptyItem ? [item] : [], onActiveItemChanged: (e) => {
31
+ const activeItem = e.detail.value;
32
+ setItem(activeItem ?? undefined);
33
+ }, ref: autoGridRef, "aria-controls": autoFormProps.id ?? `auto-form-${id ?? autoCrudId}` }), !noNewButton && (_jsx("div", { className: "auto-crud-toolbar", children: _jsx(Button, { theme: "primary", onClick: () => setItem(emptyItem), children: "+ New" }) }))] }));
34
+ const autoForm = (_jsx(AutoForm, { id: autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`, deleteButtonVisible: true, ...autoFormProps, disabled: !item, service: service, model: model, itemIdProperty: itemIdProperty, item: item, onSubmitSuccess: ({ item: submittedItem }) => {
35
+ if (fullScreen) {
36
+ setItem(undefined);
37
+ }
38
+ else {
39
+ setItem(submittedItem);
40
+ }
41
+ refreshGrid();
42
+ }, onDeleteSuccess: () => {
43
+ setItem(undefined);
44
+ refreshGrid();
45
+ } }));
46
+ if (!noNewButton || (item && item !== emptyItem)) {
47
+ return (_jsx("div", { className: `auto-crud ${className ?? ''}`, id: id, style: style, children: fullScreen ? (_jsxs(_Fragment, { children: [mainSection, _jsx(AutoCrudDialog, { opened: !!item, header: formHeader, onClose: handleCancel, children: autoForm })] })) : (_jsxs(SplitLayout, { theme: "small", children: [mainSection, _jsxs("div", { className: "auto-crud-form", children: [_jsx("div", { className: "auto-crud-form-header", children: formHeader }), autoForm] })] })) }));
48
+ }
49
+ return mainSection;
93
50
  }
94
- export {
95
- AutoCrud
96
- };
97
- //# sourceMappingURL=autocrud.js.map
51
+ //# sourceMappingURL=autocrud.js.map
package/autocrud.js.map CHANGED
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/autocrud.tsx"],
4
- "sourcesContent": ["import type { AbstractModel, DetachedModelConstructor, Value } from '@vaadin/hilla-lit-form';\nimport { Button } from '@vaadin/react-components/Button.js';\nimport { SplitLayout } from '@vaadin/react-components/SplitLayout.js';\nimport { type JSX, useId, useRef, useState } from 'react';\nimport { AutoCrudDialog } from './autocrud-dialog.js';\nimport css from './autocrud.obj.js';\nimport { type AutoFormProps, emptyItem, AutoForm } from './autoform.js';\nimport { type AutoGridProps, AutoGrid, type AutoGridRef } from './autogrid.js';\nimport type { CrudService } from './crud.js';\nimport { useMediaQuery } from './media-query.js';\nimport { type ComponentStyleProps, registerStylesheet } from './util.js';\n\nregisterStylesheet(css);\n\nexport type AutoCrudFormHeaderRenderer<TItem> = (\n editedItem: TItem | null,\n disabled: boolean,\n) => JSX.Element | null | undefined;\n\nexport type AutoCrudFormProps<TModel extends AbstractModel> = Omit<\n Partial<AutoFormProps<TModel>>,\n 'disabled' | 'item' | 'model' | 'onDeleteSuccess' | 'onSubmitSuccess' | 'service'\n> &\n Readonly<{\n /**\n * A custom renderer function to create the header for the form. The\n * function receives the edited item as the first parameter, and a boolean\n * indicating whether the form is disabled as the second parameter. The\n * edited item is `null` when creating a new item.\n *\n * By default, the header shows \"New item\" when creating a new item, and\n * \"Edit item\" when editing an existing item.\n */\n headerRenderer?: AutoCrudFormHeaderRenderer<Value<TModel>>;\n }>;\n\nexport type AutoCrudGridProps<TItem> = Omit<\n Partial<AutoGridProps<TItem>>,\n 'model' | 'onActiveItemChanged' | 'selectedItems' | 'service'\n>;\n\nexport type AutoCrudProps<TModel extends AbstractModel = AbstractModel> = ComponentStyleProps &\n Readonly<{\n /**\n * The service to use for fetching the data, as well saving and deleting\n * items. This must be a TypeScript service that has been generated by Hilla\n * from a backend Java service that implements the\n * `com.vaadin.hilla.crud.CrudService` interface.\n */\n service: CrudService<Value<TModel>>;\n /**\n * The entity model to use for the CRUD. This determines which columns to\n * show in the grid, and which fields to show in the form. This must be a\n * Typescript model class that has been generated by Hilla from a backend\n * Java class. The model must match with the type of the items returned by\n * the service. For example, a `PersonModel` can be used with a service that\n * returns `Person` instances.\n *\n * By default, the grid shows columns for all properties of the model which\n * have a type that is supported. Use the `gridProps.visibleColumns` option\n * to customize which columns to show and in which order.\n *\n * By default, the form shows fields for all properties of the model which\n * have a type that is supported. Use the `formProps.visibleFields`\n * option to customize which fields to show and in which order.\n */\n model: DetachedModelConstructor<TModel>;\n /**\n * The property to use to detect an item's ID. The item ID is required for\n * deleting items via the `CrudService.delete` method as well as keeping the\n * selection state after reloading the grid.\n *\n * By default, the component uses the property annotated with\n * `jakarta.persistence.Id`, or a property named `id`, in that order.\n * This option can be used to override the default behavior, or define the ID\n * property in case a class doesn't have a property matching the defaults.\n */\n itemIdProperty?: string;\n /**\n * Props to pass to the form. See the `AutoForm` component for details.\n */\n formProps?: AutoCrudFormProps<TModel>;\n /**\n * Props to pass to the grid. See the `AutoGrid` component for details.\n */\n gridProps?: AutoCrudGridProps<Value<TModel>>;\n }>;\n\nfunction defaultFormHeaderRenderer<TItem>(editedItem: TItem | null, disabled: boolean): JSX.Element | null | undefined {\n const style = { color: disabled ? 'var(--lumo-disabled-text-color)' : 'var(--lumo-text-color)' };\n return editedItem ? <h3 style={style}>Edit item</h3> : <h3 style={style}>New item</h3>;\n}\n\n/**\n * Auto CRUD is a component that provides CRUD (create, read, update, delete)\n * functionality based on a Java backend service. It automatically generates a\n * grid that shows data from the service, and a form for creating, updating and\n * deleting items.\n *\n * Example usage:\n * ```tsx\n * import { AutoCrud } from '@hilla/react-crud';\n * import PersonService from 'Frontend/generated/endpoints';\n * import PersonModel from 'Frontend/generated/com/example/application/Person';\n *\n * <AutoCrud service={PersonService} model={PersonModel} />\n * ```\n */\nexport function AutoCrud<TModel extends AbstractModel>({\n service,\n model,\n itemIdProperty,\n formProps,\n gridProps,\n style,\n id,\n className,\n}: AutoCrudProps<TModel>): JSX.Element {\n const [item, setItem] = useState<Value<TModel> | typeof emptyItem | undefined>(undefined);\n const fullScreen = useMediaQuery('(max-width: 600px), (max-height: 600px)');\n const autoGridRef = useRef<AutoGridRef>(null);\n const { headerRenderer: customFormHeaderRenderer, ...autoFormProps } = formProps ?? {};\n const formHeaderRenderer: AutoCrudFormHeaderRenderer<Value<TModel>> =\n customFormHeaderRenderer ?? defaultFormHeaderRenderer;\n\n const autoCrudId = useId();\n\n function refreshGrid() {\n autoGridRef.current?.refresh();\n }\n\n function handleCancel() {\n setItem(undefined);\n }\n\n const formHeader = item && item !== emptyItem ? formHeaderRenderer(item, !item) : formHeaderRenderer(null, !item);\n\n const mainSection = (\n <div className=\"auto-crud-main\">\n <AutoGrid\n {...gridProps}\n service={service}\n model={model as DetachedModelConstructor<AbstractModel<Value<TModel>>>}\n itemIdProperty={itemIdProperty}\n selectedItems={item && item !== emptyItem ? [item] : []}\n onActiveItemChanged={(e) => {\n const activeItem = e.detail.value;\n setItem(activeItem ?? undefined);\n }}\n ref={autoGridRef}\n aria-controls={autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`}\n ></AutoGrid>\n <div className=\"auto-crud-toolbar\">\n <Button theme=\"primary\" onClick={() => setItem(emptyItem)}>\n + New\n </Button>\n </div>\n </div>\n );\n\n const autoForm = (\n <AutoForm\n id={autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`}\n deleteButtonVisible={true}\n {...autoFormProps}\n disabled={!item}\n service={service}\n model={model}\n itemIdProperty={itemIdProperty}\n item={item}\n onSubmitSuccess={({ item: submittedItem }) => {\n if (fullScreen) {\n setItem(undefined);\n } else {\n setItem(submittedItem);\n }\n refreshGrid();\n }}\n onDeleteSuccess={() => {\n setItem(undefined);\n refreshGrid();\n }}\n />\n );\n\n return (\n <div className={`auto-crud ${className ?? ''}`} id={id} style={style}>\n {fullScreen ? (\n <>\n {mainSection}\n <AutoCrudDialog opened={!!item} header={formHeader} onClose={handleCancel}>\n {autoForm}\n </AutoCrudDialog>\n </>\n ) : (\n <SplitLayout theme=\"small\">\n {mainSection}\n <div className=\"auto-crud-form\">\n <div className=\"auto-crud-form-header\">{formHeader}</div>\n {autoForm}\n </div>\n </SplitLayout>\n )}\n </div>\n );\n}\n"],
5
- "mappings": "AA0FsB,SAkGd,UAlGc,KAgDlB,YAhDkB;AAzFtB,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAC5B,SAAmB,OAAO,QAAQ,gBAAgB;AAClD,SAAS,sBAAsB;AAC/B,OAAO,SAAS;AAChB,SAA6B,WAAW,gBAAgB;AACxD,SAA6B,gBAAkC;AAE/D,SAAS,qBAAqB;AAC9B,SAAmC,0BAA0B;AAE7D,mBAAmB,GAAG;AA4EtB,SAAS,0BAAiC,YAA0B,UAAmD;AACrH,QAAM,QAAQ,EAAE,OAAO,WAAW,oCAAoC,yBAAyB;AAC/F,SAAO,aAAa,oBAAC,QAAG,OAAc,uBAAS,IAAQ,oBAAC,QAAG,OAAc,sBAAQ;AACnF;AAiBO,SAAS,SAAuC;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuC;AACrC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAuD,MAAS;AACxF,QAAM,aAAa,cAAc,yCAAyC;AAC1E,QAAM,cAAc,OAAoB,IAAI;AAC5C,QAAM,EAAE,gBAAgB,0BAA0B,GAAG,cAAc,IAAI,aAAa,CAAC;AACrF,QAAM,qBACJ,4BAA4B;AAE9B,QAAM,aAAa,MAAM;AAEzB,WAAS,cAAc;AACrB,gBAAY,SAAS,QAAQ;AAAA,EAC/B;AAEA,WAAS,eAAe;AACtB,YAAQ,MAAS;AAAA,EACnB;AAEA,QAAM,aAAa,QAAQ,SAAS,YAAY,mBAAmB,MAAM,CAAC,IAAI,IAAI,mBAAmB,MAAM,CAAC,IAAI;AAEhH,QAAM,cACJ,qBAAC,SAAI,WAAU,kBACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe,QAAQ,SAAS,YAAY,CAAC,IAAI,IAAI,CAAC;AAAA,QACtD,qBAAqB,CAAC,MAAM;AAC1B,gBAAM,aAAa,EAAE,OAAO;AAC5B,kBAAQ,cAAc,MAAS;AAAA,QACjC;AAAA,QACA,KAAK;AAAA,QACL,iBAAe,cAAc,MAAM,aAAa,MAAM,UAAU;AAAA;AAAA,IACjE;AAAA,IACD,oBAAC,SAAI,WAAU,qBACb,8BAAC,UAAO,OAAM,WAAU,SAAS,MAAM,QAAQ,SAAS,GAAG,mBAE3D,GACF;AAAA,KACF;AAGF,QAAM,WACJ;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,cAAc,MAAM,aAAa,MAAM,UAAU;AAAA,MACrD,qBAAqB;AAAA,MACpB,GAAG;AAAA,MACJ,UAAU,CAAC;AAAA,MACX;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,iBAAiB,CAAC,EAAE,MAAM,cAAc,MAAM;AAC5C,YAAI,YAAY;AACd,kBAAQ,MAAS;AAAA,QACnB,OAAO;AACL,kBAAQ,aAAa;AAAA,QACvB;AACA,oBAAY;AAAA,MACd;AAAA,MACA,iBAAiB,MAAM;AACrB,gBAAQ,MAAS;AACjB,oBAAY;AAAA,MACd;AAAA;AAAA,EACF;AAGF,SACE,oBAAC,SAAI,WAAW,aAAa,aAAa,EAAE,IAAI,IAAQ,OACrD,uBACC,iCACG;AAAA;AAAA,IACD,oBAAC,kBAAe,QAAQ,CAAC,CAAC,MAAM,QAAQ,YAAY,SAAS,cAC1D,oBACH;AAAA,KACF,IAEA,qBAAC,eAAY,OAAM,SAChB;AAAA;AAAA,IACD,qBAAC,SAAI,WAAU,kBACb;AAAA,0BAAC,SAAI,WAAU,yBAAyB,sBAAW;AAAA,MAClD;AAAA,OACH;AAAA,KACF,GAEJ;AAEJ;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"autocrud.js","sourceRoot":"","sources":["src/autocrud.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { AbstractModel, DetachedModelConstructor, Value } from '@vaadin/hilla-lit-form';\nimport { Button } from '@vaadin/react-components/Button.js';\nimport { SplitLayout } from '@vaadin/react-components/SplitLayout.js';\nimport { type JSX, useId, useRef, useState } from 'react';\nimport { AutoCrudDialog } from './autocrud-dialog.js';\nimport css from './autocrud.obj.js';\nimport { type AutoFormProps, emptyItem, AutoForm } from './autoform.js';\nimport { type AutoGridProps, AutoGrid, type AutoGridRef } from './autogrid.js';\nimport type { CrudService } from './crud.js';\nimport { useMediaQuery } from './media-query.js';\nimport { type ComponentStyleProps, registerStylesheet } from './util.js';\n\nregisterStylesheet(css);\n\nexport type AutoCrudFormHeaderRenderer<TItem> = (\n editedItem: TItem | null,\n disabled: boolean,\n) => JSX.Element | null | undefined;\n\nexport type AutoCrudFormProps<TModel extends AbstractModel> = Omit<\n Partial<AutoFormProps<TModel>>,\n 'disabled' | 'item' | 'model' | 'onDeleteSuccess' | 'onSubmitSuccess' | 'service'\n> &\n Readonly<{\n /**\n * A custom renderer function to create the header for the form. The\n * function receives the edited item as the first parameter, and a boolean\n * indicating whether the form is disabled as the second parameter. The\n * edited item is `null` when creating a new item.\n *\n * By default, the header shows \"New item\" when creating a new item, and\n * \"Edit item\" when editing an existing item.\n */\n headerRenderer?: AutoCrudFormHeaderRenderer<Value<TModel>>;\n }>;\n\nexport type AutoCrudGridProps<TItem> = Omit<\n Partial<AutoGridProps<TItem>>,\n 'model' | 'onActiveItemChanged' | 'selectedItems' | 'service'\n>;\n\nexport type AutoCrudProps<TModel extends AbstractModel = AbstractModel> = ComponentStyleProps &\n Readonly<{\n /**\n * The service to use for fetching the data, as well saving and deleting\n * items. This must be a TypeScript service that has been generated by Hilla\n * from a backend Java service that implements the\n * `com.vaadin.hilla.crud.CrudService` interface.\n */\n service: CrudService<Value<TModel>>;\n /**\n * The entity model to use for the CRUD. This determines which columns to\n * show in the grid, and which fields to show in the form. This must be a\n * Typescript model class that has been generated by Hilla from a backend\n * Java class. The model must match with the type of the items returned by\n * the service. For example, a `PersonModel` can be used with a service that\n * returns `Person` instances.\n *\n * By default, the grid shows columns for all properties of the model which\n * have a type that is supported. Use the `gridProps.visibleColumns` option\n * to customize which columns to show and in which order.\n *\n * By default, the form shows fields for all properties of the model which\n * have a type that is supported. Use the `formProps.visibleFields`\n * option to customize which fields to show and in which order.\n */\n model: DetachedModelConstructor<TModel>;\n /**\n * The property to use to detect an item's ID. The item ID is required for\n * deleting items via the `CrudService.delete` method as well as keeping the\n * selection state after reloading the grid.\n *\n * By default, the component uses the property annotated with\n * `jakarta.persistence.Id`, or a property named `id`, in that order.\n * This option can be used to override the default behavior, or define the ID\n * property in case a class doesn't have a property matching the defaults.\n */\n itemIdProperty?: string;\n /**\n * Determines whether to hide the \"New\" button in the toolbar.\n *\n * NOTE: This setting only hides the button; it does not prevent new items\n * from being sent to the service. Ensure your backend Java service is\n * properly secured to prevent unauthorized creation of new items.\n *\n * @defaultValue `false` meaning the button will be shown.\n */\n noNewButton?: boolean;\n /**\n * Props to pass to the form. See the `AutoForm` component for details.\n */\n formProps?: AutoCrudFormProps<TModel>;\n /**\n * Props to pass to the grid. See the `AutoGrid` component for details.\n */\n gridProps?: AutoCrudGridProps<Value<TModel>>;\n }>;\n\nfunction defaultFormHeaderRenderer<TItem>(editedItem: TItem | null, disabled: boolean): JSX.Element | null | undefined {\n const style = { color: disabled ? 'var(--lumo-disabled-text-color)' : 'var(--lumo-text-color)' };\n return editedItem ? <h3 style={style}>Edit item</h3> : <h3 style={style}>New item</h3>;\n}\n\n/**\n * Auto CRUD is a component that provides CRUD (create, read, update, delete)\n * functionality based on a Java backend service. It automatically generates a\n * grid that shows data from the service, and a form for creating, updating and\n * deleting items.\n *\n * Example usage:\n * ```tsx\n * import { AutoCrud } from '@hilla/react-crud';\n * import PersonService from 'Frontend/generated/endpoints';\n * import PersonModel from 'Frontend/generated/com/example/application/Person';\n *\n * <AutoCrud service={PersonService} model={PersonModel} />\n * ```\n */\nexport function AutoCrud<TModel extends AbstractModel>({\n service,\n model,\n itemIdProperty,\n noNewButton,\n formProps,\n gridProps,\n style,\n id,\n className,\n}: AutoCrudProps<TModel>): JSX.Element {\n const [item, setItem] = useState<Value<TModel> | typeof emptyItem | undefined>(undefined);\n const fullScreen = useMediaQuery('(max-width: 600px), (max-height: 600px)');\n const autoGridRef = useRef<AutoGridRef>(null);\n const { headerRenderer: customFormHeaderRenderer, ...autoFormProps } = formProps ?? {};\n const formHeaderRenderer: AutoCrudFormHeaderRenderer<Value<TModel>> =\n customFormHeaderRenderer ?? defaultFormHeaderRenderer;\n\n const autoCrudId = useId();\n\n function refreshGrid() {\n autoGridRef.current?.refresh();\n }\n\n function handleCancel() {\n setItem(undefined);\n }\n\n const formHeader = item && item !== emptyItem ? formHeaderRenderer(item, !item) : formHeaderRenderer(null, !item);\n\n const mainSection = (\n <div className=\"auto-crud-main\">\n <AutoGrid\n {...gridProps}\n service={service}\n model={model as DetachedModelConstructor<AbstractModel<Value<TModel>>>}\n itemIdProperty={itemIdProperty}\n selectedItems={item && item !== emptyItem ? [item] : []}\n onActiveItemChanged={(e) => {\n const activeItem = e.detail.value;\n setItem(activeItem ?? undefined);\n }}\n ref={autoGridRef}\n aria-controls={autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`}\n ></AutoGrid>\n {/* As the toolbar only contains the \"New\" button at the moment, and as an empty toolbar\n renders as a half-height bar, let's hide it completely when the button is hidden */}\n {!noNewButton && (\n <div className=\"auto-crud-toolbar\">\n <Button theme=\"primary\" onClick={() => setItem(emptyItem)}>\n + New\n </Button>\n </div>\n )}\n </div>\n );\n\n const autoForm = (\n <AutoForm\n id={autoFormProps.id ?? `auto-form-${id ?? autoCrudId}`}\n deleteButtonVisible={true}\n {...autoFormProps}\n disabled={!item}\n service={service}\n model={model}\n itemIdProperty={itemIdProperty}\n item={item}\n onSubmitSuccess={({ item: submittedItem }) => {\n if (fullScreen) {\n setItem(undefined);\n } else {\n setItem(submittedItem);\n }\n refreshGrid();\n }}\n onDeleteSuccess={() => {\n setItem(undefined);\n refreshGrid();\n }}\n />\n );\n\n // If the \"New\" button is visible, the form is always shown.\n // Otherwise, the form is only shown when an item is being edited.\n if (!noNewButton || (item && item !== emptyItem)) {\n return (\n <div className={`auto-crud ${className ?? ''}`} id={id} style={style}>\n {fullScreen ? (\n <>\n {mainSection}\n <AutoCrudDialog opened={!!item} header={formHeader} onClose={handleCancel}>\n {autoForm}\n </AutoCrudDialog>\n </>\n ) : (\n <SplitLayout theme=\"small\">\n {mainSection}\n <div className=\"auto-crud-form\">\n <div className=\"auto-crud-form-header\">{formHeader}</div>\n {autoForm}\n </div>\n </SplitLayout>\n )}\n </div>\n );\n }\n\n return mainSection;\n}\n"]}
package/autocrud.obj.js CHANGED
@@ -1,6 +1 @@
1
- const css = new CSSStyleSheet();
2
- css.replaceSync(`.auto-crud{border:1px solid var(--lumo-contrast-20pct);display:flex;overflow:hidden}.auto-crud vaadin-split-layout{flex:1 1 100%}.auto-crud vaadin-split-layout::part(splitter){border-left:1px solid var(--lumo-contrast-20pct);border-top:1px solid var(--lumo-contrast-20pct)}.auto-crud-main{display:flex;flex:1 1 100%;flex-direction:column;min-width:200px}.auto-crud-main vaadin-grid{border:none}.auto-crud-toolbar{align-items:baseline;background-color:var(--lumo-contrast-5pct);border-top:1px solid var(--lumo-contrast-10pct);display:flex;flex-shrink:0;justify-content:flex-end;padding:var(--lumo-space-s) var(--lumo-space-m)}.auto-crud-form{align-items:stretch;display:flex;flex-direction:column;min-width:300px;width:40%}.auto-crud .auto-crud-form:before{box-shadow:var(--lumo-box-shadow-s);content:"";height:100%;pointer-events:none;position:absolute;width:100%;z-index:1}.auto-crud-form-header{padding:var(--lumo-space-m) var(--lumo-space-m) var(--lumo-space-s) var(--lumo-space-m)}.auto-crud .auto-form,.auto-crud-dialog .auto-form{align-items:stretch;display:flex;flex:1 1 0;flex-direction:column}.auto-crud .auto-form-fields,.auto-crud-dialog .auto-form-fields{flex:1 1 0;min-height:0;overflow-y:auto;padding:0 var(--lumo-space-m)}.auto-crud .auto-form-toolbar,.auto-crud-dialog .auto-form-toolbar{background-color:var(--lumo-contrast-5pct);border-top:1px solid var(--lumo-contrast-10pct);flex:0 0 auto;padding:var(--lumo-space-s) var(--lumo-space-m)}.auto-crud-dialog{bottom:0;left:0;right:0;top:0}.auto-crud-dialog::part(overlay){border-radius:0;height:100%;width:100%}.auto-crud-dialog::part(content){padding:0}.auto-crud-dialog .auto-crud-dialog-header{align-items:center;display:flex;justify-content:space-between;width:100%}.auto-crud-dialog .auto-form{height:100%;width:100%}`);
3
- export {
4
- css as default
5
- };
6
- //# sourceMappingURL=autocrud.obj.js.map
1
+ const css = new CSSStyleSheet();css.replaceSync(`.auto-crud{border:1px solid var(--lumo-contrast-20pct);display:flex;overflow:hidden}.auto-crud vaadin-split-layout{flex:1 1 100%}.auto-crud vaadin-split-layout::part(splitter){border-left:1px solid var(--lumo-contrast-20pct);border-top:1px solid var(--lumo-contrast-20pct)}.auto-crud-main{display:flex;flex:1 1 100%;flex-direction:column;min-width:200px}.auto-crud-main vaadin-grid{border:none}.auto-crud-toolbar{align-items:baseline;background-color:var(--lumo-contrast-5pct);border-top:1px solid var(--lumo-contrast-10pct);display:flex;flex-shrink:0;justify-content:flex-end;padding:var(--lumo-space-s) var(--lumo-space-m)}.auto-crud-form{align-items:stretch;display:flex;flex-direction:column;min-width:300px;width:40%}.auto-crud .auto-crud-form:before{box-shadow:var(--lumo-box-shadow-s);content:"";height:100%;pointer-events:none;position:absolute;width:100%;z-index:1}.auto-crud-form-header{padding:var(--lumo-space-m) var(--lumo-space-m) var(--lumo-space-s) var(--lumo-space-m)}.auto-crud .auto-form,.auto-crud-dialog .auto-form{align-items:stretch;display:flex;flex:1 1 0;flex-direction:column}.auto-crud .auto-form-fields,.auto-crud-dialog .auto-form-fields{flex:1 1 0;min-height:0;overflow-y:auto;padding:0 var(--lumo-space-m)}.auto-crud .auto-form-toolbar,.auto-crud-dialog .auto-form-toolbar{background-color:var(--lumo-contrast-5pct);border-top:1px solid var(--lumo-contrast-10pct);flex:0 0 auto;padding:var(--lumo-space-s) var(--lumo-space-m)}.auto-crud-dialog{bottom:0;left:0;right:0;top:0}.auto-crud-dialog::part(overlay){border-radius:0;height:100%;width:100%}.auto-crud-dialog::part(content){padding:0}.auto-crud-dialog .auto-crud-dialog-header{align-items:center;display:flex;justify-content:space-between;width:100%}.auto-crud-dialog .auto-form{height:100%;width:100%}`);export default css;
@@ -1,4 +1,3 @@
1
1
  import { AutoForm as _AutoForm } from './autoform.js';
2
2
  export * from './autoform.js';
3
3
  export declare const AutoForm: typeof _AutoForm;
4
- //# sourceMappingURL=autoform-feature.d.ts.map
@@ -1,8 +1,5 @@
1
- import { AutoForm as _AutoForm } from "./autoform.js";
2
- import { featureRegistration } from "./util";
3
- export * from "./autoform.js";
4
- const AutoForm = featureRegistration(_AutoForm, "AutoForm");
5
- export {
6
- AutoForm
7
- };
8
- //# sourceMappingURL=autoform-feature.js.map
1
+ import { AutoForm as _AutoForm } from './autoform.js';
2
+ import { featureRegistration } from './util';
3
+ export * from './autoform.js';
4
+ export const AutoForm = featureRegistration(_AutoForm, 'AutoForm');
5
+ //# sourceMappingURL=autoform-feature.js.map
@@ -1,7 +1 @@
1
- {
2
- "version": 3,
3
- "sources": ["src/autoform-feature.ts"],
4
- "sourcesContent": ["/* eslint-disable import/export */\nimport { AutoForm as _AutoForm } from './autoform.js';\nimport { featureRegistration } from './util';\n\nexport * from './autoform.js';\n\nexport const AutoForm: typeof _AutoForm = featureRegistration(_AutoForm, 'AutoForm');\n"],
5
- "mappings": "AACA,SAAS,YAAY,iBAAiB;AACtC,SAAS,2BAA2B;AAEpC,cAAc;AAEP,MAAM,WAA6B,oBAAoB,WAAW,UAAU;",
6
- "names": []
7
- }
1
+ {"version":3,"file":"autoform-feature.js","sourceRoot":"","sources":["src/autoform-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAE7C,cAAc,eAAe,CAAC;AAE9B,MAAM,CAAC,MAAM,QAAQ,GAAqB,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC","sourcesContent":["/* eslint-disable import/export */\nimport { AutoForm as _AutoForm } from './autoform.js';\nimport { featureRegistration } from './util';\n\nexport * from './autoform.js';\n\nexport const AutoForm: typeof _AutoForm = featureRegistration(_AutoForm, 'AutoForm');\n"]}
@@ -13,110 +13,20 @@ type CustomFormFieldProps = FieldDirectiveResult & Readonly<{
13
13
  disabled?: boolean;
14
14
  }>;
15
15
  export type FieldOptions = Readonly<{
16
- /**
17
- * The id to apply to the field.
18
- */
19
16
  id?: string;
20
- /**
21
- * The class names to add to the field.
22
- */
23
17
  className?: string;
24
- /**
25
- * The style to apply to the field.
26
- */
27
18
  style?: CSSProperties;
28
- /**
29
- * The label to show for the field. If not specified, a human-readable label
30
- * is generated from the property name.
31
- */
32
19
  label?: string;
33
- /**
34
- * The placeholder to when the field is empty.
35
- *
36
- * Note that some field types, such as checkbox, do not support a placeholder.
37
- */
38
20
  placeholder?: string;
39
- /**
40
- * The helper text to display below the field.
41
- *
42
- * Note that some field types, such as checkbox, do not support a helper text.
43
- */
44
21
  helperText?: string;
45
- /**
46
- * The number of columns to span. This value is passed to the underlying
47
- * FormLayout, unless a custom layout is used. In that case, the value is
48
- * ignored.
49
- */
50
22
  colspan?: number;
51
- /**
52
- * Whether the field should be disabled.
53
- */
54
23
  disabled?: boolean;
55
- /**
56
- * Whether the field should be readonly.
57
- */
58
24
  readonly?: boolean;
59
- /**
60
- * The element to render for the field. This allows customizing field props
61
- * that are not supported by the field options, or to render a different field
62
- * component. Other field options are automatically applied to the element,
63
- * and the element is automatically bound to the form. If not specified, a
64
- * default field element is rendered based on the property type.
65
- *
66
- * The element must be a field component, such as TextField, TextArea,
67
- * NumberField, etc., otherwise form binding will not work. For more
68
- * sophisticated customizations, use the `renderer` option.
69
- *
70
- * If the field options also specify a renderer function, then the element is
71
- * ignored.
72
- *
73
- * Example enabling the clear button for a text field:
74
- * ```tsx
75
- * {
76
- * element: <TextField clearButtonVisible />
77
- * }
78
- * ```
79
- *
80
- * Example rendering a text area instead of a text field:
81
- * ```tsx
82
- * {
83
- * element: <TextArea />
84
- * }
85
- * ```
86
- */
87
25
  element?: JSX.Element;
88
- /**
89
- * Allows to specify a custom renderer for the field, for example to render a
90
- * custom type of field or apply an additional layout around the field. The
91
- * renderer receives field props that must be applied to the custom field
92
- * component in order to connect it to the form.
93
- *
94
- * In order to customize one of the default fields, or render a different type
95
- * of field, consider using the `element` option instead.
96
- *
97
- * Example:
98
- * ```tsx
99
- * {
100
- * renderer: ({ field }) => (
101
- * <div>
102
- * <TextArea {...field} />
103
- * <p>Number of words: {calculateNumberOfWords()}</p>
104
- * </div>
105
- * )
106
- * }
107
- * ```
108
- */
109
26
  renderer?(props: {
110
27
  field: CustomFormFieldProps;
111
28
  }): JSX.Element;
112
- /**
113
- * Validators to apply to the field. The validators are added to the form
114
- * when the field is rendered.
115
- * UseMemo is recommended for the validators, so that they are not recreated
116
- * on every render.
117
- */
118
29
  validators?: Validator[];
119
30
  }>;
120
31
  export declare function AutoFormField(props: AutoFormFieldProps): JSX.Element | null;
121
32
  export {};
122
- //# sourceMappingURL=autoform-field.d.ts.map