
Vertical text alignment for geo shapes. ### Change Type - [x] `minor` — New Feature ### Test Plan 1. Add a step-by-step description of how to test your PR here. 2. - [ ] Unit Tests - [ ] Webdriver tests ### Release Notes - This adds vertical text alignment property to geo shapes. --------- Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
103 lines
2.3 KiB
TypeScript
103 lines
2.3 KiB
TypeScript
import {
|
|
TLAlignType,
|
|
TLFillType,
|
|
TLFontType,
|
|
TLShape,
|
|
TLSizeType,
|
|
TLVerticalAlignType,
|
|
} from '@tldraw/tlschema'
|
|
import React from 'react'
|
|
import { LABEL_FONT_SIZES, TEXT_PROPS } from '../../../constants'
|
|
import { stopEventPropagation } from '../../../utils/dom'
|
|
import { TextHelpers } from '../TLTextUtil/TextHelpers'
|
|
import { useEditableText } from './useEditableText'
|
|
|
|
export const TextLabel = React.memo(function TextLabel<
|
|
T extends Extract<TLShape, { props: { text: string } }>
|
|
>({
|
|
id,
|
|
type,
|
|
text,
|
|
size,
|
|
labelColor,
|
|
font,
|
|
align,
|
|
verticalAlign,
|
|
wrap,
|
|
}: {
|
|
id: T['id']
|
|
type: T['type']
|
|
size: TLSizeType
|
|
font: TLFontType
|
|
fill?: TLFillType
|
|
align: TLAlignType
|
|
verticalAlign: TLVerticalAlignType
|
|
wrap?: boolean
|
|
text: string
|
|
labelColor: string
|
|
}) {
|
|
const {
|
|
rInput,
|
|
isEmpty,
|
|
isEditing,
|
|
isEditableFromHover,
|
|
handleFocus,
|
|
handleChange,
|
|
handleKeyDown,
|
|
handleBlur,
|
|
} = useEditableText(id, type, text)
|
|
|
|
const isInteractive = isEditing || isEditableFromHover
|
|
|
|
return (
|
|
<div
|
|
className="tl-text-label"
|
|
data-font={font}
|
|
data-align={align}
|
|
data-hastext={!isEmpty}
|
|
data-isediting={isEditing}
|
|
data-textwrap={!!wrap}
|
|
style={{ alignItems: verticalAlign === 'middle' ? 'center' : verticalAlign }}
|
|
>
|
|
<div
|
|
className="tl-text-label__inner"
|
|
style={{
|
|
fontSize: LABEL_FONT_SIZES[size],
|
|
lineHeight: LABEL_FONT_SIZES[size] * TEXT_PROPS.lineHeight + 'px',
|
|
minHeight: isEmpty ? LABEL_FONT_SIZES[size] * TEXT_PROPS.lineHeight + 32 : 0,
|
|
minWidth: isEmpty ? 33 : 0,
|
|
color: labelColor,
|
|
}}
|
|
>
|
|
<div className="tl-text tl-text-content" dir="ltr">
|
|
{TextHelpers.normalizeTextForDom(text)}
|
|
</div>
|
|
{isInteractive ? (
|
|
// Consider replacing with content-editable
|
|
<textarea
|
|
ref={rInput}
|
|
className="tl-text tl-text-input"
|
|
name="text"
|
|
tabIndex={-1}
|
|
autoComplete="false"
|
|
autoCapitalize="false"
|
|
autoCorrect="false"
|
|
autoSave="false"
|
|
autoFocus={isEditing}
|
|
placeholder=""
|
|
spellCheck="true"
|
|
wrap="off"
|
|
dir="auto"
|
|
datatype="wysiwyg"
|
|
defaultValue={text}
|
|
onFocus={handleFocus}
|
|
onChange={handleChange}
|
|
onKeyDown={handleKeyDown}
|
|
onBlur={handleBlur}
|
|
onContextMenu={stopEventPropagation}
|
|
/>
|
|
) : null}
|
|
</div>
|
|
</div>
|
|
)
|
|
})
|