@webiny/app-headless-cms-common 0.0.0-unstable.eb196ccd2f → 0.0.0-unstable.f6dc066313

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 (107) hide show
  1. package/Fields/ErrorBoundary.d.ts +1 -1
  2. package/Fields/ErrorBoundary.js +1 -1
  3. package/Fields/ErrorBoundary.js.map +1 -1
  4. package/Fields/FieldElement.d.ts +2 -2
  5. package/Fields/FieldElement.js +15 -9
  6. package/Fields/FieldElement.js.map +1 -1
  7. package/Fields/FieldElementError.js +1 -2
  8. package/Fields/FieldElementError.js.map +1 -1
  9. package/Fields/FieldRulesProvider.d.ts +9 -0
  10. package/Fields/FieldRulesProvider.js +20 -0
  11. package/Fields/FieldRulesProvider.js.map +1 -0
  12. package/Fields/Fields.d.ts +1 -1
  13. package/Fields/Fields.js +137 -16
  14. package/Fields/Fields.js.map +1 -1
  15. package/Fields/LayoutDescriptorCell.d.ts +12 -0
  16. package/Fields/LayoutDescriptorCell.js +47 -0
  17. package/Fields/LayoutDescriptorCell.js.map +1 -0
  18. package/Fields/evaluateExpression.d.ts +23 -0
  19. package/Fields/evaluateExpression.js +102 -0
  20. package/Fields/evaluateExpression.js.map +1 -0
  21. package/Fields/fieldOptions.d.ts +36 -0
  22. package/Fields/fieldOptions.js +113 -0
  23. package/Fields/fieldOptions.js.map +1 -0
  24. package/Fields/index.d.ts +8 -3
  25. package/Fields/index.js +8 -3
  26. package/Fields/index.js.map +1 -1
  27. package/Fields/layoutFieldRenderers/AlertFieldRenderer.d.ts +7 -0
  28. package/Fields/layoutFieldRenderers/AlertFieldRenderer.js +13 -0
  29. package/Fields/layoutFieldRenderers/AlertFieldRenderer.js.map +1 -0
  30. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.d.ts +7 -0
  31. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js +18 -0
  32. package/Fields/layoutFieldRenderers/SeparatorFieldRenderer.js.map +1 -0
  33. package/Fields/layoutFieldRenderers/TabsFieldRenderer.d.ts +12 -0
  34. package/Fields/layoutFieldRenderers/TabsFieldRenderer.js +72 -0
  35. package/Fields/layoutFieldRenderers/TabsFieldRenderer.js.map +1 -0
  36. package/Fields/operatorOptions.d.ts +10 -0
  37. package/Fields/operatorOptions.js +92 -0
  38. package/Fields/operatorOptions.js.map +1 -0
  39. package/Fields/useBind.d.ts +2 -1
  40. package/Fields/useBind.js +12 -8
  41. package/Fields/useBind.js.map +1 -1
  42. package/Fields/useFieldRules.d.ts +32 -0
  43. package/Fields/useFieldRules.js +153 -0
  44. package/Fields/useFieldRules.js.map +1 -0
  45. package/Fields/useRenderPlugins.d.ts +2 -1
  46. package/Fields/useRenderPlugins.js.map +1 -1
  47. package/ModelFieldProvider/CanEditField.d.ts +5 -0
  48. package/ModelFieldProvider/CanEditField.js +13 -0
  49. package/ModelFieldProvider/CanEditField.js.map +1 -0
  50. package/ModelFieldProvider/ModelFieldContext.d.ts +16 -13
  51. package/ModelFieldProvider/ModelFieldContext.js.map +1 -1
  52. package/ModelFieldProvider/index.d.ts +3 -2
  53. package/ModelFieldProvider/index.js +3 -2
  54. package/ModelFieldProvider/index.js.map +1 -1
  55. package/ModelFieldProvider/useModelField.d.ts +2 -3
  56. package/ModelFieldProvider/useModelField.js +2 -2
  57. package/ModelFieldProvider/useModelField.js.map +1 -1
  58. package/ModelProvider/ModelContext.d.ts +1 -1
  59. package/ModelProvider/ModelContext.js.map +1 -1
  60. package/ModelProvider/index.d.ts +2 -2
  61. package/ModelProvider/index.js +2 -2
  62. package/ModelProvider/index.js.map +1 -1
  63. package/ModelProvider/useModel.d.ts +1 -1
  64. package/ModelProvider/useModel.js +1 -1
  65. package/ModelProvider/useModel.js.map +1 -1
  66. package/README.md +6 -13
  67. package/constants.d.ts +1 -1
  68. package/constants.js +1 -1
  69. package/constants.js.map +1 -1
  70. package/createFieldsList.d.ts +5 -1
  71. package/createFieldsList.js +4 -0
  72. package/createFieldsList.js.map +1 -1
  73. package/createValidationContainer.d.ts +2 -2
  74. package/createValidationContainer.js +5 -8
  75. package/createValidationContainer.js.map +1 -1
  76. package/createValidators.d.ts +2 -2
  77. package/createValidators.js +1 -1
  78. package/createValidators.js.map +1 -1
  79. package/entries.graphql.d.ts +1 -1
  80. package/entries.graphql.js +39 -16
  81. package/entries.graphql.js.map +1 -1
  82. package/exports/admin/cms/model.d.ts +1 -0
  83. package/exports/admin/cms/model.js +3 -0
  84. package/exports/admin/cms/model.js.map +1 -0
  85. package/exports/admin/cms.d.ts +1 -0
  86. package/exports/admin/cms.js +3 -0
  87. package/exports/admin/cms.js.map +1 -0
  88. package/getModelTitleFieldId.d.ts +1 -1
  89. package/getModelTitleFieldId.js.map +1 -1
  90. package/index.d.ts +10 -10
  91. package/index.js +10 -10
  92. package/index.js.map +1 -1
  93. package/normalizeIcon.d.ts +3 -0
  94. package/normalizeIcon.js +10 -0
  95. package/normalizeIcon.js.map +1 -0
  96. package/package.json +17 -21
  97. package/prepareFormData.d.ts +1 -1
  98. package/prepareFormData.js +1 -1
  99. package/prepareFormData.js.map +1 -1
  100. package/types/index.d.ts +89 -37
  101. package/types/index.js +1 -16
  102. package/types/index.js.map +1 -1
  103. package/types/model.d.ts +71 -18
  104. package/types/model.js +28 -1
  105. package/types/model.js.map +1 -1
  106. package/types/validation.d.ts +2 -2
  107. package/types/validation.js.map +1 -1
