Select to view content in your preferred language

In arcgis-sketch component How to set all availableCreateTools (freehandpolyline, freehandpolygon, text)

249
2
11-12-2025 03:18 AM
RavindraSingh
Frequent Contributor

How can I configure all availableCreateTools, such as freehand polyline, freehand polygon, and text?

Currently, I'm able to access all other tools except the three mentioned above.

I followed Sketch | ArcGIS Maps SDK for JavaScript

Below are the details:

ArcGIS Javascript SDK 4.32.13

React 19.0.0

NOTE: I am not using Typescript. instead, I am writing code in .jsx file.

Case-1: Below is the code snippet being used to initialize the sketch component:

const sketchElement = sketchRef.current;
            sketchElement.view = mapView;
            sketchElement.availableCreateTools = [
                "point",
                "multipoint",
                "freehandPolyline",   // Not showing
                "polyline",
                "freehandPolygon", // Not showing
                "polygon",
                "rectangle",
                "circle",
                "text" // Not showing
            ];
            sketchElement.layer = sketchLayer;

 

I’ve also attempted the second approach as outlined below. Case 2: This is the code snippet used to initialize the sketch component.

<arcgis-sketch
  ref={sketchRef}
  layout="vertical"
  creation-mode="update"
  scale="m"
  toolbar-kind="docked"
  show-create-tools-freehand-polyline
  show-create-tools-freehand-polygon
  
/>

 

Despite trying both approaches, the freehand polyline, freehand polygon, and text buttons are still not appearing in the Sketch UI. Any insights?

0 Kudos
2 Replies
ReneRubalcava
Esri Frequent Contributor

If you're using JSX, you probably need to use the the camelCase for attributes.

  • showCreateToolsFreehandPolygon
  • showCreateToolsFreehandPolyline

However, it does look like the multipoint and text options will not show at the moment. We're looking into this and will have this updated in 5.0.

Ok, small update. I had to set a timeout and the multipoint tool does show up. The text tool does not as that is not quite ready yet. https://codepen.io/odoe/pen/myPJvgd?editors=1001

 

0 Kudos
RavindraSingh
Frequent Contributor

Thanks @ReneRubalcava for response. I tried what you suggest but still freehandpolygon and freehandpolyline is not showing up in UI.

Here is full code of mine, can you have look at it and help to make it run:

/* eslint-disable react/prop-types */
import React, { useState, useEffect, useRef, useContext, useCallback  } from 'react';
import ReactDOM from 'react-dom';
import { useTheme } from '@mui/material/styles';
import { IconButton, Popper, Box, Typography } from "@mui/material";
import IconMarkup from '../../assets/icons/IconMarkup.svg?react';

import { MapContext } from './Context/MapContext.jsx';
import "@arcgis/map-components/components/arcgis-sketch";
import GraphicsLayer from "@arcgis/core/layers/GraphicsLayer";

// Import the new custom tool
import MarkupCustomTool from './MarkupCustomTool.jsx';

