From f59bfe01b18b4bc45d55c88e14d3883e7197d76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mitja=20Bezen=C5=A1ek?= Date: Fri, 19 May 2023 12:23:43 +0200 Subject: [PATCH] Vertical text alignment for geo shapes (#1414) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- assets/icons/icon/vertical-align-center.svg | 7 ++++ assets/icons/icon/vertical-align-end.svg | 5 +++ assets/icons/icon/vertical-align-start.svg | 5 +++ assets/translations/main.json | 1 + packages/assets/imports.d.ts | 3 ++ packages/assets/imports.js | 6 ++++ packages/assets/urls.d.ts | 3 ++ packages/assets/urls.js | 12 +++++++ packages/editor/api-report.md | 4 ++- packages/editor/editor.css | 1 - .../shapeutils/TLArrowUtil/TLArrowUtil.tsx | 1 + .../app/shapeutils/TLGeoUtil/TLGeoUtil.tsx | 6 +++- .../app/shapeutils/TLNoteUtil/TLNoteUtil.tsx | 2 ++ .../app/shapeutils/TLTextUtil/TLTextUtil.tsx | 1 + .../lib/app/shapeutils/shared/TextLabel.tsx | 12 ++++++- .../shapeutils/shared/getTextSvgElement.ts | 19 ++++++++-- packages/editor/src/lib/constants.ts | 5 +++ .../__snapshots__/packShapes.test.ts.snap | 6 ++++ packages/editor/src/lib/test/props.test.ts | 5 +++ packages/tlschema/api-report.md | 16 ++++++++- packages/tlschema/src/index.ts | 1 + packages/tlschema/src/migrations.test.ts | 36 +++++++++++++++++++ packages/tlschema/src/records/TLInstance.ts | 24 ++++++++++++- packages/tlschema/src/shapes/TLGeoShape.ts | 25 ++++++++++++- packages/tlschema/src/style-types.ts | 21 +++++++++++ packages/tlschema/src/validation.ts | 3 ++ packages/ui/api-report.md | 6 ++-- .../components/StylePanel/DropdownPicker.tsx | 5 +-- .../lib/components/StylePanel/StylePanel.tsx | 26 ++++++++++---- .../hooks/useTranslation/TLTranslationKey.ts | 1 + .../useTranslation/defaultTranslation.ts | 1 + packages/ui/src/lib/icon-types.ts | 6 ++++ 32 files changed, 254 insertions(+), 21 deletions(-) create mode 100644 assets/icons/icon/vertical-align-center.svg create mode 100644 assets/icons/icon/vertical-align-end.svg create mode 100644 assets/icons/icon/vertical-align-start.svg diff --git a/assets/icons/icon/vertical-align-center.svg b/assets/icons/icon/vertical-align-center.svg new file mode 100644 index 000000000..7055700d7 --- /dev/null +++ b/assets/icons/icon/vertical-align-center.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/icons/icon/vertical-align-end.svg b/assets/icons/icon/vertical-align-end.svg new file mode 100644 index 000000000..43c1af4e1 --- /dev/null +++ b/assets/icons/icon/vertical-align-end.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/icons/icon/vertical-align-start.svg b/assets/icons/icon/vertical-align-start.svg new file mode 100644 index 000000000..a3656224a --- /dev/null +++ b/assets/icons/icon/vertical-align-start.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/translations/main.json b/assets/translations/main.json index f3b459476..27fe192af 100644 --- a/assets/translations/main.json +++ b/assets/translations/main.json @@ -272,6 +272,7 @@ "shortcuts-dialog.view": "View", "style-panel.title": "Styles", "style-panel.align": "Align", + "style-panel.vertical-align": "Vertical align", "style-panel.position": "Position", "style-panel.arrowheads": "Arrowheads", "style-panel.arrowhead-start": "Start", diff --git a/packages/assets/imports.d.ts b/packages/assets/imports.d.ts index 75c5d0dfa..916615964 100644 --- a/packages/assets/imports.d.ts +++ b/packages/assets/imports.d.ts @@ -165,6 +165,9 @@ export function getAssetUrlsByImport(opts?: AssetUrlOptions): { ungroup: string 'unlock-small': string unlock: string + 'vertical-align-center': string + 'vertical-align-end': string + 'vertical-align-start': string visible: string 'warning-triangle': string 'zoom-in': string diff --git a/packages/assets/imports.js b/packages/assets/imports.js index 251df116c..44904a09d 100644 --- a/packages/assets/imports.js +++ b/packages/assets/imports.js @@ -176,6 +176,9 @@ import iconsUndo from './icons/icon/undo.svg' import iconsUngroup from './icons/icon/ungroup.svg' import iconsUnlockSmall from './icons/icon/unlock-small.svg' import iconsUnlock from './icons/icon/unlock.svg' +import iconsVerticalAlignCenter from './icons/icon/vertical-align-center.svg' +import iconsVerticalAlignEnd from './icons/icon/vertical-align-end.svg' +import iconsVerticalAlignStart from './icons/icon/vertical-align-start.svg' import iconsVisible from './icons/icon/visible.svg' import iconsWarningTriangle from './icons/icon/warning-triangle.svg' import iconsZoomIn from './icons/icon/zoom-in.svg' @@ -403,6 +406,9 @@ export function getAssetUrlsByImport(opts) { ungroup: formatAssetUrl(iconsUngroup, opts), 'unlock-small': formatAssetUrl(iconsUnlockSmall, opts), unlock: formatAssetUrl(iconsUnlock, opts), + 'vertical-align-center': formatAssetUrl(iconsVerticalAlignCenter, opts), + 'vertical-align-end': formatAssetUrl(iconsVerticalAlignEnd, opts), + 'vertical-align-start': formatAssetUrl(iconsVerticalAlignStart, opts), visible: formatAssetUrl(iconsVisible, opts), 'warning-triangle': formatAssetUrl(iconsWarningTriangle, opts), 'zoom-in': formatAssetUrl(iconsZoomIn, opts), diff --git a/packages/assets/urls.d.ts b/packages/assets/urls.d.ts index 1db9cb6a4..09b8dac4d 100644 --- a/packages/assets/urls.d.ts +++ b/packages/assets/urls.d.ts @@ -165,6 +165,9 @@ export function getAssetUrlsByMetaUrl(opts?: AssetUrlOptions): { ungroup: string 'unlock-small': string unlock: string + 'vertical-align-center': string + 'vertical-align-end': string + 'vertical-align-start': string visible: string 'warning-triangle': string 'zoom-in': string diff --git a/packages/assets/urls.js b/packages/assets/urls.js index 947ac2005..c06c3c136 100644 --- a/packages/assets/urls.js +++ b/packages/assets/urls.js @@ -539,6 +539,18 @@ export function getAssetUrlsByMetaUrl(opts) { opts ), unlock: formatAssetUrl(new URL('./icons/icon/unlock.svg', import.meta.url).href, opts), + 'vertical-align-center': formatAssetUrl( + new URL('./icons/icon/vertical-align-center.svg', import.meta.url).href, + opts + ), + 'vertical-align-end': formatAssetUrl( + new URL('./icons/icon/vertical-align-end.svg', import.meta.url).href, + opts + ), + 'vertical-align-start': formatAssetUrl( + new URL('./icons/icon/vertical-align-start.svg', import.meta.url).href, + opts + ), visible: formatAssetUrl(new URL('./icons/icon/visible.svg', import.meta.url).href, opts), 'warning-triangle': formatAssetUrl( new URL('./icons/icon/warning-triangle.svg', import.meta.url).href, diff --git a/packages/editor/api-report.md b/packages/editor/api-report.md index 3450518af..899561fac 100644 --- a/packages/editor/api-report.md +++ b/packages/editor/api-report.md @@ -1720,7 +1720,7 @@ export abstract class TLBoxTool extends StateNode { // (undocumented) abstract shapeType: string; // (undocumented) - styles: ("align" | "arrowheadEnd" | "arrowheadStart" | "color" | "dash" | "fill" | "font" | "geo" | "icon" | "labelColor" | "opacity" | "size" | "spline")[]; + styles: ("align" | "arrowheadEnd" | "arrowheadStart" | "color" | "dash" | "fill" | "font" | "geo" | "icon" | "labelColor" | "opacity" | "size" | "spline" | "verticalAlign")[]; } // @public (undocumented) @@ -2127,6 +2127,7 @@ export class TLGeoUtil extends TLBoxUtil { opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1"; font: "draw" | "mono" | "sans" | "serif"; align: "end" | "middle" | "start"; + verticalAlign: "end" | "middle" | "start"; url: string; w: number; h: number; @@ -2155,6 +2156,7 @@ export class TLGeoUtil extends TLBoxUtil { opacity: "0.1" | "0.25" | "0.5" | "0.75" | "1"; font: "draw" | "mono" | "sans" | "serif"; align: "end" | "middle" | "start"; + verticalAlign: "end" | "middle" | "start"; url: string; w: number; h: number; diff --git a/packages/editor/editor.css b/packages/editor/editor.css index 14bba52d6..c8234d297 100644 --- a/packages/editor/editor.css +++ b/packages/editor/editor.css @@ -1000,7 +1000,6 @@ input, height: 100%; display: flex; justify-content: center; - align-items: center; color: var(--color-text); text-shadow: var(--tl-text-outline); overflow: hidden; diff --git a/packages/editor/src/lib/app/shapeutils/TLArrowUtil/TLArrowUtil.tsx b/packages/editor/src/lib/app/shapeutils/TLArrowUtil/TLArrowUtil.tsx index 0c941c991..55f4ffe9b 100644 --- a/packages/editor/src/lib/app/shapeutils/TLArrowUtil/TLArrowUtil.tsx +++ b/packages/editor/src/lib/app/shapeutils/TLArrowUtil/TLArrowUtil.tsx @@ -1053,6 +1053,7 @@ export class TLArrowUtil extends TLShapeUtil { fontFamily: font, padding: 0, textAlign: 'middle' as const, + verticalTextAlign: 'middle' as const, width: labelSize.w, height: labelSize.h, fontStyle: 'normal', diff --git a/packages/editor/src/lib/app/shapeutils/TLGeoUtil/TLGeoUtil.tsx b/packages/editor/src/lib/app/shapeutils/TLGeoUtil/TLGeoUtil.tsx index 6fd870b5d..ab79284a7 100644 --- a/packages/editor/src/lib/app/shapeutils/TLGeoUtil/TLGeoUtil.tsx +++ b/packages/editor/src/lib/app/shapeutils/TLGeoUtil/TLGeoUtil.tsx @@ -66,6 +66,7 @@ export class TLGeoUtil extends TLBoxUtil { font: 'draw', text: '', align: 'middle', + verticalAlign: 'middle', growY: 0, url: '', } @@ -343,7 +344,8 @@ export class TLGeoUtil extends TLBoxUtil { const forceSolid = useForceSolid() const strokeWidth = this.app.getStrokeWidth(props.size) - const { w, color, labelColor, fill, dash, growY, font, align, size, text } = props + const { w, color, labelColor, fill, dash, growY, font, align, verticalAlign, size, text } = + props const getShape = () => { const h = props.h + growY @@ -448,6 +450,7 @@ export class TLGeoUtil extends TLBoxUtil { fill={fill} size={size} align={align} + verticalAlign={verticalAlign} text={text} labelColor={this.app.getCssColor(labelColor)} wrap @@ -641,6 +644,7 @@ export class TLGeoUtil extends TLBoxUtil { fontSize: LABEL_FONT_SIZES[shape.props.size], fontFamily: font, textAlign: shape.props.align, + verticalTextAlign: shape.props.verticalAlign, padding: 16, lineHeight: TEXT_PROPS.lineHeight, fontStyle: 'normal', diff --git a/packages/editor/src/lib/app/shapeutils/TLNoteUtil/TLNoteUtil.tsx b/packages/editor/src/lib/app/shapeutils/TLNoteUtil/TLNoteUtil.tsx index 45fd1ef67..00a1723ca 100644 --- a/packages/editor/src/lib/app/shapeutils/TLNoteUtil/TLNoteUtil.tsx +++ b/packages/editor/src/lib/app/shapeutils/TLNoteUtil/TLNoteUtil.tsx @@ -82,6 +82,7 @@ export class TLNoteUtil extends TLShapeUtil { font={font} size={size} align={align} + verticalAlign="middle" text={text} labelColor="inherit" wrap @@ -135,6 +136,7 @@ export class TLNoteUtil extends TLShapeUtil { fontSize: LABEL_FONT_SIZES[shape.props.size], fontFamily: font, textAlign: shape.props.align, + verticalTextAlign: 'middle' as const, width: bounds.width - PADDING * 2, height: bounds.height - PADDING * 2, padding: 0, diff --git a/packages/editor/src/lib/app/shapeutils/TLTextUtil/TLTextUtil.tsx b/packages/editor/src/lib/app/shapeutils/TLTextUtil/TLTextUtil.tsx index 4416b1fb0..76f44f4bc 100644 --- a/packages/editor/src/lib/app/shapeutils/TLTextUtil/TLTextUtil.tsx +++ b/packages/editor/src/lib/app/shapeutils/TLTextUtil/TLTextUtil.tsx @@ -167,6 +167,7 @@ export class TLTextUtil extends TLShapeUtil { fontSize: FONT_SIZES[shape.props.size], fontFamily: font!, textAlign: shape.props.align, + verticalTextAlign: 'middle' as const, width, height, padding: 0, // no padding? diff --git a/packages/editor/src/lib/app/shapeutils/shared/TextLabel.tsx b/packages/editor/src/lib/app/shapeutils/shared/TextLabel.tsx index 873d32fce..5155be9f1 100644 --- a/packages/editor/src/lib/app/shapeutils/shared/TextLabel.tsx +++ b/packages/editor/src/lib/app/shapeutils/shared/TextLabel.tsx @@ -1,4 +1,11 @@ -import { TLAlignType, TLFillType, TLFontType, TLShape, TLSizeType } from '@tldraw/tlschema' +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' @@ -15,6 +22,7 @@ export const TextLabel = React.memo(function TextLabel< labelColor, font, align, + verticalAlign, wrap, }: { id: T['id'] @@ -23,6 +31,7 @@ export const TextLabel = React.memo(function TextLabel< font: TLFontType fill?: TLFillType align: TLAlignType + verticalAlign: TLVerticalAlignType wrap?: boolean text: string labelColor: string @@ -48,6 +57,7 @@ export const TextLabel = React.memo(function TextLabel< data-hastext={!isEmpty} data-isediting={isEditing} data-textwrap={!!wrap} + style={{ alignItems: verticalAlign === 'middle' ? 'center' : verticalAlign }} >
{ size: 'm', font: 'draw', geo: 'rectangle', + verticalAlign: 'middle', // h: 100, // w: 100, // growY: 0, @@ -51,6 +52,7 @@ describe('App.props', () => { size: 'm', font: 'draw', geo: 'rectangle', + verticalAlign: 'middle', // h: 100, // blacklisted // w: 100, // blacklisted // growY: 0, // blacklist @@ -81,6 +83,7 @@ describe('App.props', () => { font: 'draw', geo: 'rectangle', opacity: '1', + verticalAlign: 'middle', // h: null, // mixed! but also blacklisted // w: null, // mixed! but also blacklisted // growY: 0, // blacklist @@ -110,6 +113,7 @@ describe('App.props', () => { w: 100, opacity: '0.5', url: 'https://aol.com', + verticalAlign: 'start', }, }, ]) @@ -125,6 +129,7 @@ describe('App.props', () => { size: null, font: null, opacity: null, + verticalAlign: null, // growY: null, // blacklist // url: null, // blacklist }) diff --git a/packages/tlschema/api-report.md b/packages/tlschema/api-report.md index bfe1d04a6..c4a0e5fc4 100644 --- a/packages/tlschema/api-report.md +++ b/packages/tlschema/api-report.md @@ -531,7 +531,7 @@ export const TL_SIZE_TYPES: Set<"l" | "m" | "s" | "xl">; export const TL_SPLINE_TYPES: Set<"cubic" | "line">; // @public (undocumented) -export const TL_STYLE_TYPES: Set<"align" | "arrowheadEnd" | "arrowheadStart" | "color" | "dash" | "fill" | "font" | "geo" | "icon" | "labelColor" | "opacity" | "size" | "spline">; +export const TL_STYLE_TYPES: Set<"align" | "arrowheadEnd" | "arrowheadStart" | "color" | "dash" | "fill" | "font" | "geo" | "icon" | "labelColor" | "opacity" | "size" | "spline" | "verticalAlign">; // @public (undocumented) export const TL_UI_COLOR_TYPES: Set<"accent" | "black" | "muted-1" | "selection-fill" | "selection-stroke" | "white">; @@ -544,6 +544,14 @@ export interface TLAlignStyle extends TLBaseStyle { type: 'align'; } +// @public (undocumented) +export interface TLAlignStyle extends TLBaseStyle { + // (undocumented) + id: TLAlignType; + // (undocumented) + type: 'align'; +} + // @public (undocumented) export type TLAlignType = SetValue; @@ -860,6 +868,7 @@ export type TLGeoShapeProps = { opacity: TLOpacityType; font: TLFontType; align: TLAlignType; + verticalAlign: TLVerticalAlignType; url: string; w: number; h: number; @@ -1235,6 +1244,8 @@ export interface TLStyleCollections { size: TLSizeStyle[]; // (undocumented) spline: TLSplineTypeStyle[]; + // (undocumented) + verticalAlign: TLVerticalAlignStyle[]; } // @public (undocumented) @@ -1330,6 +1341,9 @@ export const TLUserPresence: RecordType; // @public (undocumented) export type TLUserPresenceId = ID; +// @public (undocumented) +export type TLVerticalAlignType = SetValue; + // @public (undocumented) export type TLVideoAsset = TLBaseAsset<'video', { w: number; diff --git a/packages/tlschema/src/index.ts b/packages/tlschema/src/index.ts index 9b46da09e..30b2a37a4 100644 --- a/packages/tlschema/src/index.ts +++ b/packages/tlschema/src/index.ts @@ -227,6 +227,7 @@ export { type TLStyleItem, type TLStyleProps, type TLStyleType, + type TLVerticalAlignType, } from './style-types' export { TL_CURSOR_TYPES, diff --git a/packages/tlschema/src/migrations.test.ts b/packages/tlschema/src/migrations.test.ts index 74ad8228e..e81bcef0a 100644 --- a/packages/tlschema/src/migrations.test.ts +++ b/packages/tlschema/src/migrations.test.ts @@ -665,6 +665,42 @@ describe('Adding check-box to geo shape', () => { }) }) +describe('Add verticalAlign to geo shape', () => { + const { up, down } = geoShapeMigrations.migrators[5] + + test('up works as expected', () => { + expect(up({ props: { type: 'ellipse' } })).toEqual({ + props: { type: 'ellipse', verticalAlign: 'middle' }, + }) + }) + test('down works as expected', () => { + expect(down({ props: { verticalAlign: 'middle', type: 'ellipse' } })).toEqual({ + props: { type: 'ellipse' }, + }) + }) +}) + +describe('Add verticalAlign to props for next shape', () => { + const { up, down } = instanceTypeMigrations.migrators[9] + test('up works as expected', () => { + expect(up({ propsForNextShape: { color: 'red' } })).toEqual({ + propsForNextShape: { + color: 'red', + verticalAlign: 'middle', + }, + }) + }) + + test('down works as expected', () => { + const instance = { propsForNextShape: { color: 'red', verticalAlign: 'middle' } } + expect(down(instance)).toEqual({ + propsForNextShape: { + color: 'red', + }, + }) + }) +}) + describe('Removing isReadOnly from user_document', () => { const { up, down } = userDocumentTypeMigrations.migrators[userDocumentVersions.RemoveIsReadOnly] const prev = { diff --git a/packages/tlschema/src/records/TLInstance.ts b/packages/tlschema/src/records/TLInstance.ts index 2eabb8038..acd0d2e91 100644 --- a/packages/tlschema/src/records/TLInstance.ts +++ b/packages/tlschema/src/records/TLInstance.ts @@ -18,6 +18,7 @@ import { sizeValidator, splineValidator, userIdValidator, + verticalAlignValidator, } from '../validation' import { TLPageId } from './TLPage' import { TLShapeProps } from './TLShape' @@ -72,6 +73,7 @@ export const instanceTypeValidator: T.Validator = T.model( opacity: opacityValidator, font: fontValidator, align: alignValidator, + verticalAlign: verticalAlignValidator, icon: iconValidator, geo: geoValidator, arrowheadStart: arrowheadValidator, @@ -102,13 +104,14 @@ const Versions = { AddFollowingUserId: 6, RemoveAlignJustify: 7, AddZoom: 8, + AddVerticalAlign: 9, } as const /** @public */ export const instanceTypeMigrations = defineMigrations({ firstVersion: Versions.Initial, // STEP 2: Update the current version to point to your latest version - currentVersion: Versions.AddZoom, + currentVersion: Versions.AddVerticalAlign, // STEP 3: Add an up+down migration for the new version here migrators: { [Versions.AddTransparentExportBgs]: { @@ -206,6 +209,24 @@ export const instanceTypeMigrations = defineMigrations({ return instance }, }, + [Versions.AddVerticalAlign]: { + up: (instance: TLInstance) => { + return { + ...instance, + propsForNextShape: { + ...instance.propsForNextShape, + verticalAlign: 'middle', + }, + } + }, + down: (instance: TLInstance) => { + const { verticalAlign: _, ...propsForNextShape } = instance.propsForNextShape + return { + ...instance, + propsForNextShape, + } + }, + }, }, }) @@ -227,6 +248,7 @@ export const TLInstance = createRecordType('instance', { icon: 'file', font: 'draw', align: 'middle', + verticalAlign: 'middle', geo: 'rectangle', arrowheadStart: 'none', arrowheadEnd: 'arrow', diff --git a/packages/tlschema/src/shapes/TLGeoShape.ts b/packages/tlschema/src/shapes/TLGeoShape.ts index e2e9d01ab..613276659 100644 --- a/packages/tlschema/src/shapes/TLGeoShape.ts +++ b/packages/tlschema/src/shapes/TLGeoShape.ts @@ -9,6 +9,7 @@ import { TLGeoType, TLOpacityType, TLSizeType, + TLVerticalAlignType, } from '../style-types' import { alignValidator, @@ -19,6 +20,7 @@ import { geoValidator, opacityValidator, sizeValidator, + verticalAlignValidator, } from '../validation' import { TLBaseShape, createShapeValidator } from './shape-validation' @@ -33,6 +35,7 @@ export type TLGeoShapeProps = { opacity: TLOpacityType font: TLFontType align: TLAlignType + verticalAlign: TLVerticalAlignType url: string w: number h: number @@ -57,6 +60,7 @@ export const geoShapeTypeValidator: T.Validator = createShapeValidat opacity: opacityValidator, font: fontValidator, align: alignValidator, + verticalAlign: verticalAlignValidator, url: T.string, w: T.nonZeroNumber, h: T.nonZeroNumber, @@ -74,13 +78,14 @@ const Versions = { AddLabelColor: 2, RemoveJustify: 3, AddCheckBox: 4, + AddVerticalAlign: 5, } as const /** @public */ export const geoShapeMigrations = defineMigrations({ // STEP 2: Update the current version to point to your latest version firstVersion: Versions.Initial, - currentVersion: Versions.AddCheckBox, + currentVersion: Versions.AddVerticalAlign, migrators: { // STEP 3: Add an up+down migration for the new version here [Versions.AddUrlProp]: { @@ -143,5 +148,23 @@ export const geoShapeMigrations = defineMigrations({ } }, }, + [Versions.AddVerticalAlign]: { + up: (shape) => { + return { + ...shape, + props: { + ...shape.props, + verticalAlign: 'middle', + }, + } + }, + down: (shape) => { + const { verticalAlign: _, ...props } = shape.props + return { + ...shape, + props, + } + }, + }, }, }) diff --git a/packages/tlschema/src/style-types.ts b/packages/tlschema/src/style-types.ts index a0efcd7f2..6bb335d2e 100644 --- a/packages/tlschema/src/style-types.ts +++ b/packages/tlschema/src/style-types.ts @@ -11,6 +11,7 @@ export const TL_STYLE_TYPES = new Set([ 'opacity', 'font', 'align', + 'verticalAlign', 'icon', 'geo', 'arrowheadStart', @@ -133,6 +134,25 @@ export interface TLAlignStyle extends TLBaseStyle { type: 'align' } +/** @public */ +export interface TLAlignStyle extends TLBaseStyle { + id: TLAlignType + type: 'align' +} + +// Geo Text Vertical Align +/** @public */ +export const TL_VERTICAL_ALIGN_TYPES = TL_ALIGN_TYPES + +/** @public */ +export type TLVerticalAlignType = SetValue + +/** @public */ +export interface TLVerticalAlignStyle extends TLBaseStyle { + id: TLVerticalAlignType + type: 'verticalAlign' +} + // Geo /** @public */ @@ -527,6 +547,7 @@ export interface TLStyleCollections { opacity: TLOpacityStyle[] font: TLFontStyle[] align: TLAlignStyle[] + verticalAlign: TLVerticalAlignStyle[] geo: TLGeoStyle[] arrowheadStart: TLArrowheadStartStyle[] arrowheadEnd: TLArrowheadEndStyle[] diff --git a/packages/tlschema/src/validation.ts b/packages/tlschema/src/validation.ts index af0b0bc84..edc5bb44d 100644 --- a/packages/tlschema/src/validation.ts +++ b/packages/tlschema/src/validation.ts @@ -18,6 +18,7 @@ import { TL_OPACITY_TYPES, TL_SIZE_TYPES, TL_SPLINE_TYPES, + TL_VERTICAL_ALIGN_TYPES, } from './style-types' /** @internal */ @@ -65,6 +66,8 @@ export const fontValidator = T.setEnum(TL_FONT_TYPES) /** @internal */ export const alignValidator = T.setEnum(TL_ALIGN_TYPES) /** @internal */ +export const verticalAlignValidator = T.setEnum(TL_VERTICAL_ALIGN_TYPES) +/** @internal */ export const arrowheadValidator = T.setEnum(TL_ARROWHEAD_TYPES) /** @internal */ export const opacityValidator = T.setEnum(TL_OPACITY_TYPES) diff --git a/packages/ui/api-report.md b/packages/ui/api-report.md index f5157d891..3d0ef2f9e 100644 --- a/packages/ui/api-report.md +++ b/packages/ui/api-report.md @@ -712,7 +712,7 @@ export type TLTranslation = { }; // @public (undocumented) -export type TLTranslationKey = 'action.align-bottom' | 'action.align-center-horizontal.short' | 'action.align-center-horizontal' | 'action.align-center-vertical.short' | 'action.align-center-vertical' | 'action.align-left' | 'action.align-right' | 'action.align-top' | 'action.back-to-content' | 'action.bring-forward' | 'action.bring-to-front' | 'action.convert-to-bookmark' | 'action.convert-to-embed' | 'action.copy-as-json.short' | 'action.copy-as-json' | 'action.copy-as-png.short' | 'action.copy-as-png' | 'action.copy-as-svg.short' | 'action.copy-as-svg' | 'action.copy' | 'action.cut' | 'action.delete' | 'action.distribute-horizontal.short' | 'action.distribute-horizontal' | 'action.distribute-vertical.short' | 'action.distribute-vertical' | 'action.duplicate' | 'action.edit-link' | 'action.exit-pen-mode' | 'action.export-as-json.short' | 'action.export-as-json' | 'action.export-as-png.short' | 'action.export-as-png' | 'action.export-as-svg.short' | 'action.export-as-svg' | 'action.flip-horizontal.short' | 'action.flip-horizontal' | 'action.flip-vertical.short' | 'action.flip-vertical' | 'action.group' | 'action.insert-embed' | 'action.insert-media' | 'action.new-project' | 'action.new-shared-project' | 'action.open-embed-link' | 'action.open-file' | 'action.pack' | 'action.paste' | 'action.print' | 'action.redo' | 'action.rotate-ccw' | 'action.rotate-cw' | 'action.save-copy' | 'action.select-all' | 'action.select-none' | 'action.send-backward' | 'action.send-to-back' | 'action.share-project' | 'action.stack-horizontal.short' | 'action.stack-horizontal' | 'action.stack-vertical.short' | 'action.stack-vertical' | 'action.stop-following' | 'action.stretch-horizontal.short' | 'action.stretch-horizontal' | 'action.stretch-vertical.short' | 'action.stretch-vertical' | 'action.toggle-auto-size' | 'action.toggle-dark-mode.menu' | 'action.toggle-dark-mode' | 'action.toggle-debug-mode.menu' | 'action.toggle-debug-mode' | 'action.toggle-focus-mode.menu' | 'action.toggle-focus-mode' | 'action.toggle-grid.menu' | 'action.toggle-grid' | 'action.toggle-snap-mode.menu' | 'action.toggle-snap-mode' | 'action.toggle-tool-lock.menu' | 'action.toggle-tool-lock' | 'action.toggle-transparent.context-menu' | 'action.toggle-transparent.menu' | 'action.toggle-transparent' | 'action.undo' | 'action.ungroup' | 'action.zoom-in' | 'action.zoom-out' | 'action.zoom-to-100' | 'action.zoom-to-fit' | 'action.zoom-to-selection' | 'actions-menu.title' | 'align-style.end' | 'align-style.justify' | 'align-style.middle' | 'align-style.start' | 'arrowheadEnd-style.arrow' | 'arrowheadEnd-style.bar' | 'arrowheadEnd-style.diamond' | 'arrowheadEnd-style.dot' | 'arrowheadEnd-style.inverted' | 'arrowheadEnd-style.none' | 'arrowheadEnd-style.pipe' | 'arrowheadEnd-style.square' | 'arrowheadEnd-style.triangle' | 'arrowheadStart-style.arrow' | 'arrowheadStart-style.bar' | 'arrowheadStart-style.diamond' | 'arrowheadStart-style.dot' | 'arrowheadStart-style.inverted' | 'arrowheadStart-style.none' | 'arrowheadStart-style.pipe' | 'arrowheadStart-style.square' | 'arrowheadStart-style.triangle' | 'color-style.black' | 'color-style.blue' | 'color-style.green' | 'color-style.grey' | 'color-style.light-blue' | 'color-style.light-green' | 'color-style.light-red' | 'color-style.light-violet' | 'color-style.orange' | 'color-style.red' | 'color-style.violet' | 'color-style.yellow' | 'context-menu.arrange' | 'context-menu.copy-as' | 'context-menu.export-as' | 'context-menu.move-to-page' | 'context-menu.reorder' | 'context.pages.new-page' | 'dash-style.dashed' | 'dash-style.dotted' | 'dash-style.draw' | 'dash-style.solid' | 'debug-panel.more' | 'edit-link-dialog.cancel' | 'edit-link-dialog.clear' | 'edit-link-dialog.detail' | 'edit-link-dialog.invalid-url' | 'edit-link-dialog.save' | 'edit-link-dialog.title' | 'edit-link-dialog.url' | 'edit-pages-dialog.move-down' | 'edit-pages-dialog.move-up' | 'embed-dialog.back' | 'embed-dialog.cancel' | 'embed-dialog.create' | 'embed-dialog.instruction' | 'embed-dialog.invalid-url' | 'embed-dialog.title' | 'embed-dialog.url' | 'file-system.confirm-clear.cancel' | 'file-system.confirm-clear.continue' | 'file-system.confirm-clear.description' | 'file-system.confirm-clear.dont-show-again' | 'file-system.confirm-clear.title' | 'file-system.confirm-open.cancel' | 'file-system.confirm-open.description' | 'file-system.confirm-open.dont-show-again' | 'file-system.confirm-open.open' | 'file-system.confirm-open.title' | 'file-system.file-open-error.file-format-version-too-new' | 'file-system.file-open-error.generic-corrupted-file' | 'file-system.file-open-error.not-a-tldraw-file' | 'file-system.file-open-error.title' | 'file-system.shared-document-file-open-error.description' | 'file-system.shared-document-file-open-error.title' | 'fill-style.none' | 'fill-style.pattern' | 'fill-style.semi' | 'fill-style.solid' | 'focus-mode.toggle-focus-mode' | 'font-style.draw' | 'font-style.mono' | 'font-style.sans' | 'font-style.serif' | 'geo-style.arrow-down' | 'geo-style.arrow-left' | 'geo-style.arrow-right' | 'geo-style.arrow-up' | 'geo-style.check-box' | 'geo-style.diamond' | 'geo-style.ellipse' | 'geo-style.hexagon' | 'geo-style.octagon' | 'geo-style.oval' | 'geo-style.pentagon' | 'geo-style.rectangle' | 'geo-style.rhombus-2' | 'geo-style.rhombus' | 'geo-style.star' | 'geo-style.trapezoid' | 'geo-style.triangle' | 'geo-style.x-box' | 'help-menu.about' | 'help-menu.discord' | 'help-menu.github' | 'help-menu.keyboard-shortcuts' | 'help-menu.title' | 'help-menu.twitter' | 'menu.copy-as' | 'menu.edit' | 'menu.export-as' | 'menu.file' | 'menu.language' | 'menu.preferences' | 'menu.title' | 'menu.view' | 'navigation-zone.toggle-minimap' | 'navigation-zone.zoom' | 'opacity-style.0.1' | 'opacity-style.0.25' | 'opacity-style.0.5' | 'opacity-style.0.75' | 'opacity-style.1' | 'page-menu.create-new-page' | 'page-menu.edit-done' | 'page-menu.edit-start' | 'page-menu.go-to-page' | 'page-menu.max-page-count-reached' | 'page-menu.new-page-initial-name' | 'page-menu.submenu.delete' | 'page-menu.submenu.duplicate-page' | 'page-menu.submenu.move-down' | 'page-menu.submenu.move-up' | 'page-menu.submenu.rename' | 'page-menu.submenu.title' | 'page-menu.title' | 'people-menu.change-color' | 'people-menu.change-name' | 'people-menu.follow' | 'people-menu.following' | 'people-menu.invite' | 'people-menu.leading' | 'people-menu.title' | 'people-menu.user' | 'share-menu.copy-link-note' | 'share-menu.copy-link' | 'share-menu.copy-readonly-link-note' | 'share-menu.copy-readonly-link' | 'share-menu.create-snapshot-link' | 'share-menu.fork-note' | 'share-menu.offline-note' | 'share-menu.project-too-large' | 'share-menu.readonly-link' | 'share-menu.save-note' | 'share-menu.share-project' | 'share-menu.snapshot-link-note' | 'share-menu.title' | 'share-menu.upload-failed' | 'shortcuts-dialog.edit' | 'shortcuts-dialog.file' | 'shortcuts-dialog.preferences' | 'shortcuts-dialog.title' | 'shortcuts-dialog.tools' | 'shortcuts-dialog.transform' | 'shortcuts-dialog.view' | 'size-style.l' | 'size-style.m' | 'size-style.s' | 'size-style.xl' | 'spline-style.cubic' | 'spline-style.line' | 'style-panel.align' | 'style-panel.arrowhead-end' | 'style-panel.arrowhead-start' | 'style-panel.arrowheads' | 'style-panel.color' | 'style-panel.dash' | 'style-panel.fill' | 'style-panel.font' | 'style-panel.geo' | 'style-panel.mixed' | 'style-panel.opacity' | 'style-panel.position' | 'style-panel.size' | 'style-panel.spline' | 'style-panel.title' | 'toast.close' | 'toast.error.copy-fail.desc' | 'toast.error.copy-fail.title' | 'toast.error.export-fail.desc' | 'toast.error.export-fail.title' | 'tool-panel.drawing' | 'tool-panel.more' | 'tool-panel.shapes' | 'tool.arrow-down' | 'tool.arrow-left' | 'tool.arrow-right' | 'tool.arrow-up' | 'tool.arrow' | 'tool.asset' | 'tool.check-box' | 'tool.diamond' | 'tool.draw' | 'tool.ellipse' | 'tool.embed' | 'tool.eraser' | 'tool.frame' | 'tool.hand' | 'tool.hexagon' | 'tool.line' | 'tool.note' | 'tool.octagon' | 'tool.oval' | 'tool.pentagon' | 'tool.rectangle' | 'tool.rhombus' | 'tool.select' | 'tool.star' | 'tool.text' | 'tool.trapezoid' | 'tool.triangle' | 'tool.x-box' | 'vscode.file-open.backup-failed' | 'vscode.file-open.backup-saved' | 'vscode.file-open.backup' | 'vscode.file-open.desc' | 'vscode.file-open.dont-show-again' | 'vscode.file-open.open'; +export type TLTranslationKey = 'action.align-bottom' | 'action.align-center-horizontal.short' | 'action.align-center-horizontal' | 'action.align-center-vertical.short' | 'action.align-center-vertical' | 'action.align-left' | 'action.align-right' | 'action.align-top' | 'action.back-to-content' | 'action.bring-forward' | 'action.bring-to-front' | 'action.convert-to-bookmark' | 'action.convert-to-embed' | 'action.copy-as-json.short' | 'action.copy-as-json' | 'action.copy-as-png.short' | 'action.copy-as-png' | 'action.copy-as-svg.short' | 'action.copy-as-svg' | 'action.copy' | 'action.cut' | 'action.delete' | 'action.distribute-horizontal.short' | 'action.distribute-horizontal' | 'action.distribute-vertical.short' | 'action.distribute-vertical' | 'action.duplicate' | 'action.edit-link' | 'action.exit-pen-mode' | 'action.export-as-json.short' | 'action.export-as-json' | 'action.export-as-png.short' | 'action.export-as-png' | 'action.export-as-svg.short' | 'action.export-as-svg' | 'action.flip-horizontal.short' | 'action.flip-horizontal' | 'action.flip-vertical.short' | 'action.flip-vertical' | 'action.group' | 'action.insert-embed' | 'action.insert-media' | 'action.new-project' | 'action.new-shared-project' | 'action.open-embed-link' | 'action.open-file' | 'action.pack' | 'action.paste' | 'action.print' | 'action.redo' | 'action.rotate-ccw' | 'action.rotate-cw' | 'action.save-copy' | 'action.select-all' | 'action.select-none' | 'action.send-backward' | 'action.send-to-back' | 'action.share-project' | 'action.stack-horizontal.short' | 'action.stack-horizontal' | 'action.stack-vertical.short' | 'action.stack-vertical' | 'action.stop-following' | 'action.stretch-horizontal.short' | 'action.stretch-horizontal' | 'action.stretch-vertical.short' | 'action.stretch-vertical' | 'action.toggle-auto-size' | 'action.toggle-dark-mode.menu' | 'action.toggle-dark-mode' | 'action.toggle-debug-mode.menu' | 'action.toggle-debug-mode' | 'action.toggle-focus-mode.menu' | 'action.toggle-focus-mode' | 'action.toggle-grid.menu' | 'action.toggle-grid' | 'action.toggle-snap-mode.menu' | 'action.toggle-snap-mode' | 'action.toggle-tool-lock.menu' | 'action.toggle-tool-lock' | 'action.toggle-transparent.context-menu' | 'action.toggle-transparent.menu' | 'action.toggle-transparent' | 'action.undo' | 'action.ungroup' | 'action.zoom-in' | 'action.zoom-out' | 'action.zoom-to-100' | 'action.zoom-to-fit' | 'action.zoom-to-selection' | 'actions-menu.title' | 'align-style.end' | 'align-style.justify' | 'align-style.middle' | 'align-style.start' | 'arrowheadEnd-style.arrow' | 'arrowheadEnd-style.bar' | 'arrowheadEnd-style.diamond' | 'arrowheadEnd-style.dot' | 'arrowheadEnd-style.inverted' | 'arrowheadEnd-style.none' | 'arrowheadEnd-style.pipe' | 'arrowheadEnd-style.square' | 'arrowheadEnd-style.triangle' | 'arrowheadStart-style.arrow' | 'arrowheadStart-style.bar' | 'arrowheadStart-style.diamond' | 'arrowheadStart-style.dot' | 'arrowheadStart-style.inverted' | 'arrowheadStart-style.none' | 'arrowheadStart-style.pipe' | 'arrowheadStart-style.square' | 'arrowheadStart-style.triangle' | 'color-style.black' | 'color-style.blue' | 'color-style.green' | 'color-style.grey' | 'color-style.light-blue' | 'color-style.light-green' | 'color-style.light-red' | 'color-style.light-violet' | 'color-style.orange' | 'color-style.red' | 'color-style.violet' | 'color-style.yellow' | 'context-menu.arrange' | 'context-menu.copy-as' | 'context-menu.export-as' | 'context-menu.move-to-page' | 'context-menu.reorder' | 'context.pages.new-page' | 'dash-style.dashed' | 'dash-style.dotted' | 'dash-style.draw' | 'dash-style.solid' | 'debug-panel.more' | 'edit-link-dialog.cancel' | 'edit-link-dialog.clear' | 'edit-link-dialog.detail' | 'edit-link-dialog.invalid-url' | 'edit-link-dialog.save' | 'edit-link-dialog.title' | 'edit-link-dialog.url' | 'edit-pages-dialog.move-down' | 'edit-pages-dialog.move-up' | 'embed-dialog.back' | 'embed-dialog.cancel' | 'embed-dialog.create' | 'embed-dialog.instruction' | 'embed-dialog.invalid-url' | 'embed-dialog.title' | 'embed-dialog.url' | 'file-system.confirm-clear.cancel' | 'file-system.confirm-clear.continue' | 'file-system.confirm-clear.description' | 'file-system.confirm-clear.dont-show-again' | 'file-system.confirm-clear.title' | 'file-system.confirm-open.cancel' | 'file-system.confirm-open.description' | 'file-system.confirm-open.dont-show-again' | 'file-system.confirm-open.open' | 'file-system.confirm-open.title' | 'file-system.file-open-error.file-format-version-too-new' | 'file-system.file-open-error.generic-corrupted-file' | 'file-system.file-open-error.not-a-tldraw-file' | 'file-system.file-open-error.title' | 'file-system.shared-document-file-open-error.description' | 'file-system.shared-document-file-open-error.title' | 'fill-style.none' | 'fill-style.pattern' | 'fill-style.semi' | 'fill-style.solid' | 'focus-mode.toggle-focus-mode' | 'font-style.draw' | 'font-style.mono' | 'font-style.sans' | 'font-style.serif' | 'geo-style.arrow-down' | 'geo-style.arrow-left' | 'geo-style.arrow-right' | 'geo-style.arrow-up' | 'geo-style.check-box' | 'geo-style.diamond' | 'geo-style.ellipse' | 'geo-style.hexagon' | 'geo-style.octagon' | 'geo-style.oval' | 'geo-style.pentagon' | 'geo-style.rectangle' | 'geo-style.rhombus-2' | 'geo-style.rhombus' | 'geo-style.star' | 'geo-style.trapezoid' | 'geo-style.triangle' | 'geo-style.x-box' | 'help-menu.about' | 'help-menu.discord' | 'help-menu.github' | 'help-menu.keyboard-shortcuts' | 'help-menu.title' | 'help-menu.twitter' | 'menu.copy-as' | 'menu.edit' | 'menu.export-as' | 'menu.file' | 'menu.language' | 'menu.preferences' | 'menu.title' | 'menu.view' | 'navigation-zone.toggle-minimap' | 'navigation-zone.zoom' | 'opacity-style.0.1' | 'opacity-style.0.25' | 'opacity-style.0.5' | 'opacity-style.0.75' | 'opacity-style.1' | 'page-menu.create-new-page' | 'page-menu.edit-done' | 'page-menu.edit-start' | 'page-menu.go-to-page' | 'page-menu.max-page-count-reached' | 'page-menu.new-page-initial-name' | 'page-menu.submenu.delete' | 'page-menu.submenu.duplicate-page' | 'page-menu.submenu.move-down' | 'page-menu.submenu.move-up' | 'page-menu.submenu.rename' | 'page-menu.submenu.title' | 'page-menu.title' | 'people-menu.change-color' | 'people-menu.change-name' | 'people-menu.follow' | 'people-menu.following' | 'people-menu.invite' | 'people-menu.leading' | 'people-menu.title' | 'people-menu.user' | 'share-menu.copy-link-note' | 'share-menu.copy-link' | 'share-menu.copy-readonly-link-note' | 'share-menu.copy-readonly-link' | 'share-menu.create-snapshot-link' | 'share-menu.fork-note' | 'share-menu.offline-note' | 'share-menu.project-too-large' | 'share-menu.readonly-link' | 'share-menu.save-note' | 'share-menu.share-project' | 'share-menu.snapshot-link-note' | 'share-menu.title' | 'share-menu.upload-failed' | 'shortcuts-dialog.edit' | 'shortcuts-dialog.file' | 'shortcuts-dialog.preferences' | 'shortcuts-dialog.title' | 'shortcuts-dialog.tools' | 'shortcuts-dialog.transform' | 'shortcuts-dialog.view' | 'size-style.l' | 'size-style.m' | 'size-style.s' | 'size-style.xl' | 'spline-style.cubic' | 'spline-style.line' | 'style-panel.align' | 'style-panel.arrowhead-end' | 'style-panel.arrowhead-start' | 'style-panel.arrowheads' | 'style-panel.color' | 'style-panel.dash' | 'style-panel.fill' | 'style-panel.font' | 'style-panel.geo' | 'style-panel.mixed' | 'style-panel.opacity' | 'style-panel.position' | 'style-panel.size' | 'style-panel.spline' | 'style-panel.title' | 'style-panel.vertical-align' | 'toast.close' | 'toast.error.copy-fail.desc' | 'toast.error.copy-fail.title' | 'toast.error.export-fail.desc' | 'toast.error.export-fail.title' | 'tool-panel.drawing' | 'tool-panel.more' | 'tool-panel.shapes' | 'tool.arrow-down' | 'tool.arrow-left' | 'tool.arrow-right' | 'tool.arrow-up' | 'tool.arrow' | 'tool.asset' | 'tool.check-box' | 'tool.diamond' | 'tool.draw' | 'tool.ellipse' | 'tool.embed' | 'tool.eraser' | 'tool.frame' | 'tool.hand' | 'tool.hexagon' | 'tool.line' | 'tool.note' | 'tool.octagon' | 'tool.oval' | 'tool.pentagon' | 'tool.rectangle' | 'tool.rhombus' | 'tool.select' | 'tool.star' | 'tool.text' | 'tool.trapezoid' | 'tool.triangle' | 'tool.x-box' | 'vscode.file-open.backup-failed' | 'vscode.file-open.backup-saved' | 'vscode.file-open.backup' | 'vscode.file-open.desc' | 'vscode.file-open.dont-show-again' | 'vscode.file-open.open'; // @public (undocumented) export type TLTranslationLocale = TLTranslations[number]['locale']; @@ -732,10 +732,10 @@ export type TLUiEventHandler export type TLUiEventSource = 'actions-menu' | 'context-menu' | 'debug-panel' | 'dialog' | 'export-menu' | 'help-menu' | 'helper-buttons' | 'kbd' | 'menu' | 'navigation-zone' | 'page-menu' | 'people-menu' | 'quick-actions' | 'share-menu' | 'toolbar' | 'unknown' | 'zoom-menu'; // @public (undocumented) -export type TLUiIconType = 'align-bottom-center' | 'align-bottom-left' | 'align-bottom-right' | 'align-bottom' | 'align-center-center' | 'align-center-horizontal' | 'align-center-left' | 'align-center-right' | 'align-center-vertical' | 'align-left' | 'align-right' | 'align-top-center' | 'align-top-left' | 'align-top-right' | 'align-top' | 'arrow-left' | 'arrowhead-arrow' | 'arrowhead-bar' | 'arrowhead-diamond' | 'arrowhead-dot' | 'arrowhead-none' | 'arrowhead-square' | 'arrowhead-triangle-inverted' | 'arrowhead-triangle' | 'aspect-ratio' | 'avatar' | 'blob' | 'bring-forward' | 'bring-to-front' | 'check' | 'checkbox-checked' | 'checkbox-empty' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'chevrons-ne' | 'chevrons-sw' | 'clipboard-copied' | 'clipboard-copy' | 'code' | 'collab' | 'color' | 'comment' | 'cross-2' | 'cross' | 'dash-dashed' | 'dash-dotted' | 'dash-draw' | 'dash-solid' | 'discord' | 'distribute-horizontal' | 'distribute-vertical' | 'dot' | 'dots-horizontal' | 'dots-vertical' | 'drag-handle-dots' | 'duplicate' | 'edit' | 'external-link' | 'file' | 'fill-none' | 'fill-pattern' | 'fill-semi' | 'fill-solid' | 'follow' | 'following' | 'font-draw' | 'font-mono' | 'font-sans' | 'font-serif' | 'geo-arrow-down' | 'geo-arrow-left' | 'geo-arrow-right' | 'geo-arrow-up' | 'geo-check-box' | 'geo-diamond' | 'geo-ellipse' | 'geo-hexagon' | 'geo-octagon' | 'geo-oval' | 'geo-pentagon' | 'geo-rectangle' | 'geo-rhombus-2' | 'geo-rhombus' | 'geo-star' | 'geo-trapezoid' | 'geo-triangle' | 'geo-x-box' | 'github' | 'group' | 'hidden' | 'image' | 'info-circle' | 'leading' | 'link' | 'lock-small' | 'lock' | 'menu' | 'minus' | 'mixed' | 'pack' | 'page' | 'plus' | 'question-mark-circle' | 'question-mark' | 'redo' | 'reset-zoom' | 'rotate-ccw' | 'rotate-cw' | 'ruler' | 'search' | 'send-backward' | 'send-to-back' | 'settings-horizontal' | 'settings-vertical-1' | 'settings-vertical' | 'share-1' | 'share-2' | 'size-extra-large' | 'size-large' | 'size-medium' | 'size-small' | 'spline-cubic' | 'spline-line' | 'stack-horizontal' | 'stack-vertical' | 'stretch-horizontal' | 'stretch-vertical' | 'text-align-center' | 'text-align-justify' | 'text-align-left' | 'text-align-right' | 'tool-arrow' | 'tool-embed' | 'tool-eraser' | 'tool-frame' | 'tool-hand' | 'tool-highlighter' | 'tool-line' | 'tool-media' | 'tool-note' | 'tool-pencil' | 'tool-pointer' | 'tool-text' | 'trash' | 'triangle-down' | 'triangle-up' | 'twitter' | 'undo' | 'ungroup' | 'unlock-small' | 'unlock' | 'visible' | 'warning-triangle' | 'zoom-in' | 'zoom-out'; +export type TLUiIconType = 'align-bottom-center' | 'align-bottom-left' | 'align-bottom-right' | 'align-bottom' | 'align-center-center' | 'align-center-horizontal' | 'align-center-left' | 'align-center-right' | 'align-center-vertical' | 'align-left' | 'align-right' | 'align-top-center' | 'align-top-left' | 'align-top-right' | 'align-top' | 'arrow-left' | 'arrowhead-arrow' | 'arrowhead-bar' | 'arrowhead-diamond' | 'arrowhead-dot' | 'arrowhead-none' | 'arrowhead-square' | 'arrowhead-triangle-inverted' | 'arrowhead-triangle' | 'aspect-ratio' | 'avatar' | 'blob' | 'bring-forward' | 'bring-to-front' | 'check' | 'checkbox-checked' | 'checkbox-empty' | 'chevron-down' | 'chevron-left' | 'chevron-right' | 'chevron-up' | 'chevrons-ne' | 'chevrons-sw' | 'clipboard-copied' | 'clipboard-copy' | 'code' | 'collab' | 'color' | 'comment' | 'cross-2' | 'cross' | 'dash-dashed' | 'dash-dotted' | 'dash-draw' | 'dash-solid' | 'discord' | 'distribute-horizontal' | 'distribute-vertical' | 'dot' | 'dots-horizontal' | 'dots-vertical' | 'drag-handle-dots' | 'duplicate' | 'edit' | 'external-link' | 'file' | 'fill-none' | 'fill-pattern' | 'fill-semi' | 'fill-solid' | 'follow' | 'following' | 'font-draw' | 'font-mono' | 'font-sans' | 'font-serif' | 'geo-arrow-down' | 'geo-arrow-left' | 'geo-arrow-right' | 'geo-arrow-up' | 'geo-check-box' | 'geo-diamond' | 'geo-ellipse' | 'geo-hexagon' | 'geo-octagon' | 'geo-oval' | 'geo-pentagon' | 'geo-rectangle' | 'geo-rhombus-2' | 'geo-rhombus' | 'geo-star' | 'geo-trapezoid' | 'geo-triangle' | 'geo-x-box' | 'github' | 'group' | 'hidden' | 'image' | 'info-circle' | 'leading' | 'link' | 'lock-small' | 'lock' | 'menu' | 'minus' | 'mixed' | 'pack' | 'page' | 'plus' | 'question-mark-circle' | 'question-mark' | 'redo' | 'reset-zoom' | 'rotate-ccw' | 'rotate-cw' | 'ruler' | 'search' | 'send-backward' | 'send-to-back' | 'settings-horizontal' | 'settings-vertical-1' | 'settings-vertical' | 'share-1' | 'share-2' | 'size-extra-large' | 'size-large' | 'size-medium' | 'size-small' | 'spline-cubic' | 'spline-line' | 'stack-horizontal' | 'stack-vertical' | 'stretch-horizontal' | 'stretch-vertical' | 'text-align-center' | 'text-align-justify' | 'text-align-left' | 'text-align-right' | 'tool-arrow' | 'tool-embed' | 'tool-eraser' | 'tool-frame' | 'tool-hand' | 'tool-highlighter' | 'tool-line' | 'tool-media' | 'tool-note' | 'tool-pencil' | 'tool-pointer' | 'tool-text' | 'trash' | 'triangle-down' | 'triangle-up' | 'twitter' | 'undo' | 'ungroup' | 'unlock-small' | 'unlock' | 'vertical-align-center' | 'vertical-align-end' | 'vertical-align-start' | 'visible' | 'warning-triangle' | 'zoom-in' | 'zoom-out'; // @public (undocumented) -export const TLUiIconTypes: readonly ["align-bottom-center", "align-bottom-left", "align-bottom-right", "align-bottom", "align-center-center", "align-center-horizontal", "align-center-left", "align-center-right", "align-center-vertical", "align-left", "align-right", "align-top-center", "align-top-left", "align-top-right", "align-top", "arrow-left", "arrowhead-arrow", "arrowhead-bar", "arrowhead-diamond", "arrowhead-dot", "arrowhead-none", "arrowhead-square", "arrowhead-triangle-inverted", "arrowhead-triangle", "aspect-ratio", "avatar", "blob", "bring-forward", "bring-to-front", "check", "checkbox-checked", "checkbox-empty", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-ne", "chevrons-sw", "clipboard-copied", "clipboard-copy", "code", "collab", "color", "comment", "cross-2", "cross", "dash-dashed", "dash-dotted", "dash-draw", "dash-solid", "discord", "distribute-horizontal", "distribute-vertical", "dot", "dots-horizontal", "dots-vertical", "drag-handle-dots", "duplicate", "edit", "external-link", "file", "fill-none", "fill-pattern", "fill-semi", "fill-solid", "follow", "following", "font-draw", "font-mono", "font-sans", "font-serif", "geo-arrow-down", "geo-arrow-left", "geo-arrow-right", "geo-arrow-up", "geo-check-box", "geo-diamond", "geo-ellipse", "geo-hexagon", "geo-octagon", "geo-oval", "geo-pentagon", "geo-rectangle", "geo-rhombus-2", "geo-rhombus", "geo-star", "geo-trapezoid", "geo-triangle", "geo-x-box", "github", "group", "hidden", "image", "info-circle", "leading", "link", "lock-small", "lock", "menu", "minus", "mixed", "pack", "page", "plus", "question-mark-circle", "question-mark", "redo", "reset-zoom", "rotate-ccw", "rotate-cw", "ruler", "search", "send-backward", "send-to-back", "settings-horizontal", "settings-vertical-1", "settings-vertical", "share-1", "share-2", "size-extra-large", "size-large", "size-medium", "size-small", "spline-cubic", "spline-line", "stack-horizontal", "stack-vertical", "stretch-horizontal", "stretch-vertical", "text-align-center", "text-align-justify", "text-align-left", "text-align-right", "tool-arrow", "tool-embed", "tool-eraser", "tool-frame", "tool-hand", "tool-highlighter", "tool-line", "tool-media", "tool-note", "tool-pencil", "tool-pointer", "tool-text", "trash", "triangle-down", "triangle-up", "twitter", "undo", "ungroup", "unlock-small", "unlock", "visible", "warning-triangle", "zoom-in", "zoom-out"]; +export const TLUiIconTypes: readonly ["align-bottom-center", "align-bottom-left", "align-bottom-right", "align-bottom", "align-center-center", "align-center-horizontal", "align-center-left", "align-center-right", "align-center-vertical", "align-left", "align-right", "align-top-center", "align-top-left", "align-top-right", "align-top", "arrow-left", "arrowhead-arrow", "arrowhead-bar", "arrowhead-diamond", "arrowhead-dot", "arrowhead-none", "arrowhead-square", "arrowhead-triangle-inverted", "arrowhead-triangle", "aspect-ratio", "avatar", "blob", "bring-forward", "bring-to-front", "check", "checkbox-checked", "checkbox-empty", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-ne", "chevrons-sw", "clipboard-copied", "clipboard-copy", "code", "collab", "color", "comment", "cross-2", "cross", "dash-dashed", "dash-dotted", "dash-draw", "dash-solid", "discord", "distribute-horizontal", "distribute-vertical", "dot", "dots-horizontal", "dots-vertical", "drag-handle-dots", "duplicate", "edit", "external-link", "file", "fill-none", "fill-pattern", "fill-semi", "fill-solid", "follow", "following", "font-draw", "font-mono", "font-sans", "font-serif", "geo-arrow-down", "geo-arrow-left", "geo-arrow-right", "geo-arrow-up", "geo-check-box", "geo-diamond", "geo-ellipse", "geo-hexagon", "geo-octagon", "geo-oval", "geo-pentagon", "geo-rectangle", "geo-rhombus-2", "geo-rhombus", "geo-star", "geo-trapezoid", "geo-triangle", "geo-x-box", "github", "group", "hidden", "image", "info-circle", "leading", "link", "lock-small", "lock", "menu", "minus", "mixed", "pack", "page", "plus", "question-mark-circle", "question-mark", "redo", "reset-zoom", "rotate-ccw", "rotate-cw", "ruler", "search", "send-backward", "send-to-back", "settings-horizontal", "settings-vertical-1", "settings-vertical", "share-1", "share-2", "size-extra-large", "size-large", "size-medium", "size-small", "spline-cubic", "spline-line", "stack-horizontal", "stack-vertical", "stretch-horizontal", "stretch-vertical", "text-align-center", "text-align-justify", "text-align-left", "text-align-right", "tool-arrow", "tool-embed", "tool-eraser", "tool-frame", "tool-hand", "tool-highlighter", "tool-line", "tool-media", "tool-note", "tool-pencil", "tool-pointer", "tool-text", "trash", "triangle-down", "triangle-up", "twitter", "undo", "ungroup", "unlock-small", "unlock", "vertical-align-center", "vertical-align-end", "vertical-align-start", "visible", "warning-triangle", "zoom-in", "zoom-out"]; // @public (undocumented) export const ToastsContext: Context; diff --git a/packages/ui/src/lib/components/StylePanel/DropdownPicker.tsx b/packages/ui/src/lib/components/StylePanel/DropdownPicker.tsx index 087398f42..01c9861b6 100644 --- a/packages/ui/src/lib/components/StylePanel/DropdownPicker.tsx +++ b/packages/ui/src/lib/components/StylePanel/DropdownPicker.tsx @@ -12,7 +12,7 @@ type AllStyles = typeof App.styles interface DropdownPickerProps { id: string - label: TLTranslationKey + label?: TLTranslationKey items: T[] styleType: TLStyleType value: T['id'] | null @@ -52,7 +52,8 @@ export const DropdownPicker = React.memo(function DropdownPicker<
= 4, })} > diff --git a/packages/ui/src/lib/components/StylePanel/StylePanel.tsx b/packages/ui/src/lib/components/StylePanel/StylePanel.tsx index 78627bdb1..53a1c6867 100644 --- a/packages/ui/src/lib/components/StylePanel/StylePanel.tsx +++ b/packages/ui/src/lib/components/StylePanel/StylePanel.tsx @@ -1,5 +1,6 @@ import { App, TLNullableShapeProps, TLStyleItem, useApp } from '@tldraw/editor' import React, { useCallback } from 'react' + import { useValue } from 'signia-react' import { useTranslation } from '../../hooks/useTranslation/useTranslation' import { Button } from '../primitives/Button' @@ -161,7 +162,7 @@ function TextStylePickerSet({ props }: { props: TLNullableShapeProps }) { const msg = useTranslation() const handleValueChange = useStyleChangeCallback() - const { font, align } = props + const { font, align, verticalAlign } = props if (font === undefined && align === undefined) { return null } @@ -189,12 +190,23 @@ function TextStylePickerSet({ props }: { props: TLNullableShapeProps }) { value={align} onValueChange={handleValueChange} /> -
)}
diff --git a/packages/ui/src/lib/hooks/useTranslation/TLTranslationKey.ts b/packages/ui/src/lib/hooks/useTranslation/TLTranslationKey.ts index 237734390..81abf52c8 100644 --- a/packages/ui/src/lib/hooks/useTranslation/TLTranslationKey.ts +++ b/packages/ui/src/lib/hooks/useTranslation/TLTranslationKey.ts @@ -276,6 +276,7 @@ export type TLTranslationKey = | 'shortcuts-dialog.view' | 'style-panel.title' | 'style-panel.align' + | 'style-panel.vertical-align' | 'style-panel.position' | 'style-panel.arrowheads' | 'style-panel.arrowhead-start' diff --git a/packages/ui/src/lib/hooks/useTranslation/defaultTranslation.ts b/packages/ui/src/lib/hooks/useTranslation/defaultTranslation.ts index 23a3d4796..94a1c28fb 100644 --- a/packages/ui/src/lib/hooks/useTranslation/defaultTranslation.ts +++ b/packages/ui/src/lib/hooks/useTranslation/defaultTranslation.ts @@ -279,6 +279,7 @@ export const DEFAULT_TRANSLATION = { 'shortcuts-dialog.view': 'View', 'style-panel.title': 'Styles', 'style-panel.align': 'Align', + 'style-panel.vertical-align': 'Vertical align', 'style-panel.position': 'Position', 'style-panel.arrowheads': 'Arrowheads', 'style-panel.arrowhead-start': 'Start', diff --git a/packages/ui/src/lib/icon-types.ts b/packages/ui/src/lib/icon-types.ts index bef1bab9e..8903d358e 100644 --- a/packages/ui/src/lib/icon-types.ts +++ b/packages/ui/src/lib/icon-types.ts @@ -156,6 +156,9 @@ export type TLUiIconType = | 'ungroup' | 'unlock-small' | 'unlock' + | 'vertical-align-center' + | 'vertical-align-end' + | 'vertical-align-start' | 'visible' | 'warning-triangle' | 'zoom-in' @@ -316,6 +319,9 @@ export const TLUiIconTypes = [ 'ungroup', 'unlock-small', 'unlock', + 'vertical-align-center', + 'vertical-align-end', + 'vertical-align-start', 'visible', 'warning-triangle', 'zoom-in',