@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.
- package/CHANGELOG.md +9 -1
- package/README.md +54 -12
- package/_virtual/hooks.js.map +1 -1
- package/_virtual/source-info.js +7 -1
- package/_virtual/source-info.js.map +1 -1
- package/api/editor/context.js.map +1 -1
- package/api/editor/editor.d.ts +13 -0
- package/api/editor/editor.js.map +1 -1
- package/api/model/SelectionAvailability.d.ts +39 -0
- package/i18n/de.yaml +8 -0
- package/i18n/en.yaml +8 -0
- package/implementation/FeatureEditor.js +5 -0
- package/implementation/FeatureEditor.js.map +1 -1
- package/implementation/components/action-selector/ActionSelector.d.ts +12 -5
- package/implementation/components/action-selector/ActionSelector.js +27 -2
- package/implementation/components/action-selector/ActionSelector.js.map +1 -1
- package/implementation/components/action-selector/DrawingControls.js.map +1 -1
- package/implementation/components/action-selector/SelectButton.d.ts +6 -4
- package/implementation/components/action-selector/SelectButton.js +20 -5
- package/implementation/components/action-selector/SelectButton.js.map +1 -1
- package/implementation/components/action-selector/TemplateItem.js.map +1 -1
- package/implementation/components/action-selector/TemplateSelector.js.map +1 -1
- package/implementation/components/controls/ColorPickerControl.js.map +1 -1
- package/implementation/components/controls/ComboBoxControl.js.map +1 -1
- package/implementation/components/controls/DefaultControl.js.map +1 -1
- package/implementation/components/controls/NumberFieldControl.js.map +1 -1
- package/implementation/components/controls/RadioGroupControl.js.map +1 -1
- package/implementation/components/controls/SelectControl.js.map +1 -1
- package/implementation/components/controls/option-hooks.js.map +1 -1
- package/implementation/components/property-editor/ButtonRow.js.map +1 -1
- package/implementation/components/property-editor/CancelConfirmationDialog.js.map +1 -1
- package/implementation/components/property-editor/DeleteConfirmationDialog.js.map +1 -1
- package/implementation/components/property-editor/PropertyEditor.js +25 -5
- package/implementation/components/property-editor/PropertyEditor.js.map +1 -1
- package/implementation/components/property-editor/PropertyField.js.map +1 -1
- package/implementation/components/property-editor/PropertyForm.js.map +1 -1
- package/implementation/context/PropertyFormContext.d.ts +4 -1
- package/implementation/context/PropertyFormContext.js +56 -6
- package/implementation/context/PropertyFormContext.js.map +1 -1
- package/implementation/context/usePropertyFormContext.js.map +1 -1
- package/implementation/editor/editorHooks.d.ts +6 -0
- package/implementation/editor/editorHooks.js +34 -5
- package/implementation/editor/editorHooks.js.map +1 -1
- package/implementation/editor/useEditingCallbacks.js +1 -1
- package/implementation/editor/useEditingCallbacks.js.map +1 -1
- package/implementation/geometry-editing/controller/DrawingSession.js.map +1 -1
- package/implementation/geometry-editing/controller/EditingController.js.map +1 -1
- package/implementation/geometry-editing/controller/UndoManager.js.map +1 -1
- package/implementation/geometry-editing/controller/geometryState.js.map +1 -1
- package/implementation/geometry-editing/interactions/BaseInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DoubleClickInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/DrawingInteraction.js +2 -13
- package/implementation/geometry-editing/interactions/DrawingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/HighlightingInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/KeyboardInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/ModificationInteraction.js +2 -10
- package/implementation/geometry-editing/interactions/ModificationInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/SelectionInteraction.js +6 -13
- package/implementation/geometry-editing/interactions/SelectionInteraction.js.map +1 -1
- package/implementation/geometry-editing/interactions/SnappingInteraction.js.map +1 -1
- package/implementation/geometry-editing/overlays.d.ts +9 -0
- package/implementation/geometry-editing/overlays.js +21 -0
- package/implementation/geometry-editing/overlays.js.map +1 -0
- package/implementation/geometry-editing/useGeometryEditing.js.map +1 -1
- package/index.d.ts +1 -0
- package/package.json +12 -13
- package/implementation/featureEditing.css +0 -15
- package/implementation/featureEditing.css.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
# @open-pioneer/feature-editing
|
|
2
2
|
|
|
3
|
-
## 1.5.0
|
|
3
|
+
## 1.5.0
|
|
4
4
|
|
|
5
5
|
### Minor Changes
|
|
6
6
|
|
|
7
|
+
- 40748ad: Disable the feature selection button when there are no visible layers for selection. The enabling / disabling behavior can be customized by using the new `resolveSelectionAvailability` prop.
|
|
7
8
|
- f790fda: Update to Chakra 3.37.0
|
|
9
|
+
- a9c1213: Rework the tooltips rendered on the map: help tooltips now look like chakra's tooltips, and the measurement tooltips (active and finished measurements) are also derived from chakra's tooltip styles.
|
|
10
|
+
|
|
11
|
+
The built-in styles of these tooltips are no longer shipped as plain css, chakra style props are used instead.
|
|
12
|
+
The existing css classes (`editing-tooltip`, `measurement-tooltip`, `measurement-active-tooltip`, `measurement-finished-tooltip`, `selection-tooltip`) remain on the overlay's element.
|
|
13
|
+
|
|
14
|
+
- a186f5d: Update core packages to 4.8.0.
|
|
15
|
+
- 1d303e3: When editing an existing feature: do not show the "confirm cancel" dialog when the feature wasn't actually modifified.
|
|
8
16
|
|
|
9
17
|
### Patch Changes
|
|
10
18
|
|
package/README.md
CHANGED
|
@@ -328,18 +328,19 @@ const featureWriter: FeatureWriter = {
|
|
|
328
328
|
|
|
329
329
|
The `FeatureEditor` component accepts the following props:
|
|
330
330
|
|
|
331
|
-
| Prop | Type | Required | Description
|
|
332
|
-
| -------------------------------- | ---------------------------------------- | -------- |
|
|
333
|
-
| `map` | `MapModel` | No | Map model to use (defaults to context map)
|
|
334
|
-
| `templates` | `FeatureTemplate[]` | Yes | Feature templates defining the types of features that can be created or edited
|
|
335
|
-
| `writer` | `FeatureWriter` | Yes | Storage implementation for feature create, update, and delete operations
|
|
336
|
-
| `selectableLayers` | `Layer[]` | No | Layers from which features can be selected. Defaults to layers matching template layer IDs
|
|
337
|
-
| `snappableLayers` | `Layer[]` | No | Layers for snapping during drawing/modification. Defaults to `selectableLayers`
|
|
338
|
-
| `
|
|
339
|
-
| `
|
|
340
|
-
| `
|
|
341
|
-
| `
|
|
342
|
-
| `
|
|
331
|
+
| Prop | Type | Required | Description |
|
|
332
|
+
| -------------------------------- | ---------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
333
|
+
| `map` | `MapModel` | No | Map model to use (defaults to context map) |
|
|
334
|
+
| `templates` | `FeatureTemplate[]` | Yes | Feature templates defining the types of features that can be created or edited |
|
|
335
|
+
| `writer` | `FeatureWriter` | Yes | Storage implementation for feature create, update, and delete operations |
|
|
336
|
+
| `selectableLayers` | `Layer[]` | No | Layers from which features can be selected. Defaults to layers matching template layer IDs |
|
|
337
|
+
| `snappableLayers` | `Layer[]` | No | Layers for snapping during drawing/modification. Defaults to `selectableLayers` |
|
|
338
|
+
| `resolveSelectionAvailability` | `(context) => SelectionAvailability` | No | Custom function to enable or disable the selection interaction. By default: disabled when there are no visible selectable layers. |
|
|
339
|
+
| `resolveFormTemplate` | `(context) => FormTemplate \| undefined` | No | Custom function to determine which form template to use when editing an existing feature (see below) |
|
|
340
|
+
| `showActionBar` | `boolean` | No | Whether to show undo/redo/finish/reset controls during drawing (default: `true`) |
|
|
341
|
+
| `successNotifierDisplayDuration` | `number \| false` | No | Duration in ms to display success notifications. By default, never disappears. Use `false` to completely hide the notification. |
|
|
342
|
+
| `failureNotifierDisplayDuration` | `number \| false` | No | Duration in ms to display failure notifications. By default, never disappears. Use `false` to completely hide the notification. |
|
|
343
|
+
| `onEditingStepChange` | `(newEditingStep) => void` | No | Callback invoked when the editing workflow step changes |
|
|
343
344
|
|
|
344
345
|
### Interaction Options
|
|
345
346
|
|
|
@@ -355,6 +356,47 @@ The FeatureEditor also accepts OpenLayers interaction options for fine-grained c
|
|
|
355
356
|
|
|
356
357
|
The drawing options will be merged with those of the selected feature template (if any are given), with the ones of the template taking precedence.
|
|
357
358
|
|
|
359
|
+
### Customizing the Availability of the Selection Interaction
|
|
360
|
+
|
|
361
|
+
Editing an existing feature requires the user to select it on the map first.
|
|
362
|
+
By default, the selection is only available if at least one of the selectable layers is visible; otherwise the selection button is disabled and a hint is shown to the user.
|
|
363
|
+
|
|
364
|
+
Use the `resolveSelectionAvailability` prop to implement a different rule, for example if selection should also require a certain zoom level:
|
|
365
|
+
|
|
366
|
+
```tsx
|
|
367
|
+
import type {
|
|
368
|
+
SelectionAvailability,
|
|
369
|
+
SelectionAvailabilityContext
|
|
370
|
+
} from "@open-pioneer/feature-editing";
|
|
371
|
+
|
|
372
|
+
// Use a function that does not change its value on every render.
|
|
373
|
+
const customResolveSelectionAvailability = useCallback(
|
|
374
|
+
({ mapModel, layers }: SelectionAvailabilityContext): SelectionAvailability => {
|
|
375
|
+
if (!layers.some((layer) => layer.visible)) {
|
|
376
|
+
return { status: "unavailable", reason: "Please activate an editable layer." };
|
|
377
|
+
}
|
|
378
|
+
if ((mapModel.zoomLevel ?? 0) < 12) {
|
|
379
|
+
return { status: "unavailable", reason: "Please zoom in to select a feature." };
|
|
380
|
+
}
|
|
381
|
+
return { status: "available" };
|
|
382
|
+
},
|
|
383
|
+
[]
|
|
384
|
+
);
|
|
385
|
+
|
|
386
|
+
<FeatureEditor
|
|
387
|
+
templates={templates}
|
|
388
|
+
writer={featureWriter}
|
|
389
|
+
resolveSelectionAvailability={customResolveSelectionAvailability}
|
|
390
|
+
/>;
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
The `context` contains the `mapModel` and the `layers` that would be used for the selection interaction (i.e. `selectableLayers`, or the layers derived from the templates).
|
|
394
|
+
The function is evaluated reactively: if it accesses reactive values (such as `layer.visible` or the map's zoom level),
|
|
395
|
+
the availability is recomputed automatically when those values change.
|
|
396
|
+
When `status` is `"unavailable"`, the optional `reason` is presented to the user.
|
|
397
|
+
|
|
398
|
+
Use `useCallback` or any alternative measure to ensure that the function does not change too frequently.
|
|
399
|
+
|
|
358
400
|
### Resolving Form Templates
|
|
359
401
|
|
|
360
402
|
When the user selects an existing feature on the map, the FeatureEditor needs to determine which form template to use.
|
package/_virtual/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hooks.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
package/_virtual/source-info.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
const sourceId$3 = "@open-pioneer/feature-editing/implementation/editor/editorHooks";
|
|
2
|
+
|
|
3
|
+
const sourceId$2 = "@open-pioneer/feature-editing/implementation/components/property-editor/PropertyEditor";
|
|
4
|
+
|
|
5
|
+
const sourceId$1 = "@open-pioneer/feature-editing/implementation/context/PropertyFormContext";
|
|
6
|
+
|
|
1
7
|
const sourceId = "@open-pioneer/feature-editing/implementation/editor/useEditingCallbacks";
|
|
2
8
|
|
|
3
|
-
export { sourceId };
|
|
9
|
+
export { sourceId$3 as sourceId, sourceId$1, sourceId$2, sourceId as sourceId$3 };
|
|
4
10
|
//# sourceMappingURL=source-info.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-info.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sources":["context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveMap } from \"@conterra/reactivity-core\";\nimport type { Layer } from \"@open-pioneer/map\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport type { Feature } from \"ol\";\nimport { useCustomFormContext as useCustomFormContextImpl } from \"../../implementation/context/usePropertyFormContext\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { CreationStep, ModificationStep, UpdateStep } from \"../model/EditingStep\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { DynamicFormTemplate, FeatureTemplate } from \"../model/FeatureTemplate\";\n\n/**\n * React hook for accessing the property form context within a custom form.\n *\n * Provides access to the {@link CustomFormContext} instance, which contains the current feature\n * being edited and methods to read and update its properties. This hook must be called from within\n * a component that is rendered inside a custom property form (see {@link DynamicFormTemplate}).\n *\n * The context also allows controlling the form's validity by setting the `isValid` property,\n * which determines whether the save button is enabled.\n *\n * @returns The current {@link CustomFormContext} instance.\n * @throws Error if called outside of a custom property form context (e.g., when no feature is being\n * edited).\n *\n * @example\n * ```tsx\n * import { useReactiveSnapshot, DISPATCH_SYNC } from \"@open-pioneer/reactivity\";\n *\n * function CustomForm() {\n * const context = useCustomFormContext();\n * const name = useReactiveSnapshot(\n * () => (context.properties.get(\"name\") as string) ?? \"\",\n * [context],\n * DISPATCH_SYNC\n * );\n *\n * useEffect(() => {\n * context.isValid = name.length >= 1;\n * }, [context, name]);\n *\n * return <Input value={name} onChange={(e) => context.properties.set(\"name\", e.target.value)} />;\n * }\n * ```\n *\n * @group Editor\n */\nexport const useCustomFormContext: () => CustomFormContext = useCustomFormContextImpl;\n\n/**\n * Context object providing access to feature properties and editing state during form editing.\n *\n * The context manages the state of a feature being edited, including its properties, validation\n * status, and associated metadata. It provides reactive property management through a\n * {@link ReactiveMap}, allowing components to automatically re-render when properties change.\n *\n * Access this context in custom forms using the {@link useCustomFormContext} hook.\n *\n * @group Editor\n */\nexport interface CustomFormContext {\n /**\n * The OpenLayers feature being edited.\n *\n * Provides direct access to the feature object, which includes its geometry and properties.\n */\n readonly feature: Feature;\n\n /**\n * Reactive map of feature properties.\n *\n * Provides reactive access to all feature properties (excluding geometry). Use `get()` to read\n * property values and `set()` to update them. Components can use {@link useReactiveSnapshot}\n * to automatically re-render when values change.\n *\n * @example\n * ```ts\n * const name = context.properties.get(\"name\");\n * context.properties.set(\"name\", \"New Name\");\n * ```\n */\n readonly properties: ReactiveMap<string, unknown>;\n\n /**\n * Returns all feature properties as a plain JavaScript object.\n *\n * Converts the reactive properties map to a standard object with string keys and unknown\n * values. Useful when you need to pass properties to functions that expect plain objects.\n *\n * Note that a new object is created on every change.\n * Prefer to use fine grained accesses to {@link properties} if performance matters.\n *\n * @returns A plain object containing all feature properties (excluding geometry).\n */\n readonly getPropertiesAsObject: () => Record<string, unknown>;\n\n /**\n * The current editing step containing the feature and associated metadata.\n *\n * Provides access to the complete editing step, which can be either a {@link CreationStep}\n * or {@link UpdateStep}.\n */\n readonly editingStep: ModificationStep;\n\n /**\n * The current editing mode.\n *\n * Returns `\"create\"` when creating a new feature, or `\"update\"` when editing an existing\n * feature. Use this to conditionally render different UI or apply different logic based on the\n * editing mode.\n */\n readonly mode: Mode;\n\n /**\n * The feature template used to create the feature, if in creation mode.\n *\n * Returns the {@link FeatureTemplate} when creating a new feature (`mode === \"create\"`), or\n * `undefined` when editing an existing feature (`mode === \"update\"`).\n */\n readonly template: FeatureTemplate | undefined;\n\n /**\n * The layer containing the feature being edited, if in update mode.\n *\n * Returns the {@link Layer} when editing an existing feature (`mode === \"update\"`), or\n * `undefined` when creating a new feature (`mode === \"create\"`) or if the layer is not\n * available.\n */\n readonly layer: Layer | undefined;\n\n /**\n * Whether the form is currently valid.\n *\n * Controls the enabled state of the save button in the property editor. Set this to `true`\n * when the form passes validation, or `false` when there are validation errors. For\n * declarative forms, this is managed automatically based on field validation rules.\n */\n isValid: boolean;\n}\n\n/**\n * The editing mode for a feature.\n *\n * - `\"create\"`: Creating a new feature\n * - `\"update\"`: Editing an existing feature\n *\n * @group Editor\n */\nexport type Mode = \"create\" | \"update\";\n"],"names":["useCustomFormContextImpl"],"mappings":";;AAkDO,MAAM,oBAAA,GAAgDA
|
|
1
|
+
{"version":3,"file":"context.js","sources":["context.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { ReactiveMap } from \"@conterra/reactivity-core\";\nimport type { Layer } from \"@open-pioneer/map\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport type { Feature } from \"ol\";\nimport { useCustomFormContext as useCustomFormContextImpl } from \"../../implementation/context/usePropertyFormContext\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { CreationStep, ModificationStep, UpdateStep } from \"../model/EditingStep\";\n// oxlint-disable-next-line @typescript-eslint/no-unused-vars\nimport type { DynamicFormTemplate, FeatureTemplate } from \"../model/FeatureTemplate\";\n\n/**\n * React hook for accessing the property form context within a custom form.\n *\n * Provides access to the {@link CustomFormContext} instance, which contains the current feature\n * being edited and methods to read and update its properties. This hook must be called from within\n * a component that is rendered inside a custom property form (see {@link DynamicFormTemplate}).\n *\n * The context also allows controlling the form's validity by setting the `isValid` property,\n * which determines whether the save button is enabled.\n *\n * @returns The current {@link CustomFormContext} instance.\n * @throws Error if called outside of a custom property form context (e.g., when no feature is being\n * edited).\n *\n * @example\n * ```tsx\n * import { useReactiveSnapshot, DISPATCH_SYNC } from \"@open-pioneer/reactivity\";\n *\n * function CustomForm() {\n * const context = useCustomFormContext();\n * const name = useReactiveSnapshot(\n * () => (context.properties.get(\"name\") as string) ?? \"\",\n * [context],\n * DISPATCH_SYNC\n * );\n *\n * useEffect(() => {\n * context.isValid = name.length >= 1;\n * }, [context, name]);\n *\n * return <Input value={name} onChange={(e) => context.properties.set(\"name\", e.target.value)} />;\n * }\n * ```\n *\n * @group Editor\n */\nexport const useCustomFormContext: () => CustomFormContext = useCustomFormContextImpl;\n\n/**\n * Context object providing access to feature properties and editing state during form editing.\n *\n * The context manages the state of a feature being edited, including its properties, validation\n * status, and associated metadata. It provides reactive property management through a\n * {@link ReactiveMap}, allowing components to automatically re-render when properties change.\n *\n * Access this context in custom forms using the {@link useCustomFormContext} hook.\n *\n * @group Editor\n */\nexport interface CustomFormContext {\n /**\n * The OpenLayers feature being edited.\n *\n * Provides direct access to the feature object, which includes its geometry and properties.\n */\n readonly feature: Feature;\n\n /**\n * Reactive map of feature properties.\n *\n * Provides reactive access to all feature properties (excluding geometry). Use `get()` to read\n * property values and `set()` to update them. Components can use {@link useReactiveSnapshot}\n * to automatically re-render when values change.\n *\n * @example\n * ```ts\n * const name = context.properties.get(\"name\");\n * context.properties.set(\"name\", \"New Name\");\n * ```\n */\n readonly properties: ReactiveMap<string, unknown>;\n\n /**\n * Returns all feature properties as a plain JavaScript object.\n *\n * Converts the reactive properties map to a standard object with string keys and unknown\n * values. Useful when you need to pass properties to functions that expect plain objects.\n *\n * Note that a new object is created on every change.\n * Prefer to use fine grained accesses to {@link properties} if performance matters.\n *\n * @returns A plain object containing all feature properties (excluding geometry).\n */\n readonly getPropertiesAsObject: () => Record<string, unknown>;\n\n /**\n * The current editing step containing the feature and associated metadata.\n *\n * Provides access to the complete editing step, which can be either a {@link CreationStep}\n * or {@link UpdateStep}.\n */\n readonly editingStep: ModificationStep;\n\n /**\n * The current editing mode.\n *\n * Returns `\"create\"` when creating a new feature, or `\"update\"` when editing an existing\n * feature. Use this to conditionally render different UI or apply different logic based on the\n * editing mode.\n */\n readonly mode: Mode;\n\n /**\n * The feature template used to create the feature, if in creation mode.\n *\n * Returns the {@link FeatureTemplate} when creating a new feature (`mode === \"create\"`), or\n * `undefined` when editing an existing feature (`mode === \"update\"`).\n */\n readonly template: FeatureTemplate | undefined;\n\n /**\n * The layer containing the feature being edited, if in update mode.\n *\n * Returns the {@link Layer} when editing an existing feature (`mode === \"update\"`), or\n * `undefined` when creating a new feature (`mode === \"create\"`) or if the layer is not\n * available.\n */\n readonly layer: Layer | undefined;\n\n /**\n * Whether the form is currently valid.\n *\n * Controls the enabled state of the save button in the property editor. Set this to `true`\n * when the form passes validation, or `false` when there are validation errors. For\n * declarative forms, this is managed automatically based on field validation rules.\n */\n isValid: boolean;\n}\n\n/**\n * The editing mode for a feature.\n *\n * - `\"create\"`: Creating a new feature\n * - `\"update\"`: Editing an existing feature\n *\n * @group Editor\n */\nexport type Mode = \"create\" | \"update\";\n"],"names":["useCustomFormContextImpl"],"mappings":";;AAkDO,MAAM,oBAAA,GAAgDA;;"}
|
package/api/editor/editor.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { EditingStep } from "../model/EditingStep";
|
|
|
6
6
|
import type { FeatureTemplate, FormTemplate } from "../model/FeatureTemplate";
|
|
7
7
|
import type { FeatureWriter } from "../model/FeatureWriter";
|
|
8
8
|
import type { InteractionOptions } from "../model/InteractionOptions";
|
|
9
|
+
import { SelectionAvailability, SelectionAvailabilityContext } from "../model/SelectionAvailability";
|
|
9
10
|
/**
|
|
10
11
|
* React component that provides a complete editing interface for creating and modifying map
|
|
11
12
|
* features.
|
|
@@ -79,6 +80,18 @@ export interface FeatureEditorProps extends CommonComponentProps, MapModelProps,
|
|
|
79
80
|
* @default selectableLayers
|
|
80
81
|
*/
|
|
81
82
|
readonly snappableLayers?: Layer[];
|
|
83
|
+
/**
|
|
84
|
+
* A _reactive_ function that returns the selection interaction's availability state.
|
|
85
|
+
*
|
|
86
|
+
* The selection interaction is used by the editor to pick a feature from the map for editing.
|
|
87
|
+
*
|
|
88
|
+
* This function **SHOULD** be rather stable: you should use `useCallback` or equivalent mechanisms to avoid
|
|
89
|
+
* passing in a new function every time.
|
|
90
|
+
*
|
|
91
|
+
* Default: the selection interaction is available if there are any editable layers (as configured by {@link selectableLayers} or its default value)
|
|
92
|
+
* that are _visible_.
|
|
93
|
+
*/
|
|
94
|
+
readonly resolveSelectionAvailability?: (context: SelectionAvailabilityContext) => SelectionAvailability;
|
|
82
95
|
/**
|
|
83
96
|
* Whether to show the action bar with undo/redo/finish/reset controls during drawing.
|
|
84
97
|
*
|
package/api/editor/editor.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.js","sources":["editor.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Layer, MapModelProps } from \"@open-pioneer/map\";\nimport { CommonComponentProps } from \"@open-pioneer/react-utils\";\nimport Feature from \"ol/Feature\";\nimport { FC } from \"react\";\nimport { FeatureEditor as FeatureEditorImpl } from \"../../implementation/FeatureEditor\";\nimport type { EditingStep } from \"../model/EditingStep\";\nimport type { FeatureTemplate, FormTemplate } from \"../model/FeatureTemplate\";\nimport type { FeatureWriter } from \"../model/FeatureWriter\";\nimport type { InteractionOptions } from \"../model/InteractionOptions\";\n\n/**\n * React component that provides a complete editing interface for creating and modifying map\n * features.\n *\n * The Editor component manages the entire editing workflow, including feature creation, selection,\n * modification, and deletion. It renders different UI states based on the current editing step:\n * - An action selector for choosing feature templates and initiating drawing, or selecting\n * existing features.\n * - A property editor for modifying feature attributes and geometry.\n *\n * @example\n * ```tsx\n * <Editor\n * map={mapModel}\n * templates={featureTemplates}\n * storage={{\n * addFeature: async (feature) => { ... },\n * updateFeature: async (feature) => { ... },\n * deleteFeature: async (feature) => { ... }\n * }}\n * selectableLayers={[myLayer]}\n * />\n * ```\n *\n * @group Editor\n * @expandType EditorProps\n */\nexport const FeatureEditor: FC<FeatureEditorProps> = FeatureEditorImpl;\n\n/**\n * Props for the {@link FeatureEditor} component.\n *\n * @group Editor\n */\nexport interface FeatureEditorProps\n extends CommonComponentProps, MapModelProps, InteractionOptions {\n /**\n * Feature templates defining the types of features that can be created or edited.\n *\n * Each template specifies the geometry type, drawing options, and form configuration\n * for a specific feature type.\n */\n readonly templates: FeatureTemplate[];\n\n /**\n * Responsible for persisting changes to your data source.\n */\n readonly writer: FeatureWriter;\n\n /**\n * Optional function to provide custom form templates for features.\n *\n * When specified, this function is called to determine which form template to use\n * when editing an existing feature. If not provided, the first feature template\n * matching the feature's layer ID will be used.\n *\n * @returns The form template to use for editing the feature's properties, or `undefined` if no\n * template is available.\n */\n readonly resolveFormTemplate?: (context: FormTemplateContext) => FormTemplate | undefined;\n\n /**\n * Layers from which features can be selected for editing.\n *\n * When not specified, the layer IDs from the feature templates are used to determine\n * which layers are selectable. Only specify layers that contain features you want to\n * allow users to edit.\n */\n readonly selectableLayers?: Layer[];\n\n /**\n * Layers to which drawn geometries will snap.\n *\n * Enables snapping to features in these layers during drawing and modification operations.\n * Defaults to {@link selectableLayers} if not specified.\n *\n * @default selectableLayers\n */\n readonly snappableLayers?: Layer[];\n\n /**\n * Whether to show the action bar with undo/redo/finish/reset controls during drawing.\n *\n * When `false`, the action bar is hidden. Only applies to templates with geometry types\n * that support these actions (e.g., `Polygon`, `LineString`).\n *\n * @default true\n */\n readonly showActionBar?: boolean;\n\n /**\n * Duration in milliseconds to display success notifications.\n *\n * Controls how long success messages (e.g., \"Feature saved\") are shown to the user.\n * By default, notifiers will never disappear.\n *\n * Use `false` to hide the notification altogether.\n */\n readonly successNotifierDisplayDuration?: number | false;\n\n /**\n * Duration in milliseconds to display failure notifications.\n *\n * Controls how long error messages are shown to the user.\n * By default, notifiers will never disappear.\n *\n * Use `false` to hide the notification altogether.\n */\n readonly failureNotifierDisplayDuration?: number | false;\n\n /**\n * Optional callback invoked when the editing step changes.\n *\n * Called whenever the editing workflow transitions between steps (e.g., from drawing to\n * attribute editing, or from attribute editing back to the initial state).\n *\n * Use this to track or respond to changes in the editing workflow state.\n */\n readonly onEditingStepChange?: (newEditingStep: EditingStep) => void;\n}\n\n/** @group Editor */\nexport interface FormTemplateContext {\n /** The OpenLayers feature being edited. */\n feature: Feature;\n\n /** The layer containing the feature, or `undefined` if not available. */\n layer: Layer | undefined;\n}\n"],"names":["FeatureEditorImpl"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"editor.js","sources":["editor.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport type { Layer, MapModelProps } from \"@open-pioneer/map\";\nimport { CommonComponentProps } from \"@open-pioneer/react-utils\";\nimport Feature from \"ol/Feature\";\nimport { FC } from \"react\";\nimport { FeatureEditor as FeatureEditorImpl } from \"../../implementation/FeatureEditor\";\nimport type { EditingStep } from \"../model/EditingStep\";\nimport type { FeatureTemplate, FormTemplate } from \"../model/FeatureTemplate\";\nimport type { FeatureWriter } from \"../model/FeatureWriter\";\nimport type { InteractionOptions } from \"../model/InteractionOptions\";\nimport {\n SelectionAvailability,\n SelectionAvailabilityContext\n} from \"../model/SelectionAvailability\";\n\n/**\n * React component that provides a complete editing interface for creating and modifying map\n * features.\n *\n * The Editor component manages the entire editing workflow, including feature creation, selection,\n * modification, and deletion. It renders different UI states based on the current editing step:\n * - An action selector for choosing feature templates and initiating drawing, or selecting\n * existing features.\n * - A property editor for modifying feature attributes and geometry.\n *\n * @example\n * ```tsx\n * <Editor\n * map={mapModel}\n * templates={featureTemplates}\n * storage={{\n * addFeature: async (feature) => { ... },\n * updateFeature: async (feature) => { ... },\n * deleteFeature: async (feature) => { ... }\n * }}\n * selectableLayers={[myLayer]}\n * />\n * ```\n *\n * @group Editor\n * @expandType EditorProps\n */\nexport const FeatureEditor: FC<FeatureEditorProps> = FeatureEditorImpl;\n\n/**\n * Props for the {@link FeatureEditor} component.\n *\n * @group Editor\n */\nexport interface FeatureEditorProps\n extends CommonComponentProps, MapModelProps, InteractionOptions {\n /**\n * Feature templates defining the types of features that can be created or edited.\n *\n * Each template specifies the geometry type, drawing options, and form configuration\n * for a specific feature type.\n */\n readonly templates: FeatureTemplate[];\n\n /**\n * Responsible for persisting changes to your data source.\n */\n readonly writer: FeatureWriter;\n\n /**\n * Optional function to provide custom form templates for features.\n *\n * When specified, this function is called to determine which form template to use\n * when editing an existing feature. If not provided, the first feature template\n * matching the feature's layer ID will be used.\n *\n * @returns The form template to use for editing the feature's properties, or `undefined` if no\n * template is available.\n */\n readonly resolveFormTemplate?: (context: FormTemplateContext) => FormTemplate | undefined;\n\n /**\n * Layers from which features can be selected for editing.\n *\n * When not specified, the layer IDs from the feature templates are used to determine\n * which layers are selectable. Only specify layers that contain features you want to\n * allow users to edit.\n */\n readonly selectableLayers?: Layer[];\n\n /**\n * Layers to which drawn geometries will snap.\n *\n * Enables snapping to features in these layers during drawing and modification operations.\n * Defaults to {@link selectableLayers} if not specified.\n *\n * @default selectableLayers\n */\n readonly snappableLayers?: Layer[];\n\n /**\n * A _reactive_ function that returns the selection interaction's availability state.\n *\n * The selection interaction is used by the editor to pick a feature from the map for editing.\n *\n * This function **SHOULD** be rather stable: you should use `useCallback` or equivalent mechanisms to avoid\n * passing in a new function every time.\n *\n * Default: the selection interaction is available if there are any editable layers (as configured by {@link selectableLayers} or its default value)\n * that are _visible_.\n */\n readonly resolveSelectionAvailability?: (\n context: SelectionAvailabilityContext\n ) => SelectionAvailability;\n\n /**\n * Whether to show the action bar with undo/redo/finish/reset controls during drawing.\n *\n * When `false`, the action bar is hidden. Only applies to templates with geometry types\n * that support these actions (e.g., `Polygon`, `LineString`).\n *\n * @default true\n */\n readonly showActionBar?: boolean;\n\n /**\n * Duration in milliseconds to display success notifications.\n *\n * Controls how long success messages (e.g., \"Feature saved\") are shown to the user.\n * By default, notifiers will never disappear.\n *\n * Use `false` to hide the notification altogether.\n */\n readonly successNotifierDisplayDuration?: number | false;\n\n /**\n * Duration in milliseconds to display failure notifications.\n *\n * Controls how long error messages are shown to the user.\n * By default, notifiers will never disappear.\n *\n * Use `false` to hide the notification altogether.\n */\n readonly failureNotifierDisplayDuration?: number | false;\n\n /**\n * Optional callback invoked when the editing step changes.\n *\n * Called whenever the editing workflow transitions between steps (e.g., from drawing to\n * attribute editing, or from attribute editing back to the initial state).\n *\n * Use this to track or respond to changes in the editing workflow state.\n */\n readonly onEditingStepChange?: (newEditingStep: EditingStep) => void;\n}\n\n/** @group Editor */\nexport interface FormTemplateContext {\n /** The OpenLayers feature being edited. */\n feature: Feature;\n\n /** The layer containing the feature, or `undefined` if not available. */\n layer: Layer | undefined;\n}\n"],"names":["FeatureEditorImpl"],"mappings":";;AA4CO,MAAM,aAAA,GAAwCA;;"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Layer, MapModel } from "@open-pioneer/map";
|
|
2
|
+
/**
|
|
3
|
+
* The context made available to implementations of the {@link FeatureEditorProps.resolveSelectionAvailability | resolveSelectionAvailability} property.
|
|
4
|
+
*
|
|
5
|
+
* @group Model
|
|
6
|
+
*/
|
|
7
|
+
export interface SelectionAvailabilityContext {
|
|
8
|
+
/** The map used by the feature editor. */
|
|
9
|
+
mapModel: MapModel;
|
|
10
|
+
/** The layers the feature editor would use for the selection interaction. */
|
|
11
|
+
layers: Layer[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The availability status for the selection button (available / unavailable).
|
|
15
|
+
*
|
|
16
|
+
* @group Model
|
|
17
|
+
*/
|
|
18
|
+
export type SelectionAvailability = SelectionAvailable | SelectionUnavailable;
|
|
19
|
+
/**
|
|
20
|
+
* Selection is available.
|
|
21
|
+
*
|
|
22
|
+
* @group Model
|
|
23
|
+
*/
|
|
24
|
+
export interface SelectionAvailable {
|
|
25
|
+
status: "available";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Selection is unavailable.
|
|
29
|
+
*
|
|
30
|
+
* @group Model
|
|
31
|
+
*/
|
|
32
|
+
export interface SelectionUnavailable {
|
|
33
|
+
status: "unavailable";
|
|
34
|
+
/**
|
|
35
|
+
* The reason for being unavailable.
|
|
36
|
+
* This message will be presented to the user.
|
|
37
|
+
*/
|
|
38
|
+
reason?: string;
|
|
39
|
+
}
|
package/i18n/de.yaml
CHANGED
|
@@ -8,6 +8,11 @@ messages:
|
|
|
8
8
|
resetButtonTooltip: Zeichnung zurücksetzen
|
|
9
9
|
undoButtonTooltip: Rückgängig machen
|
|
10
10
|
redoButtonTooltip: Wiederholen
|
|
11
|
+
|
|
12
|
+
selection:
|
|
13
|
+
defaultNotAvailableMessage: "Es können keine Geoobjekte ausgewählt werden."
|
|
14
|
+
noVisibleLayers: "In der Karte sind derzeit keine editierbaren Layer sichtbar."
|
|
15
|
+
|
|
11
16
|
propertyEditor:
|
|
12
17
|
defaultEditHeading: Geoobjekt bearbeiten
|
|
13
18
|
defaultCreateHeading: Geoobjekt erstellen
|
|
@@ -26,11 +31,13 @@ messages:
|
|
|
26
31
|
message: Sind Sie sicher, dass Sie dieses Geoobjekt löschen möchten?
|
|
27
32
|
deleteButtonTitle: Geoobjekt löschen
|
|
28
33
|
cancelButtonTitle: Abbrechen
|
|
34
|
+
|
|
29
35
|
cancelConfirmationDialog:
|
|
30
36
|
title: Änderungen verwerfen
|
|
31
37
|
message: Sind Sie sicher, dass Sie Ihre Änderungen verwerfen möchten?
|
|
32
38
|
confirmCancelButtonTitle: Änderungen verwerfen
|
|
33
39
|
abortCancelButtonTitle: Weiter bearbeiten
|
|
40
|
+
|
|
34
41
|
notifier:
|
|
35
42
|
creationSuccess: Geoobjekt erstellt
|
|
36
43
|
creationFailure: Das Geoobjekt konnte nicht erstellt werden.
|
|
@@ -38,6 +45,7 @@ messages:
|
|
|
38
45
|
updateFailure: Das Geoobjekt konnte nicht aktualisiert werden.
|
|
39
46
|
deletionSuccess: Geoobjekt gelöscht
|
|
40
47
|
deletionFailure: Das Geoobjekt konnte nicht gelöscht werden.
|
|
48
|
+
|
|
41
49
|
tooltips:
|
|
42
50
|
drawingMessagePoint: Klicken Sie in die Karte, um den Punkt zu zeichnen.
|
|
43
51
|
drawingMessageLineString: Klicken, um mit dem Zeichnen zu beginnen. <br></br> Doppelklicken, um die Zeichnung zu beenden.
|
package/i18n/en.yaml
CHANGED
|
@@ -8,6 +8,11 @@ messages:
|
|
|
8
8
|
resetButtonTooltip: Reset drawing
|
|
9
9
|
undoButtonTooltip: Undo
|
|
10
10
|
redoButtonTooltip: Redo
|
|
11
|
+
|
|
12
|
+
selection:
|
|
13
|
+
defaultNotAvailableMessage: "No features can be selected."
|
|
14
|
+
noVisibleLayers: "No editable layers are visible in the map."
|
|
15
|
+
|
|
11
16
|
propertyEditor:
|
|
12
17
|
defaultEditHeading: Edit Feature
|
|
13
18
|
defaultCreateHeading: Create Feature
|
|
@@ -26,11 +31,13 @@ messages:
|
|
|
26
31
|
message: Are you sure you want to delete this feature?
|
|
27
32
|
deleteButtonTitle: Delete feature
|
|
28
33
|
cancelButtonTitle: Cancel
|
|
34
|
+
|
|
29
35
|
cancelConfirmationDialog:
|
|
30
36
|
title: Discard changes
|
|
31
37
|
message: Are you sure you want to discard your changes?
|
|
32
38
|
confirmCancelButtonTitle: Discard changes
|
|
33
39
|
abortCancelButtonTitle: Continue editing
|
|
40
|
+
|
|
34
41
|
notifier:
|
|
35
42
|
creationSuccess: Feature created
|
|
36
43
|
creationFailure: The feature failed to be created.
|
|
@@ -38,6 +45,7 @@ messages:
|
|
|
38
45
|
updateFailure: The feature failed to be updated.
|
|
39
46
|
deletionSuccess: Feature deleted
|
|
40
47
|
deletionFailure: The feature failed to be deleted.
|
|
48
|
+
|
|
41
49
|
tooltips:
|
|
42
50
|
drawingMessagePoint: Click on the map to draw the point.
|
|
43
51
|
drawingMessageLineString: Click to start drawing. Double-click to finish drawing.
|
|
@@ -18,6 +18,7 @@ function FeatureEditor(props) {
|
|
|
18
18
|
resolveFormTemplate,
|
|
19
19
|
selectableLayers,
|
|
20
20
|
snappableLayers = selectableLayers,
|
|
21
|
+
resolveSelectionAvailability,
|
|
21
22
|
showActionBar = true,
|
|
22
23
|
successNotifierDisplayDuration,
|
|
23
24
|
failureNotifierDisplayDuration,
|
|
@@ -78,7 +79,11 @@ function FeatureEditor(props) {
|
|
|
78
79
|
content = /* @__PURE__ */ jsx(
|
|
79
80
|
ActionSelector,
|
|
80
81
|
{
|
|
82
|
+
editingStep,
|
|
83
|
+
mapModel,
|
|
81
84
|
templates,
|
|
85
|
+
selectableLayers,
|
|
86
|
+
resolveSelectionAvailability,
|
|
82
87
|
showActionBar,
|
|
83
88
|
onActionChange,
|
|
84
89
|
drawingState
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FeatureEditor.js","sources":["FeatureEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box } from \"@chakra-ui/react\";\nimport { useMapModelValue } from \"@open-pioneer/map\";\nimport { useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { type ReactElement, type ReactNode, useMemo } from \"react\";\nimport type { FeatureEditorProps } from \"../api/editor/editor\";\nimport { ActionSelector } from \"./components/action-selector/ActionSelector\";\nimport { PropertyEditor } from \"./components/property-editor/PropertyEditor\";\nimport { useEditingStep, useOnActionChange, useSnappingSources } from \"./editor/editorHooks\";\nimport { useEditingCallbacks } from \"./editor/useEditingCallbacks\";\nimport { TooltipMessages } from \"./geometry-editing/controller/EditingController\";\nimport { useGeometryEditing } from \"./geometry-editing/useGeometryEditing\";\n\nexport function FeatureEditor(props: FeatureEditorProps): ReactElement {\n const {\n map,\n templates,\n writer,\n resolveFormTemplate,\n selectableLayers,\n snappableLayers = selectableLayers,\n showActionBar = true,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration,\n onEditingStepChange,\n ...interactionOptions\n } = props;\n const { containerProps } = useCommonComponentProps(\"editor\", props);\n const mapModel = useMapModelValue(props);\n const intl = useIntl();\n\n const [editingStep, setEditingStep] = useEditingStep(onEditingStepChange);\n const snappingSources = useSnappingSources(mapModel, snappableLayers, templates);\n const onActionChange = useOnActionChange(mapModel, selectableLayers, templates, setEditingStep);\n\n const tooltipMessages = useMemo((): TooltipMessages => {\n return {\n getDrawingMessages() {\n return new Map<GeometryType, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePoint\" })],\n [\n \"LineString\",\n intl.formatRichMessage({ id: \"tooltips.drawingMessageLineString\" })\n ],\n [\"Polygon\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePolygon\" })],\n [\"Circle\", intl.formatRichMessage({ id: \"tooltips.drawingMessageCircle\" })]\n ]);\n },\n getSelectionMessage() {\n return intl.formatRichMessage({ id: \"tooltips.selectionMessage\" });\n },\n getModificationMessages() {\n return new Map<string, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.modificationMessagePoint\" })],\n [\"default\", intl.formatRichMessage({ id: \"tooltips.modificationMessage\" })]\n ]);\n }\n };\n }, [intl]);\n\n const drawingState = useGeometryEditing({\n map,\n editingStep,\n setEditingStep,\n snappingSources,\n tooltipMessages,\n ...interactionOptions\n });\n\n const editingCallbacks = useEditingCallbacks(\n mapModel,\n editingStep,\n writer,\n setEditingStep,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration\n );\n\n let content: ReactNode;\n switch (editingStep.id) {\n case \"initial\":\n case \"drawing\":\n case \"selection\":\n content = (\n <ActionSelector\n templates={templates}\n showActionBar={showActionBar}\n onActionChange={onActionChange}\n drawingState={drawingState}\n />\n );\n break;\n case \"creation\":\n case \"update\":\n content = (\n <PropertyEditor\n editingStep={editingStep}\n callbacks={editingCallbacks}\n templates={templates}\n resolveFormTemplate={resolveFormTemplate}\n />\n );\n break;\n }\n\n return (\n <Box {...containerProps} h=\"full\">\n {content}\n </Box>\n );\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"FeatureEditor.js","sources":["FeatureEditor.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box } from \"@chakra-ui/react\";\nimport { useMapModelValue } from \"@open-pioneer/map\";\nimport { useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { type ReactElement, type ReactNode, useMemo } from \"react\";\nimport type { FeatureEditorProps } from \"../api/editor/editor\";\nimport { ActionSelector } from \"./components/action-selector/ActionSelector\";\nimport { PropertyEditor } from \"./components/property-editor/PropertyEditor\";\nimport { useEditingStep, useOnActionChange, useSnappingSources } from \"./editor/editorHooks\";\nimport { useEditingCallbacks } from \"./editor/useEditingCallbacks\";\nimport { TooltipMessages } from \"./geometry-editing/controller/EditingController\";\nimport { useGeometryEditing } from \"./geometry-editing/useGeometryEditing\";\n\nexport function FeatureEditor(props: FeatureEditorProps): ReactElement {\n const {\n map,\n templates,\n writer,\n resolveFormTemplate,\n selectableLayers,\n snappableLayers = selectableLayers,\n resolveSelectionAvailability,\n showActionBar = true,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration,\n onEditingStepChange,\n ...interactionOptions\n } = props;\n const { containerProps } = useCommonComponentProps(\"editor\", props);\n const mapModel = useMapModelValue(props);\n const intl = useIntl();\n\n const [editingStep, setEditingStep] = useEditingStep(onEditingStepChange);\n const snappingSources = useSnappingSources(mapModel, snappableLayers, templates);\n const onActionChange = useOnActionChange(mapModel, selectableLayers, templates, setEditingStep);\n\n const tooltipMessages = useMemo((): TooltipMessages => {\n return {\n getDrawingMessages() {\n return new Map<GeometryType, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePoint\" })],\n [\n \"LineString\",\n intl.formatRichMessage({ id: \"tooltips.drawingMessageLineString\" })\n ],\n [\"Polygon\", intl.formatRichMessage({ id: \"tooltips.drawingMessagePolygon\" })],\n [\"Circle\", intl.formatRichMessage({ id: \"tooltips.drawingMessageCircle\" })]\n ]);\n },\n getSelectionMessage() {\n return intl.formatRichMessage({ id: \"tooltips.selectionMessage\" });\n },\n getModificationMessages() {\n return new Map<string, ReactNode>([\n [\"Point\", intl.formatRichMessage({ id: \"tooltips.modificationMessagePoint\" })],\n [\"default\", intl.formatRichMessage({ id: \"tooltips.modificationMessage\" })]\n ]);\n }\n };\n }, [intl]);\n\n const drawingState = useGeometryEditing({\n map,\n editingStep,\n setEditingStep,\n snappingSources,\n tooltipMessages,\n ...interactionOptions\n });\n\n const editingCallbacks = useEditingCallbacks(\n mapModel,\n editingStep,\n writer,\n setEditingStep,\n successNotifierDisplayDuration,\n failureNotifierDisplayDuration\n );\n\n let content: ReactNode;\n switch (editingStep.id) {\n case \"initial\":\n case \"drawing\":\n case \"selection\":\n content = (\n <ActionSelector\n editingStep={editingStep}\n mapModel={mapModel}\n templates={templates}\n selectableLayers={selectableLayers}\n resolveSelectionAvailability={resolveSelectionAvailability}\n showActionBar={showActionBar}\n onActionChange={onActionChange}\n drawingState={drawingState}\n />\n );\n break;\n case \"creation\":\n case \"update\":\n content = (\n <PropertyEditor\n editingStep={editingStep}\n callbacks={editingCallbacks}\n templates={templates}\n resolveFormTemplate={resolveFormTemplate}\n />\n );\n break;\n }\n\n return (\n <Box {...containerProps} h=\"full\">\n {content}\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAiBO,SAAS,cAAc,KAAA,EAAyC;AACnE,EAAA,MAAM;AAAA,IACF,GAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,mBAAA;AAAA,IACA,gBAAA;AAAA,IACA,eAAA,GAAkB,gBAAA;AAAA,IAClB,4BAAA;AAAA,IACA,aAAA,GAAgB,IAAA;AAAA,IAChB,8BAAA;AAAA,IACA,8BAAA;AAAA,IACA,mBAAA;AAAA,IACA,GAAG;AAAA,GACP,GAAI,KAAA;AACJ,EAAA,MAAM,EAAE,cAAA,EAAe,GAAI,uBAAA,CAAwB,UAAU,KAAK,CAAA;AAClE,EAAA,MAAM,QAAA,GAAW,iBAAiB,KAAK,CAAA;AACvC,EAAA,MAAM,OAAO,OAAA,EAAQ;AAErB,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,eAAe,mBAAmB,CAAA;AACxE,EAAA,MAAM,eAAA,GAAkB,kBAAA,CAAmB,QAAA,EAAU,eAAA,EAAiB,SAAS,CAAA;AAC/E,EAAA,MAAM,cAAA,GAAiB,iBAAA,CAAkB,QAAA,EAAU,gBAAA,EAAkB,WAAW,cAAc,CAAA;AAE9F,EAAA,MAAM,eAAA,GAAkB,QAAQ,MAAuB;AACnD,IAAA,OAAO;AAAA,MACH,kBAAA,GAAqB;AACjB,QAAA,2BAAW,GAAA,CAA6B;AAAA,UACpC,CAAC,SAAS,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,8BAAA,EAAgC,CAAC,CAAA;AAAA,UACxE;AAAA,YACI,YAAA;AAAA,YACA,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,qCAAqC;AAAA,WACtE;AAAA,UACA,CAAC,WAAW,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,gCAAA,EAAkC,CAAC,CAAA;AAAA,UAC5E,CAAC,UAAU,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,+BAAA,EAAiC,CAAC;AAAA,SAC7E,CAAA;AAAA,MACL,CAAA;AAAA,MACA,mBAAA,GAAsB;AAClB,QAAA,OAAO,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,6BAA6B,CAAA;AAAA,MACrE,CAAA;AAAA,MACA,uBAAA,GAA0B;AACtB,QAAA,2BAAW,GAAA,CAAuB;AAAA,UAC9B,CAAC,SAAS,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,mCAAA,EAAqC,CAAC,CAAA;AAAA,UAC7E,CAAC,WAAW,IAAA,CAAK,iBAAA,CAAkB,EAAE,EAAA,EAAI,8BAAA,EAAgC,CAAC;AAAA,SAC7E,CAAA;AAAA,MACL;AAAA,KACJ;AAAA,EACJ,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,eAAe,kBAAA,CAAmB;AAAA,IACpC,GAAA;AAAA,IACA,WAAA;AAAA,IACA,cAAA;AAAA,IACA,eAAA;AAAA,IACA,eAAA;AAAA,IACA,GAAG;AAAA,GACN,CAAA;AAED,EAAA,MAAM,gBAAA,GAAmB,mBAAA;AAAA,IACrB,QAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,cAAA;AAAA,IACA,8BAAA;AAAA,IACA;AAAA,GACJ;AAEA,EAAA,IAAI,OAAA;AACJ,EAAA,QAAQ,YAAY,EAAA;AAAI,IACpB,KAAK,SAAA;AAAA,IACL,KAAK,SAAA;AAAA,IACL,KAAK,WAAA;AACD,MAAA,OAAA,mBACI,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACG,WAAA;AAAA,UACA,QAAA;AAAA,UACA,SAAA;AAAA,UACA,gBAAA;AAAA,UACA,4BAAA;AAAA,UACA,aAAA;AAAA,UACA,cAAA;AAAA,UACA;AAAA;AAAA,OACJ;AAEJ,MAAA;AAAA,IACJ,KAAK,UAAA;AAAA,IACL,KAAK,QAAA;AACD,MAAA,OAAA,mBACI,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACG,WAAA;AAAA,UACA,SAAA,EAAW,gBAAA;AAAA,UACX,SAAA;AAAA,UACA;AAAA;AAAA,OACJ;AAEJ,MAAA;AAAA;AAGR,EAAA,2BACK,GAAA,EAAA,EAAK,GAAG,cAAA,EAAgB,CAAA,EAAE,QACtB,QAAA,EAAA,OAAA,EACL,CAAA;AAER;;"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
+
import { Layer, MapModel } from "@open-pioneer/map";
|
|
1
2
|
import { type ReactElement } from "react";
|
|
3
|
+
import { FeatureEditorProps } from "../../../api/editor/editor";
|
|
4
|
+
import { EditingStep } from "../../../api/model/EditingStep";
|
|
2
5
|
import type { FeatureTemplate } from "../../../api/model/FeatureTemplate";
|
|
3
6
|
import { DrawingState } from "../../geometry-editing/useGeometryEditing";
|
|
4
7
|
export interface ActionSelectorProps {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
mapModel: MapModel;
|
|
9
|
+
templates: FeatureTemplate[];
|
|
10
|
+
selectableLayers: Layer[] | undefined;
|
|
11
|
+
resolveSelectionAvailability: FeatureEditorProps["resolveSelectionAvailability"];
|
|
12
|
+
showActionBar: boolean;
|
|
13
|
+
editingStep: EditingStep;
|
|
14
|
+
drawingState: DrawingState;
|
|
15
|
+
onActionChange: (newAction: Action | undefined) => void;
|
|
9
16
|
}
|
|
10
17
|
export interface CreateAction {
|
|
11
18
|
readonly mode: "create";
|
|
@@ -15,4 +22,4 @@ export interface UpdateAction {
|
|
|
15
22
|
readonly mode: "update";
|
|
16
23
|
}
|
|
17
24
|
export type Action = CreateAction | UpdateAction;
|
|
18
|
-
export declare function ActionSelector({ templates, showActionBar, drawingState, onActionChange }: ActionSelectorProps): ReactElement;
|
|
25
|
+
export declare function ActionSelector({ mapModel, templates, selectableLayers, resolveSelectionAvailability, showActionBar, editingStep, drawingState, onActionChange }: ActionSelectorProps): ReactElement;
|
|
@@ -2,17 +2,34 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { Flex, Box } from '@chakra-ui/react';
|
|
3
3
|
import { useEvent, TitledSection } from '@open-pioneer/react-utils';
|
|
4
4
|
import { useIntl } from '../../../_virtual/hooks.js';
|
|
5
|
-
import { useState, useMemo } from 'react';
|
|
5
|
+
import { useEffectEvent, useEffect, useState, useMemo } from 'react';
|
|
6
|
+
import { useSelectionAvailability } from '../../editor/editorHooks.js';
|
|
6
7
|
import { DrawingControls } from './DrawingControls.js';
|
|
7
8
|
import { SelectButton } from './SelectButton.js';
|
|
8
9
|
import { TemplateSelector } from './TemplateSelector.js';
|
|
9
10
|
|
|
10
11
|
function ActionSelector({
|
|
12
|
+
mapModel,
|
|
11
13
|
templates,
|
|
14
|
+
selectableLayers,
|
|
15
|
+
resolveSelectionAvailability,
|
|
12
16
|
showActionBar,
|
|
17
|
+
editingStep,
|
|
13
18
|
drawingState,
|
|
14
19
|
onActionChange
|
|
15
20
|
}) {
|
|
21
|
+
const selectionAvailability = useSelectionAvailability(
|
|
22
|
+
mapModel,
|
|
23
|
+
templates,
|
|
24
|
+
selectableLayers,
|
|
25
|
+
resolveSelectionAvailability
|
|
26
|
+
);
|
|
27
|
+
const onActionChangeEffect = useEffectEvent(onActionChange);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (editingStep.id === "selection" && selectionAvailability.status === "unavailable") {
|
|
30
|
+
onActionChangeEffect(void 0);
|
|
31
|
+
}
|
|
32
|
+
}, [editingStep.id, selectionAvailability.status]);
|
|
16
33
|
const [selectButtonIsActive, setSelectButtonActive] = useState(false);
|
|
17
34
|
const [selectedTemplate, setSelectedTemplate] = useState();
|
|
18
35
|
const onButtonClick = useEvent(() => {
|
|
@@ -43,7 +60,15 @@ function ActionSelector({
|
|
|
43
60
|
align: "stretch",
|
|
44
61
|
overflowY: "auto",
|
|
45
62
|
children: [
|
|
46
|
-
/* @__PURE__ */ jsx(TitledSection, { title: editFeatureHeading, sectionHeadingProps: { size: "sm" }, children: /* @__PURE__ */ jsx(
|
|
63
|
+
/* @__PURE__ */ jsx(TitledSection, { title: editFeatureHeading, sectionHeadingProps: { size: "sm" }, children: /* @__PURE__ */ jsx(
|
|
64
|
+
SelectButton,
|
|
65
|
+
{
|
|
66
|
+
isAvailable: selectionAvailability.status === "available",
|
|
67
|
+
notAvailableMessage: selectionAvailability.status === "unavailable" ? selectionAvailability.reason : void 0,
|
|
68
|
+
isActive: selectButtonIsActive,
|
|
69
|
+
onClick: onButtonClick
|
|
70
|
+
}
|
|
71
|
+
) }),
|
|
47
72
|
/* @__PURE__ */ jsxs(TitledSection, { title: createFeatureHeading, sectionHeadingProps: { size: "sm", mt: 3 }, children: [
|
|
48
73
|
/* @__PURE__ */ jsx(Box, { flex: 1, overflowY: "auto", mb: 2, children: /* @__PURE__ */ jsx(
|
|
49
74
|
TemplateSelector,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionSelector.js","sources":["ActionSelector.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box, Flex } from \"@chakra-ui/react\";\nimport { TitledSection, useEvent } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, useState, type ReactElement } from \"react\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\nimport { DrawingState } from \"../../geometry-editing/useGeometryEditing\";\nimport { DrawingControls } from \"./DrawingControls\";\nimport { SelectButton } from \"./SelectButton\";\nimport { TemplateSelector } from \"./TemplateSelector\";\n\nexport interface ActionSelectorProps {\n
|
|
1
|
+
{"version":3,"file":"ActionSelector.js","sources":["ActionSelector.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Box, Flex } from \"@chakra-ui/react\";\nimport { Layer, MapModel } from \"@open-pioneer/map\";\nimport { TitledSection, useEvent } from \"@open-pioneer/react-utils\";\nimport type { Type as GeometryType } from \"ol/geom/Geometry\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useEffect, useEffectEvent, useMemo, useState, type ReactElement } from \"react\";\nimport { FeatureEditorProps } from \"../../../api/editor/editor\";\nimport { EditingStep } from \"../../../api/model/EditingStep\";\nimport type { FeatureTemplate } from \"../../../api/model/FeatureTemplate\";\nimport { useSelectionAvailability } from \"../../editor/editorHooks\";\nimport { DrawingState } from \"../../geometry-editing/useGeometryEditing\";\nimport { DrawingControls } from \"./DrawingControls\";\nimport { SelectButton } from \"./SelectButton\";\nimport { TemplateSelector } from \"./TemplateSelector\";\n\n// TODO(refactor): Takes too many props, just to show or reset the availability of the select button.\nexport interface ActionSelectorProps {\n mapModel: MapModel;\n templates: FeatureTemplate[];\n selectableLayers: Layer[] | undefined;\n resolveSelectionAvailability: FeatureEditorProps[\"resolveSelectionAvailability\"];\n showActionBar: boolean;\n editingStep: EditingStep;\n drawingState: DrawingState;\n onActionChange: (newAction: Action | undefined) => void;\n}\n\nexport interface CreateAction {\n readonly mode: \"create\";\n readonly template: FeatureTemplate;\n}\n\nexport interface UpdateAction {\n readonly mode: \"update\";\n}\n\nexport type Action = CreateAction | UpdateAction;\n\nexport function ActionSelector({\n mapModel,\n templates,\n selectableLayers,\n resolveSelectionAvailability,\n showActionBar,\n editingStep,\n drawingState,\n onActionChange\n}: ActionSelectorProps): ReactElement {\n const selectionAvailability = useSelectionAvailability(\n mapModel,\n templates,\n selectableLayers,\n resolveSelectionAvailability\n );\n\n // Reset editing step \"initial\" when the selection becomes unavailable.\n // TODO(refactor): this should be initiated by the model; not the UI.\n const onActionChangeEffect = useEffectEvent(onActionChange);\n useEffect(() => {\n if (editingStep.id === \"selection\" && selectionAvailability.status === \"unavailable\") {\n onActionChangeEffect(undefined);\n }\n }, [editingStep.id, selectionAvailability.status]);\n\n const [selectButtonIsActive, setSelectButtonActive] = useState(false);\n const [selectedTemplate, setSelectedTemplate] = useState<FeatureTemplate>();\n\n const onButtonClick = useEvent(() => {\n setSelectButtonActive((active) => !active);\n setSelectedTemplate(undefined);\n onActionChange(!selectButtonIsActive ? { mode: \"update\" } : undefined);\n });\n\n const onTemplateClick = useEvent((template: FeatureTemplate) => {\n setSelectedTemplate((current) => (current !== template ? template : undefined));\n setSelectButtonActive(false);\n onActionChange(selectedTemplate !== template ? { mode: \"create\", template } : undefined);\n });\n\n const { formatMessage } = useIntl();\n\n const [editFeatureHeading, createFeatureHeading] = useMemo(\n () => [\n formatMessage({ id: \"actionSelector.editFeatureHeading\" }),\n formatMessage({ id: \"actionSelector.createFeatureHeading\" })\n ],\n [formatMessage]\n );\n\n return (\n <Flex\n className=\"editor__action-selector\"\n direction=\"column\"\n height=\"full\"\n rowGap={3}\n align=\"stretch\"\n overflowY=\"auto\"\n >\n <TitledSection title={editFeatureHeading} sectionHeadingProps={{ size: \"sm\" }}>\n <SelectButton\n isAvailable={selectionAvailability.status === \"available\"}\n notAvailableMessage={\n selectionAvailability.status === \"unavailable\"\n ? selectionAvailability.reason\n : undefined\n }\n isActive={selectButtonIsActive}\n onClick={onButtonClick}\n />\n </TitledSection>\n\n <TitledSection title={createFeatureHeading} sectionHeadingProps={{ size: \"sm\", mt: 3 }}>\n <Box flex={1} overflowY=\"auto\" mb={2}>\n <TemplateSelector\n templates={templates}\n selectedTemplate={selectedTemplate}\n onClick={onTemplateClick}\n />\n </Box>\n {showActionBar && shouldShowActionBar(selectedTemplate) && (\n <DrawingControls drawingState={drawingState} />\n )}\n </TitledSection>\n </Flex>\n );\n}\n\nfunction shouldShowActionBar(template: FeatureTemplate | undefined): boolean {\n return template != null && ACTION_GEOMETRY_TYPES.has(template.geometryType);\n}\n\nconst ACTION_GEOMETRY_TYPES = new Set<GeometryType>([\"Polygon\", \"LineString\"]);\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DrawingControls.js","sources":["DrawingControls.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { HStack, IconButton } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, type ReactElement } from \"react\";\nimport { LuCheck, LuRedo, LuUndo, LuX } from \"react-icons/lu\";\nimport { type DrawingState } from \"../../geometry-editing/useGeometryEditing\";\n\nexport interface DrawingControlsProps {\n readonly drawingState: DrawingState;\n}\n\nexport function DrawingControls({ drawingState }: DrawingControlsProps): ReactElement {\n const capabilities = useReactiveSnapshot(\n () => ({\n canUndo: drawingState.canUndo,\n canRedo: drawingState.canRedo,\n canFinish: drawingState.canFinish,\n canReset: drawingState.canReset\n }),\n [drawingState]\n );\n\n const actions = useMemo(\n () => ({\n undo: () => drawingState.undo(),\n redo: () => drawingState.redo(),\n finish: () => drawingState.finish(),\n reset: () => drawingState.reset()\n }),\n [drawingState]\n );\n\n const { formatMessage } = useIntl();\n\n const tooltips = useMemo(\n () => ({\n finishButton: formatMessage({ id: \"actionSelector.finishButtonTooltip\" }),\n resetButton: formatMessage({ id: \"actionSelector.resetButtonTooltip\" }),\n undoButton: formatMessage({ id: \"actionSelector.undoButtonTooltip\" }),\n redoButton: formatMessage({ id: \"actionSelector.redoButtonTooltip\" })\n }),\n [formatMessage]\n );\n\n return (\n <HStack className=\"editor__drawing-controls\" justify=\"right\" gap={3} mb={\"4px\"}>\n <Tooltip content={tooltips.finishButton}>\n <IconButton\n aria-label={tooltips.finishButton}\n disabled={!capabilities.canFinish}\n onClick={actions.finish}\n >\n <LuCheck size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.resetButton}>\n <IconButton\n aria-label={tooltips.resetButton}\n disabled={!capabilities.canReset}\n onClick={actions.reset}\n >\n <LuX size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.undoButton}>\n <IconButton\n aria-label={tooltips.undoButton}\n disabled={!capabilities.canUndo}\n onClick={actions.undo}\n >\n <LuUndo size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.redoButton}>\n <IconButton\n aria-label={tooltips.redoButton}\n disabled={!capabilities.canRedo}\n onClick={actions.redo}\n >\n <LuRedo size={25} />\n </IconButton>\n </Tooltip>\n </HStack>\n );\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"DrawingControls.js","sources":["DrawingControls.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { HStack, IconButton } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { useReactiveSnapshot } from \"@open-pioneer/reactivity\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, type ReactElement } from \"react\";\nimport { LuCheck, LuRedo, LuUndo, LuX } from \"react-icons/lu\";\nimport { type DrawingState } from \"../../geometry-editing/useGeometryEditing\";\n\nexport interface DrawingControlsProps {\n readonly drawingState: DrawingState;\n}\n\nexport function DrawingControls({ drawingState }: DrawingControlsProps): ReactElement {\n const capabilities = useReactiveSnapshot(\n () => ({\n canUndo: drawingState.canUndo,\n canRedo: drawingState.canRedo,\n canFinish: drawingState.canFinish,\n canReset: drawingState.canReset\n }),\n [drawingState]\n );\n\n const actions = useMemo(\n () => ({\n undo: () => drawingState.undo(),\n redo: () => drawingState.redo(),\n finish: () => drawingState.finish(),\n reset: () => drawingState.reset()\n }),\n [drawingState]\n );\n\n const { formatMessage } = useIntl();\n\n const tooltips = useMemo(\n () => ({\n finishButton: formatMessage({ id: \"actionSelector.finishButtonTooltip\" }),\n resetButton: formatMessage({ id: \"actionSelector.resetButtonTooltip\" }),\n undoButton: formatMessage({ id: \"actionSelector.undoButtonTooltip\" }),\n redoButton: formatMessage({ id: \"actionSelector.redoButtonTooltip\" })\n }),\n [formatMessage]\n );\n\n return (\n <HStack className=\"editor__drawing-controls\" justify=\"right\" gap={3} mb={\"4px\"}>\n <Tooltip content={tooltips.finishButton}>\n <IconButton\n aria-label={tooltips.finishButton}\n disabled={!capabilities.canFinish}\n onClick={actions.finish}\n >\n <LuCheck size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.resetButton}>\n <IconButton\n aria-label={tooltips.resetButton}\n disabled={!capabilities.canReset}\n onClick={actions.reset}\n >\n <LuX size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.undoButton}>\n <IconButton\n aria-label={tooltips.undoButton}\n disabled={!capabilities.canUndo}\n onClick={actions.undo}\n >\n <LuUndo size={25} />\n </IconButton>\n </Tooltip>\n\n <Tooltip content={tooltips.redoButton}>\n <IconButton\n aria-label={tooltips.redoButton}\n disabled={!capabilities.canRedo}\n onClick={actions.redo}\n >\n <LuRedo size={25} />\n </IconButton>\n </Tooltip>\n </HStack>\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
2
|
interface SelectButtonProps {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
isAvailable: boolean;
|
|
4
|
+
notAvailableMessage: string | undefined;
|
|
5
|
+
isActive: boolean;
|
|
6
|
+
onClick: () => void;
|
|
5
7
|
}
|
|
6
|
-
export declare function SelectButton(
|
|
8
|
+
export declare function SelectButton(props: SelectButtonProps): ReactElement;
|
|
7
9
|
export {};
|
|
@@ -1,11 +1,26 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { Toggle, Button } from '@chakra-ui/react';
|
|
3
|
+
import { Tooltip } from '@open-pioneer/chakra-snippets/tooltip';
|
|
3
4
|
import { useIntl } from '../../../_virtual/hooks.js';
|
|
5
|
+
import { useMemo } from 'react';
|
|
4
6
|
import { LuMousePointerClick } from 'react-icons/lu';
|
|
5
7
|
|
|
6
|
-
function SelectButton(
|
|
7
|
-
const {
|
|
8
|
-
|
|
8
|
+
function SelectButton(props) {
|
|
9
|
+
const {
|
|
10
|
+
isAvailable,
|
|
11
|
+
notAvailableMessage: notAvailableMessageProp,
|
|
12
|
+
isActive: isActiveProp,
|
|
13
|
+
onClick
|
|
14
|
+
} = props;
|
|
15
|
+
const intl = useIntl();
|
|
16
|
+
const isActive = isAvailable && isActiveProp;
|
|
17
|
+
const notAvailableMessage = useMemo(() => {
|
|
18
|
+
if (isAvailable) {
|
|
19
|
+
return void 0;
|
|
20
|
+
}
|
|
21
|
+
return notAvailableMessageProp ?? intl.formatMessage({ id: "selection.defaultNotAvailableMessage" });
|
|
22
|
+
}, [intl, isAvailable, notAvailableMessageProp]);
|
|
23
|
+
return /* @__PURE__ */ jsx(Tooltip, { disabled: notAvailableMessage == null, content: notAvailableMessage, children: /* @__PURE__ */ jsx(Toggle.Root, { disabled: !isAvailable, pressed: isActive, asChild: true, children: /* @__PURE__ */ jsxs(
|
|
9
24
|
Button,
|
|
10
25
|
{
|
|
11
26
|
className: "editor__action-selector-select-button",
|
|
@@ -16,10 +31,10 @@ function SelectButton({ isActive, onClick }) {
|
|
|
16
31
|
onClick,
|
|
17
32
|
children: [
|
|
18
33
|
/* @__PURE__ */ jsx(LuMousePointerClick, { "aria-hidden": "true" }),
|
|
19
|
-
isActive ? formatMessage({ id: "actionSelector.selectButtonActiveTitle" }) : formatMessage({ id: "actionSelector.selectButtonTitle" })
|
|
34
|
+
isActive ? intl.formatMessage({ id: "actionSelector.selectButtonActiveTitle" }) : intl.formatMessage({ id: "actionSelector.selectButtonTitle" })
|
|
20
35
|
]
|
|
21
36
|
}
|
|
22
|
-
) });
|
|
37
|
+
) }) });
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
export { SelectButton };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SelectButton.js","sources":["SelectButton.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Toggle } from \"@chakra-ui/react\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport type
|
|
1
|
+
{"version":3,"file":"SelectButton.js","sources":["SelectButton.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023-2025 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\n\nimport { Button, Toggle } from \"@chakra-ui/react\";\nimport { Tooltip } from \"@open-pioneer/chakra-snippets/tooltip\";\nimport { useIntl } from \"open-pioneer:react-hooks\";\nimport { useMemo, type ReactElement } from \"react\";\nimport { LuMousePointerClick } from \"react-icons/lu\";\n\ninterface SelectButtonProps {\n isAvailable: boolean;\n notAvailableMessage: string | undefined;\n\n isActive: boolean;\n onClick: () => void;\n}\n\nexport function SelectButton(props: SelectButtonProps): ReactElement {\n const {\n isAvailable,\n notAvailableMessage: notAvailableMessageProp,\n isActive: isActiveProp,\n onClick\n } = props;\n const intl = useIntl();\n\n const isActive = isAvailable && isActiveProp;\n\n const notAvailableMessage = useMemo(() => {\n if (isAvailable) {\n return undefined;\n }\n return (\n notAvailableMessageProp ??\n intl.formatMessage({ id: \"selection.defaultNotAvailableMessage\" })\n );\n }, [intl, isAvailable, notAvailableMessageProp]);\n\n return (\n <Tooltip disabled={notAvailableMessage == null} content={notAvailableMessage}>\n <Toggle.Root disabled={!isAvailable} pressed={isActive} asChild>\n <Button\n className=\"editor__action-selector-select-button\"\n variant=\"outline\"\n _hover={{ bg: isActive ? \"colorPalette.700\" : \"colorPalette.subtle\" }}\n _pressed={{ bg: \"colorPalette.800\", color: \"colorPalette.contrast\" }}\n // Margin for focus outline\n marginX=\"4px\"\n onClick={onClick}\n >\n <LuMousePointerClick aria-hidden=\"true\" />\n {isActive\n ? intl.formatMessage({ id: \"actionSelector.selectButtonActiveTitle\" })\n : intl.formatMessage({ id: \"actionSelector.selectButtonTitle\" })}\n </Button>\n </Toggle.Root>\n </Tooltip>\n );\n}\n"],"names":[],"mappings":";;;;;;;AAiBO,SAAS,aAAa,KAAA,EAAwC;AACjE,EAAA,MAAM;AAAA,IACF,WAAA;AAAA,IACA,mBAAA,EAAqB,uBAAA;AAAA,IACrB,QAAA,EAAU,YAAA;AAAA,IACV;AAAA,GACJ,GAAI,KAAA;AACJ,EAAA,MAAM,OAAO,OAAA,EAAQ;AAErB,EAAA,MAAM,WAAW,WAAA,IAAe,YAAA;AAEhC,EAAA,MAAM,mBAAA,GAAsB,QAAQ,MAAM;AACtC,IAAA,IAAI,WAAA,EAAa;AACb,MAAA,OAAO,MAAA;AAAA,IACX;AACA,IAAA,OACI,2BACA,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,wCAAwC,CAAA;AAAA,EAEzE,CAAA,EAAG,CAAC,IAAA,EAAM,WAAA,EAAa,uBAAuB,CAAC,CAAA;AAE/C,EAAA,2BACK,OAAA,EAAA,EAAQ,QAAA,EAAU,mBAAA,IAAuB,IAAA,EAAM,SAAS,mBAAA,EACrD,QAAA,kBAAA,GAAA,CAAC,MAAA,CAAO,IAAA,EAAP,EAAY,QAAA,EAAU,CAAC,aAAa,OAAA,EAAS,QAAA,EAAU,SAAO,IAAA,EAC3D,QAAA,kBAAA,IAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACG,SAAA,EAAU,uCAAA;AAAA,MACV,OAAA,EAAQ,SAAA;AAAA,MACR,MAAA,EAAQ,EAAE,EAAA,EAAI,QAAA,GAAW,qBAAqB,qBAAA,EAAsB;AAAA,MACpE,QAAA,EAAU,EAAE,EAAA,EAAI,kBAAA,EAAoB,OAAO,uBAAA,EAAwB;AAAA,MAEnE,OAAA,EAAQ,KAAA;AAAA,MACR,OAAA;AAAA,MAEA,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,eAAY,MAAA,EAAO,CAAA;AAAA,QACvC,QAAA,GACK,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,wCAAA,EAA0C,CAAA,GACnE,IAAA,CAAK,aAAA,CAAc,EAAE,EAAA,EAAI,oCAAoC;AAAA;AAAA;AAAA,KAE3E,CAAA,EACJ,CAAA;AAER;;"}
|