@asup/context-menu 1.3.2 → 1.3.3

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/dist/cjs/main.css CHANGED
@@ -69,7 +69,6 @@
69
69
  z-index: 2;
70
70
  -webkit-font-smoothing: antialiased;
71
71
  -moz-osx-font-smoothing: grayscale;
72
- opacity: .5;
73
72
  background-color: #111418;
74
73
  border: 2px solid #111418;
75
74
  border-top-right-radius: 4px;
@@ -87,7 +86,11 @@
87
86
  box-shadow: 2px 2px 2px #40404080;
88
87
  }
89
88
 
90
- .low-menu:hover {
89
+ .low-menu.hidden {
90
+ opacity: 0;
91
+ }
92
+
93
+ .low-menu.visible, .low-menu:hover {
91
94
  opacity: 1;
92
95
  }
93
96
 
@@ -1 +1 @@
1
- {"mappings":"AAAA;;;;;;;;;;AAWA;;;;AAIA;;;;;;;;;;;;;AAaA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;AAIA;;;;;AAKA;;;;;AAKA;;;;AAIA;;;;;AAKA;;;;AChEA;;;;;;;;;;;;;;;;;;;;;;AAyBA;;;;AAIA;;;;;;;;;;;;;;AAcA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;;ACxDA;;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;AAYA;;;;AAIA;;;;;;;;;;AAUA;;;;;;;;;;;AAWA;;;;;AAKA;;;;;;;AAOA;;;;;AAKA;;;;;AAKA;;;;;;AAMA","sources":["src/components/ContextMenu.css","src/components/LowMenu.css","src/components/ContextWindow.css"],"sourcesContent":[".context-menu {\n position: absolute;\n visibility: hidden;\n border: 1px solid;\n border-color: rgb(17, 20, 24);\n border-radius: 8px;\n opacity: 1;\n background-color: rgb(251, 253, 246);\n z-index: 10000;\n}\n\n.context-menu.visible {\n visibility: inherit;\n}\n\n.context-menu-item {\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n min-width: 80px;\n height: 21px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.context-menu-item.disabled {\n background-color: rgba(0, 0, 0, 0.2);\n cursor: not-allowed;\n}\n\n.context-menu-item:first-child {\n margin-top: 4px;\n}\n\n.context-menu-item:last-child {\n margin-bottom: 4px;\n}\n\n.context-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.context-menu-item:hover:first-child {\n border-top-left-radius: 6px;\n border-top-right-radius: 6px;\n}\n\n.context-menu-item:hover:last-child {\n border-bottom-left-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n\n.context-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.context-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n\n.context-menu-item-label {\n flex-grow: 1;\n}\n",".low-menu {\n z-index: 2;\n position: absolute;\n top: 0;\n margin: 0px;\n border: 2px solid rgb(17, 20, 24);\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n background-color: rgb(17, 20, 24);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n font-size: 9pt;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 2px 2px 2px rgb(64, 64, 64, 0.5);\n opacity: 0.5;\n transition: opacity 0.3s linear;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n gap: 2px;\n row-gap: 2px;\n}\n\n.low-menu:hover {\n opacity: 1;\n}\n\n.low-menu-item {\n background-color: rgb(251, 253, 246);\n border: 0;\n border-radius: 4px;\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.low-menu-item.disabled {\n background-color: rgba(200, 200, 200);\n cursor: not-allowed;\n}\n\n.low-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.low-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.low-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n",".contextwindow {\n z-index: 2001;\n border: 1px black solid;\n margin: 0;\n padding: 4px;\n background-color: rgb(250, 250, 250);\n box-shadow: 6px 6px 6px rgb(64, 64, 64, 0.5);\n transition: opacity 0.25s linear;\n justify-content: flex-start;\n position: absolute;\n border-top-left-radius: 8px;\n border-top-right-radius: 8px;\n border-bottom-left-radius: 8px;\n resize: both;\n overflow: auto;\n}\n\n.contextwindow-title {\n border-bottom: 1px black dashed;\n padding-bottom: 4px;\n margin: 0 4px 3px 4px;\n height: 24px;\n max-height: 24px;\n cursor: grab;\n align-items: top;\n display: flex;\n width: calc(100% - 8px);\n}\n\n.contextwindow-title.moving {\n cursor: grabbing;\n}\n\n.contextwindow-title-text {\n font-size: 18px;\n font-weight: 600;\n display: inline-block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: calc(100% - 16px);\n}\n\n.contextwindow-title-close {\n display: inline-block;\n color: black;\n background-color: white;\n height: 16px;\n width: 16px;\n border-radius: 3px;\n margin-left: 2px;\n cursor: pointer;\n}\n\n.contextwindow-title-close:hover {\n background-color: black;\n color: white;\n}\n\n.contextwindow-body {\n overflow: auto;\n padding-bottom: 8px;\n margin-right: 4px;\n height: calc(100% - 40px);\n}\n\n.contextwindow-body::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-track {\n background: white;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb {\n background: lightgrey;\n border: none;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb:hover {\n background: grey;\n}\n"],"names":[],"version":3,"file":"main.css.map"}
1
+ {"mappings":"AAAA;;;;;;;;;;AAWA;;;;AAIA;;;;;;;;;;;;;AAaA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;AAIA;;;;;AAKA;;;;;AAKA;;;;AAIA;;;;;AAKA;;;;AChEA;;;;;;;;;;;;;;;;;;;;;AAwBA;;;;AAIA;;;;AAKA;;;;;;;;;;;;;;AAcA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;;AC5DA;;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;AAYA;;;;AAIA;;;;;;;;;;AAUA;;;;;;;;;;;AAWA;;;;;AAKA;;;;;;;AAOA;;;;;AAKA;;;;;AAKA;;;;;;AAMA","sources":["src/components/ContextMenu.css","src/components/LowMenu.css","src/components/ContextWindow.css"],"sourcesContent":[".context-menu {\n position: absolute;\n visibility: hidden;\n border: 1px solid;\n border-color: rgb(17, 20, 24);\n border-radius: 8px;\n opacity: 1;\n background-color: rgb(251, 253, 246);\n z-index: 10000;\n}\n\n.context-menu.visible {\n visibility: inherit;\n}\n\n.context-menu-item {\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n min-width: 80px;\n height: 21px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.context-menu-item.disabled {\n background-color: rgba(0, 0, 0, 0.2);\n cursor: not-allowed;\n}\n\n.context-menu-item:first-child {\n margin-top: 4px;\n}\n\n.context-menu-item:last-child {\n margin-bottom: 4px;\n}\n\n.context-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.context-menu-item:hover:first-child {\n border-top-left-radius: 6px;\n border-top-right-radius: 6px;\n}\n\n.context-menu-item:hover:last-child {\n border-bottom-left-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n\n.context-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.context-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n\n.context-menu-item-label {\n flex-grow: 1;\n}\n",".low-menu {\n z-index: 2;\n position: absolute;\n top: 0;\n margin: 0px;\n border: 2px solid rgb(17, 20, 24);\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n background-color: rgb(17, 20, 24);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n font-size: 9pt;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 2px 2px 2px rgb(64, 64, 64, 0.5);\n transition: opacity 0.3s linear;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n gap: 2px;\n row-gap: 2px;\n}\n\n.low-menu.hidden {\n opacity: 0;\n}\n\n.low-menu.visible,\n.low-menu:hover {\n opacity: 1;\n}\n\n.low-menu-item {\n background-color: rgb(251, 253, 246);\n border: 0;\n border-radius: 4px;\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.low-menu-item.disabled {\n background-color: rgba(200, 200, 200);\n cursor: not-allowed;\n}\n\n.low-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.low-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.low-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n",".contextwindow {\n z-index: 2001;\n border: 1px black solid;\n margin: 0;\n padding: 4px;\n background-color: rgb(250, 250, 250);\n box-shadow: 6px 6px 6px rgb(64, 64, 64, 0.5);\n transition: opacity 0.25s linear;\n justify-content: flex-start;\n position: absolute;\n border-top-left-radius: 8px;\n border-top-right-radius: 8px;\n border-bottom-left-radius: 8px;\n resize: both;\n overflow: auto;\n}\n\n.contextwindow-title {\n border-bottom: 1px black dashed;\n padding-bottom: 4px;\n margin: 0 4px 3px 4px;\n height: 24px;\n max-height: 24px;\n cursor: grab;\n align-items: top;\n display: flex;\n width: calc(100% - 8px);\n}\n\n.contextwindow-title.moving {\n cursor: grabbing;\n}\n\n.contextwindow-title-text {\n font-size: 18px;\n font-weight: 600;\n display: inline-block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: calc(100% - 16px);\n}\n\n.contextwindow-title-close {\n display: inline-block;\n color: black;\n background-color: white;\n height: 16px;\n width: 16px;\n border-radius: 3px;\n margin-left: 2px;\n cursor: pointer;\n}\n\n.contextwindow-title-close:hover {\n background-color: black;\n color: white;\n}\n\n.contextwindow-body {\n overflow: auto;\n padding-bottom: 8px;\n margin-right: 4px;\n height: calc(100% - 40px);\n}\n\n.contextwindow-body::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-track {\n background: white;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb {\n background: lightgrey;\n border: none;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb:hover {\n background: grey;\n}\n"],"names":[],"version":3,"file":"main.css.map"}
package/dist/cjs/main.js CHANGED
@@ -191,9 +191,9 @@ const $b34598671fff4a77$export$aafc28aea571c4bc = ({ entry: entry, target: targe
191
191
  $b34598671fff4a77$export$aafc28aea571c4bc.displayName = "LowMenuButton";
192
192
 
193
193
 
194
- const $10d1ee4e7fc9bbbd$export$49e8edc8ebca5f25 = ({ entries: entries, target: target })=>{
194
+ const $10d1ee4e7fc9bbbd$export$49e8edc8ebca5f25 = ({ entries: entries, target: target, visible: visible })=>{
195
195
  return /*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)("div", {
196
- className: "low-menu",
196
+ className: `low-menu ${visible ? "visible" : "hidden"}`,
197
197
  "aria-label": "Low context menu",
198
198
  children: entries.map((e, i)=>/*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)((0, $b34598671fff4a77$export$aafc28aea571c4bc), {
199
199
  entry: e,
@@ -216,6 +216,7 @@ const $3c568ee547c732c3$export$ed4f9641643dc7e4 = ({ children: children, menuIte
216
216
  const [menuVisible, setMenuVisible] = (0, $gTuX4$react.useState)(false);
217
217
  const [target, setTarget] = (0, $gTuX4$react.useState)(null);
218
218
  const [lowTarget, setLowTarget] = (0, $gTuX4$react.useState)(null);
219
+ const [lowMenuVisible, setLowMenuVisible] = (0, $gTuX4$react.useState)(false);
219
220
  // Show menu when context is requested
220
221
  const showMenu = (e)=>{
221
222
  const sel = window.getSelection();
@@ -248,6 +249,12 @@ const $3c568ee547c732c3$export$ed4f9641643dc7e4 = ({ children: children, menuIte
248
249
  onContextMenu: showLowMenu ? undefined : showMenu,
249
250
  className: "context-menu-handler",
250
251
  style: style,
252
+ onMouseEnter: ()=>{
253
+ showLowMenu && setLowMenuVisible(true);
254
+ },
255
+ onMouseLeave: ()=>{
256
+ showLowMenu && setLowMenuVisible(false);
257
+ },
251
258
  children: children
252
259
  }),
253
260
  menuVisible && !showLowMenu && /*#__PURE__*/ (0, $gTuX4$reactdom.createPortal)(/*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)("div", {
@@ -280,11 +287,11 @@ const $3c568ee547c732c3$export$ed4f9641643dc7e4 = ({ children: children, menuIte
280
287
  setLowTarget(null);
281
288
  },
282
289
  children: /*#__PURE__*/ (0, $gTuX4$reactjsxruntime.jsx)((0, $10d1ee4e7fc9bbbd$export$49e8edc8ebca5f25), {
290
+ visible: lowMenuVisible,
283
291
  entries: menuItems,
284
292
  target: lowTarget
285
293
  })
286
- }),
287
- " "
294
+ })
288
295
  ]
289
296
  });