@@ -0,0 +1,36 @@
1
+ import type { CmsModelField, CmsEditorFieldsLayout } from "../types/model.js";
2
+ import type { CmsModelLayoutFieldTypePlugin } from "../types/index.js";
3
+ export interface FieldOption {
4
+ label: string;
5
+ value: string;
6
+ fieldType: string;
7
+ }
8
+ /**
9
+ * Walk a model layout and collect label prefixes for each field ID by delegating
10
+ * to `getFieldLabelPrefixes` on the matching layout-field-type plugin.
11
+ *
12
+ * Returns a map from fieldId to its label prefix string
13
+ * (e.g., `"metaTitle" → "My Tabs › SEO"`).
14
+ */
15
+ export declare function buildFieldLabelPrefixes(layout: CmsEditorFieldsLayout, plugins: CmsModelLayoutFieldTypePlugin[]): Map<string, string>;
16
+ /**
17
+ * Build a flat list of field options from the model's field tree.
18
+ * Paths are absolute using fieldId segments, with `$` for list-object children
19
+ * (e.g., `panorama.hotspots.$.title`).
20
+ *
21
+ * When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will
22
+ * have the layout hierarchy prepended to their labels
23
+ * (e.g., `"My Tabs › SEO › Meta Title"`).
24
+ *
25
+ * When `layoutPlugins` is provided, nested layouts inside object fields
26
+ * (e.g., tabs inside an object field) are also scanned for label prefixes.
27
+ *
28
+ * Recursion rules:
29
+ * - Leaf field (no settings.fields): emit option
30
+ * - Object field (settings.fields, not list): recurse with prefix
31
+ * - List object field (settings.fields, list: true): emit `.length` pseudo-option,
32
+ * then recurse children with `.$` segment
33
+ * - dynamicZone: skip
34
+ * - ref: emit for isEmpty checks, skip children
35
+ */
36
+ export declare function buildFieldOptions(fields: CmsModelField[], prefix?: string, labelPrefix?: string, fieldLabelPrefixes?: Map<string, string>, layoutPlugins?: CmsModelLayoutFieldTypePlugin[]): FieldOption[];
@@ -0,0 +1,113 @@
1
+ import { isLayoutField } from "../types/model.js";
2
+ /**
3
+ * Walk a model layout and collect label prefixes for each field ID by delegating
4
+ * to `getFieldLabelPrefixes` on the matching layout-field-type plugin.
5
+ *
6
+ * Returns a map from fieldId to its label prefix string
7
+ * (e.g., `"metaTitle" → "My Tabs › SEO"`).
8
+ */
9
+ export function buildFieldLabelPrefixes(layout, plugins) {
10
+ const map = new Map();
11
+ const pluginByType = new Map(plugins.map(p => [p.field.type, p]));
12
+ for (const row of layout) {
13
+ for (const cell of row) {
14
+ if (!isLayoutField(cell)) {
15
+ continue;
16
+ }
17
+ const plugin = pluginByType.get(cell.type);
18
+ if (!plugin?.field.getFieldLabelPrefixes) {
19
+ continue;
20
+ }
21
+ const prefixes = plugin.field.getFieldLabelPrefixes({
22
+ field: cell
23
+ });
24
+ for (const [fieldId, prefix] of Object.entries(prefixes)) {
25
+ map.set(fieldId, prefix);
26
+ }
27
+ }
28
+ }
29
+ return map;
30
+ }
31
+
32
+ /**
33
+ * Build a flat list of field options from the model's field tree.
34
+ * Paths are absolute using fieldId segments, with `$` for list-object children
35
+ * (e.g., `panorama.hotspots.$.title`).
36
+ *
37
+ * When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will
38
+ * have the layout hierarchy prepended to their labels
39
+ * (e.g., `"My Tabs › SEO › Meta Title"`).
40
+ *
41
+ * When `layoutPlugins` is provided, nested layouts inside object fields
42
+ * (e.g., tabs inside an object field) are also scanned for label prefixes.
43
+ *
44
+ * Recursion rules:
45
+ * - Leaf field (no settings.fields): emit option
46
+ * - Object field (settings.fields, not list): recurse with prefix
47
+ * - List object field (settings.fields, list: true): emit `.length` pseudo-option,
48
+ * then recurse children with `.$` segment
49
+ * - dynamicZone: skip
50
+ * - ref: emit for isEmpty checks, skip children
51
+ */
52
+ export function buildFieldOptions(fields, prefix = "", labelPrefix = "", fieldLabelPrefixes, layoutPlugins) {
53
+ const options = [];
54
+ for (const field of fields) {
55
+ const path = prefix + field.fieldId;
56
+ const layoutPrefix = fieldLabelPrefixes?.get(field.id);
57
+ const label = layoutPrefix ? `${labelPrefix}${layoutPrefix} › ${field.label}` : labelPrefix + field.label;
58
+
59
+ // Dynamic zone: emit .length pseudo-option only, skip children
60
+ if (field.type === "dynamicZone") {
61
+ options.push({
62
+ label: `${label} › Length`,
63
+ value: `${path}.length`,
64
+ fieldType: "number"
65
+ });
66
+ continue;
67
+ }
68
+ const childFields = field.settings?.fields;
69
+
70
+ // Ref field: include for isEmpty checks, skip children
71
+ if (field.type === "ref") {
72
+ options.push({
73
+ label,
74
+ value: path,
75
+ fieldType: field.type
76
+ });
77
+ continue;
78
+ }
79
+
80
+ // Object with child fields
81
+ if (childFields && childFields.length > 0) {
82
+ // Build label prefixes from the object field's own layout (e.g., tabs inside an object).
83
+ let childPrefixes;
84
+ if (layoutPlugins && field.settings?.layout) {
85
+ childPrefixes = buildFieldLabelPrefixes(field.settings.layout, layoutPlugins);
86
+ }
87
+ if (field.list) {
88
+ // List object: emit .length pseudo-option
89
+ options.push({
90
+ label: `${label} › Length`,
91
+ value: `${path}.length`,
92
+ fieldType: "number"
93
+ });
94
+ // Recurse children with $ segment
95
+ options.push(...buildFieldOptions(childFields, `${path}.$.`, `${label} › `, childPrefixes, layoutPlugins));
96
+ } else {
97
+ // Non-list object: recurse into children
98
+ options.push(...buildFieldOptions(childFields, `${path}.`, `${label} › `, childPrefixes, layoutPlugins));
99
+ }
100
+ continue;
101
+ }
102
+
103
+ // Leaf field
104
+ options.push({
105
+ label,
106
+ value: path,
107
+ fieldType: field.type
108
+ });
109
+ }
110
+ return options;
111
+ }
112
+
113
+ //# sourceMappingURL=fieldOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["isLayoutField","buildFieldLabelPrefixes","layout","plugins","map","Map","pluginByType","p","field","type","row","cell","plugin","get","getFieldLabelPrefixes","prefixes","fieldId","prefix","Object","entries","set","buildFieldOptions","fields","labelPrefix","fieldLabelPrefixes","layoutPlugins","options","path","layoutPrefix","id","label","push","value","fieldType","childFields","settings","length","childPrefixes","list"],"sources":["fieldOptions.ts"],"sourcesContent":["import type { CmsModelField, CmsEditorFieldsLayout } from \"~/types/model.js\";\nimport type { CmsModelLayoutFieldTypePlugin } from \"~/types/index.js\";\nimport { isLayoutField } from \"~/types/model.js\";\n\nexport interface FieldOption {\n label: string;\n value: string;\n fieldType: string;\n}\n\n/**\n * Walk a model layout and collect label prefixes for each field ID by delegating\n * to `getFieldLabelPrefixes` on the matching layout-field-type plugin.\n *\n * Returns a map from fieldId to its label prefix string\n * (e.g., `\"metaTitle\" → \"My Tabs › SEO\"`).\n */\nexport function buildFieldLabelPrefixes(\n layout: CmsEditorFieldsLayout,\n plugins: CmsModelLayoutFieldTypePlugin[]\n): Map<string, string> {\n const map = new Map<string, string>();\n const pluginByType = new Map(plugins.map(p => [p.field.type, p]));\n\n for (const row of layout) {\n for (const cell of row) {\n if (!isLayoutField(cell)) {\n continue;\n }\n\n const plugin = pluginByType.get(cell.type);\n if (!plugin?.field.getFieldLabelPrefixes) {\n continue;\n }\n\n const prefixes = plugin.field.getFieldLabelPrefixes({ field: cell });\n for (const [fieldId, prefix] of Object.entries(prefixes)) {\n map.set(fieldId, prefix);\n }\n }\n }\n\n return map;\n}\n\n/**\n * Build a flat list of field options from the model's field tree.\n * Paths are absolute using fieldId segments, with `$` for list-object children\n * (e.g., `panorama.hotspots.$.title`).\n *\n * When `fieldLabelPrefixes` is provided, fields whose IDs appear in the map will\n * have the layout hierarchy prepended to their labels\n * (e.g., `\"My Tabs › SEO › Meta Title\"`).\n *\n * When `layoutPlugins` is provided, nested layouts inside object fields\n * (e.g., tabs inside an object field) are also scanned for label prefixes.\n *\n * Recursion rules:\n * - Leaf field (no settings.fields): emit option\n * - Object field (settings.fields, not list): recurse with prefix\n * - List object field (settings.fields, list: true): emit `.length` pseudo-option,\n * then recurse children with `.$` segment\n * - dynamicZone: skip\n * - ref: emit for isEmpty checks, skip children\n */\nexport function buildFieldOptions(\n fields: CmsModelField[],\n prefix = \"\",\n labelPrefix = \"\",\n fieldLabelPrefixes?: Map<string, string>,\n layoutPlugins?: CmsModelLayoutFieldTypePlugin[]\n): FieldOption[] {\n const options: FieldOption[] = [];\n\n for (const field of fields) {\n const path = prefix + field.fieldId;\n const layoutPrefix = fieldLabelPrefixes?.get(field.id);\n const label = layoutPrefix\n ? `${labelPrefix}${layoutPrefix} › ${field.label}`\n : labelPrefix + field.label;\n\n // Dynamic zone: emit .length pseudo-option only, skip children\n if (field.type === \"dynamicZone\") {\n options.push({\n label: `${label} › Length`,\n value: `${path}.length`,\n fieldType: \"number\"\n });\n continue;\n }\n\n const childFields = field.settings?.fields;\n\n // Ref field: include for isEmpty checks, skip children\n if (field.type === \"ref\") {\n options.push({ label, value: path, fieldType: field.type });\n continue;\n }\n\n // Object with child fields\n if (childFields && childFields.length > 0) {\n // Build label prefixes from the object field's own layout (e.g., tabs inside an object).\n let childPrefixes: Map<string, string> | undefined;\n if (layoutPlugins && field.settings?.layout) {\n childPrefixes = buildFieldLabelPrefixes(field.settings.layout, layoutPlugins);\n }\n\n if (field.list) {\n // List object: emit .length pseudo-option\n options.push({\n label: `${label} › Length`,\n value: `${path}.length`,\n fieldType: \"number\"\n });\n // Recurse children with $ segment\n options.push(\n ...buildFieldOptions(\n childFields,\n `${path}.$.`,\n `${label} › `,\n childPrefixes,\n layoutPlugins\n )\n );\n } else {\n // Non-list object: recurse into children\n options.push(\n ...buildFieldOptions(\n childFields,\n `${path}.`,\n `${label} › `,\n childPrefixes,\n layoutPlugins\n )\n );\n }\n continue;\n }\n\n // Leaf field\n options.push({ label, value: path, fieldType: field.type });\n }\n\n return options;\n}\n"],"mappings":"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","ignoreList":[]}
package/Fields/index.d.ts CHANGED
@@ -1,3 +1,8 @@
1
- export * from "./FieldElement";
2
- export * from "./Fields";
3
- export * from "./useBind";
1
+ export * from "./FieldElement.js";
2
+ export * from "./Fields.js";
3
+ export * from "./useBind.js";
4
+ export * from "./FieldRulesProvider.js";
5
+ export * from "./evaluateExpression.js";
6
+ export * from "./useFieldRules.js";
7
+ export * from "./fieldOptions.js";
8
+ export * from "./operatorOptions.js";
package/Fields/index.js CHANGED
@@ -1,5 +1,10 @@
1
- export * from "./FieldElement";
2
- export * from "./Fields";
3
- export * from "./useBind";
1
+ export * from "./FieldElement.js";
2
+ export * from "./Fields.js";
3
+ export * from "./useBind.js";
4
+ export * from "./FieldRulesProvider.js";
5
+ export * from "./evaluateExpression.js";
6
+ export * from "./useFieldRules.js";
7
+ export * from "./fieldOptions.js";
8
+ export * from "./operatorOptions.js";
4
9
 
