@open-pioneer/feature-editing 1.5.0-dev.20260911123645 → 1.5.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 (68) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/README.md +54 -12
  3. package/_virtual/hooks.js.map +1 -1
  4. package/_virtual/source-info.js +7 -1
  5. package/_virtual/source-info.js.map +1 -1
  6. package/api/editor/context.js.map +1 -1
  7. package/api/editor/editor.d.ts +13 -0
  8. package/api/editor/editor.js.map +1 -1
  9. package/api/model/SelectionAvailability.d.ts +39 -0
  10. package/i18n/de.yaml +8 -0
  11. package/i18n/en.yaml +8 -0
  12. package/implementation/FeatureEditor.js +5 -0
  13. package/implementation/FeatureEditor.js.map +1 -1
  14. package/implementation/components/action-selector/ActionSelector.d.ts +12 -5
  15. package/implementation/components/action-selector/ActionSelector.js +27 -2
  16. package/implementation/components/action-selector/ActionSelector.js.map +1 -1
  17. package/implementation/components/action-selector/DrawingControls.js.map +1 -1
  18. package/implementation/components/action-selector/SelectButton.d.ts +6 -4
  19. package/implementation/components/action-selector/SelectButton.js +20 -5
  20. package/implementation/components/action-selector/SelectButton.js.map +1 -1
  21. package/implementation/components/action-selector/TemplateItem.js.map +1 -1
  22. package/implementation/components/action-selector/TemplateSelector.js.map +1 -1
  23. package/implementation/components/controls/ColorPickerControl.js.map +1 -1
  24. package/implementation/components/controls/ComboBoxControl.js.map +1 -1
  25. package/implementation/components/controls/DefaultControl.js.map +1 -1
  26. package/implementation/components/controls/NumberFieldControl.js.map +1 -1
  27. package/implementation/components/controls/RadioGroupControl.js.map +1 -1
  28. package/implementation/components/controls/SelectControl.js.map +1 -1
  29. package/implementation/components/controls/option-hooks.js.map +1 -1
  30. package/implementation/components/property-editor/ButtonRow.js.map +1 -1
  31. package/implementation/components/property-editor/CancelConfirmationDialog.js.map +1 -1
  32. package/implementation/components/property-editor/DeleteConfirmationDialog.js.map +1 -1
  33. package/implementation/components/property-editor/PropertyEditor.js +25 -5
  34. package/implementation/components/property-editor/PropertyEditor.js.map +1 -1
  35. package/implementation/components/property-editor/PropertyField.js.map +1 -1
  36. package/implementation/components/property-editor/PropertyForm.js.map +1 -1
  37. package/implementation/context/PropertyFormContext.d.ts +4 -1
  38. package/implementation/context/PropertyFormContext.js +56 -6
  39. package/implementation/context/PropertyFormContext.js.map +1 -1
  40. package/implementation/context/usePropertyFormContext.js.map +1 -1
  41. package/implementation/editor/editorHooks.d.ts +6 -0
  42. package/implementation/editor/editorHooks.js +34 -5
  43. package/implementation/editor/editorHooks.js.map +1 -1
  44. package/implementation/editor/useEditingCallbacks.js +1 -1
  45. package/implementation/editor/useEditingCallbacks.js.map +1 -1
  46. package/implementation/geometry-editing/controller/DrawingSession.js.map +1 -1
  47. package/implementation/geometry-editing/controller/EditingController.js.map +1 -1
  48. package/implementation/geometry-editing/controller/UndoManager.js.map +1 -1
  49. package/implementation/geometry-editing/controller/geometryState.js.map +1 -1
  50. package/implementation/geometry-editing/interactions/BaseInteraction.js.map +1 -1
  51. package/implementation/geometry-editing/interactions/DoubleClickInteraction.js.map +1 -1
  52. package/implementation/geometry-editing/interactions/DrawingInteraction.js +2 -13
  53. package/implementation/geometry-editing/interactions/DrawingInteraction.js.map +1 -1
  54. package/implementation/geometry-editing/interactions/HighlightingInteraction.js.map +1 -1
  55. package/implementation/geometry-editing/interactions/KeyboardInteraction.js.map +1 -1
  56. package/implementation/geometry-editing/interactions/ModificationInteraction.js +2 -10
  57. package/implementation/geometry-editing/interactions/ModificationInteraction.js.map +1 -1
  58. package/implementation/geometry-editing/interactions/SelectionInteraction.js +6 -13
  59. package/implementation/geometry-editing/interactions/SelectionInteraction.js.map +1 -1
  60. package/implementation/geometry-editing/interactions/SnappingInteraction.js.map +1 -1
  61. package/implementation/geometry-editing/overlays.d.ts +9 -0
  62. package/implementation/geometry-editing/overlays.js +21 -0
  63. package/implementation/geometry-editing/overlays.js.map +1 -0
  64. package/implementation/geometry-editing/useGeometryEditing.js.map +1 -1
  65. package/index.d.ts +1 -0
  66. package/package.json +12 -13
  67. package/implementation/featureEditing.css +0 -15
  68. package/implementation/featureEditing.css.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateItem.js","sources":["TemplateItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { HStack, Span, Table, Text } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useId, type KeyboardEvent, type ReactElement, type ReactNode } from \"react\";\nimport { PiCircleBold, PiDotOutlineBold, PiLineSegmentsFill, PiPolygonFill } from \"react-icons/pi\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\n\ninterface TemplateItemProps {\n readonly template: FeatureTemplate;\n readonly isSelected: boolean;\n readonly onClick: (featureTemplate: FeatureTemplate) => void;\n}\n\ninterface TemplateIconProps {\n readonly template: FeatureTemplate;\n}\n\nexport function TemplateItem({ template, isSelected, onClick }: TemplateItemProps): ReactElement {\n const templateNameId = useId();\n const onRowClick = useEvent(() => onClick(template));\n const onRowKeyDown = useEvent((event: KeyboardEvent<HTMLTableRowElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick(template);\n }\n });\n\n return (\n <Table.Row\n height=\"45px\"\n cursor=\"pointer\"\n tabIndex={0}\n aria-selected={isSelected}\n aria-labelledby={templateNameId}\n role={\"option\"}\n bg={isSelected ? \"colorPalette.800\" : \"bg\"}\n color={isSelected ? \"colorPalette.contrast\" : \"fg\"}\n _hover={{ bg: isSelected ? \"colorPalette.700\" : \"colorPalette.subtle\" }}\n _focusVisible={{\n outline: \"2px solid\",\n outlineColor: \"colorPalette.focusRing\",\n outlineOffset: \"-2px\"\n }}\n userSelect=\"none\"\n onClick={onRowClick}\n onKeyDown={onRowKeyDown}\n >\n <Table.Cell role=\"presentation\">\n <HStack className=\"editor__template-selector-item\" gap=\"4\">\n <Span aria-hidden=\"true\">\n <TemplateIcon template={template} />\n </Span>\n <Text id={templateNameId}>{template.name}</Text>\n </HStack>\n </Table.Cell>\n </Table.Row>\n );\n}\n\n// Render the icon provided for the template, or a default one if it is 'undefined'. Do not render\n// anything if the icon is 'null'.\nfunction TemplateIcon({ template }: TemplateIconProps): ReactNode | undefined {\n if (template.icon !== undefined) {\n return template.icon;\n }\n\n switch (template.geometryType) {\n case \"Polygon\":\n return <PiPolygonFill size={20} />;\n case \"Circle\":\n return <PiCircleBold size={20} />;\n case \"LineString\":\n return <PiLineSegmentsFill size={20} />;\n case \"Point\":\n return <PiDotOutlineBold size={20} />;\n default:\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;AAmBO,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,UAAA,EAAY,SAAQ,EAAoC;AAC7F,EAAA,MAAM,iBAAiB,KAAA,EAAM;AAC7B,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,MAAM,OAAA,CAAQ,QAAQ,CAAC,CAAA;AACnD,EAAA,MAAM,YAAA,GAAe,QAAA,CAAS,CAAC,KAAA,KAA8C;AACzE,IAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,EAAK;AAC5C,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACpB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,uBACI,GAAA;AAAA,IAAC,KAAA,CAAM,GAAA;AAAA,IAAN;AAAA,MACG,MAAA,EAAO,MAAA;AAAA,MACP,MAAA,EAAO,SAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,eAAA,EAAe,UAAA;AAAA,MACf,iBAAA,EAAiB,cAAA;AAAA,MACjB,IAAA,EAAM,QAAA;AAAA,MACN,EAAA,EAAI,aAAa,kBAAA,GAAqB,IAAA;AAAA,MACtC,KAAA,EAAO,aAAa,uBAAA,GAA0B,IAAA;AAAA,MAC9C,MAAA,EAAQ,EAAE,EAAA,EAAI,UAAA,GAAa,qBAAqB,qBAAA,EAAsB;AAAA,MACtE,aAAA,EAAe;AAAA,QACX,OAAA,EAAS,WAAA;AAAA,QACT,YAAA,EAAc,wBAAA;AAAA,QACd,aAAA,EAAe;AAAA,OACnB;AAAA,MACA,UAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,UAAA;AAAA,MACT,SAAA,EAAW,YAAA;AAAA,MAEX,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,IAAA,EAAK,cAAA,EACb,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,gCAAA,EAAiC,GAAA,EAAI,GAAA,EACnD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAK,aAAA,EAAY,MAAA,EACd,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,UAAoB,CAAA,EACtC,CAAA;AAAA,wBACA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,cAAA,EAAiB,mBAAS,IAAA,EAAK;AAAA,OAAA,EAC7C,CAAA,EACJ;AAAA;AAAA,GACJ;AAER;AAIA,SAAS,YAAA,CAAa,EAAE,QAAA,EAAS,EAA6C;AAC1E,EAAA,IAAI,QAAA,CAAS,SAAS,MAAA,EAAW;AAC7B,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EACpB;AAEA,EAAA,QAAQ,SAAS,YAAA;AAAc,IAC3B,KAAK,SAAA;AACD,MAAA,uBAAO,GAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACpC,KAAK,QAAA;AACD,MAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACnC,KAAK,YAAA;AACD,MAAA,uBAAO,GAAA,CAAC,kBAAA,EAAA,EAAmB,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACzC,KAAK,OAAA;AACD,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACvC;AACI,MAAA,OAAO,MAAA;AAAA;AAEnB;;;;"}
