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.
pull/2889/head
David Sheldrick 2024-02-20 15:09:45 +00:00 zatwierdzone przez GitHub
rodzic 9b65b0e20f
commit 3e12b27728
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
8 zmienionych plików z 30 dodań i 25 usunięć

Wyświetl plik

@ -7168,19 +7168,17 @@ export class Editor extends EventEmitter<TLEventMap> {
*
* @internal
*/
private _selectionSharedStyles = computed<ReadonlySharedStyleMap>(
'_selectionSharedStyles',
() => {
const selectedShapes = this.getSelectedShapes()
@computed
private _getSelectionSharedStyles(): ReadonlySharedStyleMap {
const selectedShapes = this.getSelectedShapes()
const sharedStyles = new SharedStyleMap()
for (const selectedShape of selectedShapes) {
this._extractSharedStyles(selectedShape, sharedStyles)
}
return sharedStyles
const sharedStyles = new SharedStyleMap()
for (const selectedShape of selectedShapes) {
this._extractSharedStyles(selectedShape, sharedStyles)
}
)
return sharedStyles
}
/** @internal */
getStyleForNextShape<T>(style: StyleProp<T>): T {
@ -7213,7 +7211,7 @@ export class Editor extends EventEmitter<TLEventMap> {
// If we're in selecting and if we have a selection, return the shared styles from the
// current selection
if (this.isIn('select') && this.getSelectedShapeIds().length > 0) {
return this._selectionSharedStyles.get()
return this._getSelectionSharedStyles()
}
// If the current tool is associated with a shape, return the styles for that shape.

Wyświetl plik

@ -23513,7 +23513,7 @@
"text": ";"
}
],
"fileUrlPath": "packages/tldraw/src/lib/ui/hooks/useRevelantStyles.ts",
"fileUrlPath": "packages/tldraw/src/lib/ui/hooks/useRelevantStyles.ts",
"returnTypeTokenRange": {
"startIndex": 5,
"endIndex": 7

Wyświetl plik

@ -81,7 +81,7 @@ export { useKeyboardShortcuts } from './lib/ui/hooks/useKeyboardShortcuts'
export { useLocalStorageState } from './lib/ui/hooks/useLocalStorageState'
export { useMenuIsOpen } from './lib/ui/hooks/useMenuIsOpen'
export { useReadonly } from './lib/ui/hooks/useReadonly'
export { useRelevantStyles } from './lib/ui/hooks/useRevelantStyles'
export { useRelevantStyles } from './lib/ui/hooks/useRelevantStyles'
export {
toolbarItem,
useToolbarSchema,

Wyświetl plik

@ -7,7 +7,7 @@ import {
} from '@tldraw/editor'
import { useCallback } from 'react'
import { useTldrawUiComponents } from '../context/components'
import { useRelevantStyles } from '../hooks/useRevelantStyles'
import { useRelevantStyles } from '../hooks/useRelevantStyles'
import { useTranslation } from '../hooks/useTranslation/useTranslation'
import { TldrawUiButton } from './primitives/Button/TldrawUiButton'
import { TldrawUiButtonIcon } from './primitives/Button/TldrawUiButtonIcon'

Wyświetl plik

@ -1,7 +1,7 @@
import { useEditor } from '@tldraw/editor'
import classNames from 'classnames'
import { memo, useCallback } from 'react'
import { useRelevantStyles } from '../../hooks/useRevelantStyles'
import { useRelevantStyles } from '../../hooks/useRelevantStyles'
import { DefaultStylePanelContent } from './DefaultStylePanelContent'
/** @public */

Wyświetl plik

@ -13,7 +13,6 @@ import {
ReadonlySharedStyleMap,
StyleProp,
TLArrowShapeArrowheadStyle,
TLDefaultVerticalAlignStyle,
minBy,
useEditor,
useValue,
@ -21,7 +20,7 @@ import {
import React from 'react'
import { STYLES } from '../../../styles'
import { useUiEvents } from '../../context/events'
import { useRelevantStyles } from '../../hooks/useRevelantStyles'
import { useRelevantStyles } from '../../hooks/useRelevantStyles'
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
import { TldrawUiButton } from '../primitives/Button/TldrawUiButton'
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
@ -201,7 +200,7 @@ function TextStylePickerSet({ styles }: { styles: ReadonlySharedStyleMap }) {
<TldrawUiButtonIcon icon="vertical-align-center" />
</TldrawUiButton>
) : (
<DropdownPicker<TLDefaultVerticalAlignStyle>
<DropdownPicker
type="icon"
id="geo-vertical-alignment"
uiType="verticalAlign"

Wyświetl plik

@ -82,9 +82,9 @@ function _DoubleDropdownPicker<T extends string>({
</TldrawUiDropdownMenuTrigger>
<TldrawUiDropdownMenuContent side="bottom" align="end" sideOffset={0} alignOffset={-2}>
<div className="tlui-buttons__grid">
{itemsA.map((item) => {
{itemsA.map((item, i) => {
return (
<TldrawUiDropdownMenuItem data-testid={`style.${uiTypeA}.${item.value}`}>
<TldrawUiDropdownMenuItem key={i} data-testid={`style.${uiTypeA}.${item.value}`}>
<TldrawUiButton
type="icon"
key={item.value}

Wyświetl plik

@ -24,8 +24,8 @@ export function useRelevantStyles(stylesToCheck = selectToolStyles): ReadonlySha
'getRelevantStyles',
() => {
const styles = new SharedStyleMap(editor.getSharedStyles())
const hasShape =
editor.getSelectedShapeIds().length > 0 || !!editor.root.getCurrent()?.shapeType
const isInShapeSpecificTool = !!editor.root.getCurrent()?.shapeType
const hasShapesSelected = editor.isIn('select') && editor.getSelectedShapeIds().length > 0
if (styles.size === 0 && editor.isIn('select') && editor.getSelectedShapeIds().length === 0) {
for (const style of stylesToCheck) {
@ -33,8 +33,16 @@ export function useRelevantStyles(stylesToCheck = selectToolStyles): ReadonlySha
}
}
if (styles.size === 0 && !hasShape) return null
return styles
if (isInShapeSpecificTool || hasShapesSelected || styles.size > 0) {
// If size is 0 we may still want to return an empty styles map to allow
// the opacity slider to show up.
// This can happen in two situations:
// 1. When the user is in the select tool and has multiple shapes selected but they have no supported styles (beyond opacity).
// 2. When the user is in a shape-specific tool and the shape has no supported styles (beyond opacity obvs).
return styles
}
return null
},
[editor]
)