[tiny] lift theme in style panel (#3170)

The button pickers in the style panel pop in and out all the time as
different shapes are selected. This PR lifts the dark mode check up to
the style panel itself, rather than in each picker.

### Change Type

<!--  Please select a 'Scope' label ️ -->

- [x] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [ ] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [ ] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [x] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Use the style panel
2. Change the them
This commit is contained in:
Steve Ruiz 2024-03-17 17:45:45 +00:00 committed by GitHub
parent 307495f010
commit 4e0df0730d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 96 additions and 25 deletions

View file

@ -62,6 +62,7 @@ import { TLBookmarkShape } from '@tldraw/editor';
import { TLCancelEvent } from '@tldraw/editor'; import { TLCancelEvent } from '@tldraw/editor';
import { TLClickEvent } from '@tldraw/editor'; import { TLClickEvent } from '@tldraw/editor';
import { TLClickEventInfo } from '@tldraw/editor'; import { TLClickEventInfo } from '@tldraw/editor';
import { TLDefaultColorTheme } from '@tldraw/editor';
import { TLDefaultSizeStyle } from '@tldraw/editor'; import { TLDefaultSizeStyle } from '@tldraw/editor';
import { TldrawEditorBaseProps } from '@tldraw/editor'; import { TldrawEditorBaseProps } from '@tldraw/editor';
import { TLDrawShape } from '@tldraw/editor'; import { TLDrawShape } from '@tldraw/editor';
@ -308,8 +309,9 @@ export function ClipboardMenuGroup(): JSX_2.Element;
export function CloudToolbarItem(): JSX_2.Element; export function CloudToolbarItem(): JSX_2.Element;
// @public (undocumented) // @public (undocumented)
export function CommonStylePickerSet({ styles }: { export function CommonStylePickerSet({ styles, theme, }: {
styles: ReadonlySharedStyleMap; styles: ReadonlySharedStyleMap;
theme: TLDefaultColorTheme;
}): JSX_2.Element; }): JSX_2.Element;
// @public // @public
@ -1398,7 +1400,8 @@ export class TextShapeUtil extends ShapeUtil<TLTextShape> {
} }
// @public (undocumented) // @public (undocumented)
export function TextStylePickerSet({ styles }: { export function TextStylePickerSet({ theme, styles, }: {
theme: TLDefaultColorTheme;
styles: ReadonlySharedStyleMap; styles: ReadonlySharedStyleMap;
}): JSX_2.Element | null; }): JSX_2.Element | null;
@ -1752,6 +1755,8 @@ export interface TLUiButtonPickerProps<T extends string> {
// (undocumented) // (undocumented)
style: StyleProp<T>; style: StyleProp<T>;
// (undocumented) // (undocumented)
theme: TLDefaultColorTheme;
// (undocumented)
title: string; title: string;
// (undocumented) // (undocumented)
uiType: string; uiType: string;

View file

@ -2555,7 +2555,7 @@
"excerptTokens": [ "excerptTokens": [
{ {
"kind": "Content", "kind": "Content",
"text": "export declare function CommonStylePickerSet({ styles }: " "text": "export declare function CommonStylePickerSet({ styles, theme, }: "
}, },
{ {
"kind": "Content", "kind": "Content",
@ -2566,6 +2566,15 @@
"text": "ReadonlySharedStyleMap", "text": "ReadonlySharedStyleMap",
"canonicalReference": "@tldraw/editor!ReadonlySharedStyleMap:class" "canonicalReference": "@tldraw/editor!ReadonlySharedStyleMap:class"
}, },
{
"kind": "Content",
"text": ";\n theme: "
},
{
"kind": "Reference",
"text": "TLDefaultColorTheme",
"canonicalReference": "@tldraw/tlschema!TLDefaultColorTheme:type"
},
{ {
"kind": "Content", "kind": "Content",
"text": ";\n}" "text": ";\n}"
@ -2590,17 +2599,17 @@
], ],
"fileUrlPath": "packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx", "fileUrlPath": "packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx",
"returnTypeTokenRange": { "returnTypeTokenRange": {
"startIndex": 5, "startIndex": 7,
"endIndex": 7 "endIndex": 9
}, },
"releaseTag": "Public", "releaseTag": "Public",
"overloadIndex": 1, "overloadIndex": 1,
"parameters": [ "parameters": [
{ {
"parameterName": "{ styles }", "parameterName": "{ styles, theme, }",
"parameterTypeTokenRange": { "parameterTypeTokenRange": {
"startIndex": 1, "startIndex": 1,
"endIndex": 4 "endIndex": 6
}, },
"isOptional": false "isOptional": false
} }
@ -16145,11 +16154,20 @@
"excerptTokens": [ "excerptTokens": [
{ {
"kind": "Content", "kind": "Content",
"text": "export declare function TextStylePickerSet({ styles }: " "text": "export declare function TextStylePickerSet({ theme, styles, }: "
}, },
{ {
"kind": "Content", "kind": "Content",
"text": "{\n styles: " "text": "{\n theme: "
},
{
"kind": "Reference",
"text": "TLDefaultColorTheme",
"canonicalReference": "@tldraw/tlschema!TLDefaultColorTheme:type"
},
{
"kind": "Content",
"text": ";\n styles: "
}, },
{ {
"kind": "Reference", "kind": "Reference",
@ -16184,17 +16202,17 @@
], ],
"fileUrlPath": "packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx", "fileUrlPath": "packages/tldraw/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx",
"returnTypeTokenRange": { "returnTypeTokenRange": {
"startIndex": 5, "startIndex": 7,
"endIndex": 8 "endIndex": 10
}, },
"releaseTag": "Public", "releaseTag": "Public",
"overloadIndex": 1, "overloadIndex": 1,
"parameters": [ "parameters": [
{ {
"parameterName": "{ styles }", "parameterName": "{ theme, styles, }",
"parameterTypeTokenRange": { "parameterTypeTokenRange": {
"startIndex": 1, "startIndex": 1,
"endIndex": 4 "endIndex": 6
}, },
"isOptional": false "isOptional": false
} }
@ -20543,6 +20561,34 @@
"endIndex": 3 "endIndex": 3
} }
}, },
{
"kind": "PropertySignature",
"canonicalReference": "tldraw!TLUiButtonPickerProps#theme:member",
"docComment": "",
"excerptTokens": [
{
"kind": "Content",
"text": "theme: "
},
{
"kind": "Reference",
"text": "TLDefaultColorTheme",
"canonicalReference": "@tldraw/tlschema!TLDefaultColorTheme:type"
},
{
"kind": "Content",
"text": ";"
}
],
"isReadonly": false,
"isOptional": false,
"releaseTag": "Public",
"name": "theme",
"propertyTypeTokenRange": {
"startIndex": 1,
"endIndex": 2
}
},
{ {
"kind": "PropertySignature", "kind": "PropertySignature",
"canonicalReference": "tldraw!TLUiButtonPickerProps#title:member", "canonicalReference": "tldraw!TLUiButtonPickerProps#title:member",

View file

@ -13,8 +13,11 @@ import {
ReadonlySharedStyleMap, ReadonlySharedStyleMap,
StyleProp, StyleProp,
TLArrowShapeArrowheadStyle, TLArrowShapeArrowheadStyle,
TLDefaultColorTheme,
getDefaultColorTheme,
minBy, minBy,
useEditor, useEditor,
useIsDarkMode,
useValue, useValue,
} from '@tldraw/editor' } from '@tldraw/editor'
import React from 'react' import React from 'react'
@ -36,6 +39,8 @@ export type TLUiStylePanelContentProps = {
/** @public */ /** @public */
export function DefaultStylePanelContent({ styles }: TLUiStylePanelContentProps) { export function DefaultStylePanelContent({ styles }: TLUiStylePanelContentProps) {
const isDarkMode = useIsDarkMode()
if (!styles) return null if (!styles) return null
const geo = styles.get(GeoShapeGeoStyle) const geo = styles.get(GeoShapeGeoStyle)
@ -49,10 +54,12 @@ export function DefaultStylePanelContent({ styles }: TLUiStylePanelContentProps)
const hideSpline = spline === undefined const hideSpline = spline === undefined
const hideText = font === undefined const hideText = font === undefined
const theme = getDefaultColorTheme({ isDarkMode: isDarkMode })
return ( return (
<> <>
<CommonStylePickerSet styles={styles} /> <CommonStylePickerSet theme={theme} styles={styles} />
{!hideText && <TextStylePickerSet styles={styles} />} {!hideText && <TextStylePickerSet theme={theme} styles={styles} />}
{!(hideGeo && hideArrowHeads && hideSpline) && ( {!(hideGeo && hideArrowHeads && hideSpline) && (
<div className="tlui-style-panel__section" aria-label="style panel styles"> <div className="tlui-style-panel__section" aria-label="style panel styles">
<GeoStylePickerSet styles={styles} /> <GeoStylePickerSet styles={styles} />
@ -86,7 +93,13 @@ function useStyleChangeCallback() {
} }
/** @public */ /** @public */
export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMap }) { export function CommonStylePickerSet({
styles,
theme,
}: {
styles: ReadonlySharedStyleMap
theme: TLDefaultColorTheme
}) {
const msg = useTranslation() const msg = useTranslation()
const handleValueChange = useStyleChangeCallback() const handleValueChange = useStyleChangeCallback()
@ -114,6 +127,7 @@ export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMa
items={STYLES.color} items={STYLES.color}
value={color} value={color}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
)} )}
<OpacitySlider /> <OpacitySlider />
@ -128,6 +142,7 @@ export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMa
items={STYLES.fill} items={STYLES.fill}
value={fill} value={fill}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
)} )}
{dash === undefined ? null : ( {dash === undefined ? null : (
@ -138,6 +153,7 @@ export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMa
items={STYLES.dash} items={STYLES.dash}
value={dash} value={dash}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
)} )}
{size === undefined ? null : ( {size === undefined ? null : (
@ -148,6 +164,7 @@ export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMa
items={STYLES.size} items={STYLES.size}
value={size} value={size}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
)} )}
</div> </div>
@ -157,7 +174,13 @@ export function CommonStylePickerSet({ styles }: { styles: ReadonlySharedStyleMa
} }
/** @public */ /** @public */
export function TextStylePickerSet({ styles }: { styles: ReadonlySharedStyleMap }) { export function TextStylePickerSet({
theme,
styles,
}: {
theme: TLDefaultColorTheme
styles: ReadonlySharedStyleMap
}) {
const msg = useTranslation() const msg = useTranslation()
const handleValueChange = useStyleChangeCallback() const handleValueChange = useStyleChangeCallback()
@ -178,6 +201,7 @@ export function TextStylePickerSet({ styles }: { styles: ReadonlySharedStyleMap
items={STYLES.font} items={STYLES.font}
value={font} value={font}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
)} )}
@ -190,6 +214,7 @@ export function TextStylePickerSet({ styles }: { styles: ReadonlySharedStyleMap
items={STYLES.horizontalAlign} items={STYLES.horizontalAlign}
value={align} value={align}
onValueChange={handleValueChange} onValueChange={handleValueChange}
theme={theme}
/> />
<div className="tlui-style-panel__row__extra-button"> <div className="tlui-style-panel__row__extra-button">
{verticalAlign === undefined ? ( {verticalAlign === undefined ? (

View file

@ -3,9 +3,8 @@ import {
SharedStyle, SharedStyle,
StyleProp, StyleProp,
TLDefaultColorStyle, TLDefaultColorStyle,
getDefaultColorTheme, TLDefaultColorTheme,
useEditor, useEditor,
useValue,
} from '@tldraw/editor' } from '@tldraw/editor'
import classNames from 'classnames' import classNames from 'classnames'
import { memo, useMemo, useRef } from 'react' import { memo, useMemo, useRef } from 'react'
@ -22,6 +21,7 @@ export interface TLUiButtonPickerProps<T extends string> {
style: StyleProp<T> style: StyleProp<T>
value: SharedStyle<T> value: SharedStyle<T>
items: StyleValuesForUi<T> items: StyleValuesForUi<T>
theme: TLDefaultColorTheme
onValueChange: (style: StyleProp<T>, value: T, squashing: boolean) => void onValueChange: (style: StyleProp<T>, value: T, squashing: boolean) => void
} }
@ -34,6 +34,7 @@ function _TldrawUiButtonPicker<T extends string>(props: TLUiButtonPickerProps<T>
value, value,
// columns = clamp(items.length, 2, 4), // columns = clamp(items.length, 2, 4),
onValueChange, onValueChange,
theme,
} = props } = props
const editor = useEditor() const editor = useEditor()
const msg = useTranslation() const msg = useTranslation()
@ -91,12 +92,6 @@ function _TldrawUiButtonPicker<T extends string>(props: TLUiButtonPickerProps<T>
} }
}, [value, editor, onValueChange, style]) }, [value, editor, onValueChange, style])
const theme = useValue(
'theme',
() => getDefaultColorTheme({ isDarkMode: editor.user.getIsDarkMode() }),
[editor]
)
return ( return (
<div data-testid={`style.${uiType}`} className={classNames('tlui-buttons__grid')}> <div data-testid={`style.${uiType}`} className={classNames('tlui-buttons__grid')}>
{items.map((item) => ( {items.map((item) => (