Skip to main content

createWidgetComponent

The createWidgetComponent function can be used to create any type of component that extends from the ESRI Widget class. It takes in a function that creates the widget instance, a ref, and the widget properties, and returns a react-ready component that can be used as a child of a MapView.

Function signature

/**
* Factory function to create an esrieact widget component
* @param createWidget Function that takes in the widget properties
* (which must extend from __esri.WidgetProperties) and returns the widget instance
* @param ref The react ref to be passed from the parent
* @param properties The widget properties
* @returns A context provider whose context is the instance to be passed to children,
* or if there are no children, returns null.
*/
createWidgetComponent<P extends WidgetComponentProps>(
createWidget: CreateWidgetFunction,
ref: Ref<EsriWidget>,
{ children, events, position, view: viewFromProps, ...properties }: P,
) => JSX.Element | null;

Where

/**
* Properties that can be applied to any ESRIEACT Widget component. Extends from
* esri's WidgetProperties to include child components and the widget position
*/
export type WidgetComponentProps<
T extends __esri.WidgetProperties = __esri.WidgetProperties & {
view?: __esri.MapView;
},
E extends Record<string, Function> = {},
> = React.PropsWithChildren<T> & {
events?: E;
position?: string | __esri.UIAddPosition;
};

/**
* Function that takes in layer properties and returns an esri Layer instance. Properties must be
* any esri properties that extend esri.LayerProperties, and optional children
*/
export type CreateWidgetFunction<
T extends WidgetComponentProps = WidgetComponentProps,
> = (properties: T) => __esri.Widget;

Example Usage

Typescript

If you need to create a widget component that is not in ESRIEACT, you can use createWidgetComponent to create it. For example, here we want to create a DirectionalPad component. We first define the event handler function map for the DirectionalPad component, and then define the createWidget function that takes in the widget properties and returns the DirectionalPad instance. Finally, we use createWidgetComponent to create the DirectionalPad component.

/**
* Event handler function map for events specific the Sketch widget
*
* Note that most widgets do not have events
*/
type SketchEventHandlerFnMap = Partial<{
delete: __esri.SketchDeleteEventHandler;
create: __esri.SketchCreateEventHandler;
update: __esri.SketchUpdateEventHandler;
redo: __esri.SketchRedoEventHandler;
undo: __esri.SketchUndoEventHandler;
}>;

/**
* Special properties for this specific widget
*/
interface SketchProperties extends __esri.SketchProperties {
layer: __esri.GraphicsLayer;
}

/**
* Function that takes in the widget specific properties and returns the widget instance
*/
const createWidget = (
properties: WidgetComponentProps<SketchProperties, SketchEventHandlerFnMap>,
): EsriSketch => {
return new EsriSketch(properties);
};

/**
* The react Sketch component
*/
export const Sketch = React.forwardRef<
EsriSketch,
WidgetComponentProps<SketchProperties, SketchEventHandlerFnMap>
>((properties, ref) => createWidgetComponent(createWidget, ref, properties));

Javascript

Most of the above code is careful typescript typing to ensure correctly typed props and event handlers. The javascript version is much simpler:

const createWidget = (properties) => new EsriSketch(properties);

export const Sketch = React.forwardRef((properties, ref) =>
createWidgetComponent(createWidget, ref, properties),
);

Usage

Now you can use the Sketch component as a child of a MapView:

Live Editor
// Example.tsx
function Example() {
  return (
    <MapView
      ViewProperties={{ extent: OAHU_EXTENT_2 }}
      MapProperties={{ basemap: "topo-vector" }}
      style={{ height: "300px", width: "100%" }}
    >
      <Sketch position="top-right" />
    </MapView>
  );
}
Result
Loading...

(Note that the Sketch widget requires you to specify a GraphicsLayer to work - see the GraphicsLayer example.)