1
+ {"version":3,"file":"TemplateItem.js","sources":["TemplateItem.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { HStack, Span, Table, Text } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useId, type KeyboardEvent, type ReactElement, type ReactNode } from \"react\";\nimport { PiCircleBold, PiDotOutlineBold, PiLineSegmentsFill, PiPolygonFill } from \"react-icons/pi\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\n\ninterface TemplateItemProps {\n readonly template: FeatureTemplate;\n readonly isSelected: boolean;\n readonly onClick: (featureTemplate: FeatureTemplate) => void;\n}\n\ninterface TemplateIconProps {\n readonly template: FeatureTemplate;\n}\n\nexport function TemplateItem({ template, isSelected, onClick }: TemplateItemProps): ReactElement {\n const templateNameId = useId();\n const onRowClick = useEvent(() => onClick(template));\n const onRowKeyDown = useEvent((event: KeyboardEvent<HTMLTableRowElement>) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n onClick(template);\n }\n });\n\n return (\n <Table.Row\n height=\"45px\"\n cursor=\"pointer\"\n tabIndex={0}\n aria-selected={isSelected}\n aria-labelledby={templateNameId}\n role={\"option\"}\n bg={isSelected ? \"colorPalette.800\" : \"bg\"}\n color={isSelected ? \"colorPalette.contrast\" : \"fg\"}\n _hover={{ bg: isSelected ? \"colorPalette.700\" : \"colorPalette.subtle\" }}\n _focusVisible={{\n outline: \"2px solid\",\n outlineColor: \"colorPalette.focusRing\",\n outlineOffset: \"-2px\"\n }}\n userSelect=\"none\"\n onClick={onRowClick}\n onKeyDown={onRowKeyDown}\n >\n <Table.Cell role=\"presentation\">\n <HStack className=\"editor__template-selector-item\" gap=\"4\">\n <Span aria-hidden=\"true\">\n <TemplateIcon template={template} />\n </Span>\n <Text id={templateNameId}>{template.name}</Text>\n </HStack>\n </Table.Cell>\n </Table.Row>\n );\n}\n\n// Render the icon provided for the template, or a default one if it is 'undefined'. Do not render\n// anything if the icon is 'null'.\nfunction TemplateIcon({ template }: TemplateIconProps): ReactNode | undefined {\n if (template.icon !== undefined) {\n return template.icon;\n }\n\n switch (template.geometryType) {\n case \"Polygon\":\n return <PiPolygonFill size={20} />;\n case \"Circle\":\n return <PiCircleBold size={20} />;\n case \"LineString\":\n return <PiLineSegmentsFill size={20} />;\n case \"Point\":\n return <PiDotOutlineBold size={20} />;\n default:\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;AAmBO,SAAS,YAAA,CAAa,EAAE,QAAA,EAAU,UAAA,EAAY,SAAQ,EAAoC;AAC7F,EAAA,MAAM,iBAAiB,KAAA,EAAM;AAC7B,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,MAAM,OAAA,CAAQ,QAAQ,CAAC,CAAA;AACnD,EAAA,MAAM,YAAA,GAAe,QAAA,CAAS,CAAC,KAAA,KAA8C;AACzE,IAAA,IAAI,KAAA,CAAM,GAAA,KAAQ,OAAA,IAAW,KAAA,CAAM,QAAQ,GAAA,EAAK;AAC5C,MAAA,KAAA,CAAM,cAAA,EAAe;AACrB,MAAA,OAAA,CAAQ,QAAQ,CAAA;AAAA,IACpB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,uBACI,GAAA;AAAA,IAAC,KAAA,CAAM,GAAA;AAAA,IAAN;AAAA,MACG,MAAA,EAAO,MAAA;AAAA,MACP,MAAA,EAAO,SAAA;AAAA,MACP,QAAA,EAAU,CAAA;AAAA,MACV,eAAA,EAAe,UAAA;AAAA,MACf,iBAAA,EAAiB,cAAA;AAAA,MACjB,IAAA,EAAM,QAAA;AAAA,MACN,EAAA,EAAI,aAAa,kBAAA,GAAqB,IAAA;AAAA,MACtC,KAAA,EAAO,aAAa,uBAAA,GAA0B,IAAA;AAAA,MAC9C,MAAA,EAAQ,EAAE,EAAA,EAAI,UAAA,GAAa,qBAAqB,qBAAA,EAAsB;AAAA,MACtE,aAAA,EAAe;AAAA,QACX,OAAA,EAAS,WAAA;AAAA,QACT,YAAA,EAAc,wBAAA;AAAA,QACd,aAAA,EAAe;AAAA,OACnB;AAAA,MACA,UAAA,EAAW,MAAA;AAAA,MACX,OAAA,EAAS,UAAA;AAAA,MACT,SAAA,EAAW,YAAA;AAAA,MAEX,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,IAAA,EAAK,cAAA,EACb,QAAA,kBAAA,IAAA,CAAC,MAAA,EAAA,EAAO,SAAA,EAAU,gCAAA,EAAiC,GAAA,EAAI,GAAA,EACnD,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAK,aAAA,EAAY,MAAA,EACd,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,UAAoB,CAAA,EACtC,CAAA;AAAA,wBACA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAI,cAAA,EAAiB,mBAAS,IAAA,EAAK;AAAA,OAAA,EAC7C,CAAA,EACJ;AAAA;AAAA,GACJ;AAER;AAIA,SAAS,YAAA,CAAa,EAAE,QAAA,EAAS,EAA6C;AAC1E,EAAA,IAAI,QAAA,CAAS,SAAS,MAAA,EAAW;AAC7B,IAAA,OAAO,QAAA,CAAS,IAAA;AAAA,EACpB;AAEA,EAAA,QAAQ,SAAS,YAAA;AAAc,IAC3B,KAAK,SAAA;AACD,MAAA,uBAAO,GAAA,CAAC,aAAA,EAAA,EAAc,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACpC,KAAK,QAAA;AACD,MAAA,uBAAO,GAAA,CAAC,YAAA,EAAA,EAAa,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACnC,KAAK,YAAA;AACD,MAAA,uBAAO,GAAA,CAAC,kBAAA,EAAA,EAAmB,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACzC,KAAK,OAAA;AACD,MAAA,uBAAO,GAAA,CAAC,gBAAA,EAAA,EAAiB,IAAA,EAAM,EAAA,EAAI,CAAA;AAAA,IACvC;AACI,MAAA,OAAO,MAAA;AAAA;AAEnB;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"TemplateSelector.js","sources":["TemplateSelector.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Table } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\nimport { TemplateItem } from \"./TemplateItem\";\n\ninterface TemplateSelectorProps {\n readonly templates: FeatureTemplate[];\n readonly selectedTemplate: FeatureTemplate | undefined;\n readonly onClick: (featureTemplate: FeatureTemplate) => void;\n}\n\nexport function TemplateSelector({\n templates,\n selectedTemplate,\n onClick\n}: TemplateSelectorProps): ReactElement {\n return (\n <Table.Root\n role=\"presentation\" // Note: the body/rows implement a listbox pattern\n className=\"editor__template-selector\"\n variant=\"line\"\n size=\"sm\"\n >\n <Table.Body role={\"listbox\"}>\n {templates.map((template, index) => (\n <TemplateItem\n // oxlint-disable-next-line react/no-array-index-key\n key={index}\n template={template}\n isSelected={selectedTemplate === template}\n onClick={onClick}\n />\n ))}\n </Table.Body>\n </Table.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAcO,SAAS,gBAAA,CAAiB;AAAA,EAC7B,SAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACJ,CAAA,EAAwC;AACpC,EAAA,uBACI,GAAA;AAAA,IAAC,KAAA,CAAM,IAAA;AAAA,IAAN;AAAA,MACG,IAAA,EAAK,cAAA;AAAA,MACL,SAAA,EAAU,2BAAA;AAAA,MACV,OAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MAEL,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,IAAA,EAAM,WACb,QAAA,EAAA,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,EAAU,KAAA,qBACtB,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UAGG,QAAA;AAAA,UACA,YAAY,gBAAA,KAAqB,QAAA;AAAA,UACjC;AAAA,SAAA;AAAA,QAHK;AAAA,OAKZ,CAAA,EACL;AAAA;AAAA,GACJ;AAER;;;;"}
1
+ {"version":3,"file":"TemplateSelector.js","sources":["TemplateSelector.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Table } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\nimport { TemplateItem } from \"./TemplateItem\";\n\ninterface TemplateSelectorProps {\n readonly templates: FeatureTemplate[];\n readonly selectedTemplate: FeatureTemplate | undefined;\n readonly onClick: (featureTemplate: FeatureTemplate) => void;\n}\n\nexport function TemplateSelector({\n templates,\n selectedTemplate,\n onClick\n}: TemplateSelectorProps): ReactElement {\n return (\n <Table.Root\n role=\"presentation\" // Note: the body/rows implement a listbox pattern\n className=\"editor__template-selector\"\n variant=\"line\"\n size=\"sm\"\n >\n <Table.Body role={\"listbox\"}>\n {templates.map((template, index) => (\n <TemplateItem\n // oxlint-disable-next-line react/no-array-index-key\n key={index}\n template={template}\n isSelected={selectedTemplate === template}\n onClick={onClick}\n />\n ))}\n </Table.Body>\n </Table.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAcO,SAAS,gBAAA,CAAiB;AAAA,EAC7B,SAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACJ,CAAA,EAAwC;AACpC,EAAA,uBACI,GAAA;AAAA,IAAC,KAAA,CAAM,IAAA;AAAA,IAAN;AAAA,MACG,IAAA,EAAK,cAAA;AAAA,MACL,SAAA,EAAU,2BAAA;AAAA,MACV,OAAA,EAAQ,MAAA;AAAA,MACR,IAAA,EAAK,IAAA;AAAA,MAEL,QAAA,kBAAA,GAAA,CAAC,KAAA,CAAM,IAAA,EAAN,EAAW,IAAA,EAAM,WACb,QAAA,EAAA,SAAA,CAAU,GAAA,CAAI,CAAC,QAAA,EAAU,KAAA,qBACtB,GAAA;AAAA,QAAC,YAAA;AAAA,QAAA;AAAA,UAGG,QAAA;AAAA,UACA,YAAY,gBAAA,KAAqB,QAAA;AAAA,UACjC;AAAA,SAAA;AAAA,QAHK;AAAA,OAKZ,CAAA,EACL;AAAA;AAAA,GACJ;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPickerControl.js","sources":["ColorPickerControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ColorPicker,\n HStack,\n Portal,\n parseColor,\n type ColorPickerValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo, type ReactElement } from \"react\";\nimport { LuCheck } from \"react-icons/lu\";\nimport type { ColorPickerConfig } from \"../../../api/fields/standardFieldConfigs\";\n\ninterface ColorPickerControlProps {\n readonly hexColor: string | undefined;\n readonly field: ColorPickerConfig;\n readonly onChange: (newHexColor: string) => void;\n}\n\ninterface SwatchGroupProps {\n readonly swatchColors: string[] | undefined;\n}\n\nexport function ColorPickerControl({\n hexColor,\n field,\n onChange\n}: ColorPickerControlProps): ReactElement {\n const defaultValue = useMemo(() => parseColor(hexColor ?? \"black\"), [hexColor]);\n\n const onValueChange = useEvent((details: ColorPickerValueChangeDetails) => {\n onChange(details.value.toString(\"hexa\"));\n });\n\n return (\n <ColorPicker.Root defaultValue={defaultValue} onValueChange={onValueChange}>\n <ColorPicker.Control>\n <ColorPicker.Input />\n <ColorPicker.Trigger />\n </ColorPicker.Control>\n <Portal>\n <ColorPicker.Positioner>\n <ColorPicker.Content>\n <ColorPicker.Area />\n <HStack>\n <ColorPicker.EyeDropper size=\"xs\" variant=\"outline\" />\n <ColorPicker.Sliders />\n </HStack>\n <SwatchGroup swatchColors={field.swatchColors} />\n </ColorPicker.Content>\n </ColorPicker.Positioner>\n </Portal>\n </ColorPicker.Root>\n );\n}\n\nfunction SwatchGroup({ swatchColors }: SwatchGroupProps): ReactElement | undefined {\n if (swatchColors != null && swatchColors.length >= 1) {\n return (\n <ColorPicker.SwatchGroup>\n {swatchColors.map((color) => (\n <ColorPicker.SwatchTrigger key={color} value={color}>\n <ColorPicker.Swatch boxSize={4.5} value={color}>\n <ColorPicker.SwatchIndicator>\n <LuCheck />\n </ColorPicker.SwatchIndicator>\n </ColorPicker.Swatch>\n </ColorPicker.SwatchTrigger>\n ))}\n </ColorPicker.SwatchGroup>\n );\n } else {\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;AAyBO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,QAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAA0C;AACtC,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM,UAAA,CAAW,YAAY,OAAO,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAE9E,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,CAAC,OAAA,KAA2C;AACvE,IAAA,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EAC3C,CAAC,CAAA;AAED,EAAA,uBACI,IAAA,CAAC,WAAA,CAAY,IAAA,EAAZ,EAAiB,cAA4B,aAAA,EAC1C,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,WAAA,CAAY,SAAZ,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,CAAY,OAAZ,EAAkB,CAAA;AAAA,sBACnB,GAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EAAoB;AAAA,KAAA,EACzB,CAAA;AAAA,oBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,WAAA,CAAY,YAAZ,EACG,QAAA,kBAAA,IAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,CAAY,MAAZ,EAAiB,CAAA;AAAA,2BACjB,MAAA,EAAA,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAY,UAAA,EAAZ,EAAuB,IAAA,EAAK,IAAA,EAAK,SAAQ,SAAA,EAAU,CAAA;AAAA,wBACpD,GAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EAAoB;AAAA,OAAA,EACzB,CAAA;AAAA,sBACA,GAAA,CAAC,WAAA,EAAA,EAAY,YAAA,EAAc,KAAA,CAAM,YAAA,EAAc;AAAA,KAAA,EACnD,GACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;AAEA,SAAS,WAAA,CAAY,EAAE,YAAA,EAAa,EAA+C;AAC/E,EAAA,IAAI,YAAA,IAAgB,IAAA,IAAQ,YAAA,CAAa,MAAA,IAAU,CAAA,EAAG;AAClD,IAAA,uBACI,GAAA,CAAC,WAAA,CAAY,WAAA,EAAZ,EACI,uBAAa,GAAA,CAAI,CAAC,KAAA,qBACf,GAAA,CAAC,WAAA,CAAY,aAAA,EAAZ,EAAsC,KAAA,EAAO,OAC1C,QAAA,kBAAA,GAAA,CAAC,WAAA,CAAY,MAAA,EAAZ,EAAmB,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,KAAA,EACrC,8BAAC,WAAA,CAAY,eAAA,EAAZ,EACG,QAAA,kBAAA,GAAA,CAAC,WAAQ,CAAA,EACb,CAAA,EACJ,CAAA,EAAA,EAL4B,KAMhC,CACH,CAAA,EACL,CAAA;AAAA,EAER,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;;;;"}
1
+ {"version":3,"file":"ColorPickerControl.js","sources":["ColorPickerControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n ColorPicker,\n HStack,\n Portal,\n parseColor,\n type ColorPickerValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo, type ReactElement } from \"react\";\nimport { LuCheck } from \"react-icons/lu\";\nimport type { ColorPickerConfig } from \"../../../api/fields/standardFieldConfigs\";\n\ninterface ColorPickerControlProps {\n readonly hexColor: string | undefined;\n readonly field: ColorPickerConfig;\n readonly onChange: (newHexColor: string) => void;\n}\n\ninterface SwatchGroupProps {\n readonly swatchColors: string[] | undefined;\n}\n\nexport function ColorPickerControl({\n hexColor,\n field,\n onChange\n}: ColorPickerControlProps): ReactElement {\n const defaultValue = useMemo(() => parseColor(hexColor ?? \"black\"), [hexColor]);\n\n const onValueChange = useEvent((details: ColorPickerValueChangeDetails) => {\n onChange(details.value.toString(\"hexa\"));\n });\n\n return (\n <ColorPicker.Root defaultValue={defaultValue} onValueChange={onValueChange}>\n <ColorPicker.Control>\n <ColorPicker.Input />\n <ColorPicker.Trigger />\n </ColorPicker.Control>\n <Portal>\n <ColorPicker.Positioner>\n <ColorPicker.Content>\n <ColorPicker.Area />\n <HStack>\n <ColorPicker.EyeDropper size=\"xs\" variant=\"outline\" />\n <ColorPicker.Sliders />\n </HStack>\n <SwatchGroup swatchColors={field.swatchColors} />\n </ColorPicker.Content>\n </ColorPicker.Positioner>\n </Portal>\n </ColorPicker.Root>\n );\n}\n\nfunction SwatchGroup({ swatchColors }: SwatchGroupProps): ReactElement | undefined {\n if (swatchColors != null && swatchColors.length >= 1) {\n return (\n <ColorPicker.SwatchGroup>\n {swatchColors.map((color) => (\n <ColorPicker.SwatchTrigger key={color} value={color}>\n <ColorPicker.Swatch boxSize={4.5} value={color}>\n <ColorPicker.SwatchIndicator>\n <LuCheck />\n </ColorPicker.SwatchIndicator>\n </ColorPicker.Swatch>\n </ColorPicker.SwatchTrigger>\n ))}\n </ColorPicker.SwatchGroup>\n );\n } else {\n return undefined;\n }\n}\n"],"names":[],"mappings":";;;;;;AAyBO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,QAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAA0C;AACtC,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM,UAAA,CAAW,YAAY,OAAO,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAE9E,EAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,CAAC,OAAA,KAA2C;AACvE,IAAA,QAAA,CAAS,OAAA,CAAQ,KAAA,CAAM,QAAA,CAAS,MAAM,CAAC,CAAA;AAAA,EAC3C,CAAC,CAAA;AAED,EAAA,uBACI,IAAA,CAAC,WAAA,CAAY,IAAA,EAAZ,EAAiB,cAA4B,aAAA,EAC1C,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,WAAA,CAAY,SAAZ,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,CAAY,OAAZ,EAAkB,CAAA;AAAA,sBACnB,GAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EAAoB;AAAA,KAAA,EACzB,CAAA;AAAA,oBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,WAAA,CAAY,YAAZ,EACG,QAAA,kBAAA,IAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,CAAY,MAAZ,EAAiB,CAAA;AAAA,2BACjB,MAAA,EAAA,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAY,UAAA,EAAZ,EAAuB,IAAA,EAAK,IAAA,EAAK,SAAQ,SAAA,EAAU,CAAA;AAAA,wBACpD,GAAA,CAAC,WAAA,CAAY,OAAA,EAAZ,EAAoB;AAAA,OAAA,EACzB,CAAA;AAAA,sBACA,GAAA,CAAC,WAAA,EAAA,EAAY,YAAA,EAAc,KAAA,CAAM,YAAA,EAAc;AAAA,KAAA,EACnD,GACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;AAEA,SAAS,WAAA,CAAY,EAAE,YAAA,EAAa,EAA+C;AAC/E,EAAA,IAAI,YAAA,IAAgB,IAAA,IAAQ,YAAA,CAAa,MAAA,IAAU,CAAA,EAAG;AAClD,IAAA,uBACI,GAAA,CAAC,WAAA,CAAY,WAAA,EAAZ,EACI,uBAAa,GAAA,CAAI,CAAC,KAAA,qBACf,GAAA,CAAC,WAAA,CAAY,aAAA,EAAZ,EAAsC,KAAA,EAAO,OAC1C,QAAA,kBAAA,GAAA,CAAC,WAAA,CAAY,MAAA,EAAZ,EAAmB,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,KAAA,EACrC,8BAAC,WAAA,CAAY,eAAA,EAAZ,EACG,QAAA,kBAAA,GAAA,CAAC,WAAQ,CAAA,EACb,CAAA,EACJ,CAAA,EAAA,EAL4B,KAMhC,CACH,CAAA,EACL,CAAA;AAAA,EAER,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ComboBoxControl.js","sources":["ComboBoxControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Combobox, Portal } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOptionProps, type OptionControlProps } from \"./option-hooks\";\n\nexport function ComboBoxControl(props: OptionControlProps<ComboBoxConfig>): ReactElement {\n const {\n selectedValue,\n collection,\n placeholder,\n showClearTrigger,\n onInputValueChange,\n onValueChange\n } = useOptionProps(props);\n\n return (\n <Combobox.Root\n value={selectedValue}\n collection={collection}\n onInputValueChange={onInputValueChange}\n onValueChange={onValueChange}\n >\n <Combobox.Control>\n <Combobox.Input placeholder={placeholder} />\n <Combobox.IndicatorGroup>\n {showClearTrigger && <Combobox.ClearTrigger />}\n <Combobox.Trigger />\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n <Portal>\n <Combobox.Positioner>\n <Combobox.Content>\n {collection.items.map((option) => (\n <Combobox.Item key={option.value} item={option}>\n {option.label}\n <Combobox.ItemIndicator />\n </Combobox.Item>\n ))}\n </Combobox.Content>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,gBAAgB,KAAA,EAAyD;AACrF,EAAA,MAAM;AAAA,IACF,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACJ,GAAI,eAAe,KAAK,CAAA;AAExB,EAAA,uBACI,IAAA;AAAA,IAAC,QAAA,CAAS,IAAA;AAAA,IAAT;AAAA,MACG,KAAA,EAAO,aAAA;AAAA,MACP,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,aAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,QAAA,CAAS,SAAT,EACG,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAA,CAAS,KAAA,EAAT,EAAe,WAAA,EAA0B,CAAA;AAAA,0BAC1C,IAAA,CAAC,QAAA,CAAS,cAAA,EAAT,EACI,QAAA,EAAA;AAAA,YAAA,gBAAA,oBAAoB,GAAA,CAAC,QAAA,CAAS,YAAA,EAAT,EAAsB,CAAA;AAAA,4BAC5C,GAAA,CAAC,QAAA,CAAS,OAAA,EAAT,EAAiB;AAAA,WAAA,EACtB;AAAA,SAAA,EACJ,CAAA;AAAA,wBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,QAAA,CAAS,YAAT,EACG,QAAA,kBAAA,GAAA,CAAC,SAAS,OAAA,EAAT,EACI,qBAAW,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,qBACnB,IAAA,CAAC,SAAS,IAAA,EAAT,EAAiC,MAAM,MAAA,EACnC,QAAA,EAAA;AAAA,UAAA,MAAA,CAAO,KAAA;AAAA,0BACR,GAAA,CAAC,QAAA,CAAS,aAAA,EAAT,EAAuB;AAAA,SAAA,EAAA,EAFR,MAAA,CAAO,KAG3B,CACH,CAAA,EACL,GACJ,CAAA,EACJ;AAAA;AAAA;AAAA,GACJ;AAER;;;;"}
1
+ {"version":3,"file":"ComboBoxControl.js","sources":["ComboBoxControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Combobox, Portal } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOptionProps, type OptionControlProps } from \"./option-hooks\";\n\nexport function ComboBoxControl(props: OptionControlProps<ComboBoxConfig>): ReactElement {\n const {\n selectedValue,\n collection,\n placeholder,\n showClearTrigger,\n onInputValueChange,\n onValueChange\n } = useOptionProps(props);\n\n return (\n <Combobox.Root\n value={selectedValue}\n collection={collection}\n onInputValueChange={onInputValueChange}\n onValueChange={onValueChange}\n >\n <Combobox.Control>\n <Combobox.Input placeholder={placeholder} />\n <Combobox.IndicatorGroup>\n {showClearTrigger && <Combobox.ClearTrigger />}\n <Combobox.Trigger />\n </Combobox.IndicatorGroup>\n </Combobox.Control>\n <Portal>\n <Combobox.Positioner>\n <Combobox.Content>\n {collection.items.map((option) => (\n <Combobox.Item key={option.value} item={option}>\n {option.label}\n <Combobox.ItemIndicator />\n </Combobox.Item>\n ))}\n </Combobox.Content>\n </Combobox.Positioner>\n </Portal>\n </Combobox.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,gBAAgB,KAAA,EAAyD;AACrF,EAAA,MAAM;AAAA,IACF,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,kBAAA;AAAA,IACA;AAAA,GACJ,GAAI,eAAe,KAAK,CAAA;AAExB,EAAA,uBACI,IAAA;AAAA,IAAC,QAAA,CAAS,IAAA;AAAA,IAAT;AAAA,MACG,KAAA,EAAO,aAAA;AAAA,MACP,UAAA;AAAA,MACA,kBAAA;AAAA,MACA,aAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,IAAA,CAAC,QAAA,CAAS,SAAT,EACG,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,QAAA,CAAS,KAAA,EAAT,EAAe,WAAA,EAA0B,CAAA;AAAA,0BAC1C,IAAA,CAAC,QAAA,CAAS,cAAA,EAAT,EACI,QAAA,EAAA;AAAA,YAAA,gBAAA,oBAAoB,GAAA,CAAC,QAAA,CAAS,YAAA,EAAT,EAAsB,CAAA;AAAA,4BAC5C,GAAA,CAAC,QAAA,CAAS,OAAA,EAAT,EAAiB;AAAA,WAAA,EACtB;AAAA,SAAA,EACJ,CAAA;AAAA,wBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,QAAA,CAAS,YAAT,EACG,QAAA,kBAAA,GAAA,CAAC,SAAS,OAAA,EAAT,EACI,qBAAW,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,qBACnB,IAAA,CAAC,SAAS,IAAA,EAAT,EAAiC,MAAM,MAAA,EACnC,QAAA,EAAA;AAAA,UAAA,MAAA,CAAO,KAAA;AAAA,0BACR,GAAA,CAAC,QAAA,CAAS,aAAA,EAAT,EAAuB;AAAA,SAAA,EAAA,EAFR,MAAA,CAAO,KAG3B,CACH,CAAA,EACL,GACJ,CAAA,EACJ;AAAA;AAAA;AAAA,GACJ;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultControl.js","sources":["DefaultControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n Checkbox,\n Input,\n Switch,\n Textarea,\n type CheckboxCheckedChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot, DISPATCH_SYNC } from \"@open-pioneer/reactivity\";\nimport type { ChangeEvent, ReactNode } from \"react\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\nimport { ColorPickerControl } from \"./ColorPickerControl\";\nimport { ComboBoxControl } from \"./ComboBoxControl\";\nimport { NumberFieldControl } from \"./NumberFieldControl\";\nimport { RadioGroupControl } from \"./RadioGroupControl\";\nimport { SelectControl } from \"./SelectControl\";\n\nexport interface DefaultControlProps {\n readonly field: FieldConfig;\n}\n\ntype InputElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\nexport function DefaultControl({ field }: DefaultControlProps): ReactNode {\n const { properties } = usePropertyFormContext();\n\n const value = useReactiveSnapshot(\n () => properties.get(field.propertyName),\n [field.propertyName, properties],\n DISPATCH_SYNC\n );\n\n const onInputChange = useEvent((event: ChangeEvent<InputElement>) => {\n if (event.target.value !== \"\") {\n if (field.type === \"select\") {\n properties.set(field.propertyName, parseFloat(event.target.value));\n } else {\n properties.set(field.propertyName, event.target.value);\n }\n } else {\n properties.set(field.propertyName, undefined);\n }\n });\n\n const onChange = useEvent((value: unknown) => {\n properties.set(field.propertyName, value);\n });\n\n const onCheckBoxChange = useEvent((details: CheckboxCheckedChangeDetails) => {\n properties.set(field.propertyName, details.checked === true);\n });\n\n switch (field.type) {\n case \"check-box\":\n return (\n <Checkbox.Root\n checked={!!value}\n onCheckedChange={onCheckBoxChange}\n ml={\"3px\"} // for focus ring\n >\n <Checkbox.HiddenInput />\n <Checkbox.Control />\n <Checkbox.Label>{field.checkBoxLabel ?? field.label}</Checkbox.Label>\n </Checkbox.Root>\n );\n\n case \"combo-box\":\n return (\n <ComboBoxControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"custom\":\n return field.render(value, onChange);\n\n case \"color-picker\":\n return (\n <ColorPickerControl\n hexColor={value?.toString()}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"date-picker\":\n return (\n <Input\n type={field.includeTime ? \"datetime-local\" : \"date\"}\n value={value?.toString() ?? \"\"}\n onChange={onInputChange}\n />\n );\n\n case \"number-field\":\n return (\n <NumberFieldControl\n value={value as number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"radio-group\":\n return (\n <RadioGroupControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"select\":\n return (\n <SelectControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"switch\":\n return (\n <Switch.Root\n checked={!!value}\n onCheckedChange={onCheckBoxChange}\n ml={\"3px\"} // for focus ring\n >\n <Switch.HiddenInput />\n <Switch.Control>\n <Switch.Thumb />\n </Switch.Control>\n <Switch.Label>{field.switchLabel ?? field.label}</Switch.Label>\n </Switch.Root>\n );\n\n case \"text-area\":\n return (\n <Textarea\n placeholder={field.placeholder ?? field.label}\n value={value?.toString()}\n onChange={onInputChange}\n />\n );\n\n case \"text-field\":\n return (\n <Input\n type=\"text\"\n placeholder={field.placeholder ?? field.label}\n value={value?.toString() ?? \"\"}\n onChange={onInputChange}\n />\n );\n }\n}\n"],"names":["value"],"mappings":"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"}
1
+ {"version":3,"file":"DefaultControl.js","sources":["DefaultControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n Checkbox,\n Input,\n Switch,\n Textarea,\n type CheckboxCheckedChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot, DISPATCH_SYNC } from \"@open-pioneer/reactivity\";\nimport type { ChangeEvent, ReactNode } from \"react\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\nimport { ColorPickerControl } from \"./ColorPickerControl\";\nimport { ComboBoxControl } from \"./ComboBoxControl\";\nimport { NumberFieldControl } from \"./NumberFieldControl\";\nimport { RadioGroupControl } from \"./RadioGroupControl\";\nimport { SelectControl } from \"./SelectControl\";\n\nexport interface DefaultControlProps {\n readonly field: FieldConfig;\n}\n\ntype InputElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\nexport function DefaultControl({ field }: DefaultControlProps): ReactNode {\n const { properties } = usePropertyFormContext();\n\n const value = useReactiveSnapshot(\n () => properties.get(field.propertyName),\n [field.propertyName, properties],\n DISPATCH_SYNC\n );\n\n const onInputChange = useEvent((event: ChangeEvent<InputElement>) => {\n if (event.target.value !== \"\") {\n if (field.type === \"select\") {\n properties.set(field.propertyName, parseFloat(event.target.value));\n } else {\n properties.set(field.propertyName, event.target.value);\n }\n } else {\n properties.set(field.propertyName, undefined);\n }\n });\n\n const onChange = useEvent((value: unknown) => {\n properties.set(field.propertyName, value);\n });\n\n const onCheckBoxChange = useEvent((details: CheckboxCheckedChangeDetails) => {\n properties.set(field.propertyName, details.checked === true);\n });\n\n switch (field.type) {\n case \"check-box\":\n return (\n <Checkbox.Root\n checked={!!value}\n onCheckedChange={onCheckBoxChange}\n ml={\"3px\"} // for focus ring\n >\n <Checkbox.HiddenInput />\n <Checkbox.Control />\n <Checkbox.Label>{field.checkBoxLabel ?? field.label}</Checkbox.Label>\n </Checkbox.Root>\n );\n\n case \"combo-box\":\n return (\n <ComboBoxControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"custom\":\n return field.render(value, onChange);\n\n case \"color-picker\":\n return (\n <ColorPickerControl\n hexColor={value?.toString()}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"date-picker\":\n return (\n <Input\n type={field.includeTime ? \"datetime-local\" : \"date\"}\n value={value?.toString() ?? \"\"}\n onChange={onInputChange}\n />\n );\n\n case \"number-field\":\n return (\n <NumberFieldControl\n value={value as number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"radio-group\":\n return (\n <RadioGroupControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"select\":\n return (\n <SelectControl\n value={value as string | number | undefined}\n field={field}\n onChange={onChange}\n />\n );\n\n case \"switch\":\n return (\n <Switch.Root\n checked={!!value}\n onCheckedChange={onCheckBoxChange}\n ml={\"3px\"} // for focus ring\n >\n <Switch.HiddenInput />\n <Switch.Control>\n <Switch.Thumb />\n </Switch.Control>\n <Switch.Label>{field.switchLabel ?? field.label}</Switch.Label>\n </Switch.Root>\n );\n\n case \"text-area\":\n return (\n <Textarea\n placeholder={field.placeholder ?? field.label}\n value={value?.toString()}\n onChange={onInputChange}\n />\n );\n\n case \"text-field\":\n return (\n <Input\n type=\"text\"\n placeholder={field.placeholder ?? field.label}\n value={value?.toString() ?? \"\"}\n onChange={onInputChange}\n />\n );\n }\n}\n"],"names":["value"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"NumberFieldControl.js","sources":["NumberFieldControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { NumberInput, type NumberInputValueChangeDetails } from \"@chakra-ui/react\";\nimport { type FormatNumberOptions } from \"@formatjs/intl\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useEffect, useRef, useState, type ReactElement } from \"react\";\nimport type { NumberFieldConfig } from \"../../../api/fields/standardFieldConfigs\";\n\ninterface NumberFieldControlProps {\n readonly value: number | undefined;\n readonly field: NumberFieldConfig;\n readonly onChange: (newNumber: number | undefined) => void;\n}\n\n// This component allows its value to be specified as a number. The value is still stored as a\n// string internally to allow non-numeric characters (such as '-', '.', or 'e') to be entered.\nexport function NumberFieldControl({\n value,\n field,\n onChange\n}: NumberFieldControlProps): ReactElement {\n const formatNumber = useFormatNumber(field.formatOptions);\n const [stringValue, setStringValue] = useState(() => formatNumber(value));\n const setNumericValue = useNumericState(value, field.formatOptions, setStringValue);\n\n const onValueChange = useEvent(({ value, valueAsNumber }: NumberInputValueChangeDetails) => {\n setStringValue(value);\n if (!isNaN(valueAsNumber)) {\n setNumericValue(valueAsNumber);\n onChange?.(valueAsNumber);\n } else if (value === \"\") {\n setNumericValue(undefined);\n onChange?.(undefined);\n }\n });\n\n const element = useRef<HTMLInputElement>(null);\n\n return (\n <NumberInput.Root\n value={stringValue ?? \"\"}\n min={field.min}\n max={field.max}\n step={field.step}\n formatOptions={field.formatOptions}\n onValueChange={onValueChange}\n clampValueOnBlur={false}\n >\n <NumberInput.Input ref={element} placeholder={field.placeholder ?? field.label} />\n {field.showSteppers && <NumberInput.Control />}\n </NumberInput.Root>\n );\n}\n\n// Additionally store the state as a number to be able to react to outside changes of 'value'.\nfunction useNumericState(\n value: number | undefined,\n formatOptions: FormatNumberOptions | undefined,\n setStringValue: (newValue: string | undefined) => void\n) {\n const [numericValue, setNumericValue] = useState(value);\n const formatNumber = useFormatNumber(formatOptions);\n\n useEffect(() => {\n if (value !== numericValue) {\n const stringValue = formatNumber(value);\n setStringValue(stringValue);\n setNumericValue(value);\n }\n }, [formatNumber, numericValue, setStringValue, value]);\n\n return setNumericValue;\n}\n\nfunction useFormatNumber(formatOptions: FormatNumberOptions | undefined) {\n const { formatNumber } = useIntl();\n\n return useCallback(\n (number: number | undefined) => {\n if (number != null) {\n return formatNumber(number, { maximumFractionDigits: 20, ...formatOptions });\n } else {\n return undefined;\n }\n },\n [formatNumber, formatOptions]\n );\n}\n"],"names":["value"],"mappings":";;;;;;AAkBO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAA0C;AACtC,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,aAAa,CAAA;AACxD,EAAA,MAAM,CAAC,aAAa,cAAc,CAAA,GAAI,SAAS,MAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AACxE,EAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,KAAA,EAAO,KAAA,CAAM,eAAe,cAAc,CAAA;AAElF,EAAA,MAAM,gBAAgB,QAAA,CAAS,CAAC,EAAE,KAAA,EAAAA,MAAAA,EAAO,eAAc,KAAqC;AACxF,IAAA,cAAA,CAAeA,MAAK,CAAA;AACpB,IAAA,IAAI,CAAC,KAAA,CAAM,aAAa,CAAA,EAAG;AACvB,MAAA,eAAA,CAAgB,aAAa,CAAA;AAC7B,MAAA,QAAA,GAAW,aAAa,CAAA;AAAA,IAC5B,CAAA,MAAA,IAAWA,WAAU,EAAA,EAAI;AACrB,MAAA,eAAA,CAAgB,MAAS,CAAA;AACzB,MAAA,QAAA,GAAW,MAAS,CAAA;AAAA,IACxB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,OAAyB,IAAI,CAAA;AAE7C,EAAA,uBACI,IAAA;AAAA,IAAC,WAAA,CAAY,IAAA;AAAA,IAAZ;AAAA,MACG,OAAO,WAAA,IAAe,EAAA;AAAA,MACtB,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,eAAe,KAAA,CAAM,aAAA;AAAA,MACrB,aAAA;AAAA,MACA,gBAAA,EAAkB,KAAA;AAAA,MAElB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,WAAA,CAAY,OAAZ,EAAkB,GAAA,EAAK,SAAS,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,KAAA,EAAO,CAAA;AAAA,QAC/E,KAAA,CAAM,YAAA,oBAAgB,GAAA,CAAC,WAAA,CAAY,SAAZ,EAAoB;AAAA;AAAA;AAAA,GAChD;AAER;AAGA,SAAS,eAAA,CACL,KAAA,EACA,aAAA,EACA,cAAA,EACF;AACE,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,YAAA,GAAe,gBAAgB,aAAa,CAAA;AAElD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,UAAU,YAAA,EAAc;AACxB,MAAA,MAAM,WAAA,GAAc,aAAa,KAAK,CAAA;AACtC,MAAA,cAAA,CAAe,WAAW,CAAA;AAC1B,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACzB;AAAA,EACJ,GAAG,CAAC,YAAA,EAAc,YAAA,EAAc,cAAA,EAAgB,KAAK,CAAC,CAAA;AAEtD,EAAA,OAAO,eAAA;AACX;AAEA,SAAS,gBAAgB,aAAA,EAAgD;AACrE,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,OAAA,EAAQ;AAEjC,EAAA,OAAO,WAAA;AAAA,IACH,CAAC,MAAA,KAA+B;AAC5B,MAAA,IAAI,UAAU,IAAA,EAAM;AAChB,QAAA,OAAO,aAAa,MAAA,EAAQ,EAAE,uBAAuB,EAAA,EAAI,GAAG,eAAe,CAAA;AAAA,MAC/E,CAAA,MAAO;AACH,QAAA,OAAO,MAAA;AAAA,MACX;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,cAAc,aAAa;AAAA,GAChC;AACJ;;;;"}
1
+ {"version":3,"file":"NumberFieldControl.js","sources":["NumberFieldControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { NumberInput, type NumberInputValueChangeDetails } from \"@chakra-ui/react\";\nimport { type FormatNumberOptions } from \"@formatjs/intl\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useEffect, useRef, useState, type ReactElement } from \"react\";\nimport type { NumberFieldConfig } from \"../../../api/fields/standardFieldConfigs\";\n\ninterface NumberFieldControlProps {\n readonly value: number | undefined;\n readonly field: NumberFieldConfig;\n readonly onChange: (newNumber: number | undefined) => void;\n}\n\n// This component allows its value to be specified as a number. The value is still stored as a\n// string internally to allow non-numeric characters (such as '-', '.', or 'e') to be entered.\nexport function NumberFieldControl({\n value,\n field,\n onChange\n}: NumberFieldControlProps): ReactElement {\n const formatNumber = useFormatNumber(field.formatOptions);\n const [stringValue, setStringValue] = useState(() => formatNumber(value));\n const setNumericValue = useNumericState(value, field.formatOptions, setStringValue);\n\n const onValueChange = useEvent(({ value, valueAsNumber }: NumberInputValueChangeDetails) => {\n setStringValue(value);\n if (!isNaN(valueAsNumber)) {\n setNumericValue(valueAsNumber);\n onChange?.(valueAsNumber);\n } else if (value === \"\") {\n setNumericValue(undefined);\n onChange?.(undefined);\n }\n });\n\n const element = useRef<HTMLInputElement>(null);\n\n return (\n <NumberInput.Root\n value={stringValue ?? \"\"}\n min={field.min}\n max={field.max}\n step={field.step}\n formatOptions={field.formatOptions}\n onValueChange={onValueChange}\n clampValueOnBlur={false}\n >\n <NumberInput.Input ref={element} placeholder={field.placeholder ?? field.label} />\n {field.showSteppers && <NumberInput.Control />}\n </NumberInput.Root>\n );\n}\n\n// Additionally store the state as a number to be able to react to outside changes of 'value'.\nfunction useNumericState(\n value: number | undefined,\n formatOptions: FormatNumberOptions | undefined,\n setStringValue: (newValue: string | undefined) => void\n) {\n const [numericValue, setNumericValue] = useState(value);\n const formatNumber = useFormatNumber(formatOptions);\n\n useEffect(() => {\n if (value !== numericValue) {\n const stringValue = formatNumber(value);\n setStringValue(stringValue);\n setNumericValue(value);\n }\n }, [formatNumber, numericValue, setStringValue, value]);\n\n return setNumericValue;\n}\n\nfunction useFormatNumber(formatOptions: FormatNumberOptions | undefined) {\n const { formatNumber } = useIntl();\n\n return useCallback(\n (number: number | undefined) => {\n if (number != null) {\n return formatNumber(number, { maximumFractionDigits: 20, ...formatOptions });\n } else {\n return undefined;\n }\n },\n [formatNumber, formatOptions]\n );\n}\n"],"names":["value"],"mappings":";;;;;;AAkBO,SAAS,kBAAA,CAAmB;AAAA,EAC/B,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAA0C;AACtC,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,aAAa,CAAA;AACxD,EAAA,MAAM,CAAC,aAAa,cAAc,CAAA,GAAI,SAAS,MAAM,YAAA,CAAa,KAAK,CAAC,CAAA;AACxE,EAAA,MAAM,eAAA,GAAkB,eAAA,CAAgB,KAAA,EAAO,KAAA,CAAM,eAAe,cAAc,CAAA;AAElF,EAAA,MAAM,gBAAgB,QAAA,CAAS,CAAC,EAAE,KAAA,EAAAA,MAAAA,EAAO,eAAc,KAAqC;AACxF,IAAA,cAAA,CAAeA,MAAK,CAAA;AACpB,IAAA,IAAI,CAAC,KAAA,CAAM,aAAa,CAAA,EAAG;AACvB,MAAA,eAAA,CAAgB,aAAa,CAAA;AAC7B,MAAA,QAAA,GAAW,aAAa,CAAA;AAAA,IAC5B,CAAA,MAAA,IAAWA,WAAU,EAAA,EAAI;AACrB,MAAA,eAAA,CAAgB,MAAS,CAAA;AACzB,MAAA,QAAA,GAAW,MAAS,CAAA;AAAA,IACxB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,OAAA,GAAU,OAAyB,IAAI,CAAA;AAE7C,EAAA,uBACI,IAAA;AAAA,IAAC,WAAA,CAAY,IAAA;AAAA,IAAZ;AAAA,MACG,OAAO,WAAA,IAAe,EAAA;AAAA,MACtB,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,KAAK,KAAA,CAAM,GAAA;AAAA,MACX,MAAM,KAAA,CAAM,IAAA;AAAA,MACZ,eAAe,KAAA,CAAM,aAAA;AAAA,MACrB,aAAA;AAAA,MACA,gBAAA,EAAkB,KAAA;AAAA,MAElB,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,WAAA,CAAY,OAAZ,EAAkB,GAAA,EAAK,SAAS,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,KAAA,EAAO,CAAA;AAAA,QAC/E,KAAA,CAAM,YAAA,oBAAgB,GAAA,CAAC,WAAA,CAAY,SAAZ,EAAoB;AAAA;AAAA;AAAA,GAChD;AAER;AAGA,SAAS,eAAA,CACL,KAAA,EACA,aAAA,EACA,cAAA,EACF;AACE,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,KAAK,CAAA;AACtD,EAAA,MAAM,YAAA,GAAe,gBAAgB,aAAa,CAAA;AAElD,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,UAAU,YAAA,EAAc;AACxB,MAAA,MAAM,WAAA,GAAc,aAAa,KAAK,CAAA;AACtC,MAAA,cAAA,CAAe,WAAW,CAAA;AAC1B,MAAA,eAAA,CAAgB,KAAK,CAAA;AAAA,IACzB;AAAA,EACJ,GAAG,CAAC,YAAA,EAAc,YAAA,EAAc,cAAA,EAAgB,KAAK,CAAC,CAAA;AAEtD,EAAA,OAAO,eAAA;AACX;AAEA,SAAS,gBAAgB,aAAA,EAAgD;AACrE,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,OAAA,EAAQ;AAEjC,EAAA,OAAO,WAAA;AAAA,IACH,CAAC,MAAA,KAA+B;AAC5B,MAAA,IAAI,UAAU,IAAA,EAAM;AAChB,QAAA,OAAO,aAAa,MAAA,EAAQ,EAAE,uBAAuB,EAAA,EAAI,GAAG,eAAe,CAAA;AAAA,MAC/E,CAAA,MAAO;AACH,QAAA,OAAO,MAAA;AAAA,MACX;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,cAAc,aAAa;AAAA,GAChC;AACJ;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"RadioGroupControl.js","sources":["RadioGroupControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { VStack } from \"@chakra-ui/react\";\nimport { Radio, RadioGroup } from \"@open-pioneer/chakra-snippets/radio\";\nimport type { ReactElement } from \"react\";\nimport type { RadioGroupConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOnValueChange, type OptionControlProps } from \"./option-hooks\";\n\nexport function RadioGroupControl({\n value,\n field,\n onChange\n}: OptionControlProps<RadioGroupConfig>): ReactElement {\n const selectedValue = value?.toString();\n const onValueChange = useOnValueChange(field.valueType, onChange);\n\n return (\n <RadioGroup\n value={selectedValue}\n orientation=\"vertical\"\n onValueChange={onValueChange}\n ml={\"3px\"} // for focus ring\n >\n <VStack align=\"start\" gap={2}>\n {field.options.map((option) => (\n <Radio key={option.value} value={option.value.toString()}>\n {option.label}\n </Radio>\n ))}\n </VStack>\n </RadioGroup>\n );\n}\n"],"names":[],"mappings":";;;;;AASO,SAAS,iBAAA,CAAkB;AAAA,EAC9B,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAAuD;AACnD,EAAA,MAAM,aAAA,GAAgB,OAAO,QAAA,EAAS;AACtC,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAEhE,EAAA,uBACI,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,KAAA,EAAO,aAAA;AAAA,MACP,WAAA,EAAY,UAAA;AAAA,MACZ,aAAA;AAAA,MACA,EAAA,EAAI,KAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,UAAO,KAAA,EAAM,OAAA,EAAQ,KAAK,CAAA,EACtB,QAAA,EAAA,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,yBACf,KAAA,EAAA,EAAyB,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS,EAClD,iBAAO,KAAA,EAAA,EADA,MAAA,CAAO,KAEnB,CACH,CAAA,EACL;AAAA;AAAA,GACJ;AAER;;;;"}
1
+ {"version":3,"file":"RadioGroupControl.js","sources":["RadioGroupControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { VStack } from \"@chakra-ui/react\";\nimport { Radio, RadioGroup } from \"@open-pioneer/chakra-snippets/radio\";\nimport type { ReactElement } from \"react\";\nimport type { RadioGroupConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOnValueChange, type OptionControlProps } from \"./option-hooks\";\n\nexport function RadioGroupControl({\n value,\n field,\n onChange\n}: OptionControlProps<RadioGroupConfig>): ReactElement {\n const selectedValue = value?.toString();\n const onValueChange = useOnValueChange(field.valueType, onChange);\n\n return (\n <RadioGroup\n value={selectedValue}\n orientation=\"vertical\"\n onValueChange={onValueChange}\n ml={\"3px\"} // for focus ring\n >\n <VStack align=\"start\" gap={2}>\n {field.options.map((option) => (\n <Radio key={option.value} value={option.value.toString()}>\n {option.label}\n </Radio>\n ))}\n </VStack>\n </RadioGroup>\n );\n}\n"],"names":[],"mappings":";;;;;AASO,SAAS,iBAAA,CAAkB;AAAA,EAC9B,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACJ,CAAA,EAAuD;AACnD,EAAA,MAAM,aAAA,GAAgB,OAAO,QAAA,EAAS;AACtC,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAEhE,EAAA,uBACI,GAAA;AAAA,IAAC,UAAA;AAAA,IAAA;AAAA,MACG,KAAA,EAAO,aAAA;AAAA,MACP,WAAA,EAAY,UAAA;AAAA,MACZ,aAAA;AAAA,MACA,EAAA,EAAI,KAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,UAAO,KAAA,EAAM,OAAA,EAAQ,KAAK,CAAA,EACtB,QAAA,EAAA,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAA,yBACf,KAAA,EAAA,EAAyB,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,QAAA,EAAS,EAClD,iBAAO,KAAA,EAAA,EADA,MAAA,CAAO,KAEnB,CACH,CAAA,EACL;AAAA;AAAA,GACJ;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectControl.js","sources":["SelectControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Select, Portal } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { SelectConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOptionProps, type OptionControlProps } from \"./option-hooks\";\n\nexport function SelectControl(props: OptionControlProps<SelectConfig>): ReactElement {\n const { selectedValue, collection, placeholder, showClearTrigger, onValueChange } =\n useOptionProps(props);\n\n return (\n <Select.Root value={selectedValue} collection={collection} onValueChange={onValueChange}>\n <Select.HiddenSelect />\n <Select.Control>\n <Select.Trigger>\n <Select.ValueText placeholder={placeholder} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {showClearTrigger && <Select.ClearTrigger />}\n <Select.Indicator />\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <Select.Content>\n {collection.items.map((option) => (\n <Select.Item key={option.value} item={option.value}>\n {option.label}\n <Select.ItemIndicator />\n </Select.Item>\n ))}\n </Select.Content>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,cAAc,KAAA,EAAuD;AACjF,EAAA,MAAM,EAAE,eAAe,UAAA,EAAY,WAAA,EAAa,kBAAkB,aAAA,EAAc,GAC5E,eAAe,KAAK,CAAA;AAExB,EAAA,4BACK,MAAA,CAAO,IAAA,EAAP,EAAY,KAAA,EAAO,aAAA,EAAe,YAAwB,aAAA,EACvD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,cAAP,EAAoB,CAAA;AAAA,oBACrB,IAAA,CAAC,MAAA,CAAO,OAAA,EAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,kBAAA,GAAA,CAAC,OAAO,SAAA,EAAP,EAAiB,aAA0B,CAAA,EAChD,CAAA;AAAA,sBACA,IAAA,CAAC,MAAA,CAAO,cAAA,EAAP,EACI,QAAA,EAAA;AAAA,QAAA,gBAAA,oBAAoB,GAAA,CAAC,MAAA,CAAO,YAAA,EAAP,EAAoB,CAAA;AAAA,wBAC1C,GAAA,CAAC,MAAA,CAAO,SAAA,EAAP,EAAiB;AAAA,OAAA,EACtB;AAAA,KAAA,EACJ,CAAA;AAAA,oBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,MAAA,CAAO,YAAP,EACG,QAAA,kBAAA,GAAA,CAAC,OAAO,OAAA,EAAP,EACI,qBAAW,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,qBACnB,IAAA,CAAC,OAAO,IAAA,EAAP,EAA+B,IAAA,EAAM,MAAA,CAAO,KAAA,EACxC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA;AAAA,sBACR,GAAA,CAAC,MAAA,CAAO,aAAA,EAAP,EAAqB;AAAA,KAAA,EAAA,EAFR,MAAA,CAAO,KAGzB,CACH,CAAA,EACL,GACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"SelectControl.js","sources":["SelectControl.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Select, Portal } from \"@chakra-ui/react\";\nimport type { ReactElement } from \"react\";\nimport type { SelectConfig } from \"../../../api/fields/optionFieldConfigs\";\nimport { useOptionProps, type OptionControlProps } from \"./option-hooks\";\n\nexport function SelectControl(props: OptionControlProps<SelectConfig>): ReactElement {\n const { selectedValue, collection, placeholder, showClearTrigger, onValueChange } =\n useOptionProps(props);\n\n return (\n <Select.Root value={selectedValue} collection={collection} onValueChange={onValueChange}>\n <Select.HiddenSelect />\n <Select.Control>\n <Select.Trigger>\n <Select.ValueText placeholder={placeholder} />\n </Select.Trigger>\n <Select.IndicatorGroup>\n {showClearTrigger && <Select.ClearTrigger />}\n <Select.Indicator />\n </Select.IndicatorGroup>\n </Select.Control>\n <Portal>\n <Select.Positioner>\n <Select.Content>\n {collection.items.map((option) => (\n <Select.Item key={option.value} item={option.value}>\n {option.label}\n <Select.ItemIndicator />\n </Select.Item>\n ))}\n </Select.Content>\n </Select.Positioner>\n </Portal>\n </Select.Root>\n );\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,cAAc,KAAA,EAAuD;AACjF,EAAA,MAAM,EAAE,eAAe,UAAA,EAAY,WAAA,EAAa,kBAAkB,aAAA,EAAc,GAC5E,eAAe,KAAK,CAAA;AAExB,EAAA,4BACK,MAAA,CAAO,IAAA,EAAP,EAAY,KAAA,EAAO,aAAA,EAAe,YAAwB,aAAA,EACvD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,cAAP,EAAoB,CAAA;AAAA,oBACrB,IAAA,CAAC,MAAA,CAAO,OAAA,EAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,kBAAA,GAAA,CAAC,OAAO,SAAA,EAAP,EAAiB,aAA0B,CAAA,EAChD,CAAA;AAAA,sBACA,IAAA,CAAC,MAAA,CAAO,cAAA,EAAP,EACI,QAAA,EAAA;AAAA,QAAA,gBAAA,oBAAoB,GAAA,CAAC,MAAA,CAAO,YAAA,EAAP,EAAoB,CAAA;AAAA,wBAC1C,GAAA,CAAC,MAAA,CAAO,SAAA,EAAP,EAAiB;AAAA,OAAA,EACtB;AAAA,KAAA,EACJ,CAAA;AAAA,oBACA,GAAA,CAAC,UACG,QAAA,kBAAA,GAAA,CAAC,MAAA,CAAO,YAAP,EACG,QAAA,kBAAA,GAAA,CAAC,OAAO,OAAA,EAAP,EACI,qBAAW,KAAA,CAAM,GAAA,CAAI,CAAC,MAAA,qBACnB,IAAA,CAAC,OAAO,IAAA,EAAP,EAA+B,IAAA,EAAM,MAAA,CAAO,KAAA,EACxC,QAAA,EAAA;AAAA,MAAA,MAAA,CAAO,KAAA;AAAA,sBACR,GAAA,CAAC,MAAA,CAAO,aAAA,EAAP,EAAqB;AAAA,KAAA,EAAA,EAFR,MAAA,CAAO,KAGzB,CACH,CAAA,EACL,GACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"option-hooks.js","sources":["option-hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n useListCollection,\n useFilter,\n type ComboboxInputValueChangeDetails,\n type ComboboxValueChangeDetails,\n type SelectValueChangeDetails,\n type RadioGroupValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo } from \"react\";\nimport type { SelectConfig, ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\n\nexport interface OptionControlProps<T = SelectConfig | ComboBoxConfig> {\n readonly value: string | number | undefined;\n readonly field: T;\n readonly onChange: (value: unknown) => void;\n}\n\ntype ValueChangeDetails =\n | SelectValueChangeDetails\n | ComboboxValueChangeDetails\n | RadioGroupValueChangeDetails;\n\nexport function useOptionProps({ value, field, onChange }: OptionControlProps) {\n const selectedValue = useMemo(() => (value != undefined ? [value.toString()] : []), [value]);\n const { collection, onInputValueChange } = useCollection(field);\n const onValueChange = useOnValueChange(field.valueType, onChange);\n\n return {\n selectedValue,\n collection,\n placeholder: field.placeholder ?? field.label,\n showClearTrigger: field.showClearTrigger ?? !(field.isRequired ?? false),\n onInputValueChange,\n onValueChange\n };\n}\n\nexport function useOnValueChange(\n valueType: \"string\" | \"number\",\n onChange: (value: unknown) => void\n) {\n return useEvent((details: ValueChangeDetails) => {\n const newValue = details.value?.[0];\n if (valueType === \"number\") {\n onChange(newValue !== undefined ? parseFloat(newValue) : undefined);\n } else {\n onChange(newValue);\n }\n });\n}\n\nfunction useCollection(field: SelectConfig | ComboBoxConfig) {\n const initialItems = useMemo(() => {\n return field.options.map(({ label, value }) => ({ label, value: value.toString() }));\n }, [field.options]);\n\n const { contains } = useFilter({ sensitivity: \"base\" });\n const { collection, filter } = useListCollection({ initialItems, filter: contains });\n\n const onInputValueChange = useEvent((details: ComboboxInputValueChangeDetails) => {\n filter(details.inputValue);\n });\n\n return { collection, onInputValueChange };\n}\n"],"names":[],"mappings":";;;;AA0BO,SAAS,cAAA,CAAe,EAAE,KAAA,EAAO,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAO,KAAA,IAAS,SAAY,CAAC,KAAA,CAAM,QAAA,EAAU,CAAA,GAAI,EAAC,EAAI,CAAC,KAAK,CAAC,CAAA;AAC3F,EAAA,MAAM,EAAE,UAAA,EAAY,kBAAA,EAAmB,GAAI,cAAc,KAAK,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAEhE,EAAA,OAAO;AAAA,IACH,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,KAAA;AAAA,IACxC,gBAAA,EAAkB,KAAA,CAAM,gBAAA,IAAoB,EAAE,MAAM,UAAA,IAAc,KAAA,CAAA;AAAA,IAClE,kBAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAEO,SAAS,gBAAA,CACZ,WACA,QAAA,EACF;AACE,EAAA,OAAO,QAAA,CAAS,CAAC,OAAA,KAAgC;AAC7C,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,GAAQ,CAAC,CAAA;AAClC,IAAA,IAAI,cAAc,QAAA,EAAU;AACxB,MAAA,QAAA,CAAS,QAAA,KAAa,MAAA,GAAY,UAAA,CAAW,QAAQ,IAAI,MAAS,CAAA;AAAA,IACtE,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AACL;AAEA,SAAS,cAAc,KAAA,EAAsC;AACzD,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AAC/B,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,EAAE,KAAA,EAAO,KAAA,EAAM,MAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAA,IAAW,CAAE,CAAA;AAAA,EACvF,CAAA,EAAG,CAAC,KAAA,CAAM,OAAO,CAAC,CAAA;AAElB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,UAAU,EAAE,WAAA,EAAa,QAAQ,CAAA;AACtD,EAAA,MAAM,EAAE,YAAY,MAAA,EAAO,GAAI,kBAAkB,EAAE,YAAA,EAAc,MAAA,EAAQ,QAAA,EAAU,CAAA;AAEnF,EAAA,MAAM,kBAAA,GAAqB,QAAA,CAAS,CAAC,OAAA,KAA6C;AAC9E,IAAA,MAAA,CAAO,QAAQ,UAAU,CAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,YAAY,kBAAA,EAAmB;AAC5C;;;;"}
1
+ {"version":3,"file":"option-hooks.js","sources":["option-hooks.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport {\n useListCollection,\n useFilter,\n type ComboboxInputValueChangeDetails,\n type ComboboxValueChangeDetails,\n type SelectValueChangeDetails,\n type RadioGroupValueChangeDetails\n} from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useMemo } from \"react\";\nimport type { SelectConfig, ComboBoxConfig } from \"../../../api/fields/optionFieldConfigs\";\n\nexport interface OptionControlProps<T = SelectConfig | ComboBoxConfig> {\n readonly value: string | number | undefined;\n readonly field: T;\n readonly onChange: (value: unknown) => void;\n}\n\ntype ValueChangeDetails =\n | SelectValueChangeDetails\n | ComboboxValueChangeDetails\n | RadioGroupValueChangeDetails;\n\nexport function useOptionProps({ value, field, onChange }: OptionControlProps) {\n const selectedValue = useMemo(() => (value != undefined ? [value.toString()] : []), [value]);\n const { collection, onInputValueChange } = useCollection(field);\n const onValueChange = useOnValueChange(field.valueType, onChange);\n\n return {\n selectedValue,\n collection,\n placeholder: field.placeholder ?? field.label,\n showClearTrigger: field.showClearTrigger ?? !(field.isRequired ?? false),\n onInputValueChange,\n onValueChange\n };\n}\n\nexport function useOnValueChange(\n valueType: \"string\" | \"number\",\n onChange: (value: unknown) => void\n) {\n return useEvent((details: ValueChangeDetails) => {\n const newValue = details.value?.[0];\n if (valueType === \"number\") {\n onChange(newValue !== undefined ? parseFloat(newValue) : undefined);\n } else {\n onChange(newValue);\n }\n });\n}\n\nfunction useCollection(field: SelectConfig | ComboBoxConfig) {\n const initialItems = useMemo(() => {\n return field.options.map(({ label, value }) => ({ label, value: value.toString() }));\n }, [field.options]);\n\n const { contains } = useFilter({ sensitivity: \"base\" });\n const { collection, filter } = useListCollection({ initialItems, filter: contains });\n\n const onInputValueChange = useEvent((details: ComboboxInputValueChangeDetails) => {\n filter(details.inputValue);\n });\n\n return { collection, onInputValueChange };\n}\n"],"names":[],"mappings":";;;;AA0BO,SAAS,cAAA,CAAe,EAAE,KAAA,EAAO,KAAA,EAAO,UAAS,EAAuB;AAC3E,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,MAAO,KAAA,IAAS,SAAY,CAAC,KAAA,CAAM,QAAA,EAAU,CAAA,GAAI,EAAC,EAAI,CAAC,KAAK,CAAC,CAAA;AAC3F,EAAA,MAAM,EAAE,UAAA,EAAY,kBAAA,EAAmB,GAAI,cAAc,KAAK,CAAA;AAC9D,EAAA,MAAM,aAAA,GAAgB,gBAAA,CAAiB,KAAA,CAAM,SAAA,EAAW,QAAQ,CAAA;AAEhE,EAAA,OAAO;AAAA,IACH,aAAA;AAAA,IACA,UAAA;AAAA,IACA,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,KAAA,CAAM,KAAA;AAAA,IACxC,gBAAA,EAAkB,KAAA,CAAM,gBAAA,IAAoB,EAAE,MAAM,UAAA,IAAc,KAAA,CAAA;AAAA,IAClE,kBAAA;AAAA,IACA;AAAA,GACJ;AACJ;AAEO,SAAS,gBAAA,CACZ,WACA,QAAA,EACF;AACE,EAAA,OAAO,QAAA,CAAS,CAAC,OAAA,KAAgC;AAC7C,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,KAAA,GAAQ,CAAC,CAAA;AAClC,IAAA,IAAI,cAAc,QAAA,EAAU;AACxB,MAAA,QAAA,CAAS,QAAA,KAAa,MAAA,GAAY,UAAA,CAAW,QAAQ,IAAI,MAAS,CAAA;AAAA,IACtE,CAAA,MAAO;AACH,MAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AACL;AAEA,SAAS,cAAc,KAAA,EAAsC;AACzD,EAAA,MAAM,YAAA,GAAe,QAAQ,MAAM;AAC/B,IAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,EAAE,KAAA,EAAO,KAAA,EAAM,MAAO,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,CAAM,QAAA,IAAW,CAAE,CAAA;AAAA,EACvF,CAAA,EAAG,CAAC,KAAA,CAAM,OAAO,CAAC,CAAA;AAElB,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,UAAU,EAAE,WAAA,EAAa,QAAQ,CAAA;AACtD,EAAA,MAAM,EAAE,YAAY,MAAA,EAAO,GAAI,kBAAkB,EAAE,YAAA,EAAc,MAAA,EAAQ,QAAA,EAAU,CAAA;AAEnF,EAAA,MAAM,kBAAA,GAAqB,QAAA,CAAS,CAAC,OAAA,KAA6C;AAC9E,IAAA,MAAA,CAAO,QAAQ,UAAU,CAAA;AAAA,EAC7B,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,YAAY,kBAAA,EAAmB;AAC5C;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ButtonRow.js","sources":["ButtonRow.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, Button, Spacer } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport { LuTrash2 } from \"react-icons/lu\";\n\ninterface ButtonRowProps {\n readonly canSave: boolean;\n readonly showDeleteButton: boolean;\n\n readonly onSave: () => Promise<void>;\n readonly onDelete: () => void;\n readonly onCancel: () => void;\n}\n\nexport function ButtonRow({\n canSave,\n showDeleteButton,\n onSave,\n onDelete,\n onCancel\n}: ButtonRowProps): ReactElement {\n const [isSaving, setSaving] = useState(false);\n\n const onSaveClick = useEvent(async () => {\n try {\n setSaving(true);\n await onSave();\n } finally {\n setSaving(false);\n }\n });\n\n const { formatMessage } = useIntl();\n\n const { saveButtonTitle, cancelButtonTitle, deleteButtonTooltip } = useMemo(\n () => ({\n saveButtonTitle: formatMessage({ id: \"propertyEditor.saveButtonTitle\" }),\n cancelButtonTitle: formatMessage({ id: \"propertyEditor.cancelButtonTitle\" }),\n deleteButtonTooltip: formatMessage({ id: \"propertyEditor.deleteButtonTooltip\" })\n }),\n [formatMessage]\n );\n\n return (\n <Flex\n className=\"editor__property-editor-buttons\"\n flexDirection=\"row\"\n columnGap={2}\n // Margins for focus ring:\n marginX={\"4px\"}\n marginBottom={\"4px\"}\n >\n {showDeleteButton && (\n <Tooltip content={deleteButtonTooltip}>\n <Button\n width={65}\n variant=\"outline\"\n colorPalette=\"red\"\n aria-label={deleteButtonTooltip}\n disabled={isSaving}\n onClick={onDelete}\n >\n <LuTrash2 strokeWidth={1.5} />\n </Button>\n </Tooltip>\n )}\n <Spacer />\n <Button\n width={120}\n disabled={!canSave}\n loading={isSaving}\n loadingText={saveButtonTitle}\n onClick={onSaveClick}\n >\n {saveButtonTitle}\n </Button>\n <Button width={120} variant=\"outline\" disabled={isSaving} onClick={onCancel}>\n {cancelButtonTitle}\n </Button>\n </Flex>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAmBO,SAAS,SAAA,CAAU;AAAA,EACtB,OAAA;AAAA,EACA,gBAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAAiC;AAC7B,EAAA,MAAM,CAAC,QAAA,EAAU,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,SAAS,YAAY;AACrC,IAAA,IAAI;AACA,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,MAAM,MAAA,EAAO;AAAA,IACjB,CAAA,SAAE;AACE,MAAA,SAAA,CAAU,KAAK,CAAA;AAAA,IACnB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAA,EAAmB,mBAAA,EAAoB,GAAI,OAAA;AAAA,IAChE,OAAO;AAAA,MACH,eAAA,EAAiB,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MACvE,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MAC3E,mBAAA,EAAqB,aAAA,CAAc,EAAE,EAAA,EAAI,sCAAsC;AAAA,KACnF,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,iCAAA;AAAA,MACV,aAAA,EAAc,KAAA;AAAA,MACd,SAAA,EAAW,CAAA;AAAA,MAEX,OAAA,EAAS,KAAA;AAAA,MACT,YAAA,EAAc,KAAA;AAAA,MAEb,QAAA,EAAA;AAAA,QAAA,gBAAA,oBACG,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAS,mBAAA,EACd,QAAA,kBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,KAAA,EAAO,EAAA;AAAA,YACP,OAAA,EAAQ,SAAA;AAAA,YACR,YAAA,EAAa,KAAA;AAAA,YACb,YAAA,EAAY,mBAAA;AAAA,YACZ,QAAA,EAAU,QAAA;AAAA,YACV,OAAA,EAAS,QAAA;AAAA,YAET,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,WAAA,EAAa,GAAA,EAAK;AAAA;AAAA,SAChC,EACJ,CAAA;AAAA,4BAEH,MAAA,EAAA,EAAO,CAAA;AAAA,wBACR,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,KAAA,EAAO,GAAA;AAAA,YACP,UAAU,CAAC,OAAA;AAAA,YACX,OAAA,EAAS,QAAA;AAAA,YACT,WAAA,EAAa,eAAA;AAAA,YACb,OAAA,EAAS,WAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,GAAA,EAAK,OAAA,EAAQ,WAAU,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,QAAA,EAC9D,QAAA,EAAA,iBAAA,EACL;AAAA;AAAA;AAAA,GACJ;AAER;;;;"}
1
+ {"version":3,"file":"ButtonRow.js","sources":["ButtonRow.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, Button, Spacer } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport { LuTrash2 } from \"react-icons/lu\";\n\ninterface ButtonRowProps {\n readonly canSave: boolean;\n readonly showDeleteButton: boolean;\n\n readonly onSave: () => Promise<void>;\n readonly onDelete: () => void;\n readonly onCancel: () => void;\n}\n\nexport function ButtonRow({\n canSave,\n showDeleteButton,\n onSave,\n onDelete,\n onCancel\n}: ButtonRowProps): ReactElement {\n const [isSaving, setSaving] = useState(false);\n\n const onSaveClick = useEvent(async () => {\n try {\n setSaving(true);\n await onSave();\n } finally {\n setSaving(false);\n }\n });\n\n const { formatMessage } = useIntl();\n\n const { saveButtonTitle, cancelButtonTitle, deleteButtonTooltip } = useMemo(\n () => ({\n saveButtonTitle: formatMessage({ id: \"propertyEditor.saveButtonTitle\" }),\n cancelButtonTitle: formatMessage({ id: \"propertyEditor.cancelButtonTitle\" }),\n deleteButtonTooltip: formatMessage({ id: \"propertyEditor.deleteButtonTooltip\" })\n }),\n [formatMessage]\n );\n\n return (\n <Flex\n className=\"editor__property-editor-buttons\"\n flexDirection=\"row\"\n columnGap={2}\n // Margins for focus ring:\n marginX={\"4px\"}\n marginBottom={\"4px\"}\n >\n {showDeleteButton && (\n <Tooltip content={deleteButtonTooltip}>\n <Button\n width={65}\n variant=\"outline\"\n colorPalette=\"red\"\n aria-label={deleteButtonTooltip}\n disabled={isSaving}\n onClick={onDelete}\n >\n <LuTrash2 strokeWidth={1.5} />\n </Button>\n </Tooltip>\n )}\n <Spacer />\n <Button\n width={120}\n disabled={!canSave}\n loading={isSaving}\n loadingText={saveButtonTitle}\n onClick={onSaveClick}\n >\n {saveButtonTitle}\n </Button>\n <Button width={120} variant=\"outline\" disabled={isSaving} onClick={onCancel}>\n {cancelButtonTitle}\n </Button>\n </Flex>\n );\n}\n"],"names":[],"mappings":";;;;;;;;AAmBO,SAAS,SAAA,CAAU;AAAA,EACtB,OAAA;AAAA,EACA,gBAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAAiC;AAC7B,EAAA,MAAM,CAAC,QAAA,EAAU,SAAS,CAAA,GAAI,SAAS,KAAK,CAAA;AAE5C,EAAA,MAAM,WAAA,GAAc,SAAS,YAAY;AACrC,IAAA,IAAI;AACA,MAAA,SAAA,CAAU,IAAI,CAAA;AACd,MAAA,MAAM,MAAA,EAAO;AAAA,IACjB,CAAA,SAAE;AACE,MAAA,SAAA,CAAU,KAAK,CAAA;AAAA,IACnB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAA,EAAmB,mBAAA,EAAoB,GAAI,OAAA;AAAA,IAChE,OAAO;AAAA,MACH,eAAA,EAAiB,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MACvE,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MAC3E,mBAAA,EAAqB,aAAA,CAAc,EAAE,EAAA,EAAI,sCAAsC;AAAA,KACnF,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,iCAAA;AAAA,MACV,aAAA,EAAc,KAAA;AAAA,MACd,SAAA,EAAW,CAAA;AAAA,MAEX,OAAA,EAAS,KAAA;AAAA,MACT,YAAA,EAAc,KAAA;AAAA,MAEb,QAAA,EAAA;AAAA,QAAA,gBAAA,oBACG,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAS,mBAAA,EACd,QAAA,kBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,KAAA,EAAO,EAAA;AAAA,YACP,OAAA,EAAQ,SAAA;AAAA,YACR,YAAA,EAAa,KAAA;AAAA,YACb,YAAA,EAAY,mBAAA;AAAA,YACZ,QAAA,EAAU,QAAA;AAAA,YACV,OAAA,EAAS,QAAA;AAAA,YAET,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,WAAA,EAAa,GAAA,EAAK;AAAA;AAAA,SAChC,EACJ,CAAA;AAAA,4BAEH,MAAA,EAAA,EAAO,CAAA;AAAA,wBACR,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,KAAA,EAAO,GAAA;AAAA,YACP,UAAU,CAAC,OAAA;AAAA,YACX,OAAA,EAAS,QAAA;AAAA,YACT,WAAA,EAAa,eAAA;AAAA,YACb,OAAA,EAAS,WAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAO,KAAA,EAAO,GAAA,EAAK,OAAA,EAAQ,WAAU,QAAA,EAAU,QAAA,EAAU,OAAA,EAAS,QAAA,EAC9D,QAAA,EAAA,iBAAA,EACL;AAAA;AAAA;AAAA,GACJ;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"CancelConfirmationDialog.js","sources":["CancelConfirmationDialog.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Dialog } from \"@chakra-ui/react\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useMemo, useRef, type ReactElement } from \"react\";\n\ninterface CancelConfirmationDialogProps {\n readonly isOpen: boolean;\n readonly onConfirmCancel: () => void;\n readonly onAbortCancel: () => void;\n}\n\nexport function CancelConfirmationDialog({\n isOpen,\n onConfirmCancel,\n onAbortCancel\n}: CancelConfirmationDialogProps): ReactElement {\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const initialFocusEl = useCallback(() => cancelButtonRef.current, []);\n const { formatMessage } = useIntl();\n\n const { title, message, confirmCancelButtonTitle, abortCancelButtonTitle } = useMemo(\n () => ({\n title: formatMessage({ id: \"cancelConfirmationDialog.title\" }),\n message: formatMessage({ id: \"cancelConfirmationDialog.message\" }),\n confirmCancelButtonTitle: formatMessage({\n id: \"cancelConfirmationDialog.confirmCancelButtonTitle\"\n }),\n abortCancelButtonTitle: formatMessage({\n id: \"cancelConfirmationDialog.abortCancelButtonTitle\"\n })\n }),\n [formatMessage]\n );\n\n return (\n <Dialog.Root open={isOpen} initialFocusEl={initialFocusEl} role=\"alertdialog\">\n <Dialog.Backdrop />\n <Dialog.Positioner>\n <Dialog.Content>\n <Dialog.Header fontSize=\"large\" fontWeight=\"bold\">\n {title}\n </Dialog.Header>\n <Dialog.Body>{message}</Dialog.Body>\n <Dialog.Footer>\n <Button\n bg=\"red.solid\"\n color=\"red.contrast\"\n _hover={{ bg: \"red.solid/90\" }}\n loadingText={confirmCancelButtonTitle}\n onClick={onConfirmCancel}\n >\n {confirmCancelButtonTitle}\n </Button>\n <Button variant=\"outline\" ref={cancelButtonRef} onClick={onAbortCancel}>\n {abortCancelButtonTitle}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Positioner>\n </Dialog.Root>\n );\n}\n"],"names":[],"mappings":";;;;;AAaO,SAAS,wBAAA,CAAyB;AAAA,EACrC,MAAA;AAAA,EACA,eAAA;AAAA,EACA;AACJ,CAAA,EAAgD;AAC5C,EAAA,MAAM,eAAA,GAAkB,OAA0B,IAAI,CAAA;AACtD,EAAA,MAAM,iBAAiB,WAAA,CAAY,MAAM,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,wBAAA,EAA0B,wBAAuB,GAAI,OAAA;AAAA,IACzE,OAAO;AAAA,MACH,KAAA,EAAO,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MAC7D,OAAA,EAAS,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MACjE,0BAA0B,aAAA,CAAc;AAAA,QACpC,EAAA,EAAI;AAAA,OACP,CAAA;AAAA,MACD,wBAAwB,aAAA,CAAc;AAAA,QAClC,EAAA,EAAI;AAAA,OACP;AAAA,KACL,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA,CAAC,OAAO,IAAA,EAAP,EAAY,MAAM,MAAA,EAAQ,cAAA,EAAgC,MAAK,aAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,UAAP,EAAgB,CAAA;AAAA,wBAChB,MAAA,CAAO,UAAA,EAAP,EACG,QAAA,kBAAA,IAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAO,MAAA,EAAP,EAAc,UAAS,OAAA,EAAQ,UAAA,EAAW,QACtC,QAAA,EAAA,KAAA,EACL,CAAA;AAAA,sBACA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,sBACtB,IAAA,CAAC,MAAA,CAAO,MAAA,EAAP,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,EAAA,EAAG,WAAA;AAAA,YACH,KAAA,EAAM,cAAA;AAAA,YACN,MAAA,EAAQ,EAAE,EAAA,EAAI,cAAA,EAAe;AAAA,YAC7B,WAAA,EAAa,wBAAA;AAAA,YACb,OAAA,EAAS,eAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,KAAK,eAAA,EAAiB,OAAA,EAAS,eACpD,QAAA,EAAA,sBAAA,EACL;AAAA,OAAA,EACJ;AAAA,KAAA,EACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"CancelConfirmationDialog.js","sources":["CancelConfirmationDialog.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Dialog } from \"@chakra-ui/react\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useMemo, useRef, type ReactElement } from \"react\";\n\ninterface CancelConfirmationDialogProps {\n readonly isOpen: boolean;\n readonly onConfirmCancel: () => void;\n readonly onAbortCancel: () => void;\n}\n\nexport function CancelConfirmationDialog({\n isOpen,\n onConfirmCancel,\n onAbortCancel\n}: CancelConfirmationDialogProps): ReactElement {\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const initialFocusEl = useCallback(() => cancelButtonRef.current, []);\n const { formatMessage } = useIntl();\n\n const { title, message, confirmCancelButtonTitle, abortCancelButtonTitle } = useMemo(\n () => ({\n title: formatMessage({ id: \"cancelConfirmationDialog.title\" }),\n message: formatMessage({ id: \"cancelConfirmationDialog.message\" }),\n confirmCancelButtonTitle: formatMessage({\n id: \"cancelConfirmationDialog.confirmCancelButtonTitle\"\n }),\n abortCancelButtonTitle: formatMessage({\n id: \"cancelConfirmationDialog.abortCancelButtonTitle\"\n })\n }),\n [formatMessage]\n );\n\n return (\n <Dialog.Root open={isOpen} initialFocusEl={initialFocusEl} role=\"alertdialog\">\n <Dialog.Backdrop />\n <Dialog.Positioner>\n <Dialog.Content>\n <Dialog.Header fontSize=\"large\" fontWeight=\"bold\">\n {title}\n </Dialog.Header>\n <Dialog.Body>{message}</Dialog.Body>\n <Dialog.Footer>\n <Button\n bg=\"red.solid\"\n color=\"red.contrast\"\n _hover={{ bg: \"red.solid/90\" }}\n loadingText={confirmCancelButtonTitle}\n onClick={onConfirmCancel}\n >\n {confirmCancelButtonTitle}\n </Button>\n <Button variant=\"outline\" ref={cancelButtonRef} onClick={onAbortCancel}>\n {abortCancelButtonTitle}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Positioner>\n </Dialog.Root>\n );\n}\n"],"names":[],"mappings":";;;;;AAaO,SAAS,wBAAA,CAAyB;AAAA,EACrC,MAAA;AAAA,EACA,eAAA;AAAA,EACA;AACJ,CAAA,EAAgD;AAC5C,EAAA,MAAM,eAAA,GAAkB,OAA0B,IAAI,CAAA;AACtD,EAAA,MAAM,iBAAiB,WAAA,CAAY,MAAM,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,wBAAA,EAA0B,wBAAuB,GAAI,OAAA;AAAA,IACzE,OAAO;AAAA,MACH,KAAA,EAAO,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MAC7D,OAAA,EAAS,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MACjE,0BAA0B,aAAA,CAAc;AAAA,QACpC,EAAA,EAAI;AAAA,OACP,CAAA;AAAA,MACD,wBAAwB,aAAA,CAAc;AAAA,QAClC,EAAA,EAAI;AAAA,OACP;AAAA,KACL,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA,CAAC,OAAO,IAAA,EAAP,EAAY,MAAM,MAAA,EAAQ,cAAA,EAAgC,MAAK,aAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,UAAP,EAAgB,CAAA;AAAA,wBAChB,MAAA,CAAO,UAAA,EAAP,EACG,QAAA,kBAAA,IAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAO,MAAA,EAAP,EAAc,UAAS,OAAA,EAAQ,UAAA,EAAW,QACtC,QAAA,EAAA,KAAA,EACL,CAAA;AAAA,sBACA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,sBACtB,IAAA,CAAC,MAAA,CAAO,MAAA,EAAP,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,EAAA,EAAG,WAAA;AAAA,YACH,KAAA,EAAM,cAAA;AAAA,YACN,MAAA,EAAQ,EAAE,EAAA,EAAI,cAAA,EAAe;AAAA,YAC7B,WAAA,EAAa,wBAAA;AAAA,YACb,OAAA,EAAS,eAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,KAAK,eAAA,EAAiB,OAAA,EAAS,eACpD,QAAA,EAAA,sBAAA,EACL;AAAA,OAAA,EACJ;AAAA,KAAA,EACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"DeleteConfirmationDialog.js","sources":["DeleteConfirmationDialog.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Dialog } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useMemo, useRef, useState, type ReactElement } from \"react\";\n\ninterface DeleteConfirmationDialogProps {\n readonly isOpen: boolean;\n readonly onDelete: () => Promise<void>;\n readonly onCancel: () => void;\n}\n\nexport function DeleteConfirmationDialog({\n isOpen,\n onDelete,\n onCancel\n}: DeleteConfirmationDialogProps): ReactElement {\n const [isDeleting, setDeleting] = useState(false);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const initialFocusEl = useCallback(() => cancelButtonRef.current, []);\n const { formatMessage } = useIntl();\n\n const onDeleteClick = useEvent(async () => {\n try {\n setDeleting(true);\n await onDelete();\n } finally {\n setDeleting(false);\n }\n });\n\n const { title, message, deleteButtonTitle, cancelButtonTitle } = useMemo(\n () => ({\n title: formatMessage({ id: \"deleteConfirmationDialog.title\" }),\n message: formatMessage({ id: \"deleteConfirmationDialog.message\" }),\n deleteButtonTitle: formatMessage({ id: \"deleteConfirmationDialog.deleteButtonTitle\" }),\n cancelButtonTitle: formatMessage({ id: \"deleteConfirmationDialog.cancelButtonTitle\" })\n }),\n [formatMessage]\n );\n\n return (\n <Dialog.Root open={isOpen} initialFocusEl={initialFocusEl} role=\"alertdialog\">\n <Dialog.Backdrop />\n <Dialog.Positioner>\n <Dialog.Content>\n <Dialog.Header fontSize=\"large\" fontWeight=\"bold\">\n {title}\n </Dialog.Header>\n <Dialog.Body>{message}</Dialog.Body>\n <Dialog.Footer>\n <Button\n bg=\"red.solid\"\n color=\"red.contrast\"\n _hover={{ bg: \"red.solid/90\" }}\n loading={isDeleting}\n loadingText={deleteButtonTitle}\n onClick={onDeleteClick}\n >\n {deleteButtonTitle}\n </Button>\n <Button variant=\"outline\" ref={cancelButtonRef} onClick={onCancel}>\n {cancelButtonTitle}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Positioner>\n </Dialog.Root>\n );\n}\n"],"names":[],"mappings":";;;;;;AAcO,SAAS,wBAAA,CAAyB;AAAA,EACrC,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAAgD;AAC5C,EAAA,MAAM,CAAC,UAAA,EAAY,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,eAAA,GAAkB,OAA0B,IAAI,CAAA;AACtD,EAAA,MAAM,iBAAiB,WAAA,CAAY,MAAM,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,aAAA,GAAgB,SAAS,YAAY;AACvC,IAAA,IAAI;AACA,MAAA,WAAA,CAAY,IAAI,CAAA;AAChB,MAAA,MAAM,QAAA,EAAS;AAAA,IACnB,CAAA,SAAE;AACE,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,iBAAA,EAAmB,mBAAkB,GAAI,OAAA;AAAA,IAC7D,OAAO;AAAA,MACH,KAAA,EAAO,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MAC7D,OAAA,EAAS,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MACjE,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,8CAA8C,CAAA;AAAA,MACrF,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,8CAA8C;AAAA,KACzF,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA,CAAC,OAAO,IAAA,EAAP,EAAY,MAAM,MAAA,EAAQ,cAAA,EAAgC,MAAK,aAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,UAAP,EAAgB,CAAA;AAAA,wBAChB,MAAA,CAAO,UAAA,EAAP,EACG,QAAA,kBAAA,IAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAO,MAAA,EAAP,EAAc,UAAS,OAAA,EAAQ,UAAA,EAAW,QACtC,QAAA,EAAA,KAAA,EACL,CAAA;AAAA,sBACA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,sBACtB,IAAA,CAAC,MAAA,CAAO,MAAA,EAAP,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,EAAA,EAAG,WAAA;AAAA,YACH,KAAA,EAAM,cAAA;AAAA,YACN,MAAA,EAAQ,EAAE,EAAA,EAAI,cAAA,EAAe;AAAA,YAC7B,OAAA,EAAS,UAAA;AAAA,YACT,WAAA,EAAa,iBAAA;AAAA,YACb,OAAA,EAAS,aAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,KAAK,eAAA,EAAiB,OAAA,EAAS,UACpD,QAAA,EAAA,iBAAA,EACL;AAAA,OAAA,EACJ;AAAA,KAAA,EACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;;;"}
1
+ {"version":3,"file":"DeleteConfirmationDialog.js","sources":["DeleteConfirmationDialog.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Dialog } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useCallback, useMemo, useRef, useState, type ReactElement } from \"react\";\n\ninterface DeleteConfirmationDialogProps {\n readonly isOpen: boolean;\n readonly onDelete: () => Promise<void>;\n readonly onCancel: () => void;\n}\n\nexport function DeleteConfirmationDialog({\n isOpen,\n onDelete,\n onCancel\n}: DeleteConfirmationDialogProps): ReactElement {\n const [isDeleting, setDeleting] = useState(false);\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n const initialFocusEl = useCallback(() => cancelButtonRef.current, []);\n const { formatMessage } = useIntl();\n\n const onDeleteClick = useEvent(async () => {\n try {\n setDeleting(true);\n await onDelete();\n } finally {\n setDeleting(false);\n }\n });\n\n const { title, message, deleteButtonTitle, cancelButtonTitle } = useMemo(\n () => ({\n title: formatMessage({ id: \"deleteConfirmationDialog.title\" }),\n message: formatMessage({ id: \"deleteConfirmationDialog.message\" }),\n deleteButtonTitle: formatMessage({ id: \"deleteConfirmationDialog.deleteButtonTitle\" }),\n cancelButtonTitle: formatMessage({ id: \"deleteConfirmationDialog.cancelButtonTitle\" })\n }),\n [formatMessage]\n );\n\n return (\n <Dialog.Root open={isOpen} initialFocusEl={initialFocusEl} role=\"alertdialog\">\n <Dialog.Backdrop />\n <Dialog.Positioner>\n <Dialog.Content>\n <Dialog.Header fontSize=\"large\" fontWeight=\"bold\">\n {title}\n </Dialog.Header>\n <Dialog.Body>{message}</Dialog.Body>\n <Dialog.Footer>\n <Button\n bg=\"red.solid\"\n color=\"red.contrast\"\n _hover={{ bg: \"red.solid/90\" }}\n loading={isDeleting}\n loadingText={deleteButtonTitle}\n onClick={onDeleteClick}\n >\n {deleteButtonTitle}\n </Button>\n <Button variant=\"outline\" ref={cancelButtonRef} onClick={onCancel}>\n {cancelButtonTitle}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Positioner>\n </Dialog.Root>\n );\n}\n"],"names":[],"mappings":";;;;;;AAcO,SAAS,wBAAA,CAAyB;AAAA,EACrC,MAAA;AAAA,EACA,QAAA;AAAA,EACA;AACJ,CAAA,EAAgD;AAC5C,EAAA,MAAM,CAAC,UAAA,EAAY,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,eAAA,GAAkB,OAA0B,IAAI,CAAA;AACtD,EAAA,MAAM,iBAAiB,WAAA,CAAY,MAAM,eAAA,CAAgB,OAAA,EAAS,EAAE,CAAA;AACpE,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,OAAA,EAAQ;AAElC,EAAA,MAAM,aAAA,GAAgB,SAAS,YAAY;AACvC,IAAA,IAAI;AACA,MAAA,WAAA,CAAY,IAAI,CAAA;AAChB,MAAA,MAAM,QAAA,EAAS;AAAA,IACnB,CAAA,SAAE;AACE,MAAA,WAAA,CAAY,KAAK,CAAA;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,iBAAA,EAAmB,mBAAkB,GAAI,OAAA;AAAA,IAC7D,OAAO;AAAA,MACH,KAAA,EAAO,aAAA,CAAc,EAAE,EAAA,EAAI,kCAAkC,CAAA;AAAA,MAC7D,OAAA,EAAS,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC,CAAA;AAAA,MACjE,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,8CAA8C,CAAA;AAAA,MACrF,iBAAA,EAAmB,aAAA,CAAc,EAAE,EAAA,EAAI,8CAA8C;AAAA,KACzF,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAClB;AAEA,EAAA,uBACI,IAAA,CAAC,OAAO,IAAA,EAAP,EAAY,MAAM,MAAA,EAAQ,cAAA,EAAgC,MAAK,aAAA,EAC5D,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,MAAA,CAAO,UAAP,EAAgB,CAAA;AAAA,wBAChB,MAAA,CAAO,UAAA,EAAP,EACG,QAAA,kBAAA,IAAA,CAAC,MAAA,CAAO,SAAP,EACG,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,OAAO,MAAA,EAAP,EAAc,UAAS,OAAA,EAAQ,UAAA,EAAW,QACtC,QAAA,EAAA,KAAA,EACL,CAAA;AAAA,sBACA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAa,QAAA,EAAA,OAAA,EAAQ,CAAA;AAAA,sBACtB,IAAA,CAAC,MAAA,CAAO,MAAA,EAAP,EACG,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,EAAA,EAAG,WAAA;AAAA,YACH,KAAA,EAAM,cAAA;AAAA,YACN,MAAA,EAAQ,EAAE,EAAA,EAAI,cAAA,EAAe;AAAA,YAC7B,OAAA,EAAS,UAAA;AAAA,YACT,WAAA,EAAa,iBAAA;AAAA,YACb,OAAA,EAAS,aAAA;AAAA,YAER,QAAA,EAAA;AAAA;AAAA,SACL;AAAA,wBACA,GAAA,CAAC,UAAO,OAAA,EAAQ,SAAA,EAAU,KAAK,eAAA,EAAiB,OAAA,EAAS,UACpD,QAAA,EAAA,iBAAA,EACL;AAAA,OAAA,EACJ;AAAA,KAAA,EACJ,CAAA,EACJ;AAAA,GAAA,EACJ,CAAA;AAER;;"}
@@ -1,8 +1,10 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
2
  import { Flex, useDisclosure } from '@chakra-ui/react';
