@box/metadata-template-editor 1.19.0

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 (215) hide show
  1. package/LICENSE +379 -0
  2. package/README.md +57 -0
  3. package/dist/chunks/metadata-field-configurator.module.js +17 -0
  4. package/dist/chunks/types.js +34 -0
  5. package/dist/esm/index.js +34 -0
  6. package/dist/esm/lib/components/field-selector/field-selector.js +39 -0
  7. package/dist/esm/lib/components/field-selector/index.js +4 -0
  8. package/dist/esm/lib/components/field-selector/messages.js +14 -0
  9. package/dist/esm/lib/components/field-type-dropdown/field-type-dropdown.js +47 -0
  10. package/dist/esm/lib/components/field-type-dropdown/index.js +4 -0
  11. package/dist/esm/lib/components/field-type-dropdown/messages.js +14 -0
  12. package/dist/esm/lib/components/field-type-tiles/field-type-tiles.js +40 -0
  13. package/dist/esm/lib/components/field-type-tiles/index.js +4 -0
  14. package/dist/esm/lib/components/field-type-tiles/messages.js +14 -0
  15. package/dist/esm/lib/components/metadata-field-configurator/components/confirmation-modal/confirmation-modal.js +46 -0
  16. package/dist/esm/lib/components/metadata-field-configurator/components/confirmation-modal/messages.js +18 -0
  17. package/dist/esm/lib/components/metadata-field-configurator/components/field-action-slot/field-action-slot.js +80 -0
  18. package/dist/esm/lib/components/metadata-field-configurator/components/field-context-menu/field-context-menu.js +115 -0
  19. package/dist/esm/lib/components/metadata-field-configurator/components/field-edit-content/field-edit-content.js +101 -0
  20. package/dist/esm/lib/components/metadata-field-configurator/components/levels-chain/chip.js +33 -0
  21. package/dist/esm/lib/components/metadata-field-configurator/components/levels-chain/index.js +4 -0
  22. package/dist/esm/lib/components/metadata-field-configurator/components/levels-chain/levels-chain.js +118 -0
  23. package/dist/esm/lib/components/metadata-field-configurator/components/levels-chain/utils.js +34 -0
  24. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/__mocks__/getInitialValues.js +33 -0
  25. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/dropdown-default-values.js +15 -0
  26. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/dropdown-field-configuration.js +66 -0
  27. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/sortable-option-list.js +294 -0
  28. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/index.js +6 -0
  29. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-default-values.js +15 -0
  30. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-field-configuration.js +149 -0
  31. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-field-configurator-initial-state.js +54 -0
  32. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-selector-messages.js +38 -0
  33. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-selector.js +103 -0
  34. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/useTaxonomySelect.js +19 -0
  35. package/dist/esm/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/utils.js +4 -0
  36. package/dist/esm/lib/components/metadata-field-configurator/context/field-configurator-context.js +68 -0
  37. package/dist/esm/lib/components/metadata-field-configurator/context/field-extensions-context.js +9 -0
  38. package/dist/esm/lib/components/metadata-field-configurator/context/taxonomy-options-context.js +23 -0
  39. package/dist/esm/lib/components/metadata-field-configurator/hooks/useFieldConfiguratorBehavior.js +119 -0
  40. package/dist/esm/lib/components/metadata-field-configurator/hooks/useFieldValidation.js +68 -0
  41. package/dist/esm/lib/components/metadata-field-configurator/hooks/useTaxonomyFetch.js +27 -0
  42. package/dist/esm/lib/components/metadata-field-configurator/hooks/useTemplateFieldSchema.js +44 -0
  43. package/dist/esm/lib/components/metadata-field-configurator/index.js +11 -0
  44. package/dist/esm/lib/components/metadata-field-configurator/messages/configurator-messages.js +136 -0
  45. package/dist/esm/lib/components/metadata-field-configurator/messages/dropdown-messages.js +38 -0
  46. package/dist/esm/lib/components/metadata-field-configurator/messages/levels-chain-messages.js +18 -0
  47. package/dist/esm/lib/components/metadata-field-configurator/messages/taxonomy-messages.js +38 -0
  48. package/dist/esm/lib/components/metadata-field-configurator/metadata-field-configurator.js +154 -0
  49. package/dist/esm/lib/components/metadata-field-configurator/utils.js +53 -0
  50. package/dist/esm/lib/components/metadata-field-list/index.js +5 -0
  51. package/dist/esm/lib/components/metadata-field-list/metadata-field-list.js +279 -0
  52. package/dist/esm/lib/components/metadata-template-editor-form/metadata-template-editor-form.js +137 -0
  53. package/dist/esm/lib/components/metadata-template-editor-modal/index.js +4 -0
  54. package/dist/esm/lib/components/metadata-template-editor-modal/metadata-template-editor-modal.js +103 -0
  55. package/dist/esm/lib/hooks/useMetadataTemplateFormSchema.js +16 -0
  56. package/dist/esm/lib/hooks/useTemplateNameSchema.js +12 -0
  57. package/dist/esm/lib/index.js +14 -0
  58. package/dist/esm/lib/messages.js +118 -0
  59. package/dist/esm/lib/metadata-template-editor.js +179 -0
  60. package/dist/esm/lib/utils/constants.js +8 -0
  61. package/dist/esm/lib/utils/field-options/field-type-icon.js +34 -0
  62. package/dist/esm/lib/utils/field-options/index.js +9 -0
  63. package/dist/esm/lib/utils/field-options/messages.js +48 -0
  64. package/dist/esm/lib/utils/field-options/useFieldOptions.js +19 -0
  65. package/dist/esm/lib/utils/key-generation.js +29 -0
  66. package/dist/esm/lib/utils/template-type-conversion/convertLocalConfiguratorToTemplateField.js +78 -0
  67. package/dist/esm/lib/utils/template-type-conversion/convertTemplateFieldToLocalConfigurator.js +90 -0
  68. package/dist/esm/lib/utils/template-type-conversion/generateJSONPatchTemplateOperations.js +179 -0
  69. package/dist/esm/lib/utils/template-type-conversion/mapFieldsWithUniqueKeys.js +14 -0
  70. package/dist/i18n/bn-IN.js +108 -0
  71. package/dist/i18n/bn-IN.properties +196 -0
  72. package/dist/i18n/da-DK.js +108 -0
  73. package/dist/i18n/da-DK.properties +196 -0
  74. package/dist/i18n/de-DE.js +108 -0
  75. package/dist/i18n/de-DE.properties +196 -0
  76. package/dist/i18n/en-AU.js +108 -0
  77. package/dist/i18n/en-AU.properties +196 -0
  78. package/dist/i18n/en-CA.js +108 -0
  79. package/dist/i18n/en-CA.properties +196 -0
  80. package/dist/i18n/en-GB.js +108 -0
  81. package/dist/i18n/en-GB.properties +196 -0
  82. package/dist/i18n/en-US.js +108 -0
  83. package/dist/i18n/en-US.properties +212 -0
  84. package/dist/i18n/en-x-pseudo.js +108 -0
  85. package/dist/i18n/en-x-pseudo.properties +196 -0
  86. package/dist/i18n/es-419.js +108 -0
  87. package/dist/i18n/es-419.properties +196 -0
  88. package/dist/i18n/es-ES.js +108 -0
  89. package/dist/i18n/es-ES.properties +196 -0
  90. package/dist/i18n/fi-FI.js +108 -0
  91. package/dist/i18n/fi-FI.properties +196 -0
  92. package/dist/i18n/fr-CA.js +108 -0
  93. package/dist/i18n/fr-CA.properties +196 -0
  94. package/dist/i18n/fr-FR.js +108 -0
  95. package/dist/i18n/fr-FR.properties +196 -0
  96. package/dist/i18n/hi-IN.js +108 -0
  97. package/dist/i18n/hi-IN.properties +196 -0
  98. package/dist/i18n/it-IT.js +108 -0
  99. package/dist/i18n/it-IT.properties +196 -0
  100. package/dist/i18n/ja-JP.js +108 -0
  101. package/dist/i18n/ja-JP.properties +196 -0
  102. package/dist/i18n/json/src/lib/components/field-selector/messages.json +1 -0
  103. package/dist/i18n/json/src/lib/components/field-type-dropdown/messages.json +1 -0
  104. package/dist/i18n/json/src/lib/components/field-type-tiles/messages.json +1 -0
  105. package/dist/i18n/json/src/lib/components/metadata-field-configurator/components/confirmation-modal/messages.json +1 -0
  106. package/dist/i18n/json/src/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-selector-messages.json +1 -0
  107. package/dist/i18n/json/src/lib/components/metadata-field-configurator/messages/configurator-messages.json +1 -0
  108. package/dist/i18n/json/src/lib/components/metadata-field-configurator/messages/dropdown-messages.json +1 -0
  109. package/dist/i18n/json/src/lib/components/metadata-field-configurator/messages/levels-chain-messages.json +1 -0
  110. package/dist/i18n/json/src/lib/components/metadata-field-configurator/messages/taxonomy-messages.json +1 -0
  111. package/dist/i18n/json/src/lib/messages.json +1 -0
  112. package/dist/i18n/json/src/lib/utils/field-options/messages.json +1 -0
  113. package/dist/i18n/ko-KR.js +108 -0
  114. package/dist/i18n/ko-KR.properties +196 -0
  115. package/dist/i18n/nb-NO.js +108 -0
  116. package/dist/i18n/nb-NO.properties +196 -0
  117. package/dist/i18n/nl-NL.js +108 -0
  118. package/dist/i18n/nl-NL.properties +196 -0
  119. package/dist/i18n/pl-PL.js +108 -0
  120. package/dist/i18n/pl-PL.properties +196 -0
  121. package/dist/i18n/pt-BR.js +108 -0
  122. package/dist/i18n/pt-BR.properties +196 -0
  123. package/dist/i18n/ru-RU.js +108 -0
  124. package/dist/i18n/ru-RU.properties +196 -0
  125. package/dist/i18n/sv-SE.js +108 -0
  126. package/dist/i18n/sv-SE.properties +196 -0
  127. package/dist/i18n/tr-TR.js +108 -0
  128. package/dist/i18n/tr-TR.properties +196 -0
  129. package/dist/i18n/zh-CN.js +108 -0
  130. package/dist/i18n/zh-CN.properties +196 -0
  131. package/dist/i18n/zh-TW.js +108 -0
  132. package/dist/i18n/zh-TW.properties +196 -0
  133. package/dist/styles/chip.css +1 -0
  134. package/dist/styles/dropdown-field-configuration.css +1 -0
  135. package/dist/styles/field-context-menu.css +1 -0
  136. package/dist/styles/field-selector.css +1 -0
  137. package/dist/styles/field-type-dropdown.css +1 -0
  138. package/dist/styles/levels-chain.css +1 -0
  139. package/dist/styles/metadata-field-configurator.css +1 -0
  140. package/dist/styles/metadata-field-list.css +1 -0
  141. package/dist/styles/metadata-template-editor-form.css +1 -0
  142. package/dist/styles/metadata-template-editor-modal.css +1 -0
  143. package/dist/styles/metadata-template-editor.css +1 -0
  144. package/dist/styles/sortable-option-list.css +1 -0
  145. package/dist/styles/taxonomy-field-configuration.css +1 -0
  146. package/dist/styles/taxonomy-field-configurator-initial-state.css +1 -0
  147. package/dist/styles/taxonomy-selector.css +1 -0
  148. package/dist/types/index.d.ts +8 -0
  149. package/dist/types/lib/components/field-selector/field-selector.d.ts +16 -0
  150. package/dist/types/lib/components/field-selector/index.d.ts +1 -0
  151. package/dist/types/lib/components/field-selector/messages.d.ts +13 -0
  152. package/dist/types/lib/components/field-type-dropdown/field-type-dropdown.d.ts +15 -0
  153. package/dist/types/lib/components/field-type-dropdown/index.d.ts +2 -0
  154. package/dist/types/lib/components/field-type-dropdown/messages.d.ts +12 -0
  155. package/dist/types/lib/components/field-type-tiles/field-type-tiles.d.ts +12 -0
  156. package/dist/types/lib/components/field-type-tiles/index.d.ts +2 -0
  157. package/dist/types/lib/components/field-type-tiles/messages.d.ts +12 -0
  158. package/dist/types/lib/components/metadata-field-configurator/components/confirmation-modal/confirmation-modal.d.ts +31 -0
  159. package/dist/types/lib/components/metadata-field-configurator/components/confirmation-modal/messages.d.ts +18 -0
  160. package/dist/types/lib/components/metadata-field-configurator/components/field-action-slot/field-action-slot.d.ts +30 -0
  161. package/dist/types/lib/components/metadata-field-configurator/components/field-context-menu/field-context-menu.d.ts +23 -0
  162. package/dist/types/lib/components/metadata-field-configurator/components/field-edit-content/field-edit-content.d.ts +20 -0
  163. package/dist/types/lib/components/metadata-field-configurator/components/levels-chain/chip.d.ts +17 -0
  164. package/dist/types/lib/components/metadata-field-configurator/components/levels-chain/index.d.ts +1 -0
  165. package/dist/types/lib/components/metadata-field-configurator/components/levels-chain/levels-chain.d.ts +31 -0
  166. package/dist/types/lib/components/metadata-field-configurator/components/levels-chain/utils.d.ts +10 -0
  167. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/__mocks__/getInitialValues.d.ts +2 -0
  168. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/dropdown-default-values.d.ts +2 -0
  169. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/dropdown-field-configuration.d.ts +1 -0
  170. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/dropdown/sortable-option-list.d.ts +6 -0
  171. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/index.d.ts +2 -0
  172. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-default-values.d.ts +2 -0
  173. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-field-configuration.d.ts +1 -0
  174. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-field-configurator-initial-state.d.ts +1 -0
  175. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-selector-messages.d.ts +43 -0
  176. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/taxonomy-selector.d.ts +12 -0
  177. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/useTaxonomySelect.d.ts +5 -0
  178. package/dist/types/lib/components/metadata-field-configurator/components/type-specific-configuration/taxonomy/utils.d.ts +2 -0
  179. package/dist/types/lib/components/metadata-field-configurator/context/field-configurator-context.d.ts +57 -0
  180. package/dist/types/lib/components/metadata-field-configurator/context/field-extensions-context.d.ts +52 -0
  181. package/dist/types/lib/components/metadata-field-configurator/context/taxonomy-options-context.d.ts +21 -0
  182. package/dist/types/lib/components/metadata-field-configurator/hooks/useFieldConfiguratorBehavior.d.ts +57 -0
  183. package/dist/types/lib/components/metadata-field-configurator/hooks/useFieldValidation.d.ts +27 -0
  184. package/dist/types/lib/components/metadata-field-configurator/hooks/useTaxonomyFetch.d.ts +19 -0
  185. package/dist/types/lib/components/metadata-field-configurator/hooks/useTemplateFieldSchema.d.ts +15 -0
  186. package/dist/types/lib/components/metadata-field-configurator/index.d.ts +6 -0
  187. package/dist/types/lib/components/metadata-field-configurator/messages/configurator-messages.d.ts +164 -0
  188. package/dist/types/lib/components/metadata-field-configurator/messages/dropdown-messages.d.ts +43 -0
  189. package/dist/types/lib/components/metadata-field-configurator/messages/levels-chain-messages.d.ts +18 -0
  190. package/dist/types/lib/components/metadata-field-configurator/messages/taxonomy-messages.d.ts +43 -0
  191. package/dist/types/lib/components/metadata-field-configurator/metadata-field-configurator.d.ts +191 -0
  192. package/dist/types/lib/components/metadata-field-configurator/stories/story-fixtures.d.ts +5 -0
  193. package/dist/types/lib/components/metadata-field-configurator/utils.d.ts +24 -0
  194. package/dist/types/lib/components/metadata-field-list/index.d.ts +2 -0
  195. package/dist/types/lib/components/metadata-field-list/metadata-field-list.d.ts +109 -0
  196. package/dist/types/lib/components/metadata-template-editor-form/metadata-template-editor-form.d.ts +20 -0
  197. package/dist/types/lib/components/metadata-template-editor-modal/index.d.ts +1 -0
  198. package/dist/types/lib/components/metadata-template-editor-modal/metadata-template-editor-modal.d.ts +56 -0
  199. package/dist/types/lib/hooks/useMetadataTemplateFormSchema.d.ts +17 -0
  200. package/dist/types/lib/hooks/useTemplateNameSchema.d.ts +2 -0
  201. package/dist/types/lib/index.d.ts +7 -0
  202. package/dist/types/lib/messages.d.ts +143 -0
  203. package/dist/types/lib/metadata-template-editor.d.ts +290 -0
  204. package/dist/types/lib/types.d.ts +311 -0
  205. package/dist/types/lib/utils/constants.d.ts +9 -0
  206. package/dist/types/lib/utils/field-options/field-type-icon.d.ts +6 -0
  207. package/dist/types/lib/utils/field-options/index.d.ts +4 -0
  208. package/dist/types/lib/utils/field-options/messages.d.ts +60 -0
  209. package/dist/types/lib/utils/field-options/useFieldOptions.d.ts +34 -0
  210. package/dist/types/lib/utils/key-generation.d.ts +24 -0
  211. package/dist/types/lib/utils/template-type-conversion/convertLocalConfiguratorToTemplateField.d.ts +25 -0
  212. package/dist/types/lib/utils/template-type-conversion/convertTemplateFieldToLocalConfigurator.d.ts +8 -0
  213. package/dist/types/lib/utils/template-type-conversion/generateJSONPatchTemplateOperations.d.ts +16 -0
  214. package/dist/types/lib/utils/template-type-conversion/mapFieldsWithUniqueKeys.d.ts +8 -0
  215. package/package.json +61 -0