5
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./FieldElement\";\nexport * from \"./Fields\";\nexport * from \"./useBind\";\n"],"mappings":"AAAA;AACA;AACA","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["index.ts"],"sourcesContent":["export * from \"./FieldElement.js\";\nexport * from \"./Fields.js\";\nexport * from \"./useBind.js\";\nexport * from \"./FieldRulesProvider.js\";\nexport * from \"./evaluateExpression.js\";\nexport * from \"./useFieldRules.js\";\nexport * from \"./fieldOptions.js\";\nexport * from \"./operatorOptions.js\";\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import type { CmsAlertLayoutField } from "../../types/model.js";
3
+ interface AlertFieldRendererProps {
4
+ field: CmsAlertLayoutField;
5
+ }
6
+ export declare const AlertFieldRenderer: ({ field }: AlertFieldRendererProps) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { Alert, Grid } from "@webiny/admin-ui";
3
+ export const AlertFieldRenderer = ({
4
+ field
5
+ }) => {
6
+ return /*#__PURE__*/React.createElement(Grid.Column, {
7
+ span: 12
8
+ }, /*#__PURE__*/React.createElement(Alert, {
9
+ type: field.alertType
10
+ }, field.label));
11
+ };
12
+
13
+ //# sourceMappingURL=AlertFieldRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Alert","Grid","AlertFieldRenderer","field","createElement","Column","span","type","alertType","label"],"sources":["AlertFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Alert, Grid } from \"@webiny/admin-ui\";\nimport type { CmsAlertLayoutField } from \"~/types/model.js\";\n\ninterface AlertFieldRendererProps {\n field: CmsAlertLayoutField;\n}\n\nexport const AlertFieldRenderer = ({ field }: AlertFieldRendererProps) => {\n return (\n <Grid.Column span={12}>\n <Alert type={field.alertType}>{field.label}</Alert>\n </Grid.Column>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,KAAK,EAAEC,IAAI,QAAQ,kBAAkB;AAO9C,OAAO,MAAMC,kBAAkB,GAAGA,CAAC;EAAEC;AAA+B,CAAC,KAAK;EACtE,oBACIJ,KAAA,CAAAK,aAAA,CAACH,IAAI,CAACI,MAAM;IAACC,IAAI,EAAE;EAAG,gBAClBP,KAAA,CAAAK,aAAA,CAACJ,KAAK;IAACO,IAAI,EAAEJ,KAAK,CAACK;EAAU,GAAEL,KAAK,CAACM,KAAa,CACzC,CAAC;AAEtB,CAAC","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import type { CmsSeparatorLayoutField } from "../../types/model.js";
3
+ interface SeparatorFieldRendererProps {
4
+ field: CmsSeparatorLayoutField;
5
+ }
6
+ export declare const SeparatorFieldRenderer: ({ field }: SeparatorFieldRendererProps) => React.JSX.Element;
7
+ export {};
@@ -0,0 +1,18 @@
1
+ import React from "react";
2
+ import { Grid, Separator, Text } from "@webiny/admin-ui";
3
+ export const SeparatorFieldRenderer = ({
4
+ field
5
+ }) => {
6
+ return /*#__PURE__*/React.createElement(Grid.Column, {
7
+ span: 12
8
+ }, /*#__PURE__*/React.createElement(Separator, {
9
+ variant: "accent",
10
+ labelPosition: "start"
11
+ }, field.label), field.description && /*#__PURE__*/React.createElement(Text, {
12
+ as: "div",
13
+ size: "sm",
14
+ className: "text-neutral-strong mt-sm"
15
+ }, field.description));
16
+ };
17
+
18
+ //# sourceMappingURL=SeparatorFieldRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Grid","Separator","Text","SeparatorFieldRenderer","field","createElement","Column","span","variant","labelPosition","label","description","as","size","className"],"sources":["SeparatorFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Grid, Separator, Text } from \"@webiny/admin-ui\";\nimport type { CmsSeparatorLayoutField } from \"~/types/model.js\";\n\ninterface SeparatorFieldRendererProps {\n field: CmsSeparatorLayoutField;\n}\n\nexport const SeparatorFieldRenderer = ({ field }: SeparatorFieldRendererProps) => {\n return (\n <Grid.Column span={12}>\n <Separator variant={\"accent\"} labelPosition={\"start\"}>\n {field.label}\n </Separator>\n {field.description && (\n <Text as={\"div\"} size={\"sm\"} className={\"text-neutral-strong mt-sm\"}>\n {field.description}\n </Text>\n )}\n </Grid.Column>\n );\n};\n"],"mappings":"AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,EAAEC,SAAS,EAAEC,IAAI,QAAQ,kBAAkB;AAOxD,OAAO,MAAMC,sBAAsB,GAAGA,CAAC;EAAEC;AAAmC,CAAC,KAAK;EAC9E,oBACIL,KAAA,CAAAM,aAAA,CAACL,IAAI,CAACM,MAAM;IAACC,IAAI,EAAE;EAAG,gBAClBR,KAAA,CAAAM,aAAA,CAACJ,SAAS;IAACO,OAAO,EAAE,QAAS;IAACC,aAAa,EAAE;EAAQ,GAChDL,KAAK,CAACM,KACA,CAAC,EACXN,KAAK,CAACO,WAAW,iBACdZ,KAAA,CAAAM,aAAA,CAACH,IAAI;IAACU,EAAE,EAAE,KAAM;IAACC,IAAI,EAAE,IAAK;IAACC,SAAS,EAAE;EAA4B,GAC/DV,KAAK,CAACO,WACL,CAED,CAAC;AAEtB,CAAC","ignoreList":[]}
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import type { CmsTabLayoutField } from "../../types/model.js";
3
+ import type { BindComponent, CmsEditorContentModel, CmsModelField } from "../../types/index.js";
4
+ interface TabsFieldRendererProps {
5
+ field: CmsTabLayoutField;
6
+ Bind: BindComponent;
7
+ fields: CmsModelField[];
8
+ contentModel: CmsEditorContentModel;
9
+ gridClassName?: string;
10
+ }
11
+ export declare const TabsFieldRenderer: ({ field, Bind, fields, contentModel, gridClassName }: TabsFieldRendererProps) => React.JSX.Element;
12
+ export {};
@@ -0,0 +1,72 @@
1
+ import React from "react";
2
+ import { Grid, FormComponentLabel, FormComponentDescription, Tabs } from "@webiny/admin-ui";
3
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
4
+ import { normalizeIcon } from "../../normalizeIcon.js";
5
+ import { Fields } from "../index.js";
6
+ import { FieldRulesProvider } from "../FieldRulesProvider.js";
7
+ import { useFieldEffectiveRules } from "../useFieldRules.js";
8
+ const TabPanel = ({
9
+ tab,
10
+ Bind,
11
+ fields,
12
+ contentModel,
13
+ gridClassName
14
+ }) => {
15
+ const rules = useFieldEffectiveRules(tab);
16
+ const icon = normalizeIcon(tab.icon);
17
+ return /*#__PURE__*/React.createElement(Tabs.Tab, {
18
+ disabled: rules.disabled,
19
+ visible: rules.canView && !rules.hidden,
20
+ value: tab.id,
21
+ trigger: tab.label,
22
+ icon: icon ? /*#__PURE__*/React.createElement(FontAwesomeIcon, {
23
+ icon: icon,
24
+ size: "sm"
25
+ }) : undefined,
26
+ content: /*#__PURE__*/React.createElement(FieldRulesProvider, {
27
+ rules: rules
28
+ }, /*#__PURE__*/React.createElement(Fields, {
29
+ Bind: Bind,
30
+ fields: fields,
31
+ layout: tab.layout,
32
+ contentModel: contentModel,
33
+ gridClassName: gridClassName
34
+ }))
35
+ });
36
+ };
37
+ const tabsWrapperClassName = ["bg-white!", "opacity-100!", "border-neutral-muted", "text-neutral-strong", "fill-neutral-xstrong", "w-full", "border-sm", "rounded-md"].join(" ");
38
+ export const TabsFieldRenderer = ({
39
+ field,
40
+ Bind,
41
+ fields,
42
+ contentModel,
43
+ gridClassName
44
+ }) => {
45
+ const tabElements = field.tabs.map(tab => /*#__PURE__*/React.createElement(TabPanel, {
46
+ key: tab.id,
47
+ tab: tab,
48
+ Bind: Bind,
49
+ fields: fields,
50
+ contentModel: contentModel,
51
+ gridClassName: gridClassName
52
+ }));
53
+ const firstTab = field.tabs[0];
54
+ return /*#__PURE__*/React.createElement(Grid.Column, {
55
+ span: 12
56
+ }, field.label ? /*#__PURE__*/React.createElement(FormComponentLabel, {
57
+ text: field.label,
58
+ hint: field.help
59
+ }) : null, field.description ? /*#__PURE__*/React.createElement(FormComponentDescription, {
60
+ text: field.description
61
+ }) : null, /*#__PURE__*/React.createElement("div", {
62
+ className: tabsWrapperClassName
63
+ }, /*#__PURE__*/React.createElement(Tabs, {
64
+ size: "md",
65
+ spacing: "md",
66
+ separator: true,
67
+ tabs: tabElements,
68
+ defaultValue: firstTab?.id
69
+ })));
70
+ };
71
+
72
+ //# sourceMappingURL=TabsFieldRenderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["React","Grid","FormComponentLabel","FormComponentDescription","Tabs","FontAwesomeIcon","normalizeIcon","Fields","FieldRulesProvider","useFieldEffectiveRules","TabPanel","tab","Bind","fields","contentModel","gridClassName","rules","icon","createElement","Tab","disabled","visible","canView","hidden","value","id","trigger","label","size","undefined","content","layout","tabsWrapperClassName","join","TabsFieldRenderer","field","tabElements","tabs","map","key","firstTab","Column","span","text","hint","help","description","className","spacing","separator","defaultValue"],"sources":["TabsFieldRenderer.tsx"],"sourcesContent":["import React from \"react\";\nimport { Grid, FormComponentLabel, FormComponentDescription, Tabs } from \"@webiny/admin-ui\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\nimport type { CmsTabLayoutField, CmsTabLayoutTab } from \"~/types/model.js\";\nimport type { BindComponent, CmsEditorContentModel, CmsModelField } from \"~/types/index.js\";\nimport { normalizeIcon } from \"~/normalizeIcon.js\";\nimport { Fields } from \"~/Fields/index.js\";\nimport { FieldRulesProvider } from \"~/Fields/FieldRulesProvider.js\";\nimport { useFieldEffectiveRules } from \"~/Fields/useFieldRules.js\";\n\ninterface TabsFieldRendererProps {\n field: CmsTabLayoutField;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\ninterface TabPanelProps {\n tab: CmsTabLayoutTab;\n Bind: BindComponent;\n fields: CmsModelField[];\n contentModel: CmsEditorContentModel;\n gridClassName?: string;\n}\n\nconst TabPanel = ({ tab, Bind, fields, contentModel, gridClassName }: TabPanelProps) => {\n const rules = useFieldEffectiveRules(tab);\n\n const icon = normalizeIcon(tab.icon);\n\n return (\n <Tabs.Tab\n disabled={rules.disabled}\n visible={rules.canView && !rules.hidden}\n value={tab.id}\n trigger={tab.label}\n icon={icon ? <FontAwesomeIcon icon={icon} size={\"sm\"} /> : undefined}\n content={\n <FieldRulesProvider rules={rules}>\n <Fields\n Bind={Bind}\n fields={fields}\n layout={tab.layout}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n </FieldRulesProvider>\n }\n />\n );\n};\n\nconst tabsWrapperClassName = [\n \"bg-white!\",\n \"opacity-100!\",\n \"border-neutral-muted\",\n \"text-neutral-strong\",\n \"fill-neutral-xstrong\",\n \"w-full\",\n \"border-sm\",\n \"rounded-md\"\n].join(\" \");\n\nexport const TabsFieldRenderer = ({\n field,\n Bind,\n fields,\n contentModel,\n gridClassName\n}: TabsFieldRendererProps) => {\n const tabElements = field.tabs.map(tab => (\n <TabPanel\n key={tab.id}\n tab={tab}\n Bind={Bind}\n fields={fields}\n contentModel={contentModel}\n gridClassName={gridClassName}\n />\n ));\n\n const firstTab = field.tabs[0];\n\n return (\n <Grid.Column span={12}>\n {field.label ? <FormComponentLabel text={field.label} hint={field.help} /> : null}\n {field.description ? <FormComponentDescription text={field.description} /> : null}\n <div className={tabsWrapperClassName}>\n <Tabs\n size=\"md\"\n spacing=\"md\"\n separator={true}\n tabs={tabElements}\n defaultValue={firstTab?.id}\n />\n </div>\n </Grid.Column>\n );\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,10 @@
1
+ import type { Operator } from "./evaluateExpression.js";
2
+ export interface OperatorOption {
3
+ value: Operator;
4
+ label: string;
5
+ }
6
+ export declare function getOperatorOptions(fieldType: string): OperatorOption[];
7
+ /**
8
+ * Operators that don't need a value input (the value is implicit).
9
+ */
10
+ export declare const VALUE_HIDDEN_OPERATORS: Set<Operator>;
@@ -0,0 +1,92 @@
1
+ const NUMERIC_OPERATORS = [{
2
+ value: "==",
3
+ label: "Equals"
4
+ }, {
5
+ value: "!=",
6
+ label: "Not equals"
7
+ }, {
8
+ value: ">",
9
+ label: "Greater than"
10
+ }, {
11
+ value: "<",
12
+ label: "Less than"
13
+ }, {
14
+ value: ">=",
15
+ label: "Greater or equal"
16
+ }, {
17
+ value: "<=",
18
+ label: "Less or equal"
19
+ }, {
20
+ value: "isEmpty",
21
+ label: "Is empty"
22
+ }, {
23
+ value: "isNotEmpty",
24
+ label: "Is not empty"
25
+ }];
26
+ const TEXT_OPERATORS = [{
27
+ value: "==",
28
+ label: "Equals"
29
+ }, {
30
+ value: "!=",
31
+ label: "Not equals"
32
+ }, {
33
+ value: "contains",
34
+ label: "Contains"
35
+ }, {
36
+ value: "startsWith",
37
+ label: "Starts with"
38
+ }, {
39
+ value: "endsWith",
40
+ label: "Ends with"
41
+ }, {
42
+ value: "isEmpty",
43
+ label: "Is empty"
44
+ }, {
45
+ value: "isNotEmpty",
46
+ label: "Is not empty"
47
+ }];
48
+ const BOOLEAN_OPERATORS = [{
49
+ value: "==",
50
+ label: "Equals"
51
+ }, {
52
+ value: "!=",
53
+ label: "Not equals"
54
+ }];
55
+ const FILE_OPERATORS = [{
56
+ value: "isEmpty",
57
+ label: "Is empty"
58
+ }, {
59
+ value: "isNotEmpty",
60
+ label: "Is not empty"
61
+ }];
62
+ const DEFAULT_OPERATORS = [{
63
+ value: "==",
64
+ label: "Equals"
65
+ }, {
66
+ value: "!=",
67
+ label: "Not equals"
68
+ }, {
69
+ value: "isEmpty",
70
+ label: "Is empty"
71
+ }, {
72
+ value: "isNotEmpty",
73
+ label: "Is not empty"
74
+ }];
75
+ const OPERATORS_BY_TYPE = {
76
+ number: NUMERIC_OPERATORS,
77
+ datetime: NUMERIC_OPERATORS,
78
+ text: TEXT_OPERATORS,
79
+ "long-text": TEXT_OPERATORS,
80
+ boolean: BOOLEAN_OPERATORS,
81
+ file: FILE_OPERATORS
82
+ };
83
+ export function getOperatorOptions(fieldType) {
84
+ return OPERATORS_BY_TYPE[fieldType] ?? DEFAULT_OPERATORS;
85
+ }
86
+
87
+ /**
88
+ * Operators that don't need a value input (the value is implicit).
89
+ */
90
+ export const VALUE_HIDDEN_OPERATORS = new Set(["isEmpty", "isNotEmpty"]);
91
+
92
+ //# sourceMappingURL=operatorOptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NUMERIC_OPERATORS","value","label","TEXT_OPERATORS","BOOLEAN_OPERATORS","FILE_OPERATORS","DEFAULT_OPERATORS","OPERATORS_BY_TYPE","number","datetime","text","boolean","file","getOperatorOptions","fieldType","VALUE_HIDDEN_OPERATORS","Set"],"sources":["operatorOptions.ts"],"sourcesContent":["import type { Operator } from \"./evaluateExpression.js\";\n\nexport interface OperatorOption {\n value: Operator;\n label: string;\n}\n\nconst NUMERIC_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \">\", label: \"Greater than\" },\n { value: \"<\", label: \"Less than\" },\n { value: \">=\", label: \"Greater or equal\" },\n { value: \"<=\", label: \"Less or equal\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst TEXT_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \"contains\", label: \"Contains\" },\n { value: \"startsWith\", label: \"Starts with\" },\n { value: \"endsWith\", label: \"Ends with\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst BOOLEAN_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" }\n];\n\nconst FILE_OPERATORS: OperatorOption[] = [\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst DEFAULT_OPERATORS: OperatorOption[] = [\n { value: \"==\", label: \"Equals\" },\n { value: \"!=\", label: \"Not equals\" },\n { value: \"isEmpty\", label: \"Is empty\" },\n { value: \"isNotEmpty\", label: \"Is not empty\" }\n];\n\nconst OPERATORS_BY_TYPE: Record<string, OperatorOption[]> = {\n number: NUMERIC_OPERATORS,\n datetime: NUMERIC_OPERATORS,\n text: TEXT_OPERATORS,\n \"long-text\": TEXT_OPERATORS,\n boolean: BOOLEAN_OPERATORS,\n file: FILE_OPERATORS\n};\n\nexport function getOperatorOptions(fieldType: string): OperatorOption[] {\n return OPERATORS_BY_TYPE[fieldType] ?? DEFAULT_OPERATORS;\n}\n\n/**\n * Operators that don't need a value input (the value is implicit).\n */\nexport const VALUE_HIDDEN_OPERATORS: Set<Operator> = new Set([\"isEmpty\", \"isNotEmpty\"]);\n"],"mappings":"AAOA,MAAMA,iBAAmC,GAAG,CACxC;EAAEC,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,GAAG;EAAEC,KAAK,EAAE;AAAe,CAAC,EACrC;EAAED,KAAK,EAAE,GAAG;EAAEC,KAAK,EAAE;AAAY,CAAC,EAClC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAmB,CAAC,EAC1C;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAgB,CAAC,EACvC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMC,cAAgC,GAAG,CACrC;EAAEF,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,UAAU;EAAEC,KAAK,EAAE;AAAW,CAAC,EACxC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAc,CAAC,EAC7C;EAAED,KAAK,EAAE,UAAU;EAAEC,KAAK,EAAE;AAAY,CAAC,EACzC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAME,iBAAmC,GAAG,CACxC;EAAEH,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,CACvC;AAED,MAAMG,cAAgC,GAAG,CACrC;EAAEJ,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMI,iBAAmC,GAAG,CACxC;EAAEL,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAS,CAAC,EAChC;EAAED,KAAK,EAAE,IAAI;EAAEC,KAAK,EAAE;AAAa,CAAC,EACpC;EAAED,KAAK,EAAE,SAAS;EAAEC,KAAK,EAAE;AAAW,CAAC,EACvC;EAAED,KAAK,EAAE,YAAY;EAAEC,KAAK,EAAE;AAAe,CAAC,CACjD;AAED,MAAMK,iBAAmD,GAAG;EACxDC,MAAM,EAAER,iBAAiB;EACzBS,QAAQ,EAAET,iBAAiB;EAC3BU,IAAI,EAAEP,cAAc;EACpB,WAAW,EAAEA,cAAc;EAC3BQ,OAAO,EAAEP,iBAAiB;EAC1BQ,IAAI,EAAEP;AACV,CAAC;AAED,OAAO,SAASQ,kBAAkBA,CAACC,SAAiB,EAAoB;EACpE,OAAOP,iBAAiB,CAACO,SAAS,CAAC,IAAIR,iBAAiB;AAC5D;;AAEA;AACA;AACA;AACA,OAAO,MAAMS,sBAAqC,GAAG,IAAIC,GAAG,CAAC,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC","ignoreList":[]}
@@ -1,4 +1,5 @@
1
- import type { BindComponent } from "../types";
1
+ import type { BindComponent } from "../types/index.js";
2
+ export declare const useBindParentName: () => string;
2
3
  interface UseBindProps {
3
4
  Bind: BindComponent;
4
5
  }