3
+ import { createLogger } from '@open-pioneer/core';
3
4
  import { useEvent } from '@open-pioneer/react-utils';
4
5
  import { useReactiveSnapshot } from '@open-pioneer/reactivity';
5
- import { useMemo, useCallback } from 'react';
6
+ import { sourceId$2 as sourceId } from '../../../_virtual/source-info.js';
7
+ import { useState, useEffect, useMemo, useCallback } from 'react';
6
8
  import { DeclarativeFormContext, CustomFormContextImpl, FormContext } from '../../context/PropertyFormContext.js';
7
9
  import { usePropertyFormContext } from '../../context/usePropertyFormContext.js';
8
10
  import { ButtonRow } from './ButtonRow.js';
@@ -11,18 +13,26 @@ import { DeleteConfirmationDialog } from './DeleteConfirmationDialog.js';
11
13
  import { PropertyField } from './PropertyField.js';
12
14
  import { PropertyForm } from './PropertyForm.js';
13
15
 
16
+ const LOG = createLogger(sourceId);
14
17
  function PropertyEditor(props) {
15
18
  const { editingStep, callbacks, templates, resolveFormTemplate } = props;
16
19
  const formTemplate = useFormTemplate(templates, resolveFormTemplate, editingStep);
17
- const context = useMemo(() => {
20
+ const [context, setContext] = useState();
21
+ useEffect(() => {
18
22
  if (!formTemplate) {
19
23
  return void 0;
20
24
  }
25
+ let ctx;
21
26
  if (formTemplate.kind === "declarative") {
22
- return new DeclarativeFormContext(editingStep, callbacks, formTemplate);
27
+ ctx = new DeclarativeFormContext(editingStep, callbacks, formTemplate);
23
28
  } else {
24
- return new CustomFormContextImpl(editingStep, callbacks, formTemplate);
29
+ ctx = new CustomFormContextImpl(editingStep, callbacks, formTemplate);
25
30
  }
31
+ setContext(ctx);
32
+ return () => {
33
+ ctx.destroy();
34
+ setContext(void 0);
35
+ };
26
36
  }, [formTemplate, editingStep, callbacks]);
27
37
  return context && formTemplate && /* @__PURE__ */ jsx(FormContext, { value: context, children: /* @__PURE__ */ jsxs(
28
38
  Flex,
@@ -95,6 +105,16 @@ function EditorControls() {
95
105
  context.callbacks.onCancel();
96
106
  closeCancelConfirmationDialog();
97
107
  });
108
+ const onCancelClick = useEvent(() => {
109
+ if (!context.didEdit) {
110
+ LOG.debug(
111
+ "Skipping cancel confirmation dialog because the user did not edit the feature"
112
+ );
113
+ onConfirmCancelClick();
114
+ } else {
115
+ openCancelDialog();
116
+ }
117
+ });
98
118
  return /* @__PURE__ */ jsxs(Fragment, { children: [
99
119
  /* @__PURE__ */ jsx(
100
120
  ButtonRow,
@@ -103,7 +123,7 @@ function EditorControls() {
103
123
  showDeleteButton: context.mode === "update",
104
124
  onSave: onSaveClick,
105
125
  onDelete: openDeleteDialog,
106
- onCancel: openCancelDialog
126
+ onCancel: onCancelClick
107
127
  }
108
128
  ),
109
129
  /* @__PURE__ */ jsx(
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyEditor.js","sources":["PropertyEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, useDisclosure } from \"@chakra-ui/react\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useCallback, useMemo, type ReactElement } from \"react\";\nimport { FeatureEditorProps, FormTemplateContext } from \"../../../api/editor/editor\";\nimport { CreationStep, UpdateStep } from \"../../../api/model/EditingStep\";\nimport { FeatureTemplate, FormTemplate } from \"../../../api/model/FeatureTemplate\";\nimport {\n DeclarativeFormContext,\n CustomFormContextImpl,\n FormContext\n} from \"../../context/PropertyFormContext\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\nimport { EditingCallbacks } from \"../../editor/useEditingCallbacks\";\nimport { ButtonRow } from \"./ButtonRow\";\nimport { CancelConfirmationDialog } from \"./CancelConfirmationDialog\";\nimport { DeleteConfirmationDialog } from \"./DeleteConfirmationDialog\";\nimport { PropertyField } from \"./PropertyField\";\nimport { PropertyForm } from \"./PropertyForm\";\n\nexport function PropertyEditor(props: {\n editingStep: CreationStep | UpdateStep;\n callbacks: EditingCallbacks;\n templates: FeatureTemplate[];\n resolveFormTemplate: FeatureEditorProps[\"resolveFormTemplate\"];\n}) {\n const { editingStep, callbacks, templates, resolveFormTemplate } = props;\n const formTemplate = useFormTemplate(templates, resolveFormTemplate, editingStep);\n\n const context = useMemo(() => {\n if (!formTemplate) {\n return undefined;\n }\n\n if (formTemplate.kind === \"declarative\") {\n return new DeclarativeFormContext(editingStep, callbacks, formTemplate);\n } else {\n return new CustomFormContextImpl(editingStep, callbacks, formTemplate);\n }\n }, [formTemplate, editingStep, callbacks]);\n\n return (\n context &&\n formTemplate && (\n <FormContext value={context}>\n <Flex\n className=\"editor__property-editor\"\n direction=\"column\"\n height=\"full\"\n overflowY={\"hidden\"}\n >\n <PropertyForm>\n {formTemplate.kind === \"dynamic\"\n ? formTemplate.renderForm()\n : formTemplate.fields.map((field, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <PropertyField key={index} field={field} />\n ))}\n </PropertyForm>\n <EditorControls />\n </Flex>\n </FormContext>\n )\n );\n}\n\nfunction useFormTemplate(\n templates: FeatureTemplate[],\n customResolver: FeatureEditorProps[\"resolveFormTemplate\"],\n editingStep: CreationStep | UpdateStep\n): FormTemplate | undefined {\n const defaultResolver = useDefaultFormTemplateResolver(templates);\n const resolveFormTemplate = customResolver ?? defaultResolver;\n\n const feature = editingStep.feature;\n const layer = editingStep.id === \"update\" ? editingStep.layer : undefined;\n const explicitTemplate = editingStep.id === \"creation\" ? editingStep.template : undefined;\n\n return useMemo(() => {\n if (explicitTemplate) {\n return explicitTemplate;\n } else if (editingStep.id === \"update\") {\n return resolveFormTemplate({ feature, layer });\n } else {\n return undefined;\n }\n }, [explicitTemplate, editingStep.id, feature, layer, resolveFormTemplate]);\n}\n\nfunction useDefaultFormTemplateResolver(templates: FeatureTemplate[]) {\n return useCallback(\n ({ layer }: FormTemplateContext) => {\n if (layer?.id != null) {\n return templates.find(({ layerId }) => layer.id === layerId);\n } else {\n return undefined;\n }\n },\n [templates]\n );\n}\n\nfunction EditorControls(): ReactElement {\n const context = usePropertyFormContext();\n const canSave = useReactiveSnapshot(() => context.isValid, [context]);\n\n const {\n open: deleteDialogIsOpen,\n onOpen: openDeleteDialog,\n onClose: closeDeleteDialog\n } = useDisclosure();\n const {\n open: cancelDialogIsOpen,\n onOpen: openCancelDialog,\n onClose: closeCancelConfirmationDialog\n } = useDisclosure();\n\n const onSaveClick = useEvent(async () => {\n const properties = context.getPropertiesAsObject();\n context.feature.setProperties(properties);\n await context.callbacks.onSave();\n });\n\n const onDeleteClick = useEvent(async () => {\n await context.callbacks.onDelete();\n closeDeleteDialog();\n });\n\n const onConfirmCancelClick = useEvent(() => {\n context.callbacks.onCancel();\n closeCancelConfirmationDialog();\n });\n\n return (\n <>\n <ButtonRow\n canSave={canSave}\n showDeleteButton={context.mode === \"update\"}\n onSave={onSaveClick}\n onDelete={openDeleteDialog}\n onCancel={openCancelDialog}\n />\n <DeleteConfirmationDialog\n isOpen={deleteDialogIsOpen}\n onDelete={onDeleteClick}\n onCancel={closeDeleteDialog}\n />\n <CancelConfirmationDialog\n isOpen={cancelDialogIsOpen}\n onConfirmCancel={onConfirmCancelClick}\n onAbortCancel={closeCancelConfirmationDialog}\n />\n </>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PropertyEditor.js","sources":["PropertyEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, useDisclosure } from \"@chakra-ui/react\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { useEvent } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { sourceId } from \"open-pioneer:source-info\";\nimport { useCallback, useEffect, useMemo, useState, type ReactElement } from \"react\";\nimport { FeatureEditorProps, FormTemplateContext } from \"../../../api/editor/editor\";\nimport { CreationStep, UpdateStep } from \"../../../api/model/EditingStep\";\nimport { FeatureTemplate, FormTemplate } from \"../../../api/model/FeatureTemplate\";\nimport {\n AnyPropertyFormContext,\n CustomFormContextImpl,\n DeclarativeFormContext,\n FormContext\n} from \"../../context/PropertyFormContext\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\nimport { EditingCallbacks } from \"../../editor/useEditingCallbacks\";\nimport { ButtonRow } from \"./ButtonRow\";\nimport { CancelConfirmationDialog } from \"./CancelConfirmationDialog\";\nimport { DeleteConfirmationDialog } from \"./DeleteConfirmationDialog\";\nimport { PropertyField } from \"./PropertyField\";\nimport { PropertyForm } from \"./PropertyForm\";\n\nconst LOG = createLogger(sourceId);\n\nexport function PropertyEditor(props: {\n editingStep: CreationStep | UpdateStep;\n callbacks: EditingCallbacks;\n templates: FeatureTemplate[];\n resolveFormTemplate: FeatureEditorProps[\"resolveFormTemplate\"];\n}) {\n const { editingStep, callbacks, templates, resolveFormTemplate } = props;\n const formTemplate = useFormTemplate(templates, resolveFormTemplate, editingStep);\n\n const [context, setContext] = useState<AnyPropertyFormContext>();\n useEffect(() => {\n if (!formTemplate) {\n return undefined;\n }\n\n let ctx;\n if (formTemplate.kind === \"declarative\") {\n ctx = new DeclarativeFormContext(editingStep, callbacks, formTemplate);\n } else {\n ctx = new CustomFormContextImpl(editingStep, callbacks, formTemplate);\n }\n setContext(ctx);\n return () => {\n ctx.destroy();\n setContext(undefined);\n };\n }, [formTemplate, editingStep, callbacks]);\n\n return (\n context &&\n formTemplate && (\n <FormContext value={context}>\n <Flex\n className=\"editor__property-editor\"\n direction=\"column\"\n height=\"full\"\n overflowY={\"hidden\"}\n >\n <PropertyForm>\n {formTemplate.kind === \"dynamic\"\n ? formTemplate.renderForm()\n : formTemplate.fields.map((field, index) => (\n // oxlint-disable-next-line react/no-array-index-key\n <PropertyField key={index} field={field} />\n ))}\n </PropertyForm>\n <EditorControls />\n </Flex>\n </FormContext>\n )\n );\n}\n\nfunction useFormTemplate(\n templates: FeatureTemplate[],\n customResolver: FeatureEditorProps[\"resolveFormTemplate\"],\n editingStep: CreationStep | UpdateStep\n): FormTemplate | undefined {\n const defaultResolver = useDefaultFormTemplateResolver(templates);\n const resolveFormTemplate = customResolver ?? defaultResolver;\n\n const feature = editingStep.feature;\n const layer = editingStep.id === \"update\" ? editingStep.layer : undefined;\n const explicitTemplate = editingStep.id === \"creation\" ? editingStep.template : undefined;\n\n return useMemo(() => {\n if (explicitTemplate) {\n return explicitTemplate;\n } else if (editingStep.id === \"update\") {\n return resolveFormTemplate({ feature, layer });\n } else {\n return undefined;\n }\n }, [explicitTemplate, editingStep.id, feature, layer, resolveFormTemplate]);\n}\n\nfunction useDefaultFormTemplateResolver(templates: FeatureTemplate[]) {\n return useCallback(\n ({ layer }: FormTemplateContext) => {\n if (layer?.id != null) {\n return templates.find(({ layerId }) => layer.id === layerId);\n } else {\n return undefined;\n }\n },\n [templates]\n );\n}\n\nfunction EditorControls(): ReactElement {\n const context = usePropertyFormContext();\n const canSave = useReactiveSnapshot(() => context.isValid, [context]);\n\n const {\n open: deleteDialogIsOpen,\n onOpen: openDeleteDialog,\n onClose: closeDeleteDialog\n } = useDisclosure();\n const {\n open: cancelDialogIsOpen,\n onOpen: openCancelDialog,\n onClose: closeCancelConfirmationDialog\n } = useDisclosure();\n\n const onSaveClick = useEvent(async () => {\n const properties = context.getPropertiesAsObject();\n context.feature.setProperties(properties);\n await context.callbacks.onSave();\n });\n\n const onDeleteClick = useEvent(async () => {\n await context.callbacks.onDelete();\n closeDeleteDialog();\n });\n\n const onConfirmCancelClick = useEvent(() => {\n context.callbacks.onCancel();\n closeCancelConfirmationDialog();\n });\n\n const onCancelClick = useEvent(() => {\n if (!context.didEdit) {\n LOG.debug(\n \"Skipping cancel confirmation dialog because the user did not edit the feature\"\n );\n onConfirmCancelClick();\n } else {\n openCancelDialog();\n }\n });\n\n return (\n <>\n <ButtonRow\n canSave={canSave}\n showDeleteButton={context.mode === \"update\"}\n onSave={onSaveClick}\n onDelete={openDeleteDialog}\n onCancel={onCancelClick}\n />\n <DeleteConfirmationDialog\n isOpen={deleteDialogIsOpen}\n onDelete={onDeleteClick}\n onCancel={closeDeleteDialog}\n />\n <CancelConfirmationDialog\n isOpen={cancelDialogIsOpen}\n onConfirmCancel={onConfirmCancelClick}\n onAbortCancel={closeCancelConfirmationDialog}\n />\n </>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA0BA,MAAM,GAAA,GAAM,aAAa,QAAQ,CAAA;AAE1B,SAAS,eAAe,KAAA,EAK5B;AACC,EAAA,MAAM,EAAE,WAAA,EAAa,SAAA,EAAW,SAAA,EAAW,qBAAoB,GAAI,KAAA;AACnE,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,SAAA,EAAW,mBAAA,EAAqB,WAAW,CAAA;AAEhF,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,QAAA,EAAiC;AAC/D,EAAA,SAAA,CAAU,MAAM;AACZ,IAAA,IAAI,CAAC,YAAA,EAAc;AACf,MAAA,OAAO,MAAA;AAAA,IACX;AAEA,IAAA,IAAI,GAAA;AACJ,IAAA,IAAI,YAAA,CAAa,SAAS,aAAA,EAAe;AACrC,MAAA,GAAA,GAAM,IAAI,sBAAA,CAAuB,WAAA,EAAa,SAAA,EAAW,YAAY,CAAA;AAAA,IACzE,CAAA,MAAO;AACH,MAAA,GAAA,GAAM,IAAI,qBAAA,CAAsB,WAAA,EAAa,SAAA,EAAW,YAAY,CAAA;AAAA,IACxE;AACA,IAAA,UAAA,CAAW,GAAG,CAAA;AACd,IAAA,OAAO,MAAM;AACT,MAAA,GAAA,CAAI,OAAA,EAAQ;AACZ,MAAA,UAAA,CAAW,MAAS,CAAA;AAAA,IACxB,CAAA;AAAA,EACJ,CAAA,EAAG,CAAC,YAAA,EAAc,WAAA,EAAa,SAAS,CAAC,CAAA;AAEzC,EAAA,OACI,OAAA,IACA,YAAA,oBACI,GAAA,CAAC,WAAA,EAAA,EAAY,OAAO,OAAA,EAChB,QAAA,kBAAA,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,yBAAA;AAAA,MACV,SAAA,EAAU,QAAA;AAAA,MACV,MAAA,EAAO,MAAA;AAAA,MACP,SAAA,EAAW,QAAA;AAAA,MAEX,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,YAAA,EAAA,EACI,QAAA,EAAA,YAAA,CAAa,IAAA,KAAS,SAAA,GACjB,YAAA,CAAa,UAAA,EAAW,GACxB,YAAA,CAAa,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,EAAO,KAAA;AAAA;AAAA,0BAE5B,GAAA,CAAC,aAAA,EAAA,EAA0B,KAAA,EAAA,EAAP,KAAqB;AAAA,SAC5C,CAAA,EACX,CAAA;AAAA,4BACC,cAAA,EAAA,EAAe;AAAA;AAAA;AAAA,GACpB,EACJ,CAAA;AAGZ;AAEA,SAAS,eAAA,CACL,SAAA,EACA,cAAA,EACA,WAAA,EACwB;AACxB,EAAA,MAAM,eAAA,GAAkB,+BAA+B,SAAS,CAAA;AAChE,EAAA,MAAM,sBAAsB,cAAA,IAAkB,eAAA;AAE9C,EAAA,MAAM,UAAU,WAAA,CAAY,OAAA;AAC5B,EAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,EAAA,KAAO,QAAA,GAAW,YAAY,KAAA,GAAQ,MAAA;AAChE,EAAA,MAAM,gBAAA,GAAmB,WAAA,CAAY,EAAA,KAAO,UAAA,GAAa,YAAY,QAAA,GAAW,MAAA;AAEhF,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,IAAI,gBAAA,EAAkB;AAClB,MAAA,OAAO,gBAAA;AAAA,IACX,CAAA,MAAA,IAAW,WAAA,CAAY,EAAA,KAAO,QAAA,EAAU;AACpC,MAAA,OAAO,mBAAA,CAAoB,EAAE,OAAA,EAAS,KAAA,EAAO,CAAA;AAAA,IACjD,CAAA,MAAO;AACH,MAAA,OAAO,MAAA;AAAA,IACX;AAAA,EACJ,CAAA,EAAG,CAAC,gBAAA,EAAkB,WAAA,CAAY,IAAI,OAAA,EAAS,KAAA,EAAO,mBAAmB,CAAC,CAAA;AAC9E;AAEA,SAAS,+BAA+B,SAAA,EAA8B;AAClE,EAAA,OAAO,WAAA;AAAA,IACH,CAAC,EAAE,KAAA,EAAM,KAA2B;AAChC,MAAA,IAAI,KAAA,EAAO,MAAM,IAAA,EAAM;AACnB,QAAA,OAAO,SAAA,CAAU,KAAK,CAAC,EAAE,SAAQ,KAAM,KAAA,CAAM,OAAO,OAAO,CAAA;AAAA,MAC/D,CAAA,MAAO;AACH,QAAA,OAAO,MAAA;AAAA,MACX;AAAA,IACJ,CAAA;AAAA,IACA,CAAC,SAAS;AAAA,GACd;AACJ;AAEA,SAAS,cAAA,GAA+B;AACpC,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,MAAM,UAAU,mBAAA,CAAoB,MAAM,QAAQ,OAAA,EAAS,CAAC,OAAO,CAAC,CAAA;AAEpE,EAAA,MAAM;AAAA,IACF,IAAA,EAAM,kBAAA;AAAA,IACN,MAAA,EAAQ,gBAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACT,aAAA,EAAc;AAClB,EAAA,MAAM;AAAA,IACF,IAAA,EAAM,kBAAA;AAAA,IACN,MAAA,EAAQ,gBAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACT,aAAA,EAAc;AAElB,EAAA,MAAM,WAAA,GAAc,SAAS,YAAY;AACrC,IAAA,MAAM,UAAA,GAAa,QAAQ,qBAAA,EAAsB;AACjD,IAAA,OAAA,CAAQ,OAAA,CAAQ,cAAc,UAAU,CAAA;AACxC,IAAA,MAAM,OAAA,CAAQ,UAAU,MAAA,EAAO;AAAA,EACnC,CAAC,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,SAAS,YAAY;AACvC,IAAA,MAAM,OAAA,CAAQ,UAAU,QAAA,EAAS;AACjC,IAAA,iBAAA,EAAkB;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,MAAM,oBAAA,GAAuB,SAAS,MAAM;AACxC,IAAA,OAAA,CAAQ,UAAU,QAAA,EAAS;AAC3B,IAAA,6BAAA,EAA8B;AAAA,EAClC,CAAC,CAAA;AAED,EAAA,MAAM,aAAA,GAAgB,SAAS,MAAM;AACjC,IAAA,IAAI,CAAC,QAAQ,OAAA,EAAS;AAClB,MAAA,GAAA,CAAI,KAAA;AAAA,QACA;AAAA,OACJ;AACA,MAAA,oBAAA,EAAqB;AAAA,IACzB,CAAA,MAAO;AACH,MAAA,gBAAA,EAAiB;AAAA,IACrB;AAAA,EACJ,CAAC,CAAA;AAED,EAAA,uBACI,IAAA,CAAA,QAAA,EAAA,EACI,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACG,OAAA;AAAA,QACA,gBAAA,EAAkB,QAAQ,IAAA,KAAS,QAAA;AAAA,QACnC,MAAA,EAAQ,WAAA;AAAA,QACR,QAAA,EAAU,gBAAA;AAAA,QACV,QAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBACA,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACG,MAAA,EAAQ,kBAAA;AAAA,QACR,QAAA,EAAU,aAAA;AAAA,QACV,QAAA,EAAU;AAAA;AAAA,KACd;AAAA,oBACA,GAAA;AAAA,MAAC,wBAAA;AAAA,MAAA;AAAA,QACG,MAAA,EAAQ,kBAAA;AAAA,QACR,eAAA,EAAiB,oBAAA;AAAA,QACjB,aAAA,EAAe;AAAA;AAAA;AACnB,GAAA,EACJ,CAAA;AAER;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyField.js","sources":["PropertyField.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Field } from \"@chakra-ui/react\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport type { PropertyFunction, PropertyFunctionOr } from \"../../../api/fields/BaseFieldConfig\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport {\n useDeclarativeFormContext,\n usePropertyFormContext\n} from \"../../context/usePropertyFormContext\";\nimport { DefaultControl } from \"../controls/DefaultControl\";\n\nexport interface PropertyFieldProps {\n readonly field: FieldConfig;\n}\n\nexport function PropertyField({ field }: PropertyFieldProps): ReactElement | undefined {\n const context = useDeclarativeFormContext();\n const isRequired = useValue(field.isRequired) ?? false;\n const isEnabled = useValue(field.isEnabled) ?? true;\n const isVisible = useValue(field.isVisible) ?? true;\n const isValid = useReactiveSnapshot(() => context.isFieldValid(field), [context, field]);\n\n const defaultErrorText = useDefaultErrorText(field);\n const errorText = useValue(field.errorText) ?? defaultErrorText;\n const helperText = useValue(field.helperText);\n\n const [hadFocus, setHadFocus] = useState(false);\n\n if (isVisible) {\n return (\n <Field.Root\n className=\"editor__property-field\"\n required={isRequired}\n disabled={!isEnabled}\n invalid={hadFocus && !isValid}\n data-editor-property-name={field.propertyName}\n onFocus={() => {\n setHadFocus(true);\n }}\n >\n <Field.Label>\n {field.label}\n <Field.RequiredIndicator />\n </Field.Label>\n <DefaultControl field={field} />\n {helperText && <Field.HelperText>{helperText}</Field.HelperText>}\n {errorText && <Field.ErrorText>{errorText}</Field.ErrorText>}\n </Field.Root>\n );\n } else {\n return undefined;\n }\n}\n\nfunction useDefaultErrorText(field: FieldConfig): string | undefined {\n const intl = useIntl();\n return useMemo(() => {\n if (field.type !== \"number-field\" || (field.min == null && field.max == null)) {\n return undefined;\n }\n\n const { min, max } = field;\n let messageId;\n if (min != null && max != null) {\n messageId = \"propertyEditor.errors.minAndMax\";\n } else if (min != null) {\n messageId = \"propertyEditor.errors.minOnly\";\n } else {\n messageId = \"propertyEditor.errors.maxOnly\";\n }\n return intl.formatMessage({ id: messageId }, { min, max });\n }, [intl, field]);\n}\n\nfunction useValue<T>(value: PropertyFunctionOr<T> | undefined): T | undefined {\n const context = usePropertyFormContext();\n\n return useReactiveSnapshot(() => {\n if (isPropertyFunction(value)) {\n const properties = context.getPropertiesAsObject();\n return value(properties);\n } else {\n return value;\n }\n }, [context, value]);\n}\n\nfunction isPropertyFunction<T>(value: PropertyFunctionOr<T>): value is PropertyFunction<T> {\n return typeof value === \"function\";\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PropertyField.js","sources":["PropertyField.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Field } from \"@chakra-ui/react\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport type { PropertyFunction, PropertyFunctionOr } from \"../../../api/fields/BaseFieldConfig\";\nimport type { FieldConfig } from \"../../../api/fields/FieldConfig\";\nimport {\n useDeclarativeFormContext,\n usePropertyFormContext\n} from \"../../context/usePropertyFormContext\";\nimport { DefaultControl } from \"../controls/DefaultControl\";\n\nexport interface PropertyFieldProps {\n readonly field: FieldConfig;\n}\n\nexport function PropertyField({ field }: PropertyFieldProps): ReactElement | undefined {\n const context = useDeclarativeFormContext();\n const isRequired = useValue(field.isRequired) ?? false;\n const isEnabled = useValue(field.isEnabled) ?? true;\n const isVisible = useValue(field.isVisible) ?? true;\n const isValid = useReactiveSnapshot(() => context.isFieldValid(field), [context, field]);\n\n const defaultErrorText = useDefaultErrorText(field);\n const errorText = useValue(field.errorText) ?? defaultErrorText;\n const helperText = useValue(field.helperText);\n\n const [hadFocus, setHadFocus] = useState(false);\n\n if (isVisible) {\n return (\n <Field.Root\n className=\"editor__property-field\"\n required={isRequired}\n disabled={!isEnabled}\n invalid={hadFocus && !isValid}\n data-editor-property-name={field.propertyName}\n onFocus={() => {\n setHadFocus(true);\n }}\n >\n <Field.Label>\n {field.label}\n <Field.RequiredIndicator />\n </Field.Label>\n <DefaultControl field={field} />\n {helperText && <Field.HelperText>{helperText}</Field.HelperText>}\n {errorText && <Field.ErrorText>{errorText}</Field.ErrorText>}\n </Field.Root>\n );\n } else {\n return undefined;\n }\n}\n\nfunction useDefaultErrorText(field: FieldConfig): string | undefined {\n const intl = useIntl();\n return useMemo(() => {\n if (field.type !== \"number-field\" || (field.min == null && field.max == null)) {\n return undefined;\n }\n\n const { min, max } = field;\n let messageId;\n if (min != null && max != null) {\n messageId = \"propertyEditor.errors.minAndMax\";\n } else if (min != null) {\n messageId = \"propertyEditor.errors.minOnly\";\n } else {\n messageId = \"propertyEditor.errors.maxOnly\";\n }\n return intl.formatMessage({ id: messageId }, { min, max });\n }, [intl, field]);\n}\n\nfunction useValue<T>(value: PropertyFunctionOr<T> | undefined): T | undefined {\n const context = usePropertyFormContext();\n\n return useReactiveSnapshot(() => {\n if (isPropertyFunction(value)) {\n const properties = context.getPropertiesAsObject();\n return value(properties);\n } else {\n return value;\n }\n }, [context, value]);\n}\n\nfunction isPropertyFunction<T>(value: PropertyFunctionOr<T>): value is PropertyFunction<T> {\n return typeof value === \"function\";\n}\n"],"names":[],"mappings":";;;;;;;;AAmBO,SAAS,aAAA,CAAc,EAAE,KAAA,EAAM,EAAiD;AACnF,EAAA,MAAM,UAAU,yBAAA,EAA0B;AAC1C,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA,IAAK,KAAA;AACjD,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,IAAK,IAAA;AAC/C,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,IAAK,IAAA;AAC/C,EAAA,MAAM,OAAA,GAAU,mBAAA,CAAoB,MAAM,OAAA,CAAQ,YAAA,CAAa,KAAK,CAAA,EAAG,CAAC,OAAA,EAAS,KAAK,CAAC,CAAA;AAEvF,EAAA,MAAM,gBAAA,GAAmB,oBAAoB,KAAK,CAAA;AAClD,EAAA,MAAM,SAAA,GAAY,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,IAAK,gBAAA;AAC/C,EAAA,MAAM,UAAA,GAAa,QAAA,CAAS,KAAA,CAAM,UAAU,CAAA;AAE5C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,KAAK,CAAA;AAE9C,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,uBACI,IAAA;AAAA,MAAC,KAAA,CAAM,IAAA;AAAA,MAAN;AAAA,QACG,SAAA,EAAU,wBAAA;AAAA,QACV,QAAA,EAAU,UAAA;AAAA,QACV,UAAU,CAAC,SAAA;AAAA,QACX,OAAA,EAAS,YAAY,CAAC,OAAA;AAAA,QACtB,6BAA2B,KAAA,CAAM,YAAA;AAAA,QACjC,SAAS,MAAM;AACX,UAAA,WAAA,CAAY,IAAI,CAAA;AAAA,QACpB,CAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,CAAM,OAAN,EACI,QAAA,EAAA;AAAA,YAAA,KAAA,CAAM,KAAA;AAAA,4BACP,GAAA,CAAC,KAAA,CAAM,iBAAA,EAAN,EAAwB;AAAA,WAAA,EAC7B,CAAA;AAAA,0BACA,GAAA,CAAC,kBAAe,KAAA,EAAc,CAAA;AAAA,UAC7B,UAAA,oBAAc,GAAA,CAAC,KAAA,CAAM,UAAA,EAAN,EAAkB,QAAA,EAAA,UAAA,EAAW,CAAA;AAAA,UAC5C,SAAA,oBAAa,GAAA,CAAC,KAAA,CAAM,SAAA,EAAN,EAAiB,QAAA,EAAA,SAAA,EAAU;AAAA;AAAA;AAAA,KAC9C;AAAA,EAER,CAAA,MAAO;AACH,IAAA,OAAO,MAAA;AAAA,EACX;AACJ;AAEA,SAAS,oBAAoB,KAAA,EAAwC;AACjE,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,OAAO,QAAQ,MAAM;AACjB,IAAA,IAAI,KAAA,CAAM,SAAS,cAAA,IAAmB,KAAA,CAAM,OAAO,IAAA,IAAQ,KAAA,CAAM,OAAO,IAAA,EAAO;AAC3E,MAAA,OAAO,MAAA;AAAA,IACX;AAEA,IAAA,MAAM,EAAE,GAAA,EAAK,GAAA,EAAI,GAAI,KAAA;AACrB,IAAA,IAAI,SAAA;AACJ,IAAA,IAAI,GAAA,IAAO,IAAA,IAAQ,GAAA,IAAO,IAAA,EAAM;AAC5B,MAAA,SAAA,GAAY,iCAAA;AAAA,IAChB,CAAA,MAAA,IAAW,OAAO,IAAA,EAAM;AACpB,MAAA,SAAA,GAAY,+BAAA;AAAA,IAChB,CAAA,MAAO;AACH,MAAA,SAAA,GAAY,+BAAA;AAAA,IAChB;AACA,IAAA,OAAO,IAAA,CAAK,cAAc,EAAE,EAAA,EAAI,WAAU,EAAG,EAAE,GAAA,EAAK,GAAA,EAAK,CAAA;AAAA,EAC7D,CAAA,EAAG,CAAC,IAAA,EAAM,KAAK,CAAC,CAAA;AACpB;AAEA,SAAS,SAAY,KAAA,EAAyD;AAC1E,EAAA,MAAM,UAAU,sBAAA,EAAuB;AAEvC,EAAA,OAAO,oBAAoB,MAAM;AAC7B,IAAA,IAAI,kBAAA,CAAmB,KAAK,CAAA,EAAG;AAC3B,MAAA,MAAM,UAAA,GAAa,QAAQ,qBAAA,EAAsB;AACjD,MAAA,OAAO,MAAM,UAAU,CAAA;AAAA,IAC3B,CAAA,MAAO;AACH,MAAA,OAAO,KAAA;AAAA,IACX;AAAA,EACJ,CAAA,EAAG,CAAC,OAAA,EAAS,KAAK,CAAC,CAAA;AACvB;AAEA,SAAS,mBAAsB,KAAA,EAA4D;AACvF,EAAA,OAAO,OAAO,KAAA,KAAU,UAAA;AAC5B;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyForm.js","sources":["PropertyForm.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, VStack, Text } from \"@chakra-ui/react\";\nimport { SectionHeading, TitledSection } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { ReactNode, type ReactElement } from \"react\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\n\nexport interface PropertyFormProps {\n children?: ReactNode;\n}\n\nexport function PropertyForm(props: PropertyFormProps): ReactElement {\n const { children } = props;\n const heading = useHeading();\n const context = usePropertyFormContext();\n const hasRequiredFields = useReactiveSnapshot(() => context.hasRequiredFields, [context]);\n const { formatRichMessage } = useIntl();\n\n return (\n <TitledSection>\n <Flex\n className=\"editor__property-form\"\n direction={\"column\"}\n flex={1}\n overflowY=\"hidden\"\n >\n <SectionHeading mb={2} size=\"sm\">\n {heading}\n </SectionHeading>\n <VStack\n gap={4}\n align=\"stretch\"\n // for focus ring\n px=\"1px\"\n pb=\"4px\"\n flex={1}\n overflowY={\"auto\"}\n >\n {children}\n </VStack>\n {hasRequiredFields && (\n <Text\n fontSize={\"sm\"}\n aria-hidden=\"true\"\n textAlign={\"right\"}\n paddingRight={2}\n mb={2}\n >\n <Text as=\"span\" color=\"fg.error\">\n *\n </Text>{\" \"}\n {formatRichMessage({ id: \"propertyEditor.requiredFieldHint\" })}\n </Text>\n )}\n </Flex>\n </TitledSection>\n );\n}\n\nfunction useHeading() {\n const intl = useIntl();\n const { mode, formTemplate: template } = usePropertyFormContext();\n const defaultHeading = intl.formatMessage({\n id:\n mode === \"update\"\n ? \"propertyEditor.defaultEditHeading\"\n : \"propertyEditor.defaultCreateHeading\"\n });\n return template?.name ? `${defaultHeading}: ${template?.name} ` : defaultHeading;\n}\n"],"names":[],"mappings":";;;;;;;AAcO,SAAS,aAAa,KAAA,EAAwC;AACjE,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,MAAM,UAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,MAAM,oBAAoB,mBAAA,CAAoB,MAAM,QAAQ,iBAAA,EAAmB,CAAC,OAAO,CAAC,CAAA;AACxF,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,OAAA,EAAQ;AAEtC,EAAA,2BACK,aAAA,EAAA,EACG,QAAA,kBAAA,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,uBAAA;AAAA,MACV,SAAA,EAAW,QAAA;AAAA,MACX,IAAA,EAAM,CAAA;AAAA,MACN,SAAA,EAAU,QAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,EAAA,EAAI,CAAA,EAAG,IAAA,EAAK,MACvB,QAAA,EAAA,OAAA,EACL,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,GAAA,EAAK,CAAA;AAAA,YACL,KAAA,EAAM,SAAA;AAAA,YAEN,EAAA,EAAG,KAAA;AAAA,YACH,EAAA,EAAG,KAAA;AAAA,YACH,IAAA,EAAM,CAAA;AAAA,YACN,SAAA,EAAW,MAAA;AAAA,YAEV;AAAA;AAAA,SACL;AAAA,QACC,iBAAA,oBACG,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,QAAA,EAAU,IAAA;AAAA,YACV,aAAA,EAAY,MAAA;AAAA,YACZ,SAAA,EAAW,OAAA;AAAA,YACX,YAAA,EAAc,CAAA;AAAA,YACd,EAAA,EAAI,CAAA;AAAA,YAEJ,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAG,MAAA,EAAO,KAAA,EAAM,YAAW,QAAA,EAAA,GAAA,EAEjC,CAAA;AAAA,cAAQ,GAAA;AAAA,cACP,iBAAA,CAAkB,EAAE,EAAA,EAAI,kCAAA,EAAoC;AAAA;AAAA;AAAA;AACjE;AAAA;AAAA,GAER,EACJ,CAAA;AAER;AAEA,SAAS,UAAA,GAAa;AAClB,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,EAAE,IAAA,EAAM,YAAA,EAAc,QAAA,KAAa,sBAAA,EAAuB;AAChE,EAAA,MAAM,cAAA,GAAiB,KAAK,aAAA,CAAc;AAAA,IACtC,EAAA,EACI,IAAA,KAAS,QAAA,GACH,mCAAA,GACA;AAAA,GACb,CAAA;AACD,EAAA,OAAO,UAAU,IAAA,GAAO,CAAA,EAAG,cAAc,CAAA,EAAA,EAAK,QAAA,EAAU,IAAI,CAAA,CAAA,CAAA,GAAM,cAAA;AACtE;;;;"}
1
+ {"version":3,"file":"PropertyForm.js","sources":["PropertyForm.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Flex, VStack, Text } from \"@chakra-ui/react\";\nimport { SectionHeading, TitledSection } from \"@open-pioneer/react-utils\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { ReactNode, type ReactElement } from \"react\";\nimport { usePropertyFormContext } from \"../../context/usePropertyFormContext\";\n\nexport interface PropertyFormProps {\n children?: ReactNode;\n}\n\nexport function PropertyForm(props: PropertyFormProps): ReactElement {\n const { children } = props;\n const heading = useHeading();\n const context = usePropertyFormContext();\n const hasRequiredFields = useReactiveSnapshot(() => context.hasRequiredFields, [context]);\n const { formatRichMessage } = useIntl();\n\n return (\n <TitledSection>\n <Flex\n className=\"editor__property-form\"\n direction={\"column\"}\n flex={1}\n overflowY=\"hidden\"\n >\n <SectionHeading mb={2} size=\"sm\">\n {heading}\n </SectionHeading>\n <VStack\n gap={4}\n align=\"stretch\"\n // for focus ring\n px=\"1px\"\n pb=\"4px\"\n flex={1}\n overflowY={\"auto\"}\n >\n {children}\n </VStack>\n {hasRequiredFields && (\n <Text\n fontSize={\"sm\"}\n aria-hidden=\"true\"\n textAlign={\"right\"}\n paddingRight={2}\n mb={2}\n >\n <Text as=\"span\" color=\"fg.error\">\n *\n </Text>{\" \"}\n {formatRichMessage({ id: \"propertyEditor.requiredFieldHint\" })}\n </Text>\n )}\n </Flex>\n </TitledSection>\n );\n}\n\nfunction useHeading() {\n const intl = useIntl();\n const { mode, formTemplate: template } = usePropertyFormContext();\n const defaultHeading = intl.formatMessage({\n id:\n mode === \"update\"\n ? \"propertyEditor.defaultEditHeading\"\n : \"propertyEditor.defaultCreateHeading\"\n });\n return template?.name ? `${defaultHeading}: ${template?.name} ` : defaultHeading;\n}\n"],"names":[],"mappings":";;;;;;;AAcO,SAAS,aAAa,KAAA,EAAwC;AACjE,EAAA,MAAM,EAAE,UAAS,GAAI,KAAA;AACrB,EAAA,MAAM,UAAU,UAAA,EAAW;AAC3B,EAAA,MAAM,UAAU,sBAAA,EAAuB;AACvC,EAAA,MAAM,oBAAoB,mBAAA,CAAoB,MAAM,QAAQ,iBAAA,EAAmB,CAAC,OAAO,CAAC,CAAA;AACxF,EAAA,MAAM,EAAE,iBAAA,EAAkB,GAAI,OAAA,EAAQ;AAEtC,EAAA,2BACK,aAAA,EAAA,EACG,QAAA,kBAAA,IAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,uBAAA;AAAA,MACV,SAAA,EAAW,QAAA;AAAA,MACX,IAAA,EAAM,CAAA;AAAA,MACN,SAAA,EAAU,QAAA;AAAA,MAEV,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,EAAA,EAAI,CAAA,EAAG,IAAA,EAAK,MACvB,QAAA,EAAA,OAAA,EACL,CAAA;AAAA,wBACA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACG,GAAA,EAAK,CAAA;AAAA,YACL,KAAA,EAAM,SAAA;AAAA,YAEN,EAAA,EAAG,KAAA;AAAA,YACH,EAAA,EAAG,KAAA;AAAA,YACH,IAAA,EAAM,CAAA;AAAA,YACN,SAAA,EAAW,MAAA;AAAA,YAEV;AAAA;AAAA,SACL;AAAA,QACC,iBAAA,oBACG,IAAA;AAAA,UAAC,IAAA;AAAA,UAAA;AAAA,YACG,QAAA,EAAU,IAAA;AAAA,YACV,aAAA,EAAY,MAAA;AAAA,YACZ,SAAA,EAAW,OAAA;AAAA,YACX,YAAA,EAAc,CAAA;AAAA,YACd,EAAA,EAAI,CAAA;AAAA,YAEJ,QAAA,EAAA;AAAA,8BAAA,GAAA,CAAC,IAAA,EAAA,EAAK,EAAA,EAAG,MAAA,EAAO,KAAA,EAAM,YAAW,QAAA,EAAA,GAAA,EAEjC,CAAA;AAAA,cAAQ,GAAA;AAAA,cACP,iBAAA,CAAkB,EAAE,EAAA,EAAI,kCAAA,EAAoC;AAAA;AAAA;AAAA;AACjE;AAAA;AAAA,GAER,EACJ,CAAA;AAER;AAEA,SAAS,UAAA,GAAa;AAClB,EAAA,MAAM,OAAO,OAAA,EAAQ;AACrB,EAAA,MAAM,EAAE,IAAA,EAAM,YAAA,EAAc,QAAA,KAAa,sBAAA,EAAuB;AAChE,EAAA,MAAM,cAAA,GAAiB,KAAK,aAAA,CAAc;AAAA,IACtC,EAAA,EACI,IAAA,KAAS,QAAA,GACH,mCAAA,GACA;AAAA,GACb,CAAA;AACD,EAAA,OAAO,UAAU,IAAA,GAAO,CAAA,EAAG,cAAc,CAAA,EAAA,EAAK,QAAA,EAAU,IAAI,CAAA,CAAA,CAAA,GAAM,cAAA;AACtE;;"}
@@ -1,4 +1,5 @@
1
1
  import { type ReactiveMap } from "@conterra/reactivity-core";
2
+ import { Resource } from "@open-pioneer/core";
2
3
  import type { Layer } from "@open-pioneer/map";
3
4
  import type { Feature } from "ol";
4
5
  import type { CustomFormContext, Mode } from "../../api/editor/context";
@@ -6,14 +7,16 @@ import { FieldConfig } from "../../api/fields/FieldConfig";
6
7
  import type { ModificationStep } from "../../api/model/EditingStep";
7
8
  import type { DeclarativeFormTemplate, FeatureTemplate, FormTemplate } from "../../api/model/FeatureTemplate";
8
9
  import { EditingCallbacks } from "../editor/useEditingCallbacks";
9
- export declare abstract class BaseFormContext {
10
+ export declare abstract class BaseFormContext implements Resource {
10
11
  #private;
11
12
  readonly callbacks: EditingCallbacks;
12
13
  constructor(modificationStep: ModificationStep, callbacks: EditingCallbacks, formTemplate: FormTemplate);
14
+ destroy(): void;
13
15
  getPropertiesAsObject(): Record<string, unknown>;
14
16
  get feature(): Feature;
15
17
  get mode(): Mode;
16
18
  get editingStep(): ModificationStep;
19
+ get didEdit(): boolean;
17
20
  get properties(): ReactiveMap<string, unknown>;
18
21
  get formTemplate(): FormTemplate;
19
22
  get template(): FeatureTemplate | undefined;
@@ -1,11 +1,17 @@
1
- import { reactive, reactiveMap, computed } from '@conterra/reactivity-core';
1
+ import { reactive, reactiveMap, computed, watchValue } from '@conterra/reactivity-core';
2
+ import { createLogger, shallowEqual, destroyResources } from '@open-pioneer/core';
3
+ import { unByKey } from 'ol/Observable.js';
4
+ import { sourceId$1 as sourceId } from '../../_virtual/source-info.js';
2
5
  import { createContext } from 'react';
3
6
 
7
+ const LOG = createLogger(sourceId);
4
8
  class BaseFormContext {
5
9
  #propertiesMap;
6
10
  #modificationStep;
7
11
  #formTemplate;
8
12
  #propsAsObject;
13
+ #didEdit = reactive(false);
14
+ #watchEditResources = [];
9
15
  callbacks;
10
16
  constructor(modificationStep, callbacks, formTemplate) {
11
17
  this.#modificationStep = modificationStep;
@@ -13,11 +19,22 @@ class BaseFormContext {
13
19
  this.#formTemplate = formTemplate;
14
20
  const entries = BaseFormContext.#getPropertyEntries(modificationStep.feature);
15
21
  this.#propertiesMap = reactiveMap(entries);
16
- this.#propsAsObject = computed(() => {
17
- const entries2 = this.properties.entries();
18
- const object = Object.fromEntries(entries2);
19
- return object;
20
- });
22
+ this.#propsAsObject = computed(
23
+ () => {
24
+ const entries2 = this.properties.entries();
25
+ const object = Object.fromEntries(entries2);
26
+ return object;
27
+ },
28
+ { equal: shallowEqual }
29
+ );
30
+ if (modificationStep.id === "creation") {
31
+ this.#didEdit.value = true;
32
+ } else if (modificationStep.id === "update") {
33
+ this.#watchForAnyEdit();
34
+ }
35
+ }
36
+ destroy() {
37
+ destroyResources(this.#watchEditResources);
21
38
  }
22
39
  getPropertiesAsObject() {
23
40
  return this.#propsAsObject.value;
@@ -31,6 +48,9 @@ class BaseFormContext {
31
48
  get editingStep() {
32
49
  return this.#modificationStep;
33
50
  }
51
+ get didEdit() {
52
+ return this.#didEdit.value;
53
+ }
34
54
  get properties() {
35
55
  return this.#propertiesMap;
36
56
  }
@@ -48,6 +68,36 @@ class BaseFormContext {
48
68
  const geometryName = feature.getGeometryName();
49
69
  return Object.entries(properties).filter(([key, _]) => key !== geometryName);
50
70
  }
71
+ #watchForAnyEdit() {
72
+ const feature = this.#modificationStep.feature;
73
+ const geometry = feature.getGeometry();
74
+ const geometryChanged = () => {
75
+ LOG.debug("Geometry changed. The feature has been edited.");
76
+ this.#didEdit.value = true;
77
+ destroyResources(this.#watchEditResources);
78
+ };
79
+ const geometryKey1 = feature.on("change:geometry", geometryChanged);
80
+ const geometryKey2 = geometry?.on("change", geometryChanged);
81
+ this.#watchEditResources.push(
82
+ {
83
+ destroy() {
84
+ unByKey(geometryKey1);
85
+ geometryKey2 && unByKey(geometryKey2);
86
+ }
87
+ },
88
+ watchValue(
89
+ () => this.getPropertiesAsObject(),
90
+ (_props) => {
91
+ LOG.debug("Properties changed. The feature has been edited.");
92
+ this.#didEdit.value = true;
93
+ destroyResources(this.#watchEditResources);
94
+ },
95
+ {
96
+ dispatch: "sync"
97
+ }
98
+ )
99
+ );
100
+ }
51
101
  }
52
102
  class DeclarativeFormContext extends BaseFormContext {
53
103
  #isValid;