mirror of
https://github.com/logseq/logseq.git
synced 2026-06-01 19:01:22 +00:00
refactor: geometry tools
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { useApp } from '@tldraw/react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import * as React from 'react'
|
||||
import { ToolButton } from '../ToolButton'
|
||||
import * as Popover from '@radix-ui/react-popover'
|
||||
|
||||
export const GeometryTools = observer(function GeometryTools() {
|
||||
const geometries = [
|
||||
{
|
||||
id: 'box',
|
||||
icon: 'square',
|
||||
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
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
setActiveGeomId(prevId => {
|
||||
return geometries.find(geo => geo.id === app.selectedTool.id)?.id ?? prevId
|
||||
})
|
||||
}, [app.selectedTool.id])
|
||||
|
||||
return (
|
||||
<Popover.Root>
|
||||
<Popover.Trigger className="tl-geometry-tools-pane-anchor">
|
||||
<ToolButton {...geometries.find(geo => geo.id === activeGeomId)!} />
|
||||
</Popover.Trigger>
|
||||
|
||||
<Popover.Content
|
||||
className="tl-popover-content"
|
||||
side="left"
|
||||
sideOffset={15}
|
||||
>
|
||||
<div className="tl-toolbar tl-geometry-toolbar">
|
||||
{geometries.map(props => (
|
||||
<ToolButton key={props.id} {...props} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<Popover.Arrow className="tl-popover-arrow" />
|
||||
</Popover.Content>
|
||||
</Popover.Root>
|
||||
)
|
||||
})
|
||||
@@ -0,0 +1 @@
|
||||
export * from './GeometryTools'
|
||||
@@ -2,61 +2,10 @@ import { useApp } from '@tldraw/react'
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import * as React from 'react'
|
||||
import { ToolButton } from '../ToolButton'
|
||||
import { GeometryTools } from '../GeometryTools'
|
||||
import { ColorInput } from '../inputs/ColorInput'
|
||||
import * as Separator from '@radix-ui/react-separator'
|
||||
|
||||
const GeometryToolButtons = observer(() => {
|
||||
const geometries = [
|
||||
{
|
||||
id: 'box',
|
||||
icon: 'square',
|
||||
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()
|
||||
|
||||
@@ -78,7 +27,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 />
|
||||
<GeometryTools />
|
||||
<Separator.Root className="tl-toolbar-separator" orientation="horizontal" style={{margin: "0 -4px"}}/>
|
||||
<ColorInput
|
||||
title="Color Picker"
|
||||
|
||||
@@ -42,7 +42,7 @@ export function ColorInput({
|
||||
<Popover.Trigger className="tl-color-drip">{renderColor(color)}</Popover.Trigger>
|
||||
|
||||
<Popover.Content
|
||||
className="tl-popover-content"
|
||||
className="tl-popover-content p-1"
|
||||
side={popoverSide}
|
||||
sideOffset={15}
|
||||
collisionBoundary={collisionRef}
|
||||
|
||||
@@ -329,24 +329,6 @@ button.tl-select-input-trigger {
|
||||
font-family: var(--ls-font-family);
|
||||
}
|
||||
|
||||
.tl-geometry-tools-pane-anchor {
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
.tl-geometry-tools-pane {
|
||||
@apply absolute rounded-lg flex flex-col items-center justify-center;
|
||||
right: 100%;
|
||||
top: calc(50% - 54px);
|
||||
background-color: var(--ls-secondary-background-color);
|
||||
padding: 4px;
|
||||
gap: 8px;
|
||||
box-shadow: var(--shadow-small);
|
||||
|
||||
.tl-button:not([data-selected='true']):hover {
|
||||
background-color: var(--ls-tertiary-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
.floating-panel[data-tool-locked='true'] > .tl-button[data-selected='true']::after {
|
||||
@apply block absolute;
|
||||
|
||||
@@ -904,11 +886,15 @@ html[data-theme='dark'] {
|
||||
.tl-popover-content {
|
||||
@apply rounded-sm drop-shadow-md;
|
||||
|
||||
padding: 4px;
|
||||
background-color: var(--ls-secondary-background-color);
|
||||
z-index: 100000;
|
||||
}
|
||||
|
||||
.tl-geometry-toolbar {
|
||||
box-shadow: none;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.tl-popover-arrow {
|
||||
fill: var(--ls-secondary-background-color);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user