290
297
  };
@@ -1 +1 @@
1
- {"mappings":"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","sources":["src/main.ts","src/components/index.ts","src/components/ContextMenuHandler.tsx","src/components/ContextMenu.tsx","src/components/ContextSubMenu.tsx","src/components/LowMenu.tsx","src/components/LowMenuButton.tsx","src/components/LowSubMenu.tsx","src/components/ContextWindow.tsx","src/components/ContextWindowStack.tsx","src/functions/chkPosition.ts"],"sourcesContent":["export * from \"./components\";\n","import { ContextMenuHandler } from \"./ContextMenuHandler\";\nimport { ContextWindow } from \"./ContextWindow\";\nimport { ContextWindowStack } from \"./ContextWindowStack\";\nimport { iMenuItem } from \"./interface\";\n\nexport { ContextMenuHandler, ContextWindow, ContextWindowStack };\nexport type { iMenuItem };\n","import { MouseEvent, useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport \"./ContextMenu.css\";\nimport { LowMenu } from \"./LowMenu\";\nimport { iMenuItem } from \"./interface\";\n\ninterface contextMenuHandlerProps {\n children: JSX.Element[] | JSX.Element;\n menuItems: iMenuItem[];\n showLowMenu?: boolean;\n lowMenuTarget?: Range | null;\n style?: React.CSSProperties;\n}\n\nexport const ContextMenuHandler = ({\n children,\n menuItems,\n showLowMenu = false,\n style = {\n height: \"fit-content\",\n width: \"fit-content\",\n },\n}: contextMenuHandlerProps): JSX.Element => {\n // Menu resources\n const divRef = useRef<HTMLDivElement | null>(null);\n const menuRef = useRef<HTMLDivElement | null>(null);\n const [menuXPos, setMenuXPos] = useState<number>(0);\n const [menuYPos, setMenuYPos] = useState<number>(0);\n const [menuVisible, setMenuVisible] = useState<boolean>(false);\n const [target, setTarget] = useState<Range | null>(null);\n const [lowTarget, setLowTarget] = useState<Range | null>(null);\n\n // Show menu when context is requested\n const showMenu = (e: MouseEvent<HTMLDivElement>) => {\n const sel = window.getSelection();\n setTarget(sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null);\n e.preventDefault();\n e.stopPropagation();\n setMenuVisible(true);\n setMenuXPos(e.pageX);\n setMenuYPos(e.pageY);\n };\n\n // Handle click off the menu\n const handleClick = useCallback((e: globalThis.MouseEvent) => {\n if (\n menuRef.current &&\n ((e.target instanceof Element && !menuRef.current?.contains(e.target)) ||\n !(e.target instanceof Element))\n ) {\n setMenuVisible(false);\n }\n }, []);\n\n // Update the document click handler\n useEffect(() => {\n if (menuVisible) document.addEventListener(\"mousedown\", handleClick);\n else document.removeEventListener(\"mousedown\", handleClick);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n };\n }, [handleClick, menuVisible]);\n\n return (\n <>\n <div\n onContextMenu={showLowMenu ? undefined : showMenu}\n className=\"context-menu-handler\"\n style={style}\n >\n {children}\n </div>\n {menuVisible &&\n !showLowMenu &&\n createPortal(\n <div\n style={{ position: \"absolute\", top: 0, left: 0 }}\n ref={divRef}\n >\n <ContextMenu\n visible={true}\n ref={menuRef}\n entries={menuItems}\n xPos={menuXPos}\n yPos={menuYPos}\n target={target}\n toClose={() => setMenuVisible(false)}\n />\n </div>,\n document.body,\n )}\n {showLowMenu && (\n <div\n style={{ position: \"relative\" }}\n onMouseEnter={() => {\n const sel = window.getSelection();\n const lowSel = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n setLowTarget(lowSel);\n }}\n onMouseLeave={() => {\n setLowTarget(null);\n }}\n >\n <LowMenu\n entries={menuItems}\n target={lowTarget}\n />\n </div>\n )}{\" \"}\n </>\n );\n};\n\nContextMenuHandler.displayName = \"ContextMenuHandler\";\n","import React from \"react\";\nimport { ContextSubMenu } from \"./ContextSubMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface contextMenuProps {\n visible: boolean;\n entries: iMenuItem[];\n target: Range | null;\n xPos: number;\n yPos: number;\n toClose: () => void;\n}\n\nexport const ContextMenu = React.forwardRef<HTMLDivElement, contextMenuProps>(\n ({ visible, entries, target, xPos, yPos, toClose }, ref): JSX.Element => {\n ContextMenu.displayName = \"ContextMenu\";\n\n return (\n <div\n ref={ref}\n className={`context-menu${visible ? \" visible\" : \"\"}`}\n style={{\n top: `${yPos}px`,\n left: `${xPos}px`,\n }}\n onContextMenuCapture={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n {entries.map((entry, i) => (\n <div\n key={i}\n className={`context-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n >\n <span\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n className=\"context-menu-item-label\"\n onMouseDownCapture={(ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n !entry.disabled && toClose();\n }}\n >\n {entry.label}\n </span>\n {entry.group && (\n <ContextSubMenu\n toClose={toClose}\n entries={entry.group}\n target={target}\n />\n )}\n </div>\n ))}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface ContextSubMenuProps {\n entries: iMenuItem[];\n target: Range | null;\n toClose: () => void;\n lowMenu?: boolean;\n}\n\nexport const ContextSubMenu = ({ entries, target, toClose }: ContextSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n\n return (\n <span\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entries}\n target={target}\n xPos={14}\n yPos={-21}\n toClose={toClose}\n />\n </div>\n </span>\n );\n};\n\nContextSubMenu.displayName = \"ContextSubMenu\";\n","import { iMenuItem } from \"./interface\";\nimport \"./LowMenu.css\";\nimport { LowMenuButton } from \"./LowMenuButton\";\n\ninterface LowMenuProps {\n entries: iMenuItem[];\n target: Range | null;\n}\n\nexport const LowMenu = ({ entries, target }: LowMenuProps): JSX.Element => {\n return (\n <div\n className=\"low-menu\"\n aria-label=\"Low context menu\"\n >\n {entries.map((e, i) => (\n <LowMenuButton\n key={i}\n entry={e}\n target={target}\n />\n ))}\n </div>\n );\n};\n\nLowMenu.displayName = \"LowMenu\";\n","import { LowSubMenu } from \"./LowSubMenu\";\nimport { iMenuItem } from \"./interface\";\n\ninterface LowMenuButtonProps {\n entry: iMenuItem;\n target: Range | null;\n}\nexport const LowMenuButton = ({ entry, target }: LowMenuButtonProps) => {\n return (\n <div\n className={`low-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n }}\n >\n <span className=\"low-menu-item-label\">{entry.label}</span>\n {entry.group && (\n <LowSubMenu\n entry={entry}\n target={target}\n />\n )}\n </div>\n );\n};\n\nLowMenuButton.displayName = \"LowMenuButton\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface LowSubMenuProps {\n entry: iMenuItem;\n target: Range | null;\n lowMenu?: boolean;\n}\n\nexport const LowSubMenu = ({ entry, target }: LowSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n if (!entry.group || entry.group.length === 0) return <></>;\n return (\n <span\n aria-label={`Sub menu for ${entry.label}`}\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entry.group}\n target={target}\n xPos={14}\n yPos={entry.group.length * -21 - 8}\n toClose={() => setVisible(false)}\n />\n </div>\n </span>\n );\n};\n\nLowSubMenu.displayName = \"LowSubMenu\";\n","import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport \"./ContextWindow.css\";\nimport { ContextWindowStackContext } from \"./ContextWindowStack\";\nimport { chkPosition } from \"../functions/chkPosition\";\n\ninterface ContextWindowProps {\n id: string;\n visible: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n title: string;\n style?: React.CSSProperties;\n children: JSX.Element[] | JSX.Element | string;\n}\n\nexport const ContextWindow = ({\n id,\n visible,\n title,\n style,\n children,\n onOpen,\n onClose,\n}: ContextWindowProps): JSX.Element => {\n const windowStack = useContext(ContextWindowStackContext);\n const windowId = useRef<number | null>(null);\n const divRef = useRef<HTMLDivElement | null>(null);\n const windowRef = useRef<HTMLDivElement | null>(null);\n const [windowVisible, setWindowVisible] = useState<boolean>(false);\n const zIndex = useMemo(() => {\n return windowStack?.currentWindows.find((w) => w.windowId === windowId.current)?.zIndex ?? 1;\n }, [windowStack?.currentWindows]);\n\n // Position\n const windowPos = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n const [moving, setMoving] = useState<boolean>(false);\n\n const move = useCallback((x: number, y: number) => {\n if (windowRef.current && windowPos.current) {\n const window = windowRef.current;\n const pos = windowPos.current;\n pos.x += x;\n pos.y += y;\n window.style.transform = `translate(${pos.x}px, ${pos.y}px)`;\n }\n }, []);\n\n const checkPosition = useCallback(() => {\n const chkPos = chkPosition(windowRef);\n move(chkPos.translateX, chkPos.translateY);\n }, [move]);\n\n const mouseMove = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n move(e.movementX, e.movementY);\n },\n [move],\n );\n\n const mouseUp = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setMoving(false);\n checkPosition();\n document.removeEventListener(\"mousemove\", mouseMove);\n document.removeEventListener(\"mouseup\", mouseUp);\n window.removeEventListener(\"resize\", checkPosition);\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"auto\";\n },\n [checkPosition, mouseMove],\n );\n\n // Update visibility\n useEffect(() => {\n if (windowStack) {\n if (visible && !windowVisible) {\n if (!windowId.current) {\n const maxWindowId = Math.max(0, ...windowStack.currentWindows.map((w) => w.windowId));\n windowId.current = maxWindowId + 1;\n }\n windowStack.pushToTop(windowId.current);\n setWindowVisible(visible);\n onOpen && onOpen();\n // Get starting position\n if (divRef.current && windowRef.current) {\n const parentPos = divRef.current.getBoundingClientRect();\n const pos = windowRef.current.getBoundingClientRect();\n const windowHeight = pos.bottom - pos.top;\n windowRef.current.style.left = `${parentPos.left}px`;\n windowRef.current.style.top = `${\n parentPos.bottom + windowHeight < window.innerHeight\n ? parentPos.bottom\n : Math.max(0, parentPos.top - windowHeight)\n }px`;\n windowRef.current.style.transform = \"\";\n windowPos.current = { x: 0, y: 0 };\n }\n checkPosition();\n } else if (windowId.current && !visible && windowVisible) {\n setWindowVisible(false);\n }\n }\n }, [checkPosition, onOpen, visible, windowStack, windowVisible]);\n\n return (\n <div\n className=\"contextwindow-anchor\"\n ref={divRef}\n >\n {windowStack &&\n createPortal(\n <div\n id={id}\n className=\"contextwindow\"\n style={{\n ...style,\n opacity: moving ? 0.8 : windowVisible ? 1 : 0,\n visibility: windowVisible ? \"visible\" : \"hidden\",\n zIndex: zIndex ?? 1,\n minHeight: style?.minHeight ?? \"150px\",\n minWidth: style?.minWidth ?? \"200px\",\n maxHeight: style?.maxHeight ?? \"1000px\",\n maxWidth: style?.maxWidth ?? \"1000px\",\n }}\n onClickCapture={() => {\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n }}\n ref={windowRef}\n >\n <div\n className={`contextwindow-title ${moving ? \"moving\" : \"\"}`}\n onMouseDown={(e: React.MouseEvent) => {\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"none\";\n setMoving(true);\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n document.addEventListener(\"mouseup\", mouseUp);\n document.addEventListener(\"mousemove\", mouseMove);\n window.addEventListener(\"resize\", () => checkPosition());\n }}\n >\n <div className=\"contextwindow-title-text\">{title}</div>\n <div className=\"contextwindow-title-close\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n aria-label=\"Close window\"\n onClick={onClose}\n >\n <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n </div>\n </div>\n <div className=\"contextwindow-body\">\n <div>{children}</div>\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n};\n\nContextWindow.displayName = \"ContextWindow\";\n","import { createContext, useState } from \"react\";\n\nexport interface ContextWindowZIndex {\n windowId: number;\n zIndex: number;\n}\n\nexport interface ContextWindowStackContextProps {\n currentWindows: ContextWindowZIndex[];\n pushToTop: (ret: number) => void;\n}\n\nexport const ContextWindowStackContext = createContext<ContextWindowStackContextProps | null>(null);\n\ninterface ContextWindowStackProps {\n id?: string;\n minZIndex?: number;\n children?: JSX.Element[] | JSX.Element;\n}\n\nconst pushToTop = (\n windowId: number,\n minZIndex: number,\n windowList: ContextWindowZIndex[],\n setWindowList: (ret: ContextWindowZIndex[]) => void,\n) => {\n const otherWindows = windowList\n .filter((w) => w.windowId !== windowId)\n .map((w, i) => ({ windowId: w.windowId, zIndex: minZIndex + i }));\n setWindowList([...otherWindows, { windowId, zIndex: minZIndex + otherWindows.length }]);\n};\n\nexport const ContextWindowStack = ({\n minZIndex = 1000,\n children,\n}: ContextWindowStackProps): JSX.Element => {\n const [currentWindows, setCurrentWindows] = useState<ContextWindowZIndex[]>([]);\n\n return (\n <ContextWindowStackContext.Provider\n value={{\n currentWindows: currentWindows.map((w) => ({\n windowId: w.windowId,\n zIndex: minZIndex + w.zIndex,\n })),\n pushToTop: (ret: number) => pushToTop(ret, minZIndex, currentWindows, setCurrentWindows),\n }}\n >\n {children}\n </ContextWindowStackContext.Provider>\n );\n};\n\nContextWindowStack.displayName = \"ContextWindowStack\";\n","import { RefObject } from \"react\";\n\n/**\n * Check that an existing div is inside the viewport\n * @param divRef Check div is inside view port, and return n\n * @returns \\{ translateX, translateY \\} Amount to move on X and Y axis\n */\nexport const chkPosition = (\n divRef: RefObject<HTMLDivElement>,\n): { translateX: number; translateY: number } => {\n if (!divRef.current) {\n return { translateX: 0, translateY: 0 };\n } else {\n const innerBounce = 16;\n const posn = divRef.current.getBoundingClientRect();\n let translateX = 0;\n if (posn.left < innerBounce) {\n translateX = -posn.left + innerBounce;\n } else if (posn.right > window.innerWidth) {\n translateX = Math.max(-posn.left + innerBounce, window.innerWidth - posn.right - innerBounce);\n }\n let translateY = 0;\n if (posn.top < innerBounce) {\n translateY = -posn.top + innerBounce;\n } else if (posn.bottom > window.innerHeight) {\n translateY = Math.max(\n -posn.top + innerBounce,\n window.innerHeight - posn.bottom - innerBounce,\n );\n }\n return { translateX, translateY };\n }\n};\n"],"names":[],"version":3,"file":"main.js.map"}
1
+ {"mappings":"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","sources":["src/main.ts","src/components/index.ts","src/components/ContextMenuHandler.tsx","src/components/ContextMenu.tsx","src/components/ContextSubMenu.tsx","src/components/LowMenu.tsx","src/components/LowMenuButton.tsx","src/components/LowSubMenu.tsx","src/components/ContextWindow.tsx","src/components/ContextWindowStack.tsx","src/functions/chkPosition.ts"],"sourcesContent":["export * from \"./components\";\n","import { ContextMenuHandler } from \"./ContextMenuHandler\";\nimport { ContextWindow } from \"./ContextWindow\";\nimport { ContextWindowStack } from \"./ContextWindowStack\";\nimport { MenuItem } from \"./interface\";\n\nexport { ContextMenuHandler, ContextWindow, ContextWindowStack };\nexport type { MenuItem as iMenuItem };\n","import { MouseEvent, useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport \"./ContextMenu.css\";\nimport { LowMenu } from \"./LowMenu\";\nimport { MenuItem } from \"./interface\";\n\ninterface contextMenuHandlerProps {\n children: JSX.Element[] | JSX.Element;\n menuItems: MenuItem[];\n showLowMenu?: boolean;\n lowMenuTarget?: Range | null;\n style?: React.CSSProperties;\n}\n\nexport const ContextMenuHandler = ({\n children,\n menuItems,\n showLowMenu = false,\n style = {\n height: \"fit-content\",\n width: \"fit-content\",\n },\n}: contextMenuHandlerProps): JSX.Element => {\n // Menu resources\n const divRef = useRef<HTMLDivElement | null>(null);\n const menuRef = useRef<HTMLDivElement | null>(null);\n const [menuXPos, setMenuXPos] = useState<number>(0);\n const [menuYPos, setMenuYPos] = useState<number>(0);\n const [menuVisible, setMenuVisible] = useState<boolean>(false);\n const [target, setTarget] = useState<Range | null>(null);\n const [lowTarget, setLowTarget] = useState<Range | null>(null);\n const [lowMenuVisible, setLowMenuVisible] = useState<boolean>(false);\n\n // Show menu when context is requested\n const showMenu = (e: MouseEvent<HTMLDivElement>) => {\n const sel = window.getSelection();\n setTarget(sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null);\n e.preventDefault();\n e.stopPropagation();\n setMenuVisible(true);\n setMenuXPos(e.pageX);\n setMenuYPos(e.pageY);\n };\n\n // Handle click off the menu\n const handleClick = useCallback((e: globalThis.MouseEvent) => {\n if (\n menuRef.current &&\n ((e.target instanceof Element && !menuRef.current?.contains(e.target)) ||\n !(e.target instanceof Element))\n ) {\n setMenuVisible(false);\n }\n }, []);\n\n // Update the document click handler\n useEffect(() => {\n if (menuVisible) document.addEventListener(\"mousedown\", handleClick);\n else document.removeEventListener(\"mousedown\", handleClick);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n };\n }, [handleClick, menuVisible]);\n\n return (\n <>\n <div\n onContextMenu={showLowMenu ? undefined : showMenu}\n className=\"context-menu-handler\"\n style={style}\n onMouseEnter={() => {\n showLowMenu && setLowMenuVisible(true);\n }}\n onMouseLeave={() => {\n showLowMenu && setLowMenuVisible(false);\n }}\n >\n {children}\n </div>\n {menuVisible &&\n !showLowMenu &&\n createPortal(\n <div\n style={{ position: \"absolute\", top: 0, left: 0 }}\n ref={divRef}\n >\n <ContextMenu\n visible={true}\n ref={menuRef}\n entries={menuItems}\n xPos={menuXPos}\n yPos={menuYPos}\n target={target}\n toClose={() => setMenuVisible(false)}\n />\n </div>,\n document.body,\n )}\n {showLowMenu && (\n <div\n style={{ position: \"relative\" }}\n onMouseEnter={() => {\n const sel = window.getSelection();\n const lowSel = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n setLowTarget(lowSel);\n }}\n onMouseLeave={() => {\n setLowTarget(null);\n }}\n >\n <LowMenu\n visible={lowMenuVisible}\n entries={menuItems}\n target={lowTarget}\n />\n </div>\n )}\n </>\n );\n};\n\nContextMenuHandler.displayName = \"ContextMenuHandler\";\n","import React from \"react\";\nimport { ContextSubMenu } from \"./ContextSubMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface contextMenuProps {\n visible: boolean;\n entries: MenuItem[];\n target: Range | null;\n xPos: number;\n yPos: number;\n toClose: () => void;\n}\n\nexport const ContextMenu = React.forwardRef<HTMLDivElement, contextMenuProps>(\n ({ visible, entries, target, xPos, yPos, toClose }, ref): JSX.Element => {\n ContextMenu.displayName = \"ContextMenu\";\n\n return (\n <div\n ref={ref}\n className={`context-menu${visible ? \" visible\" : \"\"}`}\n style={{\n top: `${yPos}px`,\n left: `${xPos}px`,\n }}\n onContextMenuCapture={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n {entries.map((entry, i) => (\n <div\n key={i}\n className={`context-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n >\n <span\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n className=\"context-menu-item-label\"\n onMouseDownCapture={(ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n !entry.disabled && toClose();\n }}\n >\n {entry.label}\n </span>\n {entry.group && (\n <ContextSubMenu\n toClose={toClose}\n entries={entry.group}\n target={target}\n />\n )}\n </div>\n ))}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface ContextSubMenuProps {\n entries: MenuItem[];\n target: Range | null;\n toClose: () => void;\n lowMenu?: boolean;\n}\n\nexport const ContextSubMenu = ({ entries, target, toClose }: ContextSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n\n return (\n <span\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entries}\n target={target}\n xPos={14}\n yPos={-21}\n toClose={toClose}\n />\n </div>\n </span>\n );\n};\n\nContextSubMenu.displayName = \"ContextSubMenu\";\n","import { MenuItem } from \"./interface\";\nimport \"./LowMenu.css\";\nimport { LowMenuButton } from \"./LowMenuButton\";\n\ninterface LowMenuProps {\n entries: MenuItem[];\n target: Range | null;\n visible: boolean;\n}\n\nexport const LowMenu = ({ entries, target, visible }: LowMenuProps): JSX.Element => {\n return (\n <div\n className={`low-menu ${visible ? \"visible\" : \"hidden\"}`}\n aria-label=\"Low context menu\"\n >\n {entries.map((e, i) => (\n <LowMenuButton\n key={i}\n entry={e}\n target={target}\n />\n ))}\n </div>\n );\n};\n\nLowMenu.displayName = \"LowMenu\";\n","import { LowSubMenu } from \"./LowSubMenu\";\nimport { MenuItem } from \"./interface\";\n\ninterface LowMenuButtonProps {\n entry: MenuItem;\n target: Range | null;\n}\nexport const LowMenuButton = ({ entry, target }: LowMenuButtonProps) => {\n return (\n <div\n className={`low-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n }}\n >\n <span className=\"low-menu-item-label\">{entry.label}</span>\n {entry.group && (\n <LowSubMenu\n entry={entry}\n target={target}\n />\n )}\n </div>\n );\n};\n\nLowMenuButton.displayName = \"LowMenuButton\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface LowSubMenuProps {\n entry: MenuItem;\n target: Range | null;\n lowMenu?: boolean;\n}\n\nexport const LowSubMenu = ({ entry, target }: LowSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n if (!entry.group || entry.group.length === 0) return <></>;\n return (\n <span\n aria-label={`Sub menu for ${entry.label}`}\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entry.group}\n target={target}\n xPos={14}\n yPos={entry.group.length * -21 - 8}\n toClose={() => setVisible(false)}\n />\n </div>\n </span>\n );\n};\n\nLowSubMenu.displayName = \"LowSubMenu\";\n","import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport \"./ContextWindow.css\";\nimport { ContextWindowStackContext } from \"./ContextWindowStack\";\nimport { chkPosition } from \"../functions/chkPosition\";\n\ninterface ContextWindowProps {\n id: string;\n visible: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n title: string;\n style?: React.CSSProperties;\n children: JSX.Element[] | JSX.Element | string;\n}\n\nexport const ContextWindow = ({\n id,\n visible,\n title,\n style,\n children,\n onOpen,\n onClose,\n}: ContextWindowProps): JSX.Element => {\n const windowStack = useContext(ContextWindowStackContext);\n const windowId = useRef<number | null>(null);\n const divRef = useRef<HTMLDivElement | null>(null);\n const windowRef = useRef<HTMLDivElement | null>(null);\n const [windowVisible, setWindowVisible] = useState<boolean>(false);\n const zIndex = useMemo(() => {\n return windowStack?.currentWindows.find((w) => w.windowId === windowId.current)?.zIndex ?? 1;\n }, [windowStack?.currentWindows]);\n\n // Position\n const windowPos = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n const [moving, setMoving] = useState<boolean>(false);\n\n const move = useCallback((x: number, y: number) => {\n if (windowRef.current && windowPos.current) {\n const window = windowRef.current;\n const pos = windowPos.current;\n pos.x += x;\n pos.y += y;\n window.style.transform = `translate(${pos.x}px, ${pos.y}px)`;\n }\n }, []);\n\n const checkPosition = useCallback(() => {\n const chkPos = chkPosition(windowRef);\n move(chkPos.translateX, chkPos.translateY);\n }, [move]);\n\n const mouseMove = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n move(e.movementX, e.movementY);\n },\n [move],\n );\n\n const mouseUp = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setMoving(false);\n checkPosition();\n document.removeEventListener(\"mousemove\", mouseMove);\n document.removeEventListener(\"mouseup\", mouseUp);\n window.removeEventListener(\"resize\", checkPosition);\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"auto\";\n },\n [checkPosition, mouseMove],\n );\n\n // Update visibility\n useEffect(() => {\n if (windowStack) {\n if (visible && !windowVisible) {\n if (!windowId.current) {\n const maxWindowId = Math.max(0, ...windowStack.currentWindows.map((w) => w.windowId));\n windowId.current = maxWindowId + 1;\n }\n windowStack.pushToTop(windowId.current);\n setWindowVisible(visible);\n onOpen && onOpen();\n // Get starting position\n if (divRef.current && windowRef.current) {\n const parentPos = divRef.current.getBoundingClientRect();\n const pos = windowRef.current.getBoundingClientRect();\n const windowHeight = pos.bottom - pos.top;\n windowRef.current.style.left = `${parentPos.left}px`;\n windowRef.current.style.top = `${\n parentPos.bottom + windowHeight < window.innerHeight\n ? parentPos.bottom\n : Math.max(0, parentPos.top - windowHeight)\n }px`;\n windowRef.current.style.transform = \"\";\n windowPos.current = { x: 0, y: 0 };\n }\n checkPosition();\n } else if (windowId.current && !visible && windowVisible) {\n setWindowVisible(false);\n }\n }\n }, [checkPosition, onOpen, visible, windowStack, windowVisible]);\n\n return (\n <div\n className=\"contextwindow-anchor\"\n ref={divRef}\n >\n {windowStack &&\n createPortal(\n <div\n id={id}\n className=\"contextwindow\"\n style={{\n ...style,\n opacity: moving ? 0.8 : windowVisible ? 1 : 0,\n visibility: windowVisible ? \"visible\" : \"hidden\",\n zIndex: zIndex ?? 1,\n minHeight: style?.minHeight ?? \"150px\",\n minWidth: style?.minWidth ?? \"200px\",\n maxHeight: style?.maxHeight ?? \"1000px\",\n maxWidth: style?.maxWidth ?? \"1000px\",\n }}\n onClickCapture={() => {\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n }}\n ref={windowRef}\n >\n <div\n className={`contextwindow-title ${moving ? \"moving\" : \"\"}`}\n onMouseDown={(e: React.MouseEvent) => {\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"none\";\n setMoving(true);\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n document.addEventListener(\"mouseup\", mouseUp);\n document.addEventListener(\"mousemove\", mouseMove);\n window.addEventListener(\"resize\", () => checkPosition());\n }}\n >\n <div className=\"contextwindow-title-text\">{title}</div>\n <div className=\"contextwindow-title-close\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n aria-label=\"Close window\"\n onClick={onClose}\n >\n <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n </div>\n </div>\n <div className=\"contextwindow-body\">\n <div>{children}</div>\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n};\n\nContextWindow.displayName = \"ContextWindow\";\n","import { createContext, useState } from \"react\";\n\nexport interface ContextWindowZIndex {\n windowId: number;\n zIndex: number;\n}\n\nexport interface ContextWindowStackContextProps {\n currentWindows: ContextWindowZIndex[];\n pushToTop: (ret: number) => void;\n}\n\nexport const ContextWindowStackContext = createContext<ContextWindowStackContextProps | null>(null);\n\ninterface ContextWindowStackProps {\n id?: string;\n minZIndex?: number;\n children?: JSX.Element[] | JSX.Element;\n}\n\nconst pushToTop = (\n windowId: number,\n minZIndex: number,\n windowList: ContextWindowZIndex[],\n setWindowList: (ret: ContextWindowZIndex[]) => void,\n) => {\n const otherWindows = windowList\n .filter((w) => w.windowId !== windowId)\n .map((w, i) => ({ windowId: w.windowId, zIndex: minZIndex + i }));\n setWindowList([...otherWindows, { windowId, zIndex: minZIndex + otherWindows.length }]);\n};\n\nexport const ContextWindowStack = ({\n minZIndex = 1000,\n children,\n}: ContextWindowStackProps): JSX.Element => {\n const [currentWindows, setCurrentWindows] = useState<ContextWindowZIndex[]>([]);\n\n return (\n <ContextWindowStackContext.Provider\n value={{\n currentWindows: currentWindows.map((w) => ({\n windowId: w.windowId,\n zIndex: minZIndex + w.zIndex,\n })),\n pushToTop: (ret: number) => pushToTop(ret, minZIndex, currentWindows, setCurrentWindows),\n }}\n >\n {children}\n </ContextWindowStackContext.Provider>\n );\n};\n\nContextWindowStack.displayName = \"ContextWindowStack\";\n","import { RefObject } from \"react\";\n\n/**\n * Check that an existing div is inside the viewport\n * @param divRef Check div is inside view port, and return n\n * @returns \\{ translateX, translateY \\} Amount to move on X and Y axis\n */\nexport const chkPosition = (\n divRef: RefObject<HTMLDivElement>,\n): { translateX: number; translateY: number } => {\n if (!divRef.current) {\n return { translateX: 0, translateY: 0 };\n } else {\n const innerBounce = 16;\n const posn = divRef.current.getBoundingClientRect();\n let translateX = 0;\n if (posn.left < innerBounce) {\n translateX = -posn.left + innerBounce;\n } else if (posn.right > window.innerWidth) {\n translateX = Math.max(-posn.left + innerBounce, window.innerWidth - posn.right - innerBounce);\n }\n let translateY = 0;\n if (posn.top < innerBounce) {\n translateY = -posn.top + innerBounce;\n } else if (posn.bottom > window.innerHeight) {\n translateY = Math.max(\n -posn.top + innerBounce,\n window.innerHeight - posn.bottom - innerBounce,\n );\n }\n return { translateX, translateY };\n }\n};\n"],"names":[],"version":3,"file":"main.js.map"}
@@ -1,13 +1,13 @@
1
1
  import React from "react";
