فهرست منبع

feat: add geometry shapes tool

Peng Xiao 3 سال پیش
والد
کامیت
229e64a07b

+ 51 - 0
tldraw/apps/tldraw-logseq/src/components/PrimaryTools/PrimaryTools.tsx

@@ -40,6 +40,56 @@ const ToolButton = observer(({ id, icon, title, ...props }: ToolButtonProps) =>
   )
 })
 
+const GeometryToolButtons = observer(() => {
+  const geometries = [
+    {
+      id: 'box',
+      icon: 'rectangle',
+      title: 'Rectangle',
+    },
+    {
+      id: 'ellipse',
+      icon: 'circle',
+      title: 'Circle',
+    },
+    {
+      id: 'polygon',
+      icon: 'triangle',
+      title: 'Triangle',
+    },
+  ]
+
+  const app = useApp()
+  const [activeGeomId, setActiveGeomId] = React.useState(
+    () => (geometries.find(geo => geo.id === app.selectedTool.id) ?? geometries[0]).id
+  )
+
+  const [paneActive, setPaneActive] = React.useState(false)
+
+  React.useEffect(() => {
+    setActiveGeomId(prevId => {
+      return geometries.find(geo => geo.id === app.selectedTool.id)?.id ?? prevId
+    })
+  }, [app.selectedTool.id])
+
+  return (
+    <div
+      className="tl-geometry-tools-pane-anchor"
+      onMouseEnter={() => setPaneActive(true)}
+      onMouseLeave={() => setPaneActive(false)}
+    >
+      {<ToolButton {...geometries.find(geo => geo.id === activeGeomId)!} />}
+      {paneActive && (
+        <div className="tl-geometry-tools-pane">
+          {geometries.map(props => (
+            <ToolButton key={props.id} {...props} />
+          ))}
+        </div>
+      )}
+    </div>
+  )
+})
+
 export const PrimaryTools = observer(function PrimaryTools() {
   const app = useApp()
 
@@ -52,6 +102,7 @@ export const PrimaryTools = observer(function PrimaryTools() {
         <ToolButton title="Eraser" id="erase" icon="eraser" />
         <ToolButton title="Connector" id="line" icon="connector" />
         <ToolButton title="Text" id="text" icon="text" />
+        <GeometryToolButtons />
         <ToolButton title="Logseq Portal" id="logseq-portal" icon={<LogseqIcon />} />
       </div>
     </div>

+ 21 - 5
tldraw/apps/tldraw-logseq/src/styles.css

@@ -212,7 +212,6 @@
   z-index: 10000;
   flex-flow: column;
   border-radius: 8px;
-  overflow: hidden;
   padding: 8px;
 
   .tl-button {
@@ -241,7 +240,6 @@
 
   flex-flow: column;
   border-radius: 8px;
-  overflow: hidden;
   padding: 4px;
   gap: 8px;
   background-color: var(--color-panel);
@@ -249,6 +247,24 @@
   pointer-events: all;
 }
 
+.tl-geometry-tools-pane-anchor {
+  @apply relative;
+}
+
+.tl-geometry-tools-pane {
+  @apply absolute flex flex-col items-center justify-center;
+  right: 100%;
+  top: calc(50% - 52px);
+  background-color: var(--ls-secondary-background-color);
+  border-radius: 8px;
+  padding: 4px;
+  gap: 8px;
+
+  .tl-button:hover {
+    background-color: var(--ls-tertiary-background-color);
+  }
+}
+
 .floating-panel[data-tool-locked='true'] > .tl-button[data-selected='true']::after {
   @apply block absolute;
 
@@ -496,7 +512,7 @@
   cursor: pointer;
   gap: 0.5em;
 
-  &[data-focused=true] {
+  &[data-focused='true'] {
     background-color: var(--ls-menu-hover-color, #f4f5f7);
   }
 }
@@ -546,7 +562,7 @@
 
   .page-ref {
     color: var(--ls-title-text-color);
-  }  
+  }
 }
 
 .tl-type-tag {
@@ -616,4 +632,4 @@ html[data-theme='dark'] {
   .tl-logseq-portal-header {
     backdrop-filter: brightness(1.2);
   }
-}
+}