tldraw 3.16.0-canary.c7d3f7d5729d → 3.16.0-canary.ca33603d9bda
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +131 -100
- package/dist-cjs/index.js +25 -14
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js +1 -3
- package/dist-cjs/lib/shapes/shared/PlainTextLabel.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js +0 -2
- package/dist-cjs/lib/shapes/shared/useEditablePlainText.js.map +2 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js +0 -2
- package/dist-cjs/lib/shapes/shared/useImageOrVideoAsset.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js +9 -4
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanel.js.map +2 -2
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js +255 -316
- package/dist-cjs/lib/ui/components/StylePanel/DefaultStylePanelContent.js.map +2 -2
- package/dist-cjs/lib/ui/components/{primitives/TldrawUiButtonPicker.js → StylePanel/StylePanelButtonPicker.js} +52 -45
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelButtonPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js +68 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelContext.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DoubleDropdownPicker.js → StylePanelDoubleDropdownPicker.js} +23 -22
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/{DropdownPicker.js → StylePanelDropdownPicker.js} +23 -20
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelDropdownPicker.js.map +7 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js +28 -0
- package/dist-cjs/lib/ui/components/StylePanel/StylePanelSubheading.js.map +7 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js +2 -0
- package/dist-cjs/lib/ui/components/primitives/TldrawUiToolbar.js.map +2 -2
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js +7 -4
- package/dist-cjs/lib/ui/components/primitives/TldrawUiTooltip.js.map +2 -2
- package/dist-cjs/lib/ui/context/actions.js +7 -8
- package/dist-cjs/lib/ui/context/actions.js.map +2 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js +3 -2
- package/dist-cjs/lib/ui/hooks/useExportAs.js.map +2 -2
- package/dist-cjs/lib/ui/version.js +3 -3
- package/dist-cjs/lib/ui/version.js.map +1 -1
- package/dist-cjs/lib/utils/export/copyAs.js +1 -2
- package/dist-cjs/lib/utils/export/copyAs.js.map +2 -2
- package/dist-cjs/lib/utils/export/export.js +0 -20
- package/dist-cjs/lib/utils/export/export.js.map +2 -2
- package/dist-cjs/lib/utils/export/exportAs.js +1 -2
- package/dist-cjs/lib/utils/export/exportAs.js.map +2 -2
- package/dist-esm/index.d.mts +131 -100
- package/dist-esm/index.mjs +51 -28
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs +1 -3
- package/dist-esm/lib/shapes/shared/PlainTextLabel.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useEditablePlainText.mjs.map +2 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs +0 -2
- package/dist-esm/lib/shapes/shared/useImageOrVideoAsset.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs +14 -5
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanel.mjs.map +2 -2
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs +257 -320
- package/dist-esm/lib/ui/components/StylePanel/DefaultStylePanelContent.mjs.map +2 -2
- package/dist-esm/lib/ui/components/{primitives/TldrawUiButtonPicker.mjs → StylePanel/StylePanelButtonPicker.mjs} +54 -43
- package/dist-esm/lib/ui/components/StylePanel/StylePanelButtonPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs +48 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelContext.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DoubleDropdownPicker.mjs → StylePanelDoubleDropdownPicker.mjs} +20 -19
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDoubleDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/{DropdownPicker.mjs → StylePanelDropdownPicker.mjs} +20 -17
- package/dist-esm/lib/ui/components/StylePanel/StylePanelDropdownPicker.mjs.map +7 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs +8 -0
- package/dist-esm/lib/ui/components/StylePanel/StylePanelSubheading.mjs.map +7 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs +2 -0
- package/dist-esm/lib/ui/components/primitives/TldrawUiToolbar.mjs.map +2 -2
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs +7 -4
- package/dist-esm/lib/ui/components/primitives/TldrawUiTooltip.mjs.map +2 -2
- package/dist-esm/lib/ui/context/actions.mjs +7 -8
- package/dist-esm/lib/ui/context/actions.mjs.map +2 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs +3 -2
- package/dist-esm/lib/ui/hooks/useExportAs.mjs.map +2 -2
- package/dist-esm/lib/ui/version.mjs +3 -3
- package/dist-esm/lib/ui/version.mjs.map +1 -1
- package/dist-esm/lib/utils/export/copyAs.mjs +1 -2
- package/dist-esm/lib/utils/export/copyAs.mjs.map +2 -2
- package/dist-esm/lib/utils/export/export.mjs +0 -20
- package/dist-esm/lib/utils/export/export.mjs.map +2 -2
- package/dist-esm/lib/utils/export/exportAs.mjs +1 -2
- package/dist-esm/lib/utils/export/exportAs.mjs.map +2 -2
- package/package.json +3 -3
- package/src/index.ts +38 -21
- package/src/lib/shapes/shared/PlainTextLabel.tsx +0 -6
- package/src/lib/shapes/shared/useEditablePlainText.ts +0 -6
- package/src/lib/shapes/shared/useImageOrVideoAsset.ts +0 -7
- package/src/lib/ui/components/StylePanel/DefaultStylePanel.tsx +27 -13
- package/src/lib/ui/components/StylePanel/DefaultStylePanelContent.tsx +260 -381
- package/src/lib/ui/components/{primitives/TldrawUiButtonPicker.tsx → StylePanel/StylePanelButtonPicker.tsx} +63 -50
- package/src/lib/ui/components/StylePanel/StylePanelContext.tsx +63 -0
- package/src/lib/ui/components/StylePanel/{DoubleDropdownPicker.tsx → StylePanelDoubleDropdownPicker.tsx} +28 -19
- package/src/lib/ui/components/StylePanel/StylePanelDropdownPicker.tsx +119 -0
- package/src/lib/ui/components/StylePanel/StylePanelSubheading.tsx +9 -0
- package/src/lib/ui/components/primitives/TldrawUiToolbar.tsx +3 -0
- package/src/lib/ui/components/primitives/TldrawUiTooltip.tsx +10 -6
- package/src/lib/ui/context/actions.tsx +7 -8
- package/src/lib/ui/hooks/useExportAs.ts +3 -2
- package/src/lib/ui/version.ts +3 -3
- package/src/lib/ui.css +16 -2
- package/src/lib/utils/export/copyAs.ts +1 -24
- package/src/lib/utils/export/export.ts +0 -36
- package/src/lib/utils/export/exportAs.ts +1 -32
- package/tldraw.css +16 -2
- package/dist-cjs/lib/ui/components/StylePanel/DoubleDropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/StylePanel/DropdownPicker.js.map +0 -7
- package/dist-cjs/lib/ui/components/primitives/TldrawUiButtonPicker.js.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DoubleDropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/StylePanel/DropdownPicker.mjs.map +0 -7
- package/dist-esm/lib/ui/components/primitives/TldrawUiButtonPicker.mjs.map +0 -7
- package/src/lib/ui/components/StylePanel/DropdownPicker.tsx +0 -110
|
@@ -12,417 +12,333 @@ import {
|
|
|
12
12
|
DefaultVerticalAlignStyle,
|
|
13
13
|
GeoShapeGeoStyle,
|
|
14
14
|
LineShapeSplineStyle,
|
|
15
|
-
ReadonlySharedStyleMap,
|
|
16
|
-
StyleProp,
|
|
17
15
|
TLArrowShapeArrowheadStyle,
|
|
18
|
-
TLDefaultColorTheme,
|
|
19
|
-
getDefaultColorTheme,
|
|
20
16
|
kickoutOccludedShapes,
|
|
21
17
|
minBy,
|
|
22
18
|
useEditor,
|
|
23
|
-
useIsDarkMode,
|
|
24
19
|
useValue,
|
|
25
20
|
} from '@tldraw/editor'
|
|
26
|
-
import React
|
|
21
|
+
import React from 'react'
|
|
27
22
|
import { STYLES } from '../../../styles'
|
|
28
23
|
import { useUiEvents } from '../../context/events'
|
|
29
|
-
import { useRelevantStyles } from '../../hooks/useRelevantStyles'
|
|
30
24
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
|
31
25
|
import { TldrawUiButtonIcon } from '../primitives/Button/TldrawUiButtonIcon'
|
|
32
|
-
import { TldrawUiButtonPicker } from '../primitives/TldrawUiButtonPicker'
|
|
33
26
|
import { TldrawUiSlider } from '../primitives/TldrawUiSlider'
|
|
34
27
|
import { TldrawUiToolbar, TldrawUiToolbarButton } from '../primitives/TldrawUiToolbar'
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
28
|
+
import { StylePanelButtonPicker } from './StylePanelButtonPicker'
|
|
29
|
+
import { useStylePanelContext } from './StylePanelContext'
|
|
30
|
+
import { StylePanelDoubleDropdownPicker } from './StylePanelDoubleDropdownPicker'
|
|
31
|
+
import { StylePanelDropdownPicker } from './StylePanelDropdownPicker'
|
|
32
|
+
import { StylePanelSubheading } from './StylePanelSubheading'
|
|
37
33
|
|
|
38
|
-
|
|
39
|
-
function
|
|
40
|
-
return
|
|
34
|
+
/** @public @react */
|
|
35
|
+
export function DefaultStylePanelContent() {
|
|
36
|
+
return (
|
|
37
|
+
<>
|
|
38
|
+
<StylePanelSection>
|
|
39
|
+
<StylePanelColorPicker />
|
|
40
|
+
<StylePanelOpacityPicker />
|
|
41
|
+
</StylePanelSection>
|
|
42
|
+
<StylePanelSection>
|
|
43
|
+
<StylePanelFillPicker />
|
|
44
|
+
<StylePanelDashPicker />
|
|
45
|
+
<StylePanelSizePicker />
|
|
46
|
+
</StylePanelSection>
|
|
47
|
+
<StylePanelSection>
|
|
48
|
+
<StylePanelFontPicker />
|
|
49
|
+
<StylePanelTextAlignPicker />
|
|
50
|
+
<StylePanelLabelAlignPicker />
|
|
51
|
+
</StylePanelSection>
|
|
52
|
+
<StylePanelSection>
|
|
53
|
+
<StylePanelGeoShapePicker />
|
|
54
|
+
<StylePanelArrowKindPicker />
|
|
55
|
+
<StylePanelArrowheadPicker />
|
|
56
|
+
<StylePanelSplinePicker />
|
|
57
|
+
</StylePanelSection>
|
|
58
|
+
</>
|
|
59
|
+
)
|
|
41
60
|
}
|
|
42
61
|
|
|
43
62
|
/** @public */
|
|
44
|
-
export interface
|
|
45
|
-
|
|
63
|
+
export interface StylePanelSectionProps {
|
|
64
|
+
children: React.ReactNode
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
/** @public @react */
|
|
49
|
-
export function
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (!styles) return null
|
|
53
|
-
|
|
54
|
-
const geo = styles.get(GeoShapeGeoStyle)
|
|
55
|
-
const arrowheadEnd = styles.get(ArrowShapeArrowheadEndStyle)
|
|
56
|
-
const arrowheadStart = styles.get(ArrowShapeArrowheadStartStyle)
|
|
57
|
-
const arrowKind = styles.get(ArrowShapeKindStyle)
|
|
58
|
-
const spline = styles.get(LineShapeSplineStyle)
|
|
59
|
-
const font = styles.get(DefaultFontStyle)
|
|
60
|
-
|
|
61
|
-
const hideGeo = geo === undefined
|
|
62
|
-
const hideArrowHeads = arrowheadEnd === undefined && arrowheadStart === undefined
|
|
63
|
-
const hideSpline = spline === undefined
|
|
64
|
-
const hideArrowKind = arrowKind === undefined
|
|
65
|
-
const hideText = font === undefined
|
|
68
|
+
export function StylePanelSection({ children }: StylePanelSectionProps) {
|
|
69
|
+
return <div className="tlui-style-panel__section">{children}</div>
|
|
70
|
+
}
|
|
66
71
|
|
|
67
|
-
|
|
72
|
+
/** @public @react */
|
|
73
|
+
export function StylePanelColorPicker() {
|
|
74
|
+
const { styles } = useStylePanelContext()
|
|
75
|
+
const msg = useTranslation()
|
|
76
|
+
const color = styles.get(DefaultColorStyle)
|
|
77
|
+
if (color === undefined) return null
|
|
68
78
|
|
|
69
79
|
return (
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<ArrowheadStylePickerSet styles={styles} />
|
|
78
|
-
<SplineStylePickerSet styles={styles} />
|
|
79
|
-
</div>
|
|
80
|
-
)}
|
|
81
|
-
</>
|
|
80
|
+
<StylePanelButtonPicker
|
|
81
|
+
title={msg('style-panel.color')}
|
|
82
|
+
uiType="color"
|
|
83
|
+
style={DefaultColorStyle}
|
|
84
|
+
items={STYLES.color}
|
|
85
|
+
value={color}
|
|
86
|
+
/>
|
|
82
87
|
)
|
|
83
88
|
}
|
|
84
89
|
|
|
85
|
-
|
|
90
|
+
const tldrawSupportedOpacities = [0.1, 0.25, 0.5, 0.75, 1] as const
|
|
91
|
+
/** @public @react */
|
|
92
|
+
export function StylePanelOpacityPicker() {
|
|
86
93
|
const editor = useEditor()
|
|
94
|
+
const { onHistoryMark, showUiLabels } = useStylePanelContext()
|
|
95
|
+
|
|
96
|
+
const opacity = useValue('opacity', () => editor.getSharedOpacity(), [editor])
|
|
87
97
|
const trackEvent = useUiEvents()
|
|
98
|
+
const msg = useTranslation()
|
|
99
|
+
|
|
100
|
+
const handleOpacityValueChange = React.useCallback(
|
|
101
|
+
(value: number) => {
|
|
102
|
+
const item = tldrawSupportedOpacities[value]
|
|
103
|
+
editor.run(() => {
|
|
104
|
+
if (editor.isIn('select')) {
|
|
105
|
+
editor.setOpacityForSelectedShapes(item)
|
|
106
|
+
}
|
|
107
|
+
editor.setOpacityForNextShapes(item)
|
|
108
|
+
editor.updateInstanceState({ isChangingStyle: true })
|
|
109
|
+
})
|
|
88
110
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
function handleStyleChange<T>(style: StyleProp<T>, value: T) {
|
|
92
|
-
editor.run(() => {
|
|
93
|
-
if (editor.isIn('select')) {
|
|
94
|
-
editor.setStyleForSelectedShapes(style, value)
|
|
95
|
-
}
|
|
96
|
-
editor.setStyleForNextShapes(style, value)
|
|
97
|
-
editor.updateInstanceState({ isChangingStyle: true })
|
|
98
|
-
})
|
|
99
|
-
|
|
100
|
-
trackEvent('set-style', { source: 'style-panel', id: style.id, value: value as string })
|
|
101
|
-
},
|
|
111
|
+
trackEvent('set-style', { source: 'style-panel', id: 'opacity', value })
|
|
112
|
+
},
|
|
102
113
|
[editor, trackEvent]
|
|
103
114
|
)
|
|
104
|
-
}
|
|
105
115
|
|
|
106
|
-
|
|
107
|
-
export interface ThemeStylePickerSetProps {
|
|
108
|
-
styles: ReadonlySharedStyleMap
|
|
109
|
-
theme: TLDefaultColorTheme
|
|
110
|
-
}
|
|
116
|
+
if (opacity === undefined) return null
|
|
111
117
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
118
|
+
const opacityIndex =
|
|
119
|
+
opacity.type === 'mixed'
|
|
120
|
+
? -1
|
|
121
|
+
: tldrawSupportedOpacities.indexOf(
|
|
122
|
+
minBy(tldrawSupportedOpacities, (supportedOpacity) =>
|
|
123
|
+
Math.abs(supportedOpacity - opacity.value)
|
|
124
|
+
)!
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
<>
|
|
129
|
+
{showUiLabels && <StylePanelSubheading>{msg('style-panel.opacity')}</StylePanelSubheading>}
|
|
130
|
+
<TldrawUiSlider
|
|
131
|
+
data-testid="style.opacity"
|
|
132
|
+
value={opacityIndex >= 0 ? opacityIndex : tldrawSupportedOpacities.length - 1}
|
|
133
|
+
label={opacity.type === 'mixed' ? 'style-panel.mixed' : `opacity-style.${opacity.value}`}
|
|
134
|
+
onValueChange={handleOpacityValueChange}
|
|
135
|
+
steps={tldrawSupportedOpacities.length - 1}
|
|
136
|
+
title={msg('style-panel.opacity')}
|
|
137
|
+
onHistoryMark={onHistoryMark}
|
|
138
|
+
ariaValueModifier={25}
|
|
139
|
+
/>
|
|
140
|
+
</>
|
|
141
|
+
)
|
|
115
142
|
}
|
|
116
143
|
|
|
117
144
|
/** @public @react */
|
|
118
|
-
export function
|
|
145
|
+
export function StylePanelFillPicker() {
|
|
146
|
+
const { styles } = useStylePanelContext()
|
|
119
147
|
const msg = useTranslation()
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
const onHistoryMark = useCallback((id: string) => editor.markHistoryStoppingPoint(id), [editor])
|
|
123
|
-
const showUiLabels = useValue('showUiLabels', () => editor.user.getShowUiLabels(), [editor])
|
|
148
|
+
const fill = styles.get(DefaultFillStyle)
|
|
149
|
+
if (fill === undefined) return null
|
|
124
150
|
|
|
125
|
-
|
|
151
|
+
return (
|
|
152
|
+
<StylePanelButtonPicker
|
|
153
|
+
title={msg('style-panel.fill')}
|
|
154
|
+
uiType="fill"
|
|
155
|
+
style={DefaultFillStyle}
|
|
156
|
+
items={STYLES.fill}
|
|
157
|
+
value={fill}
|
|
158
|
+
/>
|
|
159
|
+
)
|
|
160
|
+
}
|
|
126
161
|
|
|
127
|
-
|
|
128
|
-
|
|
162
|
+
/** @public @react */
|
|
163
|
+
export function StylePanelDashPicker() {
|
|
164
|
+
const { styles } = useStylePanelContext()
|
|
165
|
+
const msg = useTranslation()
|
|
129
166
|
const dash = styles.get(DefaultDashStyle)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const showPickers = fill !== undefined || dash !== undefined || size !== undefined
|
|
167
|
+
if (dash === undefined) return null
|
|
133
168
|
|
|
134
169
|
return (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.color')}>
|
|
143
|
-
<TldrawUiButtonPicker
|
|
144
|
-
title={msg('style-panel.color')}
|
|
145
|
-
uiType="color"
|
|
146
|
-
style={DefaultColorStyle}
|
|
147
|
-
items={STYLES.color}
|
|
148
|
-
value={color}
|
|
149
|
-
onValueChange={handleValueChange}
|
|
150
|
-
theme={theme}
|
|
151
|
-
onHistoryMark={onHistoryMark}
|
|
152
|
-
/>
|
|
153
|
-
</TldrawUiToolbar>
|
|
154
|
-
</>
|
|
155
|
-
)}
|
|
156
|
-
<OpacitySlider />
|
|
157
|
-
</div>
|
|
158
|
-
{showPickers && (
|
|
159
|
-
<div className="tlui-style-panel__section">
|
|
160
|
-
{fill === undefined ? null : (
|
|
161
|
-
<>
|
|
162
|
-
{showUiLabels && (
|
|
163
|
-
<StylePanelSubheading>{msg('style-panel.fill')}</StylePanelSubheading>
|
|
164
|
-
)}
|
|
165
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.fill')}>
|
|
166
|
-
<TldrawUiButtonPicker
|
|
167
|
-
title={msg('style-panel.fill')}
|
|
168
|
-
uiType="fill"
|
|
169
|
-
style={DefaultFillStyle}
|
|
170
|
-
items={STYLES.fill}
|
|
171
|
-
value={fill}
|
|
172
|
-
onValueChange={handleValueChange}
|
|
173
|
-
theme={theme}
|
|
174
|
-
onHistoryMark={onHistoryMark}
|
|
175
|
-
/>
|
|
176
|
-
</TldrawUiToolbar>
|
|
177
|
-
</>
|
|
178
|
-
)}
|
|
179
|
-
{dash === undefined ? null : (
|
|
180
|
-
<>
|
|
181
|
-
{showUiLabels && (
|
|
182
|
-
<StylePanelSubheading>{msg('style-panel.dash')}</StylePanelSubheading>
|
|
183
|
-
)}
|
|
184
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.dash')}>
|
|
185
|
-
<TldrawUiButtonPicker
|
|
186
|
-
title={msg('style-panel.dash')}
|
|
187
|
-
uiType="dash"
|
|
188
|
-
style={DefaultDashStyle}
|
|
189
|
-
items={STYLES.dash}
|
|
190
|
-
value={dash}
|
|
191
|
-
onValueChange={handleValueChange}
|
|
192
|
-
theme={theme}
|
|
193
|
-
onHistoryMark={onHistoryMark}
|
|
194
|
-
/>
|
|
195
|
-
</TldrawUiToolbar>
|
|
196
|
-
</>
|
|
197
|
-
)}
|
|
198
|
-
{size === undefined ? null : (
|
|
199
|
-
<>
|
|
200
|
-
{showUiLabels && (
|
|
201
|
-
<StylePanelSubheading>{msg('style-panel.size')}</StylePanelSubheading>
|
|
202
|
-
)}
|
|
203
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.size')}>
|
|
204
|
-
<TldrawUiButtonPicker
|
|
205
|
-
title={msg('style-panel.size')}
|
|
206
|
-
uiType="size"
|
|
207
|
-
style={DefaultSizeStyle}
|
|
208
|
-
items={STYLES.size}
|
|
209
|
-
value={size}
|
|
210
|
-
onValueChange={(style, value) => {
|
|
211
|
-
handleValueChange(style, value)
|
|
212
|
-
const selectedShapeIds = editor.getSelectedShapeIds()
|
|
213
|
-
if (selectedShapeIds.length > 0) {
|
|
214
|
-
kickoutOccludedShapes(editor, selectedShapeIds)
|
|
215
|
-
}
|
|
216
|
-
}}
|
|
217
|
-
theme={theme}
|
|
218
|
-
onHistoryMark={onHistoryMark}
|
|
219
|
-
/>
|
|
220
|
-
</TldrawUiToolbar>
|
|
221
|
-
</>
|
|
222
|
-
)}
|
|
223
|
-
</div>
|
|
224
|
-
)}
|
|
225
|
-
</>
|
|
170
|
+
<StylePanelButtonPicker
|
|
171
|
+
title={msg('style-panel.dash')}
|
|
172
|
+
uiType="dash"
|
|
173
|
+
style={DefaultDashStyle}
|
|
174
|
+
items={STYLES.dash}
|
|
175
|
+
value={dash}
|
|
176
|
+
/>
|
|
226
177
|
)
|
|
227
178
|
}
|
|
228
179
|
|
|
229
180
|
/** @public @react */
|
|
230
|
-
export function
|
|
181
|
+
export function StylePanelSizePicker() {
|
|
182
|
+
const editor = useEditor()
|
|
183
|
+
const { styles, onValueChange } = useStylePanelContext()
|
|
231
184
|
const msg = useTranslation()
|
|
232
|
-
const
|
|
185
|
+
const size = styles.get(DefaultSizeStyle)
|
|
186
|
+
if (size === undefined) return null
|
|
233
187
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
188
|
+
return (
|
|
189
|
+
<StylePanelButtonPicker
|
|
190
|
+
title={msg('style-panel.size')}
|
|
191
|
+
uiType="size"
|
|
192
|
+
style={DefaultSizeStyle}
|
|
193
|
+
items={STYLES.size}
|
|
194
|
+
value={size}
|
|
195
|
+
onValueChange={(style, value) => {
|
|
196
|
+
onValueChange(style, value)
|
|
197
|
+
const selectedShapeIds = editor.getSelectedShapeIds()
|
|
198
|
+
if (selectedShapeIds.length > 0) {
|
|
199
|
+
kickoutOccludedShapes(editor, selectedShapeIds)
|
|
200
|
+
}
|
|
201
|
+
}}
|
|
202
|
+
/>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
238
205
|
|
|
206
|
+
/** @public @react */
|
|
207
|
+
export function StylePanelFontPicker() {
|
|
208
|
+
const { styles } = useStylePanelContext()
|
|
209
|
+
const msg = useTranslation()
|
|
239
210
|
const font = styles.get(DefaultFontStyle)
|
|
240
|
-
|
|
241
|
-
const labelAlign = styles.get(DefaultHorizontalAlignStyle)
|
|
242
|
-
const verticalLabelAlign = styles.get(DefaultVerticalAlignStyle)
|
|
243
|
-
if (font === undefined && labelAlign === undefined) {
|
|
244
|
-
return null
|
|
245
|
-
}
|
|
211
|
+
if (font === undefined) return null
|
|
246
212
|
|
|
247
213
|
return (
|
|
248
|
-
<
|
|
249
|
-
{font
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
uiType="font"
|
|
256
|
-
style={DefaultFontStyle}
|
|
257
|
-
items={STYLES.font}
|
|
258
|
-
value={font}
|
|
259
|
-
onValueChange={handleValueChange}
|
|
260
|
-
theme={theme}
|
|
261
|
-
onHistoryMark={onHistoryMark}
|
|
262
|
-
/>
|
|
263
|
-
</TldrawUiToolbar>
|
|
264
|
-
</>
|
|
265
|
-
)}
|
|
266
|
-
|
|
267
|
-
{textAlign === undefined ? null : (
|
|
268
|
-
<>
|
|
269
|
-
{showUiLabels && <StylePanelSubheading>{msg('style-panel.align')}</StylePanelSubheading>}
|
|
270
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.align')}>
|
|
271
|
-
<TldrawUiButtonPicker
|
|
272
|
-
title={msg('style-panel.align')}
|
|
273
|
-
uiType="align"
|
|
274
|
-
style={DefaultTextAlignStyle}
|
|
275
|
-
items={STYLES.textAlign}
|
|
276
|
-
value={textAlign}
|
|
277
|
-
onValueChange={handleValueChange}
|
|
278
|
-
theme={theme}
|
|
279
|
-
onHistoryMark={onHistoryMark}
|
|
280
|
-
/>
|
|
281
|
-
<TldrawUiToolbarButton
|
|
282
|
-
type="icon"
|
|
283
|
-
title={msg('style-panel.vertical-align')}
|
|
284
|
-
data-testid="vertical-align"
|
|
285
|
-
disabled
|
|
286
|
-
>
|
|
287
|
-
<TldrawUiButtonIcon icon="vertical-align-middle" />
|
|
288
|
-
</TldrawUiToolbarButton>
|
|
289
|
-
</TldrawUiToolbar>
|
|
290
|
-
</>
|
|
291
|
-
)}
|
|
292
|
-
|
|
293
|
-
{labelAlign === undefined ? null : (
|
|
294
|
-
<>
|
|
295
|
-
{showUiLabels && (
|
|
296
|
-
<StylePanelSubheading>{msg('style-panel.label-align')}</StylePanelSubheading>
|
|
297
|
-
)}
|
|
298
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.label-align')}>
|
|
299
|
-
<TldrawUiButtonPicker
|
|
300
|
-
title={msg('style-panel.label-align')}
|
|
301
|
-
uiType="align"
|
|
302
|
-
style={DefaultHorizontalAlignStyle}
|
|
303
|
-
items={STYLES.horizontalAlign}
|
|
304
|
-
value={labelAlign}
|
|
305
|
-
onValueChange={handleValueChange}
|
|
306
|
-
theme={theme}
|
|
307
|
-
onHistoryMark={onHistoryMark}
|
|
308
|
-
/>
|
|
309
|
-
{verticalLabelAlign === undefined ? (
|
|
310
|
-
<TldrawUiToolbarButton
|
|
311
|
-
type="icon"
|
|
312
|
-
title={msg('style-panel.vertical-align')}
|
|
313
|
-
data-testid="vertical-align"
|
|
314
|
-
disabled
|
|
315
|
-
>
|
|
316
|
-
<TldrawUiButtonIcon icon="vertical-align-middle" />
|
|
317
|
-
</TldrawUiToolbarButton>
|
|
318
|
-
) : (
|
|
319
|
-
<DropdownPicker
|
|
320
|
-
type="icon"
|
|
321
|
-
id="geo-vertical-alignment"
|
|
322
|
-
uiType="verticalAlign"
|
|
323
|
-
stylePanelType="vertical-align"
|
|
324
|
-
style={DefaultVerticalAlignStyle}
|
|
325
|
-
items={STYLES.verticalAlign}
|
|
326
|
-
value={verticalLabelAlign}
|
|
327
|
-
onValueChange={handleValueChange}
|
|
328
|
-
/>
|
|
329
|
-
)}
|
|
330
|
-
</TldrawUiToolbar>
|
|
331
|
-
</>
|
|
332
|
-
)}
|
|
333
|
-
</div>
|
|
214
|
+
<StylePanelButtonPicker
|
|
215
|
+
title={msg('style-panel.font')}
|
|
216
|
+
uiType="font"
|
|
217
|
+
style={DefaultFontStyle}
|
|
218
|
+
items={STYLES.font}
|
|
219
|
+
value={font}
|
|
220
|
+
/>
|
|
334
221
|
)
|
|
335
222
|
}
|
|
223
|
+
|
|
336
224
|
/** @public @react */
|
|
337
|
-
export function
|
|
225
|
+
export function StylePanelTextAlignPicker() {
|
|
226
|
+
const { styles } = useStylePanelContext()
|
|
338
227
|
const msg = useTranslation()
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
const geo = styles.get(GeoShapeGeoStyle)
|
|
342
|
-
if (geo === undefined) {
|
|
343
|
-
return null
|
|
344
|
-
}
|
|
228
|
+
const textAlign = styles.get(DefaultTextAlignStyle)
|
|
229
|
+
if (textAlign === undefined) return null
|
|
345
230
|
|
|
346
231
|
return (
|
|
347
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
style={GeoShapeGeoStyle}
|
|
355
|
-
items={STYLES.geo}
|
|
356
|
-
value={geo}
|
|
357
|
-
onValueChange={handleValueChange}
|
|
232
|
+
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.align')}>
|
|
233
|
+
<StylePanelButtonPicker
|
|
234
|
+
title={msg('style-panel.align')}
|
|
235
|
+
uiType="align"
|
|
236
|
+
style={DefaultTextAlignStyle}
|
|
237
|
+
items={STYLES.textAlign}
|
|
238
|
+
value={textAlign}
|
|
358
239
|
/>
|
|
240
|
+
<TldrawUiToolbarButton
|
|
241
|
+
type="icon"
|
|
242
|
+
title={msg('style-panel.vertical-align')}
|
|
243
|
+
data-testid="vertical-align"
|
|
244
|
+
disabled
|
|
245
|
+
>
|
|
246
|
+
<TldrawUiButtonIcon icon="vertical-align-middle" />
|
|
247
|
+
</TldrawUiToolbarButton>
|
|
359
248
|
</TldrawUiToolbar>
|
|
360
249
|
)
|
|
361
250
|
}
|
|
251
|
+
|
|
362
252
|
/** @public @react */
|
|
363
|
-
export function
|
|
253
|
+
export function StylePanelLabelAlignPicker() {
|
|
254
|
+
const { styles } = useStylePanelContext()
|
|
364
255
|
const msg = useTranslation()
|
|
365
|
-
const
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if (spline === undefined) {
|
|
369
|
-
return null
|
|
370
|
-
}
|
|
256
|
+
const labelAlign = styles.get(DefaultHorizontalAlignStyle)
|
|
257
|
+
const verticalLabelAlign = styles.get(DefaultVerticalAlignStyle)
|
|
258
|
+
if (labelAlign === undefined) return null
|
|
371
259
|
|
|
372
260
|
return (
|
|
373
|
-
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.
|
|
374
|
-
<
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
style={LineShapeSplineStyle}
|
|
381
|
-
items={STYLES.spline}
|
|
382
|
-
value={spline}
|
|
383
|
-
onValueChange={handleValueChange}
|
|
261
|
+
<TldrawUiToolbar orientation="horizontal" label={msg('style-panel.label-align')}>
|
|
262
|
+
<StylePanelButtonPicker
|
|
263
|
+
title={msg('style-panel.label-align')}
|
|
264
|
+
uiType="align"
|
|
265
|
+
style={DefaultHorizontalAlignStyle}
|
|
266
|
+
items={STYLES.horizontalAlign}
|
|
267
|
+
value={labelAlign}
|
|
384
268
|
/>
|
|
269
|
+
{verticalLabelAlign === undefined ? (
|
|
270
|
+
<TldrawUiToolbarButton
|
|
271
|
+
type="icon"
|
|
272
|
+
title={msg('style-panel.vertical-align')}
|
|
273
|
+
data-testid="vertical-align"
|
|
274
|
+
disabled
|
|
275
|
+
>
|
|
276
|
+
<TldrawUiButtonIcon icon="vertical-align-middle" />
|
|
277
|
+
</TldrawUiToolbarButton>
|
|
278
|
+
) : (
|
|
279
|
+
<StylePanelDropdownPicker
|
|
280
|
+
type="icon"
|
|
281
|
+
id="geo-vertical-alignment"
|
|
282
|
+
uiType="verticalAlign"
|
|
283
|
+
stylePanelType="vertical-align"
|
|
284
|
+
style={DefaultVerticalAlignStyle}
|
|
285
|
+
items={STYLES.verticalAlign}
|
|
286
|
+
value={verticalLabelAlign}
|
|
287
|
+
/>
|
|
288
|
+
)}
|
|
385
289
|
</TldrawUiToolbar>
|
|
386
290
|
)
|
|
387
291
|
}
|
|
292
|
+
|
|
388
293
|
/** @public @react */
|
|
389
|
-
export function
|
|
390
|
-
const
|
|
391
|
-
const
|
|
294
|
+
export function StylePanelGeoShapePicker() {
|
|
295
|
+
const { styles } = useStylePanelContext()
|
|
296
|
+
const geo = styles.get(GeoShapeGeoStyle)
|
|
297
|
+
if (geo === undefined) return null
|
|
298
|
+
|
|
299
|
+
return (
|
|
300
|
+
<StylePanelDropdownPicker
|
|
301
|
+
label="style-panel.geo"
|
|
302
|
+
type="menu"
|
|
303
|
+
id="geo"
|
|
304
|
+
uiType="geo"
|
|
305
|
+
stylePanelType="geo"
|
|
306
|
+
style={GeoShapeGeoStyle}
|
|
307
|
+
items={STYLES.geo}
|
|
308
|
+
value={geo}
|
|
309
|
+
/>
|
|
310
|
+
)
|
|
311
|
+
}
|
|
392
312
|
|
|
313
|
+
/** @public @react */
|
|
314
|
+
export function StylePanelArrowKindPicker() {
|
|
315
|
+
const { styles } = useStylePanelContext()
|
|
393
316
|
const arrowKind = styles.get(ArrowShapeKindStyle)
|
|
394
|
-
if (arrowKind === undefined)
|
|
395
|
-
return null
|
|
396
|
-
}
|
|
317
|
+
if (arrowKind === undefined) return null
|
|
397
318
|
|
|
398
319
|
return (
|
|
399
|
-
<
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
onValueChange={handleValueChange}
|
|
410
|
-
/>
|
|
411
|
-
</TldrawUiToolbar>
|
|
320
|
+
<StylePanelDropdownPicker
|
|
321
|
+
id="arrow-kind"
|
|
322
|
+
type="menu"
|
|
323
|
+
label={'style-panel.arrow-kind'}
|
|
324
|
+
uiType="arrow-kind"
|
|
325
|
+
stylePanelType="arrow-kind"
|
|
326
|
+
style={ArrowShapeKindStyle}
|
|
327
|
+
items={STYLES.arrowKind}
|
|
328
|
+
value={arrowKind}
|
|
329
|
+
/>
|
|
412
330
|
)
|
|
413
331
|
}
|
|
414
|
-
/** @public @react */
|
|
415
|
-
export function ArrowheadStylePickerSet({ styles }: StylePickerSetProps) {
|
|
416
|
-
const handleValueChange = useStyleChangeCallback()
|
|
417
332
|
|
|
333
|
+
/** @public @react */
|
|
334
|
+
export function StylePanelArrowheadPicker() {
|
|
335
|
+
const { styles } = useStylePanelContext()
|
|
418
336
|
const arrowheadEnd = styles.get(ArrowShapeArrowheadEndStyle)
|
|
419
337
|
const arrowheadStart = styles.get(ArrowShapeArrowheadStartStyle)
|
|
420
|
-
if (
|
|
421
|
-
return null
|
|
422
|
-
}
|
|
338
|
+
if (arrowheadEnd === undefined || arrowheadStart === undefined) return null
|
|
423
339
|
|
|
424
340
|
return (
|
|
425
|
-
<
|
|
341
|
+
<StylePanelDoubleDropdownPicker<TLArrowShapeArrowheadStyle>
|
|
426
342
|
label={'style-panel.arrowheads'}
|
|
427
343
|
uiTypeA="arrowheadStart"
|
|
428
344
|
styleA={ArrowShapeArrowheadStartStyle}
|
|
@@ -432,65 +348,28 @@ export function ArrowheadStylePickerSet({ styles }: StylePickerSetProps) {
|
|
|
432
348
|
styleB={ArrowShapeArrowheadEndStyle}
|
|
433
349
|
itemsB={STYLES.arrowheadEnd}
|
|
434
350
|
valueB={arrowheadEnd}
|
|
435
|
-
onValueChange={handleValueChange}
|
|
436
351
|
labelA="style-panel.arrowhead-start"
|
|
437
352
|
labelB="style-panel.arrowhead-end"
|
|
438
353
|
/>
|
|
439
354
|
)
|
|
440
355
|
}
|
|
441
356
|
|
|
442
|
-
const tldrawSupportedOpacities = [0.1, 0.25, 0.5, 0.75, 1] as const
|
|
443
357
|
/** @public @react */
|
|
444
|
-
export function
|
|
445
|
-
const
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const showUiLabels = useValue('showUiLabels', () => editor.user.getShowUiLabels(), [editor])
|
|
449
|
-
|
|
450
|
-
const opacity = useValue('opacity', () => editor.getSharedOpacity(), [editor])
|
|
451
|
-
const trackEvent = useUiEvents()
|
|
452
|
-
const msg = useTranslation()
|
|
453
|
-
|
|
454
|
-
const handleOpacityValueChange = React.useCallback(
|
|
455
|
-
(value: number) => {
|
|
456
|
-
const item = tldrawSupportedOpacities[value]
|
|
457
|
-
editor.run(() => {
|
|
458
|
-
if (editor.isIn('select')) {
|
|
459
|
-
editor.setOpacityForSelectedShapes(item)
|
|
460
|
-
}
|
|
461
|
-
editor.setOpacityForNextShapes(item)
|
|
462
|
-
editor.updateInstanceState({ isChangingStyle: true })
|
|
463
|
-
})
|
|
464
|
-
|
|
465
|
-
trackEvent('set-style', { source: 'style-panel', id: 'opacity', value })
|
|
466
|
-
},
|
|
467
|
-
[editor, trackEvent]
|
|
468
|
-
)
|
|
469
|
-
|
|
470
|
-
if (opacity === undefined) return null
|
|
471
|
-
|
|
472
|
-
const opacityIndex =
|
|
473
|
-
opacity.type === 'mixed'
|
|
474
|
-
? -1
|
|
475
|
-
: tldrawSupportedOpacities.indexOf(
|
|
476
|
-
minBy(tldrawSupportedOpacities, (supportedOpacity) =>
|
|
477
|
-
Math.abs(supportedOpacity - opacity.value)
|
|
478
|
-
)!
|
|
479
|
-
)
|
|
358
|
+
export function StylePanelSplinePicker() {
|
|
359
|
+
const { styles } = useStylePanelContext()
|
|
360
|
+
const spline = styles.get(LineShapeSplineStyle)
|
|
361
|
+
if (spline === undefined) return null
|
|
480
362
|
|
|
481
363
|
return (
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
ariaValueModifier={25}
|
|
493
|
-
/>
|
|
494
|
-
</>
|
|
364
|
+
<StylePanelDropdownPicker
|
|
365
|
+
type="menu"
|
|
366
|
+
id="spline"
|
|
367
|
+
uiType="spline"
|
|
368
|
+
stylePanelType="spline"
|
|
369
|
+
label="style-panel.spline"
|
|
370
|
+
style={LineShapeSplineStyle}
|
|
371
|
+
items={STYLES.spline}
|
|
372
|
+
value={spline}
|
|
373
|
+
/>
|
|
495
374
|
)
|
|
496
375
|
}
|