2
- export interface iMenuItem {
2
+ interface MenuItem {
3
3
  label: string | JSX.Element;
4
4
  disabled?: boolean;
5
5
  action?: (target?: Range | null) => void;
6
- group?: iMenuItem[];
6
+ group?: MenuItem[];
7
7
  }
8
8
  interface contextMenuHandlerProps {
9
9
  children: JSX.Element[] | JSX.Element;
10
- menuItems: iMenuItem[];
10
+ menuItems: MenuItem[];
11
11
  showLowMenu?: boolean;
12
12
  lowMenuTarget?: Range | null;
13
13
  style?: React.CSSProperties;
@@ -1 +1 @@
1
- {"mappings":";AAAA;IACE,KAAK,EAAE,MAAM,GAAG,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,SAAS,EAAE,CAAC;CACrB;AMED;IACE,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC;IACtC,SAAS,EAAE,SAAS,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;CAC7B;AAED,OAAO,MAAM;mDAQV,uBAAuB,GAAG,WAAW;;CAyFvC,CAAC;AClGF;IACE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC;CACxC;AAcD,OAAO,MAAM;+BAGV,uBAAuB,GAAG,WAAW;;CAgBvC,CAAC;AE7CF;IACE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;IAC5B,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,GAAG,MAAM,CAAC;CAChD;AAED,OAAO,MAAM;gEAQV,kBAAkB,GAAG,WAAW;;CAiJlC,CAAC","sources":["src/src/components/interface.ts","src/src/components/ContextSubMenu.tsx","src/src/components/ContextMenu.tsx","src/src/components/LowSubMenu.tsx","src/src/components/LowMenuButton.tsx","src/src/components/LowMenu.tsx","src/src/components/ContextMenuHandler.tsx","src/src/components/ContextWindowStack.tsx","src/src/functions/chkPosition.ts","src/src/components/ContextWindow.tsx","src/src/components/index.ts","src/src/main.ts","src/main.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,"export * from \"./components\";\n"],"names":[],"version":3,"file":"context-menu.d.ts.map"}
1
+ {"mappings":";AAAA;IACE,KAAK,EAAE,MAAM,GAAG,IAAI,OAAO,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,QAAQ,EAAE,CAAC;CACpB;AMED;IACE,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC;IACtC,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;CAC7B;AAED,OAAO,MAAM;mDAQV,uBAAuB,GAAG,WAAW;;CAiGvC,CAAC;AC1GF;IACE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,CAAC;CACxC;AAcD,OAAO,MAAM;+BAGV,uBAAuB,GAAG,WAAW;;CAgBvC,CAAC;AE7CF;IACE,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,aAAa,CAAC;IAC5B,QAAQ,EAAE,IAAI,OAAO,EAAE,GAAG,IAAI,OAAO,GAAG,MAAM,CAAC;CAChD;AAED,OAAO,MAAM;gEAQV,kBAAkB,GAAG,WAAW;;CAiJlC,CAAC","sources":["src/src/components/interface.ts","src/src/components/ContextSubMenu.tsx","src/src/components/ContextMenu.tsx","src/src/components/LowSubMenu.tsx","src/src/components/LowMenuButton.tsx","src/src/components/LowMenu.tsx","src/src/components/ContextMenuHandler.tsx","src/src/components/ContextWindowStack.tsx","src/src/functions/chkPosition.ts","src/src/components/ContextWindow.tsx","src/src/components/index.ts","src/src/main.ts","src/main.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,"export * from \"./components\";\n"],"names":[],"version":3,"file":"context-menu.d.ts.map"}
package/dist/main.css CHANGED
@@ -69,7 +69,6 @@
69
69
  z-index: 2;
70
70
  -webkit-font-smoothing: antialiased;
71
71
  -moz-osx-font-smoothing: grayscale;
72
- opacity: .5;
73
72
  background-color: #111418;
74
73
  border: 2px solid #111418;
75
74
  border-top-right-radius: 4px;
@@ -87,7 +86,11 @@
87
86
  box-shadow: 2px 2px 2px #40404080;
88
87
  }
89
88
 
90
- .low-menu:hover {
89
+ .low-menu.hidden {
90
+ opacity: 0;
91
+ }
92
+
93
+ .low-menu.visible, .low-menu:hover {
91
94
  opacity: 1;
92
95
  }
93
96
 
package/dist/main.css.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"AAAA;;;;;;;;;;AAWA;;;;AAIA;;;;;;;;;;;;;AAaA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;AAIA;;;;;AAKA;;;;;AAKA;;;;AAIA;;;;;AAKA;;;;AChEA;;;;;;;;;;;;;;;;;;;;;;AAyBA;;;;AAIA;;;;;;;;;;;;;;AAcA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;;ACxDA;;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;AAYA;;;;AAIA;;;;;;;;;;AAUA;;;;;;;;;;;AAWA;;;;;AAKA;;;;;;;AAOA;;;;;AAKA;;;;;AAKA;;;;;;AAMA","sources":["src/components/ContextMenu.css","src/components/LowMenu.css","src/components/ContextWindow.css"],"sourcesContent":[".context-menu {\n position: absolute;\n visibility: hidden;\n border: 1px solid;\n border-color: rgb(17, 20, 24);\n border-radius: 8px;\n opacity: 1;\n background-color: rgb(251, 253, 246);\n z-index: 10000;\n}\n\n.context-menu.visible {\n visibility: inherit;\n}\n\n.context-menu-item {\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n min-width: 80px;\n height: 21px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.context-menu-item.disabled {\n background-color: rgba(0, 0, 0, 0.2);\n cursor: not-allowed;\n}\n\n.context-menu-item:first-child {\n margin-top: 4px;\n}\n\n.context-menu-item:last-child {\n margin-bottom: 4px;\n}\n\n.context-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.context-menu-item:hover:first-child {\n border-top-left-radius: 6px;\n border-top-right-radius: 6px;\n}\n\n.context-menu-item:hover:last-child {\n border-bottom-left-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n\n.context-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.context-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n\n.context-menu-item-label {\n flex-grow: 1;\n}\n",".low-menu {\n z-index: 2;\n position: absolute;\n top: 0;\n margin: 0px;\n border: 2px solid rgb(17, 20, 24);\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n background-color: rgb(17, 20, 24);\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',\n 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;\n font-size: 9pt;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 2px 2px 2px rgb(64, 64, 64, 0.5);\n opacity: 0.5;\n transition: opacity 0.3s linear;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n gap: 2px;\n row-gap: 2px;\n}\n\n.low-menu:hover {\n opacity: 1;\n}\n\n.low-menu-item {\n background-color: rgb(251, 253, 246);\n border: 0;\n border-radius: 4px;\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.low-menu-item.disabled {\n background-color: rgba(200, 200, 200);\n cursor: not-allowed;\n}\n\n.low-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.low-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.low-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n",".contextwindow {\n z-index: 2001;\n border: 1px black solid;\n margin: 0;\n padding: 4px;\n background-color: rgb(250, 250, 250);\n box-shadow: 6px 6px 6px rgb(64, 64, 64, 0.5);\n transition: opacity 0.25s linear;\n justify-content: flex-start;\n position: absolute;\n border-top-left-radius: 8px;\n border-top-right-radius: 8px;\n border-bottom-left-radius: 8px;\n resize: both;\n overflow: auto;\n}\n\n.contextwindow-title {\n border-bottom: 1px black dashed;\n padding-bottom: 4px;\n margin: 0 4px 3px 4px;\n height: 24px;\n max-height: 24px;\n cursor: grab;\n align-items: top;\n display: flex;\n width: calc(100% - 8px);\n}\n\n.contextwindow-title.moving {\n cursor: grabbing;\n}\n\n.contextwindow-title-text {\n font-size: 18px;\n font-weight: 600;\n display: inline-block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: calc(100% - 16px);\n}\n\n.contextwindow-title-close {\n display: inline-block;\n color: black;\n background-color: white;\n height: 16px;\n width: 16px;\n border-radius: 3px;\n margin-left: 2px;\n cursor: pointer;\n}\n\n.contextwindow-title-close:hover {\n background-color: black;\n color: white;\n}\n\n.contextwindow-body {\n overflow: auto;\n padding-bottom: 8px;\n margin-right: 4px;\n height: calc(100% - 40px);\n}\n\n.contextwindow-body::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-track {\n background: white;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb {\n background: lightgrey;\n border: none;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb:hover {\n background: grey;\n}\n"],"names":[],"version":3,"file":"main.css.map"}
1
+ {"mappings":"AAAA;;;;;;;;;;AAWA;;;;AAIA;;;;;;;;;;;;;AAaA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;AAIA;;;;;AAKA;;;;;AAKA;;;;AAIA;;;;;AAKA;;;;AChEA;;;;;;;;;;;;;;;;;;;;;AAwBA;;;;AAIA;;;;AAKA;;;;;;;;;;;;;;AAcA;;;;;AAKA;;;;AAIA;;;;AAIA;;;;;AC5DA;;;;;;;;;;;;;;;;;AAiBA;;;;;;;;;;;;AAYA;;;;AAIA;;;;;;;;;;AAUA;;;;;;;;;;;AAWA;;;;;AAKA;;;;;;;AAOA;;;;;AAKA;;;;;AAKA;;;;;;AAMA","sources":["src/components/ContextMenu.css","src/components/LowMenu.css","src/components/ContextWindow.css"],"sourcesContent":[".context-menu {\n position: absolute;\n visibility: hidden;\n border: 1px solid;\n border-color: rgb(17, 20, 24);\n border-radius: 8px;\n opacity: 1;\n background-color: rgb(251, 253, 246);\n z-index: 10000;\n}\n\n.context-menu.visible {\n visibility: inherit;\n}\n\n.context-menu-item {\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n min-width: 80px;\n height: 21px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.context-menu-item.disabled {\n background-color: rgba(0, 0, 0, 0.2);\n cursor: not-allowed;\n}\n\n.context-menu-item:first-child {\n margin-top: 4px;\n}\n\n.context-menu-item:last-child {\n margin-bottom: 4px;\n}\n\n.context-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.context-menu-item:hover:first-child {\n border-top-left-radius: 6px;\n border-top-right-radius: 6px;\n}\n\n.context-menu-item:hover:last-child {\n border-bottom-left-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n\n.context-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.context-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n\n.context-menu-item-label {\n flex-grow: 1;\n}\n",".low-menu {\n z-index: 2;\n position: absolute;\n top: 0;\n margin: 0px;\n border: 2px solid rgb(17, 20, 24);\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n background-color: rgb(17, 20, 24);\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\",\n \"Cantarell\", \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n font-size: 9pt;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n box-shadow: 2px 2px 2px rgb(64, 64, 64, 0.5);\n transition: opacity 0.3s linear;\n display: flex;\n flex-wrap: wrap;\n flex-direction: row;\n gap: 2px;\n row-gap: 2px;\n}\n\n.low-menu.hidden {\n opacity: 0;\n}\n\n.low-menu.visible,\n.low-menu:hover {\n opacity: 1;\n}\n\n.low-menu-item {\n background-color: rgb(251, 253, 246);\n border: 0;\n border-radius: 4px;\n color: rgb(17, 20, 24);\n cursor: pointer;\n padding: 0 4px;\n position: relative;\n display: flex;\n flex-direction: row;\n justify-content: space-between;\n white-space: nowrap;\n}\n\n.low-menu-item.disabled {\n background-color: rgba(200, 200, 200);\n cursor: not-allowed;\n}\n\n.low-menu-item:not(.disabled):hover {\n background-color: rgb(251, 233, 230);\n}\n\n.low-menu-item .caret-holder {\n align-self: flex-end;\n}\n\n.low-menu-item .caret-holder .sub-menu {\n z-index: 1;\n position: relative;\n}\n",".contextwindow {\n z-index: 2001;\n border: 1px black solid;\n margin: 0;\n padding: 4px;\n background-color: rgb(250, 250, 250);\n box-shadow: 6px 6px 6px rgb(64, 64, 64, 0.5);\n transition: opacity 0.25s linear;\n justify-content: flex-start;\n position: absolute;\n border-top-left-radius: 8px;\n border-top-right-radius: 8px;\n border-bottom-left-radius: 8px;\n resize: both;\n overflow: auto;\n}\n\n.contextwindow-title {\n border-bottom: 1px black dashed;\n padding-bottom: 4px;\n margin: 0 4px 3px 4px;\n height: 24px;\n max-height: 24px;\n cursor: grab;\n align-items: top;\n display: flex;\n width: calc(100% - 8px);\n}\n\n.contextwindow-title.moving {\n cursor: grabbing;\n}\n\n.contextwindow-title-text {\n font-size: 18px;\n font-weight: 600;\n display: inline-block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n width: calc(100% - 16px);\n}\n\n.contextwindow-title-close {\n display: inline-block;\n color: black;\n background-color: white;\n height: 16px;\n width: 16px;\n border-radius: 3px;\n margin-left: 2px;\n cursor: pointer;\n}\n\n.contextwindow-title-close:hover {\n background-color: black;\n color: white;\n}\n\n.contextwindow-body {\n overflow: auto;\n padding-bottom: 8px;\n margin-right: 4px;\n height: calc(100% - 40px);\n}\n\n.contextwindow-body::-webkit-scrollbar {\n width: 8px;\n height: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-track {\n background: white;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb {\n background: lightgrey;\n border: none;\n border-radius: 8px;\n}\n\n.contextwindow-body::-webkit-scrollbar-thumb:hover {\n background: grey;\n}\n"],"names":[],"version":3,"file":"main.css.map"}
package/dist/main.js CHANGED
@@ -170,9 +170,9 @@ const $556d6f9158abfc99$export$aafc28aea571c4bc = ({ entry: entry, target: targe
170
170
  $556d6f9158abfc99$export$aafc28aea571c4bc.displayName = "LowMenuButton";
171
171
 
172
172
 
173
- const $914758b0c9d59759$export$49e8edc8ebca5f25 = ({ entries: entries, target: target })=>{
173
+ const $914758b0c9d59759$export$49e8edc8ebca5f25 = ({ entries: entries, target: target, visible: visible })=>{
174
174
  return /*#__PURE__*/ (0, $duWW8$jsx)("div", {
175
- className: "low-menu",
175
+ className: `low-menu ${visible ? "visible" : "hidden"}`,
176
176
  "aria-label": "Low context menu",
177
177
  children: entries.map((e, i)=>/*#__PURE__*/ (0, $duWW8$jsx)((0, $556d6f9158abfc99$export$aafc28aea571c4bc), {
178
178
  entry: e,
@@ -195,6 +195,7 @@ const $1e1c1e9e0b943830$export$ed4f9641643dc7e4 = ({ children: children, menuIte
195
195
  const [menuVisible, setMenuVisible] = (0, $duWW8$useState)(false);
196
196
  const [target, setTarget] = (0, $duWW8$useState)(null);
197
197
  const [lowTarget, setLowTarget] = (0, $duWW8$useState)(null);
198
+ const [lowMenuVisible, setLowMenuVisible] = (0, $duWW8$useState)(false);
198
199
  // Show menu when context is requested
199
200
  const showMenu = (e)=>{
200
201
  const sel = window.getSelection();
@@ -227,6 +228,12 @@ const $1e1c1e9e0b943830$export$ed4f9641643dc7e4 = ({ children: children, menuIte
227
228
  onContextMenu: showLowMenu ? undefined : showMenu,
228
229
  className: "context-menu-handler",
229
230
  style: style,
231
+ onMouseEnter: ()=>{
232
+ showLowMenu && setLowMenuVisible(true);
233
+ },
234
+ onMouseLeave: ()=>{
235
+ showLowMenu && setLowMenuVisible(false);
236
+ },
230
237
  children: children
231
238
  }),
232
239
  menuVisible && !showLowMenu && /*#__PURE__*/ (0, $duWW8$createPortal)(/*#__PURE__*/ (0, $duWW8$jsx)("div", {
@@ -259,11 +266,11 @@ const $1e1c1e9e0b943830$export$ed4f9641643dc7e4 = ({ children: children, menuIte
259
266
  setLowTarget(null);
260
267
  },
261
268
  children: /*#__PURE__*/ (0, $duWW8$jsx)((0, $914758b0c9d59759$export$49e8edc8ebca5f25), {
269
+ visible: lowMenuVisible,
262
270
  entries: menuItems,
263
271
  target: lowTarget
264
272
  })
265
- }),
266
- " "
273
+ })
267
274
  ]
268
275
  });
269
276
  };
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["src/main.ts","src/components/index.ts","src/components/ContextMenuHandler.tsx","src/components/ContextMenu.tsx","src/components/ContextSubMenu.tsx","src/components/LowMenu.tsx","src/components/LowMenuButton.tsx","src/components/LowSubMenu.tsx","src/components/ContextWindow.tsx","src/components/ContextWindowStack.tsx","src/functions/chkPosition.ts"],"sourcesContent":["export * from \"./components\";\n","import { ContextMenuHandler } from \"./ContextMenuHandler\";\nimport { ContextWindow } from \"./ContextWindow\";\nimport { ContextWindowStack } from \"./ContextWindowStack\";\nimport { iMenuItem } from \"./interface\";\n\nexport { ContextMenuHandler, ContextWindow, ContextWindowStack };\nexport type { iMenuItem };\n","import { MouseEvent, useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport \"./ContextMenu.css\";\nimport { LowMenu } from \"./LowMenu\";\nimport { iMenuItem } from \"./interface\";\n\ninterface contextMenuHandlerProps {\n children: JSX.Element[] | JSX.Element;\n menuItems: iMenuItem[];\n showLowMenu?: boolean;\n lowMenuTarget?: Range | null;\n style?: React.CSSProperties;\n}\n\nexport const ContextMenuHandler = ({\n children,\n menuItems,\n showLowMenu = false,\n style = {\n height: \"fit-content\",\n width: \"fit-content\",\n },\n}: contextMenuHandlerProps): JSX.Element => {\n // Menu resources\n const divRef = useRef<HTMLDivElement | null>(null);\n const menuRef = useRef<HTMLDivElement | null>(null);\n const [menuXPos, setMenuXPos] = useState<number>(0);\n const [menuYPos, setMenuYPos] = useState<number>(0);\n const [menuVisible, setMenuVisible] = useState<boolean>(false);\n const [target, setTarget] = useState<Range | null>(null);\n const [lowTarget, setLowTarget] = useState<Range | null>(null);\n\n // Show menu when context is requested\n const showMenu = (e: MouseEvent<HTMLDivElement>) => {\n const sel = window.getSelection();\n setTarget(sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null);\n e.preventDefault();\n e.stopPropagation();\n setMenuVisible(true);\n setMenuXPos(e.pageX);\n setMenuYPos(e.pageY);\n };\n\n // Handle click off the menu\n const handleClick = useCallback((e: globalThis.MouseEvent) => {\n if (\n menuRef.current &&\n ((e.target instanceof Element && !menuRef.current?.contains(e.target)) ||\n !(e.target instanceof Element))\n ) {\n setMenuVisible(false);\n }\n }, []);\n\n // Update the document click handler\n useEffect(() => {\n if (menuVisible) document.addEventListener(\"mousedown\", handleClick);\n else document.removeEventListener(\"mousedown\", handleClick);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n };\n }, [handleClick, menuVisible]);\n\n return (\n <>\n <div\n onContextMenu={showLowMenu ? undefined : showMenu}\n className=\"context-menu-handler\"\n style={style}\n >\n {children}\n </div>\n {menuVisible &&\n !showLowMenu &&\n createPortal(\n <div\n style={{ position: \"absolute\", top: 0, left: 0 }}\n ref={divRef}\n >\n <ContextMenu\n visible={true}\n ref={menuRef}\n entries={menuItems}\n xPos={menuXPos}\n yPos={menuYPos}\n target={target}\n toClose={() => setMenuVisible(false)}\n />\n </div>,\n document.body,\n )}\n {showLowMenu && (\n <div\n style={{ position: \"relative\" }}\n onMouseEnter={() => {\n const sel = window.getSelection();\n const lowSel = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n setLowTarget(lowSel);\n }}\n onMouseLeave={() => {\n setLowTarget(null);\n }}\n >\n <LowMenu\n entries={menuItems}\n target={lowTarget}\n />\n </div>\n )}{\" \"}\n </>\n );\n};\n\nContextMenuHandler.displayName = \"ContextMenuHandler\";\n","import React from \"react\";\nimport { ContextSubMenu } from \"./ContextSubMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface contextMenuProps {\n visible: boolean;\n entries: iMenuItem[];\n target: Range | null;\n xPos: number;\n yPos: number;\n toClose: () => void;\n}\n\nexport const ContextMenu = React.forwardRef<HTMLDivElement, contextMenuProps>(\n ({ visible, entries, target, xPos, yPos, toClose }, ref): JSX.Element => {\n ContextMenu.displayName = \"ContextMenu\";\n\n return (\n <div\n ref={ref}\n className={`context-menu${visible ? \" visible\" : \"\"}`}\n style={{\n top: `${yPos}px`,\n left: `${xPos}px`,\n }}\n onContextMenuCapture={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n {entries.map((entry, i) => (\n <div\n key={i}\n className={`context-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n >\n <span\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n className=\"context-menu-item-label\"\n onMouseDownCapture={(ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n !entry.disabled && toClose();\n }}\n >\n {entry.label}\n </span>\n {entry.group && (\n <ContextSubMenu\n toClose={toClose}\n entries={entry.group}\n target={target}\n />\n )}\n </div>\n ))}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface ContextSubMenuProps {\n entries: iMenuItem[];\n target: Range | null;\n toClose: () => void;\n lowMenu?: boolean;\n}\n\nexport const ContextSubMenu = ({ entries, target, toClose }: ContextSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n\n return (\n <span\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entries}\n target={target}\n xPos={14}\n yPos={-21}\n toClose={toClose}\n />\n </div>\n </span>\n );\n};\n\nContextSubMenu.displayName = \"ContextSubMenu\";\n","import { iMenuItem } from \"./interface\";\nimport \"./LowMenu.css\";\nimport { LowMenuButton } from \"./LowMenuButton\";\n\ninterface LowMenuProps {\n entries: iMenuItem[];\n target: Range | null;\n}\n\nexport const LowMenu = ({ entries, target }: LowMenuProps): JSX.Element => {\n return (\n <div\n className=\"low-menu\"\n aria-label=\"Low context menu\"\n >\n {entries.map((e, i) => (\n <LowMenuButton\n key={i}\n entry={e}\n target={target}\n />\n ))}\n </div>\n );\n};\n\nLowMenu.displayName = \"LowMenu\";\n","import { LowSubMenu } from \"./LowSubMenu\";\nimport { iMenuItem } from \"./interface\";\n\ninterface LowMenuButtonProps {\n entry: iMenuItem;\n target: Range | null;\n}\nexport const LowMenuButton = ({ entry, target }: LowMenuButtonProps) => {\n return (\n <div\n className={`low-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n }}\n >\n <span className=\"low-menu-item-label\">{entry.label}</span>\n {entry.group && (\n <LowSubMenu\n entry={entry}\n target={target}\n />\n )}\n </div>\n );\n};\n\nLowMenuButton.displayName = \"LowMenuButton\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { iMenuItem } from \"./interface\";\n\nexport interface LowSubMenuProps {\n entry: iMenuItem;\n target: Range | null;\n lowMenu?: boolean;\n}\n\nexport const LowSubMenu = ({ entry, target }: LowSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n if (!entry.group || entry.group.length === 0) return <></>;\n return (\n <span\n aria-label={`Sub menu for ${entry.label}`}\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entry.group}\n target={target}\n xPos={14}\n yPos={entry.group.length * -21 - 8}\n toClose={() => setVisible(false)}\n />\n </div>\n </span>\n );\n};\n\nLowSubMenu.displayName = \"LowSubMenu\";\n","import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport \"./ContextWindow.css\";\nimport { ContextWindowStackContext } from \"./ContextWindowStack\";\nimport { chkPosition } from \"../functions/chkPosition\";\n\ninterface ContextWindowProps {\n id: string;\n visible: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n title: string;\n style?: React.CSSProperties;\n children: JSX.Element[] | JSX.Element | string;\n}\n\nexport const ContextWindow = ({\n id,\n visible,\n title,\n style,\n children,\n onOpen,\n onClose,\n}: ContextWindowProps): JSX.Element => {\n const windowStack = useContext(ContextWindowStackContext);\n const windowId = useRef<number | null>(null);\n const divRef = useRef<HTMLDivElement | null>(null);\n const windowRef = useRef<HTMLDivElement | null>(null);\n const [windowVisible, setWindowVisible] = useState<boolean>(false);\n const zIndex = useMemo(() => {\n return windowStack?.currentWindows.find((w) => w.windowId === windowId.current)?.zIndex ?? 1;\n }, [windowStack?.currentWindows]);\n\n // Position\n const windowPos = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n const [moving, setMoving] = useState<boolean>(false);\n\n const move = useCallback((x: number, y: number) => {\n if (windowRef.current && windowPos.current) {\n const window = windowRef.current;\n const pos = windowPos.current;\n pos.x += x;\n pos.y += y;\n window.style.transform = `translate(${pos.x}px, ${pos.y}px)`;\n }\n }, []);\n\n const checkPosition = useCallback(() => {\n const chkPos = chkPosition(windowRef);\n move(chkPos.translateX, chkPos.translateY);\n }, [move]);\n\n const mouseMove = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n move(e.movementX, e.movementY);\n },\n [move],\n );\n\n const mouseUp = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setMoving(false);\n checkPosition();\n document.removeEventListener(\"mousemove\", mouseMove);\n document.removeEventListener(\"mouseup\", mouseUp);\n window.removeEventListener(\"resize\", checkPosition);\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"auto\";\n },\n [checkPosition, mouseMove],\n );\n\n // Update visibility\n useEffect(() => {\n if (windowStack) {\n if (visible && !windowVisible) {\n if (!windowId.current) {\n const maxWindowId = Math.max(0, ...windowStack.currentWindows.map((w) => w.windowId));\n windowId.current = maxWindowId + 1;\n }\n windowStack.pushToTop(windowId.current);\n setWindowVisible(visible);\n onOpen && onOpen();\n // Get starting position\n if (divRef.current && windowRef.current) {\n const parentPos = divRef.current.getBoundingClientRect();\n const pos = windowRef.current.getBoundingClientRect();\n const windowHeight = pos.bottom - pos.top;\n windowRef.current.style.left = `${parentPos.left}px`;\n windowRef.current.style.top = `${\n parentPos.bottom + windowHeight < window.innerHeight\n ? parentPos.bottom\n : Math.max(0, parentPos.top - windowHeight)\n }px`;\n windowRef.current.style.transform = \"\";\n windowPos.current = { x: 0, y: 0 };\n }\n checkPosition();\n } else if (windowId.current && !visible && windowVisible) {\n setWindowVisible(false);\n }\n }\n }, [checkPosition, onOpen, visible, windowStack, windowVisible]);\n\n return (\n <div\n className=\"contextwindow-anchor\"\n ref={divRef}\n >\n {windowStack &&\n createPortal(\n <div\n id={id}\n className=\"contextwindow\"\n style={{\n ...style,\n opacity: moving ? 0.8 : windowVisible ? 1 : 0,\n visibility: windowVisible ? \"visible\" : \"hidden\",\n zIndex: zIndex ?? 1,\n minHeight: style?.minHeight ?? \"150px\",\n minWidth: style?.minWidth ?? \"200px\",\n maxHeight: style?.maxHeight ?? \"1000px\",\n maxWidth: style?.maxWidth ?? \"1000px\",\n }}\n onClickCapture={() => {\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n }}\n ref={windowRef}\n >\n <div\n className={`contextwindow-title ${moving ? \"moving\" : \"\"}`}\n onMouseDown={(e: React.MouseEvent) => {\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"none\";\n setMoving(true);\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n document.addEventListener(\"mouseup\", mouseUp);\n document.addEventListener(\"mousemove\", mouseMove);\n window.addEventListener(\"resize\", () => checkPosition());\n }}\n >\n <div className=\"contextwindow-title-text\">{title}</div>\n <div className=\"contextwindow-title-close\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n aria-label=\"Close window\"\n onClick={onClose}\n >\n <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n </div>\n </div>\n <div className=\"contextwindow-body\">\n <div>{children}</div>\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n};\n\nContextWindow.displayName = \"ContextWindow\";\n","import { createContext, useState } from \"react\";\n\nexport interface ContextWindowZIndex {\n windowId: number;\n zIndex: number;\n}\n\nexport interface ContextWindowStackContextProps {\n currentWindows: ContextWindowZIndex[];\n pushToTop: (ret: number) => void;\n}\n\nexport const ContextWindowStackContext = createContext<ContextWindowStackContextProps | null>(null);\n\ninterface ContextWindowStackProps {\n id?: string;\n minZIndex?: number;\n children?: JSX.Element[] | JSX.Element;\n}\n\nconst pushToTop = (\n windowId: number,\n minZIndex: number,\n windowList: ContextWindowZIndex[],\n setWindowList: (ret: ContextWindowZIndex[]) => void,\n) => {\n const otherWindows = windowList\n .filter((w) => w.windowId !== windowId)\n .map((w, i) => ({ windowId: w.windowId, zIndex: minZIndex + i }));\n setWindowList([...otherWindows, { windowId, zIndex: minZIndex + otherWindows.length }]);\n};\n\nexport const ContextWindowStack = ({\n minZIndex = 1000,\n children,\n}: ContextWindowStackProps): JSX.Element => {\n const [currentWindows, setCurrentWindows] = useState<ContextWindowZIndex[]>([]);\n\n return (\n <ContextWindowStackContext.Provider\n value={{\n currentWindows: currentWindows.map((w) => ({\n windowId: w.windowId,\n zIndex: minZIndex + w.zIndex,\n })),\n pushToTop: (ret: number) => pushToTop(ret, minZIndex, currentWindows, setCurrentWindows),\n }}\n >\n {children}\n </ContextWindowStackContext.Provider>\n );\n};\n\nContextWindowStack.displayName = \"ContextWindowStack\";\n","import { RefObject } from \"react\";\n\n/**\n * Check that an existing div is inside the viewport\n * @param divRef Check div is inside view port, and return n\n * @returns \\{ translateX, translateY \\} Amount to move on X and Y axis\n */\nexport const chkPosition = (\n divRef: RefObject<HTMLDivElement>,\n): { translateX: number; translateY: number } => {\n if (!divRef.current) {\n return { translateX: 0, translateY: 0 };\n } else {\n const innerBounce = 16;\n const posn = divRef.current.getBoundingClientRect();\n let translateX = 0;\n if (posn.left < innerBounce) {\n translateX = -posn.left + innerBounce;\n } else if (posn.right > window.innerWidth) {\n translateX = Math.max(-posn.left + innerBounce, window.innerWidth - posn.right - innerBounce);\n }\n let translateY = 0;\n if (posn.top < innerBounce) {\n translateY = -posn.top + innerBounce;\n } else if (posn.bottom > window.innerHeight) {\n translateY = Math.max(\n -posn.top + innerBounce,\n window.innerHeight - posn.bottom - innerBounce,\n );\n }\n return { translateX, translateY };\n }\n};\n"],"names":[],"version":3,"file":"main.js.map"}
1
+ {"mappings":"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","sources":["src/main.ts","src/components/index.ts","src/components/ContextMenuHandler.tsx","src/components/ContextMenu.tsx","src/components/ContextSubMenu.tsx","src/components/LowMenu.tsx","src/components/LowMenuButton.tsx","src/components/LowSubMenu.tsx","src/components/ContextWindow.tsx","src/components/ContextWindowStack.tsx","src/functions/chkPosition.ts"],"sourcesContent":["export * from \"./components\";\n","import { ContextMenuHandler } from \"./ContextMenuHandler\";\nimport { ContextWindow } from \"./ContextWindow\";\nimport { ContextWindowStack } from \"./ContextWindowStack\";\nimport { MenuItem } from \"./interface\";\n\nexport { ContextMenuHandler, ContextWindow, ContextWindowStack };\nexport type { MenuItem as iMenuItem };\n","import { MouseEvent, useCallback, useEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport \"./ContextMenu.css\";\nimport { LowMenu } from \"./LowMenu\";\nimport { MenuItem } from \"./interface\";\n\ninterface contextMenuHandlerProps {\n children: JSX.Element[] | JSX.Element;\n menuItems: MenuItem[];\n showLowMenu?: boolean;\n lowMenuTarget?: Range | null;\n style?: React.CSSProperties;\n}\n\nexport const ContextMenuHandler = ({\n children,\n menuItems,\n showLowMenu = false,\n style = {\n height: \"fit-content\",\n width: \"fit-content\",\n },\n}: contextMenuHandlerProps): JSX.Element => {\n // Menu resources\n const divRef = useRef<HTMLDivElement | null>(null);\n const menuRef = useRef<HTMLDivElement | null>(null);\n const [menuXPos, setMenuXPos] = useState<number>(0);\n const [menuYPos, setMenuYPos] = useState<number>(0);\n const [menuVisible, setMenuVisible] = useState<boolean>(false);\n const [target, setTarget] = useState<Range | null>(null);\n const [lowTarget, setLowTarget] = useState<Range | null>(null);\n const [lowMenuVisible, setLowMenuVisible] = useState<boolean>(false);\n\n // Show menu when context is requested\n const showMenu = (e: MouseEvent<HTMLDivElement>) => {\n const sel = window.getSelection();\n setTarget(sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null);\n e.preventDefault();\n e.stopPropagation();\n setMenuVisible(true);\n setMenuXPos(e.pageX);\n setMenuYPos(e.pageY);\n };\n\n // Handle click off the menu\n const handleClick = useCallback((e: globalThis.MouseEvent) => {\n if (\n menuRef.current &&\n ((e.target instanceof Element && !menuRef.current?.contains(e.target)) ||\n !(e.target instanceof Element))\n ) {\n setMenuVisible(false);\n }\n }, []);\n\n // Update the document click handler\n useEffect(() => {\n if (menuVisible) document.addEventListener(\"mousedown\", handleClick);\n else document.removeEventListener(\"mousedown\", handleClick);\n return () => {\n document.removeEventListener(\"mousedown\", handleClick);\n };\n }, [handleClick, menuVisible]);\n\n return (\n <>\n <div\n onContextMenu={showLowMenu ? undefined : showMenu}\n className=\"context-menu-handler\"\n style={style}\n onMouseEnter={() => {\n showLowMenu && setLowMenuVisible(true);\n }}\n onMouseLeave={() => {\n showLowMenu && setLowMenuVisible(false);\n }}\n >\n {children}\n </div>\n {menuVisible &&\n !showLowMenu &&\n createPortal(\n <div\n style={{ position: \"absolute\", top: 0, left: 0 }}\n ref={divRef}\n >\n <ContextMenu\n visible={true}\n ref={menuRef}\n entries={menuItems}\n xPos={menuXPos}\n yPos={menuYPos}\n target={target}\n toClose={() => setMenuVisible(false)}\n />\n </div>,\n document.body,\n )}\n {showLowMenu && (\n <div\n style={{ position: \"relative\" }}\n onMouseEnter={() => {\n const sel = window.getSelection();\n const lowSel = sel && sel.rangeCount > 0 ? sel.getRangeAt(0) : null;\n setLowTarget(lowSel);\n }}\n onMouseLeave={() => {\n setLowTarget(null);\n }}\n >\n <LowMenu\n visible={lowMenuVisible}\n entries={menuItems}\n target={lowTarget}\n />\n </div>\n )}\n </>\n );\n};\n\nContextMenuHandler.displayName = \"ContextMenuHandler\";\n","import React from \"react\";\nimport { ContextSubMenu } from \"./ContextSubMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface contextMenuProps {\n visible: boolean;\n entries: MenuItem[];\n target: Range | null;\n xPos: number;\n yPos: number;\n toClose: () => void;\n}\n\nexport const ContextMenu = React.forwardRef<HTMLDivElement, contextMenuProps>(\n ({ visible, entries, target, xPos, yPos, toClose }, ref): JSX.Element => {\n ContextMenu.displayName = \"ContextMenu\";\n\n return (\n <div\n ref={ref}\n className={`context-menu${visible ? \" visible\" : \"\"}`}\n style={{\n top: `${yPos}px`,\n left: `${xPos}px`,\n }}\n onContextMenuCapture={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n >\n {entries.map((entry, i) => (\n <div\n key={i}\n className={`context-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n >\n <span\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n className=\"context-menu-item-label\"\n onMouseDownCapture={(ev) => {\n ev.preventDefault();\n ev.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n !entry.disabled && toClose();\n }}\n >\n {entry.label}\n </span>\n {entry.group && (\n <ContextSubMenu\n toClose={toClose}\n entries={entry.group}\n target={target}\n />\n )}\n </div>\n ))}\n </div>\n );\n },\n);\n\nContextMenu.displayName = \"ContextMenu\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface ContextSubMenuProps {\n entries: MenuItem[];\n target: Range | null;\n toClose: () => void;\n lowMenu?: boolean;\n}\n\nexport const ContextSubMenu = ({ entries, target, toClose }: ContextSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n\n return (\n <span\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entries}\n target={target}\n xPos={14}\n yPos={-21}\n toClose={toClose}\n />\n </div>\n </span>\n );\n};\n\nContextSubMenu.displayName = \"ContextSubMenu\";\n","import { MenuItem } from \"./interface\";\nimport \"./LowMenu.css\";\nimport { LowMenuButton } from \"./LowMenuButton\";\n\ninterface LowMenuProps {\n entries: MenuItem[];\n target: Range | null;\n visible: boolean;\n}\n\nexport const LowMenu = ({ entries, target, visible }: LowMenuProps): JSX.Element => {\n return (\n <div\n className={`low-menu ${visible ? \"visible\" : \"hidden\"}`}\n aria-label=\"Low context menu\"\n >\n {entries.map((e, i) => (\n <LowMenuButton\n key={i}\n entry={e}\n target={target}\n />\n ))}\n </div>\n );\n};\n\nLowMenu.displayName = \"LowMenu\";\n","import { LowSubMenu } from \"./LowSubMenu\";\nimport { MenuItem } from \"./interface\";\n\ninterface LowMenuButtonProps {\n entry: MenuItem;\n target: Range | null;\n}\nexport const LowMenuButton = ({ entry, target }: LowMenuButtonProps) => {\n return (\n <div\n className={`low-menu-item${entry.disabled ? \" disabled\" : \"\"}`}\n aria-label={typeof entry.label === \"string\" ? entry.label : undefined}\n aria-disabled={entry.disabled}\n onClick={(event) => {\n event.preventDefault();\n event.stopPropagation();\n entry.action && !entry.disabled && entry.action(target);\n }}\n >\n <span className=\"low-menu-item-label\">{entry.label}</span>\n {entry.group && (\n <LowSubMenu\n entry={entry}\n target={target}\n />\n )}\n </div>\n );\n};\n\nLowMenuButton.displayName = \"LowMenuButton\";\n","import { useState } from \"react\";\nimport { ContextMenu } from \"./ContextMenu\";\nimport { MenuItem } from \"./interface\";\n\nexport interface LowSubMenuProps {\n entry: MenuItem;\n target: Range | null;\n lowMenu?: boolean;\n}\n\nexport const LowSubMenu = ({ entry, target }: LowSubMenuProps): JSX.Element => {\n const [visible, setVisible] = useState<boolean>(false);\n if (!entry.group || entry.group.length === 0) return <></>;\n return (\n <span\n aria-label={`Sub menu for ${entry.label}`}\n className=\"caret-holder\"\n onMouseEnter={() => {\n setVisible(true);\n }}\n onMouseLeave={() => {\n setVisible(false);\n }}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n >\n <path d=\"m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z\" />\n </svg>\n <div className=\"sub-menu\">\n <ContextMenu\n visible={visible}\n entries={entry.group}\n target={target}\n xPos={14}\n yPos={entry.group.length * -21 - 8}\n toClose={() => setVisible(false)}\n />\n </div>\n </span>\n );\n};\n\nLowSubMenu.displayName = \"LowSubMenu\";\n","import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport \"./ContextWindow.css\";\nimport { ContextWindowStackContext } from \"./ContextWindowStack\";\nimport { chkPosition } from \"../functions/chkPosition\";\n\ninterface ContextWindowProps {\n id: string;\n visible: boolean;\n onOpen?: () => void;\n onClose?: () => void;\n title: string;\n style?: React.CSSProperties;\n children: JSX.Element[] | JSX.Element | string;\n}\n\nexport const ContextWindow = ({\n id,\n visible,\n title,\n style,\n children,\n onOpen,\n onClose,\n}: ContextWindowProps): JSX.Element => {\n const windowStack = useContext(ContextWindowStackContext);\n const windowId = useRef<number | null>(null);\n const divRef = useRef<HTMLDivElement | null>(null);\n const windowRef = useRef<HTMLDivElement | null>(null);\n const [windowVisible, setWindowVisible] = useState<boolean>(false);\n const zIndex = useMemo(() => {\n return windowStack?.currentWindows.find((w) => w.windowId === windowId.current)?.zIndex ?? 1;\n }, [windowStack?.currentWindows]);\n\n // Position\n const windowPos = useRef<{ x: number; y: number }>({ x: 0, y: 0 });\n const [moving, setMoving] = useState<boolean>(false);\n\n const move = useCallback((x: number, y: number) => {\n if (windowRef.current && windowPos.current) {\n const window = windowRef.current;\n const pos = windowPos.current;\n pos.x += x;\n pos.y += y;\n window.style.transform = `translate(${pos.x}px, ${pos.y}px)`;\n }\n }, []);\n\n const checkPosition = useCallback(() => {\n const chkPos = chkPosition(windowRef);\n move(chkPos.translateX, chkPos.translateY);\n }, [move]);\n\n const mouseMove = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n move(e.movementX, e.movementY);\n },\n [move],\n );\n\n const mouseUp = useCallback(\n (e: MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n setMoving(false);\n checkPosition();\n document.removeEventListener(\"mousemove\", mouseMove);\n document.removeEventListener(\"mouseup\", mouseUp);\n window.removeEventListener(\"resize\", checkPosition);\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"auto\";\n },\n [checkPosition, mouseMove],\n );\n\n // Update visibility\n useEffect(() => {\n if (windowStack) {\n if (visible && !windowVisible) {\n if (!windowId.current) {\n const maxWindowId = Math.max(0, ...windowStack.currentWindows.map((w) => w.windowId));\n windowId.current = maxWindowId + 1;\n }\n windowStack.pushToTop(windowId.current);\n setWindowVisible(visible);\n onOpen && onOpen();\n // Get starting position\n if (divRef.current && windowRef.current) {\n const parentPos = divRef.current.getBoundingClientRect();\n const pos = windowRef.current.getBoundingClientRect();\n const windowHeight = pos.bottom - pos.top;\n windowRef.current.style.left = `${parentPos.left}px`;\n windowRef.current.style.top = `${\n parentPos.bottom + windowHeight < window.innerHeight\n ? parentPos.bottom\n : Math.max(0, parentPos.top - windowHeight)\n }px`;\n windowRef.current.style.transform = \"\";\n windowPos.current = { x: 0, y: 0 };\n }\n checkPosition();\n } else if (windowId.current && !visible && windowVisible) {\n setWindowVisible(false);\n }\n }\n }, [checkPosition, onOpen, visible, windowStack, windowVisible]);\n\n return (\n <div\n className=\"contextwindow-anchor\"\n ref={divRef}\n >\n {windowStack &&\n createPortal(\n <div\n id={id}\n className=\"contextwindow\"\n style={{\n ...style,\n opacity: moving ? 0.8 : windowVisible ? 1 : 0,\n visibility: windowVisible ? \"visible\" : \"hidden\",\n zIndex: zIndex ?? 1,\n minHeight: style?.minHeight ?? \"150px\",\n minWidth: style?.minWidth ?? \"200px\",\n maxHeight: style?.maxHeight ?? \"1000px\",\n maxWidth: style?.maxWidth ?? \"1000px\",\n }}\n onClickCapture={() => {\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n }}\n ref={windowRef}\n >\n <div\n className={`contextwindow-title ${moving ? \"moving\" : \"\"}`}\n onMouseDown={(e: React.MouseEvent) => {\n if (e.target && (e.target instanceof HTMLElement || e.target instanceof SVGElement))\n e.target.style.userSelect = \"none\";\n setMoving(true);\n windowId && windowId.current && windowStack.pushToTop(windowId.current);\n document.addEventListener(\"mouseup\", mouseUp);\n document.addEventListener(\"mousemove\", mouseMove);\n window.addEventListener(\"resize\", () => checkPosition());\n }}\n >\n <div className=\"contextwindow-title-text\">{title}</div>\n <div className=\"contextwindow-title-close\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n fill=\"currentColor\"\n viewBox=\"0 0 16 16\"\n aria-label=\"Close window\"\n onClick={onClose}\n >\n <path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708z\" />\n </svg>\n </div>\n </div>\n <div className=\"contextwindow-body\">\n <div>{children}</div>\n </div>\n </div>,\n document.body,\n )}\n </div>\n );\n};\n\nContextWindow.displayName = \"ContextWindow\";\n","import { createContext, useState } from \"react\";\n\nexport interface ContextWindowZIndex {\n windowId: number;\n zIndex: number;\n}\n\nexport interface ContextWindowStackContextProps {\n currentWindows: ContextWindowZIndex[];\n pushToTop: (ret: number) => void;\n}\n\nexport const ContextWindowStackContext = createContext<ContextWindowStackContextProps | null>(null);\n\ninterface ContextWindowStackProps {\n id?: string;\n minZIndex?: number;\n children?: JSX.Element[] | JSX.Element;\n}\n\nconst pushToTop = (\n windowId: number,\n minZIndex: number,\n windowList: ContextWindowZIndex[],\n setWindowList: (ret: ContextWindowZIndex[]) => void,\n) => {\n const otherWindows = windowList\n .filter((w) => w.windowId !== windowId)\n .map((w, i) => ({ windowId: w.windowId, zIndex: minZIndex + i }));\n setWindowList([...otherWindows, { windowId, zIndex: minZIndex + otherWindows.length }]);\n};\n\nexport const ContextWindowStack = ({\n minZIndex = 1000,\n children,\n}: ContextWindowStackProps): JSX.Element => {\n const [currentWindows, setCurrentWindows] = useState<ContextWindowZIndex[]>([]);\n\n return (\n <ContextWindowStackContext.Provider\n value={{\n currentWindows: currentWindows.map((w) => ({\n windowId: w.windowId,\n zIndex: minZIndex + w.zIndex,\n })),\n pushToTop: (ret: number) => pushToTop(ret, minZIndex, currentWindows, setCurrentWindows),\n }}\n >\n {children}\n </ContextWindowStackContext.Provider>\n );\n};\n\nContextWindowStack.displayName = \"ContextWindowStack\";\n","import { RefObject } from \"react\";\n\n/**\n * Check that an existing div is inside the viewport\n * @param divRef Check div is inside view port, and return n\n * @returns \\{ translateX, translateY \\} Amount to move on X and Y axis\n */\nexport const chkPosition = (\n divRef: RefObject<HTMLDivElement>,\n): { translateX: number; translateY: number } => {\n if (!divRef.current) {\n return { translateX: 0, translateY: 0 };\n } else {\n const innerBounce = 16;\n const posn = divRef.current.getBoundingClientRect();\n let translateX = 0;\n if (posn.left < innerBounce) {\n translateX = -posn.left + innerBounce;\n } else if (posn.right > window.innerWidth) {\n translateX = Math.max(-posn.left + innerBounce, window.innerWidth - posn.right - innerBounce);\n }\n let translateY = 0;\n if (posn.top < innerBounce) {\n translateY = -posn.top + innerBounce;\n } else if (posn.bottom > window.innerHeight) {\n translateY = Math.max(\n -posn.top + innerBounce,\n window.innerHeight - posn.bottom - innerBounce,\n );\n }\n return { translateX, translateY };\n }\n};\n"],"names":[],"version":3,"file":"main.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asup/context-menu",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "REACT Typescript Context menu component",
5
5
  "author": "Paul Thomas <@PaulDThomas>",
6
6
  "private": false,
@@ -9,11 +9,24 @@
9
9
  "type": "git",
10
10
  "url": "git+https://github.com/PaulDThomas/context-menu.git"
11
11
  },
12
+ "main": "dist/cjs/main.js",
13
+ "module": "dist/main.js",
14
+ "types": "dist/context-menu.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
12
18
  "keywords": [
13
19
  "react",
14
20
  "typescript",
15
21
  "context menu"
16
22
  ],
23
+ "scripts": {
24
+ "build": "rmdir /q/s .\\.parcel-cache && parcel build src/main.ts",
25
+ "prepare": "husky",
26
+ "start": "parcel demo/index.html --dist-dir demo/dist",
27
+ "test": "jest --watch",
28
+ "test:coverage-report": "npm test -- --coverage --watchAll=false"
29
+ },
17
30
  "bugs": {
18
31
  "url": "https://github.com/PaulDThomas/context-menu/issues"
19
32
  },
@@ -34,29 +47,31 @@
34
47
  "@parcel/transformer-sass": "^2.7.0",
35
48
  "@parcel/transformer-typescript-types": "^2.8.0",
36
49
  "@parcel/transformer-webmanifest": "^2.7.0",
37
- "@testing-library/jest-dom": "^6.1.5",
50
+ "@testing-library/jest-dom": "^6.4.2",
38
51
  "@testing-library/react": "^14.0.0",
39
52
  "@testing-library/user-event": "^14.4.3",
40
53
  "@types/jest": "^29.2.2",
41
- "@types/node": "^20.10.4",
54
+ "@types/node": "^20.11.19",
42
55
  "@types/react": "^18.0.25",
43
56
  "@types/react-dom": "^18.0.8",
44
- "@typescript-eslint/eslint-plugin": "^6.13.2",
45
- "@typescript-eslint/parser": "^6.13.2",
57
+ "@typescript-eslint/eslint-plugin": "^7.0.1",
58
+ "@typescript-eslint/parser": "^7.0.1",
46
59
  "eslint": "^8.32.0",
47
60
  "eslint-config-prettier": "^9.1.0",
48
- "eslint-plugin-prettier": "^5.0.1",
61
+ "eslint-plugin-prettier": "^5.1.3",
49
62
  "eslint-plugin-react": "^7.31.10",
50
63
  "eslint-plugin-react-hooks": "^4.6.0",
51
- "husky": "^8.0.1",
64
+ "husky": "^9.0.11",
52
65
  "jest": "^29.2.2",
53
66
  "jest-environment-jsdom": "^29.3.1",
54
- "lint-staged": "^15.2.0",
67
+ "jest-watch-typeahead": "^2.2.2",
68
+ "lint-staged": "^15.2.2",
55
69
  "parcel": "^2.7.0",
56
70
  "postcss": "^8.4.18",
57
- "prettier": "^3.1.0",
71
+ "prettier": "^3.2.5",
58
72
  "process": "^0.11.10",
59
73
  "ts-jest": "^29.0.3",
74
+ "ts-jest-mock-import-meta": "^1.2.0",
60
75
  "ts-node": "^10.9.1",
61
76
  "typescript": "^5.0.4",
62
77
  "typescript-plugin-css-modules": "^5.0.2"
@@ -64,12 +79,6 @@
64
79
  "lint-staged": {
65
80
  "**/*": "prettier --write --ignore-unknown"
66
81
  },
67
- "main": "dist/cjs/main.js",
68
- "module": "dist/main.js",
69
- "types": "dist/context-menu.d.ts",
70
- "files": [
71
- "dist"
72
- ],
73
82
  "eslintConfig": {
74
83
  "extends": [
75
84
  "react-app",
@@ -87,11 +96,5 @@
87
96
  "last 1 firefox version",
88
97
  "last 1 safari version"
89
98
  ]
90
- },
91
- "scripts": {
92
- "build": "parcel build src/main.ts",
93
- "start": "parcel demo/index.html --dist-dir demo/dist",
94
- "test": "jest --watch",
95
- "test:coverage-report": "npm test -- --coverage --watchAll=false"
96
99
  }
97
100
  }