tldraw/packages/tldraw/src/lib/ui/components/MobileStylePanel.tsx
David Sheldrick 3e12b27728
Fix 'style panel doesn't always disappear if you switch to the hand/laser tools' (#2886)
We had some bad logic in `useRelevantStyles` explicitly allowing an
opacity-slider to be rendered at all times when there is at least one
shape selected.

This shouldn't be the case when the editor is in non-shape-focused tools
like the move tool and the laser pointer tool. I refactored the hook
slightly to make it easier to express the correct logic. See the comment
for a more detailed description.

### Change Type

- [x] `patch` — Bug fix


[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version


### Release Notes

- Fixes an bug causing the opacity slider to show up in the move tool
and laser pointer tool.
2024-02-20 15:09:45 +00:00

71 lines
2 KiB
TypeScript

import {
DefaultColorStyle,
TLDefaultColorStyle,
getDefaultColorTheme,
useEditor,
useValue,
} from '@tldraw/editor'
import { useCallback } from 'react'
import { useTldrawUiComponents } from '../context/components'
import { useRelevantStyles } from '../hooks/useRelevantStyles'
import { useTranslation } from '../hooks/useTranslation/useTranslation'
import { TldrawUiButton } from './primitives/Button/TldrawUiButton'
import { TldrawUiButtonIcon } from './primitives/Button/TldrawUiButtonIcon'
import {
TldrawUiPopover,
TldrawUiPopoverContent,
TldrawUiPopoverTrigger,
} from './primitives/TldrawUiPopover'
export function MobileStylePanel() {
const editor = useEditor()
const msg = useTranslation()
const relevantStyles = useRelevantStyles()
const color = relevantStyles?.get(DefaultColorStyle)
const theme = getDefaultColorTheme({ isDarkMode: editor.user.getIsDarkMode() })
const currentColor = (
color?.type === 'shared' ? theme[color.value as TLDefaultColorStyle] : theme.black
).solid
const disableStylePanel = useValue(
'disable style panel',
() => editor.isInAny('hand', 'zoom', 'eraser', 'laser'),
[editor]
)
const handleStylesOpenChange = useCallback(
(isOpen: boolean) => {
if (!isOpen) {
editor.updateInstanceState({ isChangingStyle: false })
}
},
[editor]
)
const { StylePanel } = useTldrawUiComponents()
if (!StylePanel) return null
return (
<TldrawUiPopover id="mobile style menu" onOpenChange={handleStylesOpenChange}>
<TldrawUiPopoverTrigger>
<TldrawUiButton
type="tool"
data-testid="mobile-styles.button"
style={{
color: disableStylePanel ? 'var(--color-muted-1)' : currentColor,
}}
title={msg('style-panel.title')}
disabled={disableStylePanel}
>
<TldrawUiButtonIcon
icon={disableStylePanel ? 'blob' : color?.type === 'mixed' ? 'mixed' : 'blob'}
/>
</TldrawUiButton>
</TldrawUiPopoverTrigger>
<TldrawUiPopoverContent side="top" align="end">
{StylePanel && <StylePanel isMobile />}
</TldrawUiPopoverContent>
</TldrawUiPopover>
)
}