{"version":3,"file":"editor.cjs","sources":["../../src/notes/editor.ts"],"sourcesContent":["import { createContext, useState, useContext, ComponentType } from \"react\";\nimport { ModelEditorProvider, useModelEditor, ColumnContext } from \"../context\";\nimport { EditableText } from \"@blueprintjs/core\";\nimport classNames from \"classnames\";\nimport h from \"../hyper\";\nimport { NoteData } from \"./types\";\nimport { ForeignObject } from \"../util\";\nimport { NoteLayoutContext, NoteRect } from \"./layout\";\nimport { NotePositioner, NoteConnector } from \"./connector\";\nimport Draggable from \"react-draggable\";\nimport { hasSpan } from \"./utils\";\nimport { ErrorBoundary } from \"@macrostrat/ui-components\";\nimport { Spec } from \"immutability-helper\";\n\nconst NoteEditorContext = createContext({ inEditMode: false });\n\ninterface NoteEditorProps {\n  note: NoteData;\n}\n\nconst NoteTextEditor = function (props: NoteEditorProps) {\n  const { updateModel } = useModelEditor();\n  const { note } = props;\n  return h(EditableText, {\n    multiline: true,\n    className: \"col-note-label note-editing\",\n    defaultValue: note.note,\n    isEditing: true,\n    onConfirm(newText) {\n      return updateModel({ note: { $set: newText } });\n    },\n  });\n};\n\ninterface NoteEditorProviderProps {\n  inEditMode: boolean;\n  noteEditor: ComponentType<NoteEditorProps>;\n  onUpdateNote?: (n: NoteData) => void;\n  onDeleteNote?: (n: NoteData) => void;\n  onCreateNote?: Function;\n  children?: React.ReactNode;\n}\n\nfunction NoteEditorProvider(props: NoteEditorProviderProps) {\n  let { children, inEditMode = false, noteEditor } = props;\n  const { notes } = useContext(NoteLayoutContext);\n\n  const [editingNote, setEditingNote] = useState(null);\n\n  const deleteNote = function () {\n    const val = editingNote;\n    setEditingNote(null);\n    return props.onDeleteNote?.(val);\n  };\n\n  const onCreateNote = function (pos) {\n    const { height, top_height } = pos;\n    const val = { height, top_height, note: null, symbol: null };\n    return setEditingNote(val);\n  };\n\n  const value = {\n    editingNote,\n    setEditingNote,\n    deleteNote,\n    inEditMode,\n    noteEditor,\n    onCreateNote,\n  };\n\n  const onConfirmChanges = function (n) {\n    if (n?.note == null && n == editingNote) {\n      console.log(\"No changes to note\");\n      return;\n    }\n    if (notes.includes(n)) {\n      return;\n    }\n    return props.onUpdateNote?.(n);\n  };\n\n  //# Model editor provider gives us a nice store\n  return h(NoteEditorContext.Provider, { value }, [\n    h(\n      ModelEditorProvider,\n      {\n        model: editingNote,\n        onDelete: deleteNote,\n        onConfirmChanges,\n        logUpdates: true,\n        alwaysConfirm: true,\n      },\n      children,\n    ),\n  ]);\n}\n\nconst NoteConnectorPath = function (props) {\n  const { d, offsetX, className } = props;\n  return h(\"path\", {\n    d,\n    className,\n    transform: `translate(${offsetX})`,\n    fill: \"transparent\",\n  });\n};\n\nconst EditableNoteConnector = function (props) {\n  const { notes, nodes, columnIndex, generatePath, createNodeForNote } =\n    useContext(NoteLayoutContext);\n  let { note, node, index } = props;\n  if (note.id != null) {\n    node = nodes[note.id];\n  }\n  if (node == null) {\n    node = createNodeForNote(note);\n  }\n  const x = columnIndex[note.id] * 5 || 0;\n\n  const d = generatePath(node, x);\n\n  return h([\n    h(NoteConnectorPath, {\n      className: \"note-connector\",\n      d,\n      offsetX: x,\n    }),\n    h(\n      ForeignObject,\n      {\n        width: 30,\n        x,\n        y: 0,\n        height: 1,\n        style: { overflowY: \"visible\" },\n      },\n      h(PositionEditorInner, { note }),\n    ),\n  ]);\n};\n\nconst PointHandle = function (props) {\n  let { height, size, className, ...rest } = props;\n  className = classNames(\"handle point-handle\", className);\n  if (size == null) {\n    size = 10;\n  }\n  return h(\n    Draggable,\n    {\n      position: { x: 0, y: height },\n      axis: \"y\",\n      ...rest,\n    },\n    h(\"div.handle\", {\n      style: {\n        height: size,\n        width: size,\n        marginLeft: -size / 2,\n        marginTop: -size / 2,\n        position: \"absolute\",\n      },\n      className,\n    }),\n  );\n};\n\nfunction PositionEditorInner(props) {\n  let { margin } = props;\n  if (margin == null) {\n    margin = 3;\n  }\n  const { scaleClamped: scale } = useContext(ColumnContext);\n  const ctx = useModelEditor();\n  if (ctx == null) {\n    return null;\n  }\n\n  const { updatedModel, editedModel } = ctx;\n\n  const note = editedModel ?? props.note;\n\n  if (note == null) {\n    return null;\n  }\n\n  const noteHasSpan = hasSpan(note);\n\n  const bottomHeight = scale(note.height);\n  let topHeight = bottomHeight;\n  let height = 0;\n  if (noteHasSpan) {\n    topHeight = scale(note.top_height);\n    height = Math.abs(topHeight - bottomHeight);\n  }\n\n  const moveEntireNote = function (e, data) {\n    const { y } = data;\n    // Set note height\n    const spec: Spec<any> = { height: { $set: scale.invert(y + height) } };\n    if (noteHasSpan) {\n      // Set note top height\n      spec.top_height = { $set: scale.invert(y) };\n    }\n    return updateModel(spec);\n  };\n\n  const moveTop = function (e, data) {\n    const spec = { top_height: { $set: scale.invert(data.y) } };\n    if (Math.abs(data.y - bottomHeight) < 2) {\n      spec.top_height = { $set: null };\n    }\n    return updateModel(spec);\n  };\n\n  const moveBottom = function (e, data) {\n    const spec: Spec<any> = { height: { $set: scale.invert(data.y) } };\n    if (Math.abs(data.y - topHeight) < 2) {\n      spec.top_height = { $set: null };\n    }\n    return updateModel(spec);\n  };\n\n  return h(\n    ErrorBoundary,\n    null,\n    h(\"div.position-editor\", [\n      h(\n        Draggable,\n        {\n          handle: \".handle\",\n          position: { x: 0, y: topHeight },\n          onDrag: moveEntireNote,\n          axis: \"y\",\n        },\n        h(\"div\", [\n          h(\"div.handle\", {\n            className: \"handle\",\n            style: {\n              height,\n              width: 2 * margin,\n              marginLeft: -margin,\n              marginTop: -margin,\n              position: \"absolute\",\n            },\n          }),\n        ]),\n      ),\n      h(PointHandle, {\n        height: noteHasSpan ? topHeight : topHeight - 15,\n        onDrag: moveTop,\n        className: classNames(\"top-handle\", {\n          \"add-span-handle\": !noteHasSpan,\n        }),\n        bounds: { bottom: bottomHeight },\n      }),\n      h(PointHandle, {\n        height: bottomHeight,\n        onDrag: moveBottom,\n        className: \"bottom-handle\",\n        bounds: noteHasSpan ? { top: topHeight } : null,\n      }),\n    ]),\n  );\n}\n\nfunction NoteEditorUnderlay() {\n  return h(NoteRect, {\n    style: { pointerEvents: \"none\" },\n    className: \"underlay\",\n  });\n}\n\nfunction NoteEditor(props) {\n  const { allowPositionEditing } = props;\n  const { noteEditor, setEditingNote } = useContext(NoteEditorContext) as any;\n  const { notes, nodes, elementHeights, createNodeForNote } =\n    useContext(NoteLayoutContext);\n  const { editedModel, model } = useModelEditor();\n  if (editedModel == null) {\n    return null;\n  }\n  const index = notes.indexOf(editedModel);\n  const { id: noteID } = editedModel;\n  let node = nodes[noteID] || createNodeForNote(editedModel);\n  const noteHeight = elementHeights[noteID] || 20;\n\n  if (editedModel.height != null) {\n    const newNode = createNodeForNote(editedModel);\n    // Set position of note to current position\n    newNode.currentPos = node.currentPos;\n\n    const pos = newNode.centerPos || newNode.idealPos;\n    const dy = pos - node.currentPos;\n    if (dy > 50) {\n      newNode.currentPos = pos - 50;\n    }\n    if (dy < -50) {\n      newNode.currentPos = pos + 50;\n    }\n    node = newNode;\n  }\n\n  const edited = editedModel === model;\n\n  return h(ErrorBoundary, [\n    h(\"g.note-editor.note\", [\n      h(NoteEditorUnderlay),\n      h.if(!allowPositionEditing)(NoteConnector, { note: editedModel }),\n      h.if(allowPositionEditing)(EditableNoteConnector, {\n        note: editedModel,\n        node,\n      }),\n      h(\n        NotePositioner,\n        {\n          offsetY: node.currentPos,\n          noteHeight,\n          onClick(evt) {\n            if (edited) {\n              setEditingNote(null);\n              evt.stopPropagation();\n            }\n          },\n        },\n        [\n          h(noteEditor, {\n            note: editedModel,\n            key: index,\n            focused: true,\n            edited,\n          }),\n        ],\n      ),\n    ]),\n  ]);\n}\n\nexport type { NoteData };\nexport { NoteEditorProvider, NoteEditorContext, NoteTextEditor, NoteEditor };\n"],"names":["createContext","updateModel","useModelEditor","h","EditableText","useContext","NoteLayoutContext","useState","ModelEditorProvider","index","ForeignObject","classNames","Draggable","ColumnContext","hasSpan","ErrorBoundary","NoteRect","NoteConnector","NotePositioner"],"mappings":";;;;;;;;;;;;;;;;;AAcA,MAAM,oBAAoBA,MAAAA,cAAc,EAAE,YAAY,OAAO;AAM7D,MAAM,iBAAiB,SAAU,OAAwB;AACvD,QAAM,EAAE,aAAAC,aAAAA,IAAgBC,2BAAA;AACxB,QAAM,EAAE,SAAS;AACjB,SAAOC,MAAEC,KAAAA,cAAc;AAAA,IACrB,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc,KAAK;AAAA,IACnB,WAAW;AAAA,IACX,UAAU,SAAS;AACjB,aAAOH,aAAY,EAAE,MAAM,EAAE,MAAM,QAAA,GAAW;AAAA,IAChD;AAAA,EAAA,CACD;AACH;AAWA,SAAS,mBAAmB,OAAgC;AAC1D,MAAI,EAAE,UAAU,aAAa,OAAO,eAAe;AACnD,QAAM,EAAE,MAAA,IAAUI,MAAAA,WAAWC,wBAAiB;AAE9C,QAAM,CAAC,aAAa,cAAc,IAAIC,MAAAA,SAAS,IAAI;AAEnD,QAAM,aAAa,WAAY;AAC7B,UAAM,MAAM;AACZ,mBAAe,IAAI;AACnB,WAAO,MAAM,eAAe,GAAG;AAAA,EACjC;AAEA,QAAM,eAAe,SAAU,KAAK;AAClC,UAAM,EAAE,QAAQ,WAAA,IAAe;AAC/B,UAAM,MAAM,EAAE,QAAQ,YAAY,MAAM,MAAM,QAAQ,KAAA;AACtD,WAAO,eAAe,GAAG;AAAA,EAC3B;AAEA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAGF,QAAM,mBAAmB,SAAU,GAAG;AACpC,QAAI,GAAG,QAAQ,QAAQ,KAAK,aAAa;AACvC,cAAQ,IAAI,oBAAoB;AAChC;AAAA,IACF;AACA,QAAI,MAAM,SAAS,CAAC,GAAG;AACrB;AAAA,IACF;AACA,WAAO,MAAM,eAAe,CAAC;AAAA,EAC/B;AAGA,SAAOJ,MAAE,kBAAkB,UAAU,EAAE,SAAS;AAAA,IAC9CA;AAAAA,MACEK,YAAAA;AAAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP,UAAU;AAAA,QACV;AAAA,QACA,YAAY;AAAA,QACZ,eAAe;AAAA,MAAA;AAAA,MAEjB;AAAA,IAAA;AAAA,EACF,CACD;AACH;AAEA,MAAM,oBAAoB,SAAU,OAAO;AACzC,QAAM,EAAE,GAAG,SAAS,UAAA,IAAc;AAClC,SAAOL,MAAE,QAAQ;AAAA,IACf;AAAA,IACA;AAAA,IACA,WAAW,aAAa,OAAO;AAAA,IAC/B,MAAM;AAAA,EAAA,CACP;AACH;AAEA,MAAM,wBAAwB,SAAU,OAAO;AAC7C,QAAM,EAAE,OAAO,OAAO,aAAa,cAAc,kBAAA,IAC/CE,MAAAA,WAAWC,wBAAiB;AAC9B,MAAI,EAAE,MAAM,MAAA,OAAMG,QAAA,IAAU;AAC5B,MAAI,KAAK,MAAM,MAAM;AACnB,WAAO,MAAM,KAAK,EAAE;AAAA,EACtB;AACA,MAAI,QAAQ,MAAM;AAChB,WAAO,kBAAkB,IAAI;AAAA,EAC/B;AACA,QAAM,IAAI,YAAY,KAAK,EAAE,IAAI,KAAK;AAEtC,QAAM,IAAI,aAAa,MAAM,CAAC;AAE9B,SAAON,MAAE;AAAA,IACPA,MAAE,mBAAmB;AAAA,MACnB,WAAW;AAAA,MACX;AAAA,MACA,SAAS;AAAA,IAAA,CACV;AAAA,IACDA;AAAAA,MACEO,MAAAA;AAAAA,MACA;AAAA,QACE,OAAO;AAAA,QACP;AAAA,QACA,GAAG;AAAA,QACH,QAAQ;AAAA,QACR,OAAO,EAAE,WAAW,UAAA;AAAA,MAAU;AAAA,MAEhCP,MAAE,qBAAqB,EAAE,KAAA,CAAM;AAAA,IAAA;AAAA,EACjC,CACD;AACH;AAEA,MAAM,cAAc,SAAU,OAAO;AACnC,MAAI,EAAE,QAAQ,MAAM,WAAW,GAAG,SAAS;AAC3C,cAAYQ,oBAAAA,QAAW,uBAAuB,SAAS;AACvD,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AACA,SAAOR;AAAAA,IACLS,mBAAAA;AAAAA,IACA;AAAA,MACE,UAAU,EAAE,GAAG,GAAG,GAAG,OAAA;AAAA,MACrB,MAAM;AAAA,MACN,GAAG;AAAA,IAAA;AAAA,IAELT,MAAE,cAAc;AAAA,MACd,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,YAAY,CAAC,OAAO;AAAA,QACpB,WAAW,CAAC,OAAO;AAAA,QACnB,UAAU;AAAA,MAAA;AAAA,MAEZ;AAAA,IAAA,CACD;AAAA,EAAA;AAEL;AAEA,SAAS,oBAAoB,OAAO;AAClC,MAAI,EAAE,WAAW;AACjB,MAAI,UAAU,MAAM;AAClB,aAAS;AAAA,EACX;AACA,QAAM,EAAE,cAAc,UAAUE,MAAAA,WAAWQ,OAAAA,aAAa;AACxD,QAAM,MAAMX,YAAAA,eAAA;AACZ,MAAI,OAAO,MAAM;AACf,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,cAAc,YAAA,IAAgB;AAEtC,QAAM,OAAO,eAAe,MAAM;AAElC,MAAI,QAAQ,MAAM;AAChB,WAAO;AAAA,EACT;AAEA,QAAM,cAAcY,MAAAA,QAAQ,IAAI;AAEhC,QAAM,eAAe,MAAM,KAAK,MAAM;AACtC,MAAI,YAAY;AAChB,MAAI,SAAS;AACb,MAAI,aAAa;AACf,gBAAY,MAAM,KAAK,UAAU;AACjC,aAAS,KAAK,IAAI,YAAY,YAAY;AAAA,EAC5C;AAEA,QAAM,iBAAiB,SAAU,GAAG,MAAM;AACxC,UAAM,EAAE,MAAM;AAEd,UAAM,OAAkB,EAAE,QAAQ,EAAE,MAAM,MAAM,OAAO,IAAI,MAAM,IAAE;AACnE,QAAI,aAAa;AAEf,WAAK,aAAa,EAAE,MAAM,MAAM,OAAO,CAAC,EAAA;AAAA,IAC1C;AACA,WAAO,YAAY,IAAI;AAAA,EACzB;AAEA,QAAM,UAAU,SAAU,GAAG,MAAM;AACjC,UAAM,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC,IAAE;AACxD,QAAI,KAAK,IAAI,KAAK,IAAI,YAAY,IAAI,GAAG;AACvC,WAAK,aAAa,EAAE,MAAM,KAAA;AAAA,IAC5B;AACA,WAAO,YAAY,IAAI;AAAA,EACzB;AAEA,QAAM,aAAa,SAAU,GAAG,MAAM;AACpC,UAAM,OAAkB,EAAE,QAAQ,EAAE,MAAM,MAAM,OAAO,KAAK,CAAC,IAAE;AAC/D,QAAI,KAAK,IAAI,KAAK,IAAI,SAAS,IAAI,GAAG;AACpC,WAAK,aAAa,EAAE,MAAM,KAAA;AAAA,IAC5B;AACA,WAAO,YAAY,IAAI;AAAA,EACzB;AAEA,SAAOX;AAAAA,IACLY,aAAAA;AAAAA,IACA;AAAA,IACAZ,MAAE,uBAAuB;AAAA,MACvBA;AAAAA,QACES,mBAAAA;AAAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,UAAU,EAAE,GAAG,GAAG,GAAG,UAAA;AAAA,UACrB,QAAQ;AAAA,UACR,MAAM;AAAA,QAAA;AAAA,QAERT,MAAE,OAAO;AAAA,UACPA,MAAE,cAAc;AAAA,YACd,WAAW;AAAA,YACX,OAAO;AAAA,cACL;AAAA,cACA,OAAO,IAAI;AAAA,cACX,YAAY,CAAC;AAAA,cACb,WAAW,CAAC;AAAA,cACZ,UAAU;AAAA,YAAA;AAAA,UACZ,CACD;AAAA,QAAA,CACF;AAAA,MAAA;AAAA,MAEHA,MAAE,aAAa;AAAA,QACb,QAAQ,cAAc,YAAY,YAAY;AAAA,QAC9C,QAAQ;AAAA,QACR,WAAWQ,oBAAAA,QAAW,cAAc;AAAA,UAClC,mBAAmB,CAAC;AAAA,QAAA,CACrB;AAAA,QACD,QAAQ,EAAE,QAAQ,aAAA;AAAA,MAAa,CAChC;AAAA,MACDR,MAAE,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,WAAW;AAAA,QACX,QAAQ,cAAc,EAAE,KAAK,cAAc;AAAA,MAAA,CAC5C;AAAA,IAAA,CACF;AAAA,EAAA;AAEL;AAEA,SAAS,qBAAqB;AAC5B,SAAOA,MAAEa,OAAAA,UAAU;AAAA,IACjB,OAAO,EAAE,eAAe,OAAA;AAAA,IACxB,WAAW;AAAA,EAAA,CACZ;AACH;AAEA,SAAS,WAAW,OAAO;AACzB,QAAM,EAAE,yBAAyB;AACjC,QAAM,EAAE,YAAY,mBAAmBX,MAAAA,WAAW,iBAAiB;AACnE,QAAM,EAAE,OAAO,OAAO,gBAAgB,kBAAA,IACpCA,MAAAA,WAAWC,wBAAiB;AAC9B,QAAM,EAAE,aAAa,MAAA,IAAUJ,2BAAA;AAC/B,MAAI,eAAe,MAAM;AACvB,WAAO;AAAA,EACT;AACA,QAAMO,SAAQ,MAAM,QAAQ,WAAW;AACvC,QAAM,EAAE,IAAI,OAAA,IAAW;AACvB,MAAI,OAAO,MAAM,MAAM,KAAK,kBAAkB,WAAW;AACzD,QAAM,aAAa,eAAe,MAAM,KAAK;AAE7C,MAAI,YAAY,UAAU,MAAM;AAC9B,UAAM,UAAU,kBAAkB,WAAW;AAE7C,YAAQ,aAAa,KAAK;AAE1B,UAAM,MAAM,QAAQ,aAAa,QAAQ;AACzC,UAAM,KAAK,MAAM,KAAK;AACtB,QAAI,KAAK,IAAI;AACX,cAAQ,aAAa,MAAM;AAAA,IAC7B;AACA,QAAI,KAAK,KAAK;AACZ,cAAQ,aAAa,MAAM;AAAA,IAC7B;AACA,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,gBAAgB;AAE/B,SAAON,MAAEY,aAAAA,eAAe;AAAA,IACtBZ,MAAE,sBAAsB;AAAA,MACtBA,MAAE,kBAAkB;AAAA,MACpBA,MAAE,GAAG,CAAC,oBAAoB,EAAEc,UAAAA,eAAe,EAAE,MAAM,aAAa;AAAA,MAChEd,MAAE,GAAG,oBAAoB,EAAE,uBAAuB;AAAA,QAChD,MAAM;AAAA,QACN;AAAA,MAAA,CACD;AAAA,MACDA;AAAAA,QACEe,UAAAA;AAAAA,QACA;AAAA,UACE,SAAS,KAAK;AAAA,UACd;AAAA,UACA,QAAQ,KAAK;AACX,gBAAI,QAAQ;AACV,6BAAe,IAAI;AACnB,kBAAI,gBAAA;AAAA,YACN;AAAA,UACF;AAAA,QAAA;AAAA,QAEF;AAAA,UACEf,MAAE,YAAY;AAAA,YACZ,MAAM;AAAA,YACN,KAAKM;AAAA,YACL,SAAS;AAAA,YACT;AAAA,UAAA,CACD;AAAA,QAAA;AAAA,MACH;AAAA,IACF,CACD;AAAA,EAAA,CACF;AACH;;;;;"}