function MarkupTool ({
    containerStyle,
    activeDialog,
    onDialogToggle,
}) {
    const theme = useTheme();
    const dialogId = 'markupDialog';
    const dialogIsOpen = activeDialog === dialogId;

    const [tooltipAnchorEl, setTooltipAnchorEl] = useState(null); 
    const [openPopper, setOpenPopper] = useState(false);
    const id = openPopper ? 'markup-popper' : undefined;
    const [sketchLayer, setSketchLayer] = useState(null);

    const sketchRef = useRef(null);
    const { mapView } = useContext(MapContext);

    // Use useCallback for the ready handler
    const handleSketchReady = useCallback(() => {
        const sketchElement = document.querySelector("arcgis-sketch");
        if (!sketchElement) {
            console.log("Sketch element not found in handleSketchReady");
            return;
        }

        console.log("✅ Sketch element ready (handleSketchReady fired)");
        
        // Small timeout to ensure the element is fully initialized
        setTimeout(() => {
            sketchElement.availableCreateTools = [
                "point",
                "multipoint",
                "polyline",
                "freehandPolygon",
                "freehandPolyline",
                "polygon",
                "rectangle",
                "circle",
                "text" // Not showing intentionally for now
            ];
            console.log("Available tools set:", sketchElement.availableCreateTools);
        }, 1000);
    }, []);

    useEffect(() => {
        if (!mapView) return;

        const layer = new GraphicsLayer({
            id: "markup_graphics_layer",
            title: "Markup Graphics"
        });
        setSketchLayer(layer);

        mapView.map.add(layer);

        return () => {
            if (mapView && !mapView.destroyed) {
                mapView.map.remove(layer);
            }
        };
    }, [mapView]);

    const handleButtonClick = () => {
        onDialogToggle(dialogId);
        setOpenPopper(false); 
        setTooltipAnchorEl(null);
    };

    const handleMouseEnter = (event) => {
        setTooltipAnchorEl(event.currentTarget);
        if (!dialogIsOpen) {
            setOpenPopper(true);
        }
    };

    const handleMouseLeave = () => {
        setOpenPopper(false);
        setTooltipAnchorEl(null);
    };

    useEffect(() => {
        if (dialogIsOpen) {
            setOpenPopper(false);
            setTooltipAnchorEl(null);
        }
    }, [dialogIsOpen]);

    useEffect(() => {
        if (!dialogIsOpen || !mapView || !sketchLayer) return;

        // Use a slight delay to ensure the element is in the DOM
        const timer = setTimeout(() => {
            const sketchElement = document.querySelector("arcgis-sketch");
            
            if (!sketchElement) {
                console.log("Sketch element not found");
                return;
            }

            console.log("Setting up sketch element");
            
            // Set view and layer first
            sketchElement.view = mapView;
            sketchElement.layer = sketchLayer;

            // Check if already ready (widget property exists)
            if (sketchElement.widget) {
                console.log("Sketch element already ready");
                handleSketchReady();
            } else {
                console.log("Waiting for arcgisReady event");
                // Add event listener for when it becomes ready
                sketchElement.addEventListener("arcgisReady", handleSketchReady);
            }

            // Cleanup function
            return () => {
                sketchElement.removeEventListener("arcgisReady", handleSketchReady);
            };
        }, 100);

        return () => {
            clearTimeout(timer);
        };
    }, [dialogIsOpen, mapView, sketchLayer, handleSketchReady]);


    return (
        <>
            <IconButton
                variant="contained"
                style={containerStyle}
                sx={{
                    width: 48,
                    height: 48,
                    backgroundColor: dialogIsOpen ? theme.appColor.darkGray : theme.appColor.darkGray,
                    color: dialogIsOpen ? theme.appColor.lightBlue: 'white',
                    '&:hover': {
                        backgroundColor: dialogIsOpen ? theme.appColor.darkGray : 'white',
                        color: dialogIsOpen ? theme.appColor.lightBlue : theme.appColor.darkGray,
                    },
                    '&:active': {
                        backgroundColor: dialogIsOpen ? 'white' : 'white',
                        color: dialogIsOpen ? theme.appColor.darkGray : theme.appColor.lightBlue,
                    },
                }}
                onClick={handleButtonClick}
                onMouseEnter={handleMouseEnter}
                onMouseLeave={handleMouseLeave}
                aria-describedby={id}
                aria-label="MarkupButton"
            >
                <IconMarkup alt="Markup" />
            </IconButton>

            <Popper
                id={id}
                open={openPopper}
                anchorEl={tooltipAnchorEl}
                placement="left"
                disablePortal={false}
                modifiers={[{ name: 'offset', options: { offset: [0, 10] } }]}
            >
                <Box sx={{
                    border: '#DFDFDF',
                    padding: '12px',
                    bgcolor: 'white',
                    borderRadius: '8px',
                    boxShadow: 3,
                }}>
                    <Typography variant="body2">Markup Tools</Typography>
                </Box>
            </Popper>

            {dialogIsOpen && mapView && mapView.container && (
                ReactDOM.createPortal(
                    <Box
                        sx={{
                            position: 'absolute',
                            top: 150, 
                            right: 82,
                            backgroundColor: 'white',
                            boxShadow: 3,
                            borderRadius: '8px',
                            zIndex: 1300,
                        }}
                    >
                        <arcgis-sketch
                            ref={sketchRef}
                            layout="vertical"
                            creation-mode="update"
                            scale="m"
                            toolbar-kind="docked"
                            hide-selection-tools-lasso-selection
                            show-create-tools-freehand-polygon
                            show-create-tools-freehand-polyline
                            showCreateToolsFreehandPolyline
                        />
                        <MarkupCustomTool
                            sketchLayer={sketchLayer}
                            sketchRef={sketchRef}
                            dialogIsOpen={dialogIsOpen}
                        />
                    </Box>,
                    mapView.container
                )
            )}
        </>
    );
}

export default MarkupTool;

 

0 Kudos