package/Fields/useBind.js CHANGED
@@ -1,8 +1,10 @@
1
- import React, { useRef, cloneElement } from "react";
1
+ import React, { createContext, useContext, useRef, cloneElement } from "react";
2
2
  import { useForm } from "@webiny/form";
3
- import { createValidators } from "../createValidators";
4
- import { useModelField } from "../ModelFieldProvider";
5
- import { createValidationContainer } from "../createValidationContainer";
3
+ import { createValidators } from "../createValidators.js";
4
+ import { useModelField } from "../ModelFieldProvider/index.js";
5
+ import { createValidationContainer } from "../createValidationContainer.js";
6
+ const BindParentNameContext = /*#__PURE__*/createContext("");
7
+ export const useBindParentName = () => useContext(BindParentNameContext);
6
8
  const createFieldCacheKey = field => {
7
9
  return [field.id, field.fieldId, JSON.stringify(field.validation), JSON.stringify(field.listValidation)].join(";");
8
10
  };
@@ -30,7 +32,7 @@ export function useBind({
30
32
  }
31
33
  const validators = createValidators(field, field.validation || emptyValidators);
32
34
  const listValidators = createValidators(field, field.listValidation || emptyValidators);
33
- const isMultipleValues = index === -1 && field.multipleValues;
35
+ const isMultipleValues = index === -1 && field.list;
34
36
  const inputValidators = isMultipleValues ? listValidators : validators;
35
37
 
36
38
  // We only use default values for single-value fields.
@@ -45,7 +47,9 @@ export function useBind({
45
47
  const {
46
48
  field
47
49
  } = useModelField();
48
- return /*#__PURE__*/React.createElement(Bind, {
50
+ return /*#__PURE__*/React.createElement(BindParentNameContext.Provider, {
51
+ value: name
52
+ }, /*#__PURE__*/React.createElement(Bind, {
49
53
  name: childName || name,
50
54
  validators: childValidators || inputValidators,
51
55
  defaultValue: defaultValue ?? null,
@@ -57,7 +61,7 @@ export function useBind({
57
61
  const props = {
58
62
  ...bind
59
63
  };
60
- if (field.multipleValues && index === -1) {
64
+ if (field.list && index === -1) {
61
65
  props.appendValue = (newValue, index) => {
62
66
  const currentValue = bind.value || [];
63
67
  const newIndex = index ?? currentValue.length;
@@ -99,7 +103,7 @@ export function useBind({
99
103
  };
100
104
  }
101
105
  return typeof children === "function" ? children(props) : /*#__PURE__*/cloneElement(children, props);
102
- });
106
+ }));
103
107
  };
104
108
 
105
109
  // We need to keep track of current field name, to support nested fields.
@@ -1 +1 @@
1
- {"version":3,"names":["React","useRef","cloneElement","useForm","createValidators","useModelField","createValidationContainer","createFieldCacheKey","field","id","fieldId","JSON","stringify","validation","listValidation","join","emptyValidators","useBind","Bind","memoizedBindComponents","cacheKey","form","index","parentName","name","undefined","filter","v","componentId","current","validators","listValidators","isMultipleValues","multipleValues","inputValidators","defaultValueFromSettings","settings","defaultValue","UseBind","params","childName","childValidators","children","createElement","context","bind","props","appendValue","newValue","currentValue","value","newIndex","length","onChange","slice","prependValue","appendValues","newValues","removeValue","validateInput","moveValueUp","splice","moveValueDown","displayName","ValidationContainer"],"sources":["useBind.tsx"],"sourcesContent":["import React, { useRef, cloneElement } from \"react\";\nimport type { Validator } from \"@webiny/validation/types\";\nimport { useForm } from \"@webiny/form\";\nimport { createValidators } from \"~/createValidators\";\nimport type { BindComponent, CmsModelField } from \"~/types\";\nimport { useModelField } from \"~/ModelFieldProvider\";\nimport { createValidationContainer } from \"~/createValidationContainer\";\n\ninterface UseBindProps {\n Bind: BindComponent;\n}\n\ninterface UseBindParams {\n name?: string;\n validators?: Validator | Validator[];\n children?: any;\n defaultValue?: any;\n}\n\nconst createFieldCacheKey = (field: CmsModelField) => {\n return [\n field.id,\n field.fieldId,\n JSON.stringify(field.validation),\n JSON.stringify(field.listValidation)\n ].join(\";\");\n};\n\nexport interface GetBindCallable {\n (index?: number): BindComponent;\n}\n\nconst emptyValidators: Validator[] = [];\n\nexport function useBind({ Bind }: UseBindProps) {\n const { field } = useModelField();\n const memoizedBindComponents = useRef<Record<string, BindComponent>>({});\n const cacheKey = createFieldCacheKey(field);\n const form = useForm();\n\n return (index = -1) => {\n const { parentName } = Bind;\n\n // If there's a parent name assigned to the given Bind component, we need to include it in the new field \"name\".\n // This allows us to have nested fields (like \"object\" field with nested properties)\n const name = [parentName, field.fieldId, index >= 0 ? index : undefined]\n .filter(v => v !== undefined)\n .join(\".\");\n\n const componentId = `${name};${cacheKey}`;\n\n if (memoizedBindComponents.current[componentId]) {\n return memoizedBindComponents.current[componentId];\n }\n\n const validators = createValidators(field, field.validation || emptyValidators);\n const listValidators = createValidators(field, field.listValidation || emptyValidators);\n const isMultipleValues = index === -1 && field.multipleValues;\n const inputValidators = isMultipleValues ? listValidators : validators;\n\n // We only use default values for single-value fields.\n const defaultValueFromSettings = !isMultipleValues ? field.settings?.defaultValue : null;\n\n memoizedBindComponents.current[componentId] = function UseBind(params: UseBindParams) {\n const {\n name: childName,\n validators: childValidators,\n children,\n defaultValue = defaultValueFromSettings\n } = params;\n\n const { field } = useModelField();\n\n return (\n <Bind\n name={childName || name}\n validators={childValidators || inputValidators}\n defaultValue={defaultValue ?? null}\n context={{ field }}\n >\n {bind => {\n // Multiple-values functions below.\n const props = { ...bind };\n if (field.multipleValues && index === -1) {\n props.appendValue = (newValue: any, index?: number) => {\n const currentValue = bind.value || [];\n const newIndex = index ?? currentValue.length;\n\n bind.onChange([\n ...currentValue.slice(0, newIndex),\n newValue,\n ...currentValue.slice(newIndex)\n ]);\n };\n props.prependValue = (newValue: any) => {\n bind.onChange([newValue, ...(bind.value || [])]);\n };\n props.appendValues = (newValues: any[]) => {\n bind.onChange([...(bind.value || []), ...newValues]);\n };\n\n props.removeValue = (index: number) => {\n if (index < 0) {\n return;\n }\n\n const value = [\n ...bind.value.slice(0, index),\n ...bind.value.slice(index + 1)\n ];\n\n bind.onChange(value.length === 0 ? null : value);\n\n // To make sure the field is still valid, we must trigger validation.\n form.validateInput(field.fieldId);\n };\n\n props.moveValueUp = (index: number) => {\n if (index <= 0) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index - 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n\n props.moveValueDown = (index: number) => {\n if (index >= bind.value.length) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index + 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n }\n\n return typeof children === \"function\"\n ? children(props)\n : cloneElement(children, props);\n }}\n </Bind>\n );\n } as BindComponent;\n\n // We need to keep track of current field name, to support nested fields.\n memoizedBindComponents.current[componentId].parentName = name;\n memoizedBindComponents.current[componentId].displayName = `Bind<${name}>`;\n memoizedBindComponents.current[componentId].ValidationContainer =\n createValidationContainer(name);\n\n return memoizedBindComponents.current[componentId];\n };\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["React","createContext","useContext","useRef","cloneElement","useForm","createValidators","useModelField","createValidationContainer","BindParentNameContext","useBindParentName","createFieldCacheKey","field","id","fieldId","JSON","stringify","validation","listValidation","join","emptyValidators","useBind","Bind","memoizedBindComponents","cacheKey","form","index","parentName","name","undefined","filter","v","componentId","current","validators","listValidators","isMultipleValues","list","inputValidators","defaultValueFromSettings","settings","defaultValue","UseBind","params","childName","childValidators","children","createElement","Provider","value","context","bind","props","appendValue","newValue","currentValue","newIndex","length","onChange","slice","prependValue","appendValues","newValues","removeValue","validateInput","moveValueUp","splice","moveValueDown","displayName","ValidationContainer"],"sources":["useBind.tsx"],"sourcesContent":["import React, { createContext, useContext, useRef, cloneElement } from \"react\";\nimport type { Validator } from \"@webiny/validation/types.js\";\nimport { useForm } from \"@webiny/form\";\nimport { createValidators } from \"~/createValidators.js\";\nimport type { BindComponent, CmsModelField } from \"~/types/index.js\";\nimport { useModelField } from \"~/ModelFieldProvider/index.js\";\nimport { createValidationContainer } from \"~/createValidationContainer.js\";\n\nconst BindParentNameContext = createContext<string>(\"\");\n\nexport const useBindParentName = (): string => useContext(BindParentNameContext);\n\ninterface UseBindProps {\n Bind: BindComponent;\n}\n\ninterface UseBindParams {\n name?: string;\n validators?: Validator | Validator[];\n children?: any;\n defaultValue?: any;\n}\n\nconst createFieldCacheKey = (field: CmsModelField) => {\n return [\n field.id,\n field.fieldId,\n JSON.stringify(field.validation),\n JSON.stringify(field.listValidation)\n ].join(\";\");\n};\n\nexport interface GetBindCallable {\n (index?: number): BindComponent;\n}\n\nconst emptyValidators: Validator[] = [];\n\nexport function useBind({ Bind }: UseBindProps) {\n const { field } = useModelField();\n const memoizedBindComponents = useRef<Record<string, BindComponent>>({});\n const cacheKey = createFieldCacheKey(field);\n const form = useForm();\n\n return (index = -1) => {\n const { parentName } = Bind;\n\n // If there's a parent name assigned to the given Bind component, we need to include it in the new field \"name\".\n // This allows us to have nested fields (like \"object\" field with nested properties)\n const name = [parentName, field.fieldId, index >= 0 ? index : undefined]\n .filter(v => v !== undefined)\n .join(\".\");\n\n const componentId = `${name};${cacheKey}`;\n\n if (memoizedBindComponents.current[componentId]) {\n return memoizedBindComponents.current[componentId];\n }\n\n const validators = createValidators(field, field.validation || emptyValidators);\n const listValidators = createValidators(field, field.listValidation || emptyValidators);\n const isMultipleValues = index === -1 && field.list;\n const inputValidators = isMultipleValues ? listValidators : validators;\n\n // We only use default values for single-value fields.\n const defaultValueFromSettings = !isMultipleValues ? field.settings?.defaultValue : null;\n\n memoizedBindComponents.current[componentId] = function UseBind(params: UseBindParams) {\n const {\n name: childName,\n validators: childValidators,\n children,\n defaultValue = defaultValueFromSettings\n } = params;\n\n const { field } = useModelField();\n\n return (\n <BindParentNameContext.Provider value={name}>\n <Bind\n name={childName || name}\n validators={childValidators || inputValidators}\n defaultValue={defaultValue ?? null}\n context={{ field }}\n >\n {bind => {\n // Multiple-values functions below.\n const props = { ...bind };\n if (field.list && index === -1) {\n props.appendValue = (newValue: any, index?: number) => {\n const currentValue = bind.value || [];\n const newIndex = index ?? currentValue.length;\n\n bind.onChange([\n ...currentValue.slice(0, newIndex),\n newValue,\n ...currentValue.slice(newIndex)\n ]);\n };\n props.prependValue = (newValue: any) => {\n bind.onChange([newValue, ...(bind.value || [])]);\n };\n props.appendValues = (newValues: any[]) => {\n bind.onChange([...(bind.value || []), ...newValues]);\n };\n\n props.removeValue = (index: number) => {\n if (index < 0) {\n return;\n }\n\n const value = [\n ...bind.value.slice(0, index),\n ...bind.value.slice(index + 1)\n ];\n\n bind.onChange(value.length === 0 ? null : value);\n\n // To make sure the field is still valid, we must trigger validation.\n form.validateInput(field.fieldId);\n };\n\n props.moveValueUp = (index: number) => {\n if (index <= 0) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index - 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n\n props.moveValueDown = (index: number) => {\n if (index >= bind.value.length) {\n return;\n }\n\n const value = [...bind.value];\n value.splice(index, 1);\n value.splice(index + 1, 0, bind.value[index]);\n\n bind.onChange(value);\n };\n }\n\n return typeof children === \"function\"\n ? children(props)\n : cloneElement(children, props);\n }}\n </Bind>\n </BindParentNameContext.Provider>\n );\n } as BindComponent;\n\n // We need to keep track of current field name, to support nested fields.\n memoizedBindComponents.current[componentId].parentName = name;\n memoizedBindComponents.current[componentId].displayName = `Bind<${name}>`;\n memoizedBindComponents.current[componentId].ValidationContainer =\n createValidationContainer(name);\n\n return memoizedBindComponents.current[componentId];\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,32 @@
1
+ import type { FieldRule } from "../types/model.js";
2
+ export interface EffectiveFieldRules {
3
+ canView: boolean;
4
+ canEdit: boolean;
5
+ hidden: boolean;
6
+ disabled: boolean;
7
+ }
8
+ interface HasRules {
9
+ rules?: FieldRule[];
10
+ }
11
+ interface IdentityLike {
12
+ id: string;
13
+ teams: {
14
+ slug: string;
15
+ }[];
16
+ }
17
+ /**
18
+ * Hook that evaluates access control rules for the current identity.
19
+ * Does not require `bindParentName` — only identity-based permissions.
20
+ */
21
+ export declare function useFieldAccessControlRules(item: HasRules): Pick<EffectiveFieldRules, "canView" | "canEdit">;
22
+ /**
23
+ * Evaluate access control rules statically (without hooks).
24
+ * Used in RowRenderer for the visibility approximation where hooks can't be called.
25
+ */
26
+ export declare function evaluateAccessControlRules(item: HasRules, identity: IdentityLike): EffectiveFieldRules;
27
+ /**
28
+ * Composes useParentRules and useFieldRules into a single hook
29
+ * that returns the effective (intersected) rules.
30
+ */
31
+ export declare function useFieldEffectiveRules(item: HasRules): EffectiveFieldRules;
32
+ export {};