import * as React from "react"; import { ViewMode, DrawPointMode, DrawLineStringMode, DrawPolygonMode, DrawCircleFromCenterMode, DrawRectangleMode, MeasureDistanceMode, MeasureAngleMode, MeasureAreaMode, ModifyMode, TranslateMode } from "@nebula.gl/edit-modes"; import styled from "styled-components"; import { Icon } from "./icon"; import { ImportModal } from "./import-modal"; import { ExportModal } from "./export-modal"; const Tools = styled.div` position: absolute; display: flex; flex-direction: column; top: 40px; left: 10px; `; const Button = styled.button<{ active?: boolean; kind?: string }>` color: #fff; background: ${({ kind, active }) => (kind === "danger" ? "rgb(180, 40, 40)" : active ? "rgb(56, 111, 164)" : "rgb(69, 102, 131)")}; font-size: 1em; font-weight: 400; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; border: 1px solid transparent; border-radius: 0.25em; margin: 0.05em; padding: 0.1em 0.2em; :hover { background: rgb(56, 111, 164); } `; const SubToolsContainer = styled.div` position: relative; `; const SubTools = styled.div` display: flex; flex-direction: row-reverse; position: absolute; top: 0; left: 0; `; export interface ToolboxOptions { viewModeEnabled?: boolean, drawPointModeEnabled?: boolean, drawLineModeEnabled?: boolean, drawPolygonModeEnabled?: boolean, drawRectangleModeEnabled?: boolean, drawCircleModeEnabled?: boolean, measureDistanceModeEnabled?: boolean, measureAngleModeEnabled?: boolean, measureAreaModeEnabled?: boolean, editModeEnabled?: boolean, moveModeEnabled?: boolean, importEnabled?: boolean, exportEnabled?: boolean, settingsModeEnabled?: boolean, // not implemented/tested yet deleteEnabled?: boolean, } export type Props = { mode: any; modeConfig: any; geoJson: any; onSetMode: (mode: any) => unknown; onSetModeConfig: (modeConfig: any) => unknown; onSetGeoJson: (geojson: any) => unknown; onImport: (imported: any) => unknown; options?: ToolboxOptions, }; const defaultToolBoxOptions: ToolboxOptions = { viewModeEnabled: true, drawPointModeEnabled: true, drawLineModeEnabled: true, drawPolygonModeEnabled: true, drawRectangleModeEnabled: true, drawCircleModeEnabled: true, measureDistanceModeEnabled: true, measureAngleModeEnabled: true, measureAreaModeEnabled: true, editModeEnabled: true, moveModeEnabled: true, importEnabled: true, exportEnabled: true, settingsModeEnabled: false, deleteEnabled: true } const MODE_GROUPS = [ { modes: [{ mode: ViewMode, content: , id: 'viewMode' }] }, { modes: [{ mode: DrawPointMode, content: , id: 'drawPointMode', }] }, { modes: [ { mode: DrawLineStringMode, content: , id: 'drawLineMode' } ] }, { modes: [ { mode: DrawPolygonMode, content: , id: 'drawPolygonMode' }, { mode: DrawRectangleMode, content: , id: 'drawRectangleMode' }, { mode: DrawCircleFromCenterMode, content: , id: 'drawCircleMode' } ] }, { modes: [ { mode: MeasureDistanceMode, content: , id: 'measureDistanceMode' }, { mode: MeasureAngleMode, content: , id: 'measureAngleMode' }, { mode: MeasureAreaMode, content: , id: 'measureAreaMode' } ] }, { modes: [{ mode: ModifyMode, content: , id: 'editMode' }] }, { modes: [{ mode: TranslateMode, content: , id: 'moveMode' }] } ]; const isButtonEnabled = (id:string, options: ToolboxOptions) => !!Object.keys(options).find(key => `${id}Enabled` === key && options[key]) function ModeButton({ buttonConfig, mode, onClick }: any) { return ( ); } function ModeGroupButtons({ modeGroup, mode, onSetMode, options }: any) { const useOptions: ToolboxOptions = options; const [expanded, setExpanded] = React.useState(false); const { modes } = modeGroup; const mayShowMainButton = !!modes.find(m => isButtonEnabled(m.id, useOptions)); if(!mayShowMainButton){ return null; } let subTools = null; if (expanded) { subTools = ( {modes.map((buttonConfig, i) => { const mayShowCurrentButton = isButtonEnabled(buttonConfig.id, useOptions); if(!mayShowCurrentButton) return true; return { onSetMode(() => buttonConfig.mode); setExpanded(false); }} /> })} ); } // Get the button config if it is active otherwise, choose the first valid one that can be shown const buttonConfig = modes.find(m => m.mode === mode) || modes.find(m => isButtonEnabled(m.id, useOptions)); return ( {subTools} { onSetMode(() => buttonConfig.mode); setExpanded(true); }} /> ); } export function Toolbox({ mode, modeConfig, geoJson, onSetMode, onSetModeConfig, onSetGeoJson, onImport, options }: Props) { const [showConfig, setShowConfig] = React.useState(false); const [showImport, setShowImport] = React.useState(false); const [showExport, setShowExport] = React.useState(false); const [showClearConfirmation, setShowClearConfirmation] = React.useState(false); const useOptions = { ...defaultToolBoxOptions, ...(options || {}) }; const { settingsModeEnabled, importEnabled, exportEnabled, deleteEnabled } = useOptions; return ( <> {MODE_GROUPS.map((modeGroup, i) => ( ))} {/* */} {exportEnabled && } {importEnabled && } {settingsModeEnabled && ( {showConfig && ( {/* */} )} )} {deleteEnabled && {showClearConfirmation && ( )} } {/* zoom in and out */} {showImport && ( { onImport(imported); setShowImport(false); }} onClose={() => setShowImport(false)} /> )} {showExport && setShowExport(false)} />} ); }