@@ -0,0 +1,43 @@
1
+ declare const _default: {
2
+ callToActionHeader: {
3
+ defaultMessage: string;
4
+ description: string;
5
+ id: string;
6
+ };
7
+ callToActionSubheader: {
8
+ defaultMessage: string;
9
+ description: string;
10
+ id: string;
11
+ };
12
+ allowMultipleTaxonomySelections: {
13
+ defaultMessage: string;
14
+ description: string;
15
+ id: string;
16
+ };
17
+ selection: {
18
+ defaultMessage: string;
19
+ description: string;
20
+ id: string;
21
+ };
22
+ requiredSelection: {
23
+ defaultMessage: string;
24
+ description: string;
25
+ id: string;
26
+ };
27
+ anyLevelSelection: {
28
+ defaultMessage: string;
29
+ description: string;
30
+ id: string;
31
+ };
32
+ chooseTaxonomyLevel: {
33
+ defaultMessage: string;
34
+ description: string;
35
+ id: string;
36
+ };
37
+ noTaxonomySelectedError: {
38
+ defaultMessage: string;
39
+ description: string;
40
+ id: string;
41
+ };
42
+ };
43
+ export default _default;
@@ -0,0 +1,191 @@
1
+ import { DraggableAttributes } from '@dnd-kit/core';
2
+ import { useSortable } from '@dnd-kit/sortable';
3
+ import { default as React } from 'react';
4
+ import { FieldConfiguratorExtension } from './context/field-extensions-context';
5
+ import { FieldData, TaxonomyOption } from '../../types';
6
+ type ValidatableFieldNames = 'name' | 'description' | 'key' | 'type' | 'hidden' | 'taxonomy' | 'dropdown';
7
+ /** Externally supplied validation state that overrides internal errors when present. */
8
+ export type GeneralComponentProps = {
9
+ /** Per-field error messages injected from outside (e.g., server-side validation). */
10
+ externalErrors?: Partial<Record<ValidatableFieldNames, string>>;
11
+ /** Marks which fields have been touched so `externalErrors` are actually displayed. */
12
+ externalTouched?: Partial<Record<ValidatableFieldNames, boolean>>;
13
+ };
14
+ /** Props for dnd-kit drag handle integration. */
15
+ export type DndDragHandleProps = {
16
+ /** dnd-kit pointer/keyboard event listeners to spread onto the drag handle element. */
17
+ listeners?: ReturnType<typeof useSortable>['listeners'];
18
+ /** dnd-kit ARIA attributes to spread onto the drag handle element. */
19
+ attributes?: DraggableAttributes;
20
+ };
21
+ /** Drag props when using native HTML5 drag events (no dnd-kit integration). */
22
+ type NativeDragProps = {
23
+ /** Must be `undefined` to distinguish from dnd-kit mode. */
24
+ dndDragHandleProps?: undefined;
25
+ /** Called when the user starts dragging the field handle. */
26
+ onDragStart: (event: React.DragEvent<HTMLDivElement>, index: number) => void;
27
+ /** Called when the drag operation ends (dropped or cancelled). */
28
+ onDragEnd: (event: React.DragEvent<HTMLDivElement>, index: number) => void;
29
+ /** Called when the user touches the drag handle on a touch device. */
30
+ onTouchStart: (event: React.TouchEvent<HTMLDivElement>, index: number) => void;
31
+ };
32
+ /** Drag props when using dnd-kit sensors for drag-and-drop (mutually exclusive with NativeDragProps). */
33
+ type DndKitDragProps = {
34
+ /** dnd-kit listeners and ARIA attributes for the drag handle. */
35
+ dndDragHandleProps: DndDragHandleProps;
36
+ onDragStart?: never;
37
+ onDragEnd?: never;
38
+ onTouchStart?: never;
39
+ };
40
+ /**
41
+ * Fully controlled component for configuring a single metadata template field.
42
+ *
43
+ * The parent owns all form state and passes it down via props.
44
+ * Sub-components access the state through {@link FieldConfiguratorContext}
45
+ * (see {@link FieldConfiguratorContextValue}).
46
+ *
47
+ * Validation (Yup schema, touched tracking, error messages) is handled internally.
48
+ * Supply `externalErrors` / `externalTouched` only for server-side errors.
49
+ */
50
+ export type MetadataFieldConfiguratorProps = GeneralComponentProps & (NativeDragProps | DndKitDragProps) & {
51
+ /** Zero-based position of this field in its parent list. */
52
+ index: number;
53
+ /** Index of the last field; used to disable the "Move down" action on the last item. */
54
+ maxIndex?: number;
55
+ /** Current field data — the single source of truth. */
56
+ values: FieldData;
57
+ /** Called on every values change. The parent should persist the new values in state. */
58
+ onValuesChange: (values: FieldData) => void;
59
+ /** Called with the field key when the user confirms deletion. */
60
+ onDelete?: (key: string) => void;
61
+ /** Called when the user requests to duplicate this field. The parent is responsible for creating and inserting the copy. */
62
+ onDuplicate: () => void;
63
+ /** Called with source and destination indices when the user reorders this field. */
64
+ onReorderFields: (fromIndex: number, toIndex: number) => void;
65
+ /**
66
+ * When provided, the component operates in list mode: it renders only an Accordion.Item
67
+ * (no Accordion root) and this value drives the open/closed state for validation tracking.
68
+ * The parent MetadataFieldList provides the shared Accordion root.
69
+ * When omitted, the component is standalone and manages its own Accordion root.
70
+ */
71
+ isExpanded?: boolean;
72
+ /**
73
+ * Called when the component wants to be expanded (e.g. when isFieldNew becomes true).
74
+ * Only meaningful in list mode (when isExpanded is provided).
75
+ */
76
+ onExpandedChange?: (expanded: boolean) => void;
77
+ /**
78
+ * An incrementing counter supplied by the parent form.
79
+ * Each time the value increases (e.g. on a failed submit), the configurator
80
+ * calls `touchAll()` so that all validation errors become visible immediately.
81
+ */
82
+ submitAttemptCount?: number;
83
+ /**
84
+ * Static taxonomy options (pre-fetched by the host). Use when you have already loaded
85
+ * the available taxonomies before rendering this component.
86
+ *
87
+ * Mutually exclusive with `fetchTaxonomies` — if both are provided, `fetchTaxonomies` takes precedence.
88
+ */
89
+ taxonomyOptions?: TaxonomyOption[];
90
+ /**
91
+ * Async function that resolves to the list of available taxonomy options.
92
+ *
93
+ * When provided, the shared feature calls this automatically the first time the user opens the
94
+ * taxonomy selector, then caches the result for the lifetime of the component. Loading and error
95
+ * states (including a retry button) are handled internally — the implementing team only needs to
96
+ * supply the fetch logic.
97
+ *
98
+ * Mutually exclusive with `taxonomyOptions`.
99
+ */
100
+ fetchTaxonomies?: () => Promise<TaxonomyOption[]>;
101
+ /**
102
+ * Domain-specific extensions to inject into this field's configurator panel.
103
+ *
104
+ * When provided, a tab switcher appears next to the context menu in the accordion header.
105
+ * The first tab always shows the built-in Edit UI; each additional tab renders the
106
+ * corresponding extension's content with the current field data passed as an argument.
107
+ *
108
+ * Switching tabs resets to the Edit tab whenever the accordion item is collapsed.
109
+ *
110
+ * Can also be injected at a higher level via `MetadataFieldList`, `MetadataTemplateEditorForm`,
111
+ * or `MetadataTemplateEditor` — the nearest provider in the tree wins.
112
+ */
113
+ fieldExtensions?: FieldConfiguratorExtension[];
114
+ /**
115
+ * Called whenever this field's internal validation state changes.
116
+ *
117
+ * Fires with `true` only after Yup has confirmed the field is valid. Until that
118
+ * async check finishes, the hook reports `false` (conservative for submit gating).
119
+ * After the first result, fires `false` when any validation error is detected.
120
+ *
121
+ * @example
122
+ * ```tsx
123
+ * const [isFieldValid, setIsFieldValid] = useState(true);
124
+ *
125
+ * <MetadataFieldConfigurator
126
+ * values={values}
127
+ * onValuesChange={setValues}
128
+ * onValidationChange={setIsFieldValid}
129
+ * // ...
130
+ * />
131
+ * <button disabled={!isFieldValid}>Save</button>
132
+ * ```
133
+ */
134
+ onValidationChange?: (isValid: boolean) => void;
135
+ };
136
+ /**
137
+ * A form-backed accordion item for configuring a single metadata field.
138
+ *
139
+ * Supports two operating modes:
140
+ * - **Standalone**: manages its own Accordion root and open/closed state internally.
141
+ * - **List mode**: when `isExpanded` is provided, the parent `MetadataFieldList` owns
142
+ * the shared Accordion root and controls open/closed state.
143
+ *
144
+ * Drag-and-drop can be handled via native HTML5 events or dnd-kit (mutually exclusive).
145
+ *
146
+ * All state, effects, and callbacks live in {@link useFieldConfiguratorBehavior}.
147
+ * The edit form is rendered by {@link FieldEditContent}.
148
+ * The accordion header toolbar is rendered by {@link FieldActionSlot}.
149
+ *
150
+ * @example
151
+ * ```tsx
152
+ * // Standalone usage — host owns values state
153
+ * const [values, setValues] = useState<FieldData>(
154
+ * createDefaultFieldValues(FieldType.Text),
155
+ * );
156
+ * const [isValid, setIsValid] = useState(false);
157
+ *
158
+ * <MetadataFieldConfigurator
159
+ * index={0}
160
+ * maxIndex={0}
161
+ * values={values}
162
+ * onValuesChange={setValues}
163
+ * onValidationChange={setIsValid}
164
+ * onDelete={key => console.log('deleted', key)}
165
+ * onReorderFields={(from, to) => console.log('reorder', from, to)}
166
+ * // Native HTML5 drag — swap for dndDragHandleProps when using dnd-kit
167
+ * onDragStart={(e, i) => {}}
168
+ * onDragEnd={(e, i) => {}}
169
+ * onTouchStart={(e, i) => {}}
170
+ * fetchTaxonomies={() => api.getTaxonomies()}
171
+ * />
172
+ * <button disabled={!isValid}>Save</button>
173
+ * ```
174
+ *
175
+ * @example
176
+ * ```tsx
177
+ * // With dnd-kit drag handle (e.g. inside a custom sortable list)
178
+ * const { attributes, listeners } = useSortable({ id: values.id });
179
+ *
180
+ * <MetadataFieldConfigurator
181
+ * index={index}
182
+ * maxIndex={maxIndex}
183
+ * values={values}
184
+ * onValuesChange={setValues}
185
+ * onReorderFields={handleReorder}
186
+ * dndDragHandleProps={{ listeners, attributes }}
187
+ * />
188
+ * ```
189
+ */
190
+ export declare const MetadataFieldConfigurator: ({ index, maxIndex, values, onValuesChange, onDelete, onDuplicate, onReorderFields, onTouchStart, onDragStart, onDragEnd, externalErrors, externalTouched, dndDragHandleProps, isExpanded, onExpandedChange, taxonomyOptions, fetchTaxonomies, submitAttemptCount, fieldExtensions: fieldExtensionsProp, onValidationChange, }: MetadataFieldConfiguratorProps) => import("react/jsx-runtime").JSX.Element;
191
+ export {};
@@ -0,0 +1,5 @@
1
+ import { TaxonomyOption } from '../../../types';
2
+ export declare const mockRegionTaxonomyOption: TaxonomyOption;
3
+ export declare const mockDepartmentTaxonomyOption: TaxonomyOption;
4
+ /** Region (selected) + Department — the standard two-taxonomy array used across interaction tests. */
5
+ export declare const mockTaxonomyOptions: TaxonomyOption[];
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ import { FieldData, FieldType } from '../../types';
3
+ /**
4
+ * Returns a fresh default `FieldData` object for the given field type.
5
+ *
6
+ * - A new object (and new option IDs) is produced on every call.
7
+ * - `dropdown.options` contains one empty entry only when `type` is `Dropdown`;
8
+ * for all other types the array is empty.
9
+ */
10
+ export declare function createDefaultFieldValues(type?: FieldType): FieldData;
11
+ export declare const getConfigurationByType: (type: FieldType) => React.ReactElement | null;
12
+ /**
13
+ * Returns true only when `errors` contains at least one leaf error whose
14
+ * exact path in `touched` is `true`.
15
+ *
16
+ * A shallow `touched[topLevelKey]` check is insufficient because lodash `set`
17
+ * creates intermediate objects (e.g. `{ dropdown: { options: [...] } }`) as
18
+ * soon as *any* nested field is touched, making the top-level key truthy even
19
+ * when the specific erroring field (e.g. a newly-added empty option) has never
20
+ * been interacted with.
21
+ */
22
+ export declare function hasVisibleErrors(errors: unknown, touched: unknown): boolean;
23
+ /** Recursively converts an object tree into a same-shape tree with all leaves set to `true`. */
24
+ export declare function markAllTouched(obj: Record<string, unknown>): Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ export { MetadataFieldList, default as MetadataFieldListDefault } from './metadata-field-list';
2
+ export type { MetadataFieldListProps, MetadataFieldListHandle } from './metadata-field-list';
@@ -0,0 +1,109 @@
1
+ import { MetadataFieldConfiguratorProps } from '../metadata-field-configurator';
2
+ import { FieldConfiguratorExtension } from '../metadata-field-configurator/context/field-extensions-context';
3
+ import { FieldData } from '../../types';
4
+ /**
5
+ * Imperative handle exposed by `MetadataFieldList` via `forwardRef`.
6
+ * Use it to programmatically scroll to and expand a specific field.
7
+ */
8
+ export type MetadataFieldListHandle = {
9
+ /** Expands the field with the given stable UI id and scrolls it into view. */
10
+ scrollToAndExpand: (fieldId: string) => void;
11
+ };
12
+ export type MetadataFieldListProps = {
13
+ /** The ordered list of field definitions to render. */
14
+ readonly fields: FieldData[];
15
+ /** Called whenever the field list changes (edits, reorders, deletions). */
16
+ readonly onChangeFields?: (fields: FieldData[]) => void;
17
+ /**
18
+ * Called with the zero-based index and the removed field after a deletion is confirmed.
19
+ * Use this for side effects only (e.g. an API delete call).
20
+ * Do NOT update the fields array here — `onChangeFields` already does that.
21
+ */
22
+ readonly onDeleteFieldAtIndex?: (index: number, field: FieldData) => void;
23
+ /** Called with the newly created duplicate field after it is inserted into the list. */
24
+ readonly onDuplicateField?: (field: FieldData) => void;
25
+ /**
26
+ * Static taxonomy options shared across all fields in the list.
27
+ * Use `fetchTaxonomies` instead for lazy loading with built-in loading/error/retry handling.
28
+ */
29
+ readonly taxonomyOptions?: MetadataFieldConfiguratorProps['taxonomyOptions'];
30
+ /**
31
+ * Async function called to fetch available taxonomy options.
32
+ * The list sets up a single shared `TaxonomyOptionsContext` for all its fields — the fetch
33
+ * fires once (on the first taxonomy selector open) and the result is cached for the lifetime
34
+ * of the list. Mutually exclusive with `taxonomyOptions`.
35
+ */
36
+ readonly fetchTaxonomies?: MetadataFieldConfiguratorProps['fetchTaxonomies'];
37
+ /**
38
+ * Zero-based index of the first field with validation errors.
39
+ * Combined with `submitAttemptCount` to re-trigger on repeated failed submits.
40
+ */
41
+ readonly firstInvalidFieldIndex?: number | null;
42
+ /**
43
+ * Mirrors Formik's `submitCount`. Each time this increments, the list scrolls
44
+ * to `firstInvalidFieldIndex` (if set) and marks all field errors as visible.
45
+ */
46
+ readonly submitAttemptCount?: number;
47
+ /**
48
+ * Domain-specific extensions injected into every field configurator in this list.
49
+ *
50
+ * Providing this prop wraps the list in a `FieldExtensionsContext.Provider`, making
51
+ * the extensions available to all `MetadataFieldConfigurator` instances without
52
+ * requiring per-field prop drilling.
53
+ *
54
+ * See `FieldConfiguratorExtension` for the shape of each extension.
55
+ */
56
+ readonly fieldExtensions?: FieldConfiguratorExtension[];
57
+ /**
58
+ * Called whenever the aggregate validity of all fields changes.
59
+ *
60
+ * Fires `false` as soon as any field fails its internal Yup validation, and `true`
61
+ * once every field in the list satisfies the schema again. An empty list is
62
+ * considered valid.
63
+ *
64
+ * Useful for gating a custom submit button without implementing field-level
65
+ * validation yourself.
66
+ *
67
+ * @example
68
+ * ```tsx
69
+ * const [allFieldsValid, setAllFieldsValid] = useState(true);
70
+ *
71
+ * <MetadataFieldList
72
+ * fields={fields}
73
+ * onChangeFields={setFields}
74
+ * onValidationChange={setAllFieldsValid}
75
+ * />
76
+ * <button disabled={!allFieldsValid}>Save</button>
77
+ * ```
78
+ */
79
+ readonly onValidationChange?: (isValid: boolean) => void;
80
+ };
81
+ /**
82
+ * Renders an ordered, drag-and-drop list of metadata field configurators.
83
+ *
84
+ * Uses dnd-kit for pointer/touch/keyboard drag-and-drop reordering and a single
85
+ * shared Radix Accordion root so only one field is expanded at a time.
86
+ *
87
+ * @example
88
+ * ```tsx
89
+ * // Basic usage — onChangeFields handles all mutations including deletion
90
+ * <MetadataFieldList
91
+ * fields={fields}
92
+ * onChangeFields={setFields}
93
+ * />
94
+ *
95
+ * // With validation gating, lazy taxonomy loading, and an API delete side-effect
96
+ * const [allValid, setAllValid] = useState(true);
97
+ *
98
+ * <MetadataFieldList
99
+ * fields={fields}
100
+ * onChangeFields={setFields}
101
+ * onDeleteFieldAtIndex={(index, field) => api.deleteField(field.key)}
102
+ * onValidationChange={setAllValid}
103
+ * fetchTaxonomies={() => api.getTaxonomies()}
104
+ * />
105
+ * <button disabled={!allValid}>Save</button>
106
+ * ```
107
+ */
108
+ export declare const MetadataFieldList: import('react').ForwardRefExoticComponent<MetadataFieldListProps & import('react').RefAttributes<MetadataFieldListHandle>>;
109
+ export default MetadataFieldList;
@@ -0,0 +1,20 @@
1
+ import { MetadataFieldListProps } from '../metadata-field-list';
2
+ import { FieldConfiguratorExtension } from '../metadata-field-configurator/context/field-extensions-context';
3
+ type MetadataTemplateEditorFormProps = {
4
+ formId?: string;
5
+ onCancel?: () => void;
6
+ taxonomyOptions?: MetadataFieldListProps['taxonomyOptions'];
7
+ fetchTaxonomies?: MetadataFieldListProps['fetchTaxonomies'];
8
+ hideActions?: boolean;
9
+ isEditMode?: boolean;
10
+ onDirtyStateChange?: (isDirty: boolean) => void;
11
+ onValidationChange?: (isValid: boolean) => void;
12
+ /**
13
+ * Domain-specific extensions injected into every field configurator.
14
+ * Wraps the form in a `FieldExtensionsContext.Provider` so all nested
15
+ * configurators can consume the extensions without per-field prop drilling.
16
+ */
17
+ fieldExtensions?: FieldConfiguratorExtension[];
18
+ };
19
+ declare const MetadataTemplateEditorForm: ({ formId, onCancel, taxonomyOptions, fetchTaxonomies, hideActions, isEditMode, onDirtyStateChange, onValidationChange, fieldExtensions, }: MetadataTemplateEditorFormProps) => import("react/jsx-runtime").JSX.Element;
20
+ export default MetadataTemplateEditorForm;
@@ -0,0 +1 @@
1
+ export { MetadataTemplateEditorModal } from './metadata-template-editor-modal';
@@ -0,0 +1,56 @@
1
+ import { MetadataTemplateEditorProps } from '../../metadata-template-editor';
2
+ export type MetadataTemplateEditorModalProps = MetadataTemplateEditorProps & {
3
+ /** Controls whether the modal is open. */
4
+ open: boolean;
5
+ /**
6
+ * Called when the modal requests an open-state change (close button, overlay click, Escape key).
7
+ * Use this to update the `open` prop in the parent.
8
+ */
9
+ onOpenChange: (open: boolean) => void;
10
+ /**
11
+ * Text displayed in the modal header.
12
+ * @default "New Metadata Template"
13
+ */
14
+ title?: string;
15
+ };
16
+ /**
17
+ * Modal wrapper around `MetadataTemplateEditor`.
18
+ *
19
+ * Renders the full template editor inside a Blueprint `Modal`, with Cancel and
20
+ * Save buttons promoted to the modal footer. The modal closes automatically
21
+ * after a successful submission or when the user cancels.
22
+ *
23
+ * The footer Save button is disabled while a submission is in progress. In **edit mode**
24
+ * it is additionally disabled until the user makes at least one change (`dirty`).
25
+ *
26
+ * The "unsaved changes" guard (dirty check + confirmation modal) is owned entirely
27
+ * by `MetadataTemplateEditor`. The modal delegates its footer Cancel and shell-close
28
+ * triggers to the editor via an imperative ref, so the guard logic and the
29
+ * `ConfirmationModal` live in exactly one place.
30
+ *
31
+ * @example
32
+ * ```tsx
33
+ * const [open, setOpen] = useState(false);
34
+ *
35
+ * // Create flow
36
+ * <MetadataTemplateEditorModal
37
+ * open={open}
38
+ * onOpenChange={setOpen}
39
+ * onCreateTemplate={async body => { await api.createTemplate(body); }}
40
+ * onSubmitError={err => logger.error('save failed', err)}
41
+ * />
42
+ *
43
+ * // Edit flow — dynamic title, error callback
44
+ * <MetadataTemplateEditorModal
45
+ * mode={MetadataTemplateEditorMode.Edit}
46
+ * open={open}
47
+ * onOpenChange={setOpen}
48
+ * fetchTemplate={useCallback(() => api.getTemplate(templateKey), [templateKey])}
49
+ * onEditTemplate={async patches => { await api.updateTemplate(patches); }}
50
+ * onSubmitError={err => logger.error('save failed', err)}
51
+ * title="Edit Template"
52
+ * />
53
+ * ```
54
+ */
55
+ export declare function MetadataTemplateEditorModal({ open, onOpenChange, onTemplateLoad, onValidationChange, onCancel, title, ...editorProps }: MetadataTemplateEditorModalProps): import("react/jsx-runtime").JSX.Element;
56
+ export default MetadataTemplateEditorModal;
@@ -0,0 +1,17 @@
1
+ import * as Yup from 'yup';
2
+ export declare const useMetadataTemplateFormSchema: () => Yup.ObjectSchema<{
3
+ displayName: string;
4
+ templateKey: Yup.Maybe<string | undefined>;
5
+ fields: Yup.Maybe<{
6
+ description?: string | null | undefined;
7
+ name: string;
8
+ type: NonNullable<import('../types').FieldType | undefined>;
9
+ hidden: NonNullable<boolean | undefined>;
10
+ }[] | undefined>;
11
+ hidden: boolean | undefined;
12
+ }, Yup.AnyObject, {
13
+ displayName: undefined;
14
+ templateKey: undefined;
15
+ fields: "";
16
+ hidden: undefined;
17
+ }, "">;
@@ -0,0 +1,2 @@
1
+ import * as Yup from 'yup';
2
+ export declare const useTemplateNameSchema: () => Yup.StringSchema<string, Yup.AnyObject, undefined, "">;
@@ -0,0 +1,7 @@
1
+ export { MetadataTemplateEditor } from './metadata-template-editor';
2
+ export type { MetadataTemplateEditorProps } from './metadata-template-editor';
3
+ export { useMetadataTemplateFormSchema } from './hooks/useMetadataTemplateFormSchema';
4
+ export { useTemplateNameSchema } from './hooks/useTemplateNameSchema';
5
+ export { convertApiMetadataTemplateFieldToLocalConfiguratorField } from './utils/template-type-conversion/convertTemplateFieldToLocalConfigurator';
6
+ export { mapFieldsWithUniqueKeys } from './utils/template-type-conversion/mapFieldsWithUniqueKeys';
7
+ export { generateJSONPatchTemplateOperations } from './utils/template-type-conversion/generateJSONPatchTemplateOperations';
@@ -0,0 +1,143 @@
1
+ declare const _default: {
2
+ createTitle: {
3
+ defaultMessage: string;
4
+ description: string;
5
+ id: string;
6
+ };
7
+ editTitle: {
8
+ defaultMessage: string;
9
+ description: string;
10
+ id: string;
11
+ };
12
+ templateName: {
13
+ defaultMessage: string;
14
+ description: string;
15
+ id: string;
16
+ };
17
+ templateNameDescription: {
18
+ defaultMessage: string;
19
+ description: string;
20
+ id: string;
21
+ };
22
+ cancel: {
23
+ defaultMessage: string;
24
+ description: string;
25
+ id: string;
26
+ };
27
+ save: {
28
+ defaultMessage: string;
29
+ description: string;
30
+ id: string;
31
+ };
32
+ fields: {
33
+ defaultMessage: string;
34
+ description: string;
35
+ id: string;
36
+ };
37
+ fieldsAddFirst: {
38
+ defaultMessage: string;
39
+ description: string;
40
+ id: string;
41
+ };
42
+ fieldsLearnMore: {
43
+ defaultMessage: string;
44
+ description: string;
45
+ id: string;
46
+ };
47
+ fieldRequired: {
48
+ defaultMessage: string;
49
+ description: string;
50
+ id: string;
51
+ };
52
+ forbiddenDisplayName: {
53
+ defaultMessage: string;
54
+ description: string;
55
+ id: string;
56
+ };
57
+ invalidCharacters: {
58
+ defaultMessage: string;
59
+ description: string;
60
+ id: string;
61
+ };
62
+ fieldNameTooLong: {
63
+ defaultMessage: string;
64
+ description: string;
65
+ id: string;
66
+ };
67
+ displayNameUsedBefore: {
68
+ defaultMessage: string;
69
+ description: string;
70
+ id: string;
71
+ };
72
+ submitting: {
73
+ defaultMessage: string;
74
+ description: string;
75
+ id: string;
76
+ };
77
+ closeAriaLabel: {
78
+ defaultMessage: string;
79
+ description: string;
80
+ id: string;
81
+ };
82
+ saveSuccessNotification: {
83
+ defaultMessage: string;
84
+ description: string;
85
+ id: string;
86
+ };
87
+ saveErrorNotification: {
88
+ defaultMessage: string;
89
+ description: string;
90
+ id: string;
91
+ };
92
+ notificationSuccessIconAriaLabel: {
93
+ defaultMessage: string;
94
+ description: string;
95
+ id: string;
96
+ };
97
+ notificationErrorIconAriaLabel: {
98
+ defaultMessage: string;
99
+ description: string;
100
+ id: string;
101
+ };
102
+ notificationCloseButtonAriaLabel: {
103
+ defaultMessage: string;
104
+ description: string;
105
+ id: string;
106
+ };
107
+ loading: {
108
+ defaultMessage: string;
109
+ description: string;
110
+ id: string;
111
+ };
112
+ fetchError: {
113
+ defaultMessage: string;
114
+ description: string;
115
+ id: string;
116
+ };
117
+ reload: {
118
+ defaultMessage: string;
119
+ description: string;
120
+ id: string;
121
+ };
122
+ unsavedChangesTitle: {
123
+ defaultMessage: string;
124
+ description: string;
125
+ id: string;
126
+ };
127
+ unsavedChangesBody: {
128
+ defaultMessage: string;
129
+ description: string;
130
+ id: string;
131
+ };
132
+ unsavedChangesDiscard: {
133
+ defaultMessage: string;
134
+ description: string;
135
+ id: string;
136
+ };
137
+ unsavedChangesKeepEditing: {
138
+ defaultMessage: string;
139
+ description: string;
140
+ id: string;
141
+ };
142
+ };
143
+ export default _default;