Cleanup @tldraw/ui types / exports (#1504)
This PR cleans up exports from TldrawUi, unifying types under `TLUi` and removing many items from exports / marking others as internal. ### Change Type - [x] `major` — Breaking Change ### Release Notes - [editor] clean up / unify types
This commit is contained in:
parent
735f1c41b7
commit
a5e653b225
61 changed files with 807 additions and 1255 deletions
|
@ -1,4 +1,4 @@
|
||||||
import { MenuGroup, Tldraw, menuItem, toolbarItem } from '@tldraw/tldraw'
|
import { TLUiMenuGroup, Tldraw, menuItem, toolbarItem } from '@tldraw/tldraw'
|
||||||
import '@tldraw/tldraw/editor.css'
|
import '@tldraw/tldraw/editor.css'
|
||||||
import '@tldraw/tldraw/ui.css'
|
import '@tldraw/tldraw/ui.css'
|
||||||
import { CardTool } from './CardTool'
|
import { CardTool } from './CardTool'
|
||||||
|
@ -44,7 +44,7 @@ export default function CustomConfigExample() {
|
||||||
// add it to that before returning the array.
|
// add it to that before returning the array.
|
||||||
const toolsGroup = keyboardShortcutsMenu.find(
|
const toolsGroup = keyboardShortcutsMenu.find(
|
||||||
(group) => group.id === 'shortcuts-dialog.tools'
|
(group) => group.id === 'shortcuts-dialog.tools'
|
||||||
) as MenuGroup
|
) as TLUiMenuGroup
|
||||||
toolsGroup.children.push(menuItem(tools.card))
|
toolsGroup.children.push(menuItem(tools.card))
|
||||||
return keyboardShortcutsMenu
|
return keyboardShortcutsMenu
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
import { linksUiOverrides } from './utils/links'
|
import { linksUiOverrides } from './utils/links'
|
||||||
// eslint-disable-next-line import/no-internal-modules
|
// eslint-disable-next-line import/no-internal-modules
|
||||||
import '@tldraw/editor/editor.css'
|
import '@tldraw/editor/editor.css'
|
||||||
import { ContextMenu, MenuSchema, TldrawUi } from '@tldraw/ui'
|
import { ContextMenu, TLUiMenuSchema, TldrawUi } from '@tldraw/ui'
|
||||||
// eslint-disable-next-line import/no-internal-modules
|
// eslint-disable-next-line import/no-internal-modules
|
||||||
import '@tldraw/ui/ui.css'
|
import '@tldraw/ui/ui.css'
|
||||||
// eslint-disable-next-line import/no-internal-modules
|
// eslint-disable-next-line import/no-internal-modules
|
||||||
|
@ -64,7 +64,7 @@ export function WrappedTldrawEditor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const menuOverrides = {
|
const menuOverrides = {
|
||||||
menu: (_editor: Editor, schema: MenuSchema, _helpers: any) => {
|
menu: (_editor: Editor, schema: TLUiMenuSchema, _helpers: any) => {
|
||||||
schema.forEach((item) => {
|
schema.forEach((item) => {
|
||||||
if (item.id === 'menu' && item.type === 'group') {
|
if (item.id === 'menu' && item.type === 'group') {
|
||||||
item.children = item.children.filter((menuItem) => {
|
item.children = item.children.filter((menuItem) => {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { menuGroup, menuItem, TldrawUiOverrides } from '@tldraw/ui'
|
import { menuGroup, menuItem, TLUiOverrides } from '@tldraw/ui'
|
||||||
import { openUrl } from './openUrl'
|
import { openUrl } from './openUrl'
|
||||||
|
|
||||||
export const GITHUB_URL = 'https://github.com/tldraw/tldraw'
|
export const GITHUB_URL = 'https://github.com/tldraw/tldraw'
|
||||||
|
@ -43,7 +43,7 @@ const linksMenuGroup = menuGroup(
|
||||||
})
|
})
|
||||||
)!
|
)!
|
||||||
|
|
||||||
export const linksUiOverrides: TldrawUiOverrides = {
|
export const linksUiOverrides: TLUiOverrides = {
|
||||||
helpMenu(editor, schema) {
|
helpMenu(editor, schema) {
|
||||||
schema.push(linksMenuGroup)
|
schema.push(linksMenuGroup)
|
||||||
return schema
|
return schema
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { Result } from '@tldraw/utils';
|
||||||
import { SerializedSchema } from '@tldraw/tlstore';
|
import { SerializedSchema } from '@tldraw/tlstore';
|
||||||
import { TLInstanceId } from '@tldraw/editor';
|
import { TLInstanceId } from '@tldraw/editor';
|
||||||
import { TLStore } from '@tldraw/editor';
|
import { TLStore } from '@tldraw/editor';
|
||||||
import { TLTranslationKey } from '@tldraw/ui';
|
import { TLUiToastsContextType } from '@tldraw/ui';
|
||||||
import { ToastsContextType } from '@tldraw/ui';
|
import { TLUiTranslationKey } from '@tldraw/ui';
|
||||||
import { UnknownRecord } from '@tldraw/tlstore';
|
import { UnknownRecord } from '@tldraw/tlstore';
|
||||||
|
|
||||||
// @internal (undocumented)
|
// @internal (undocumented)
|
||||||
|
@ -37,7 +37,7 @@ export interface LegacyTldrawDocument {
|
||||||
}
|
}
|
||||||
|
|
||||||
// @internal (undocumented)
|
// @internal (undocumented)
|
||||||
export function parseAndLoadDocument(editor: Editor, document: string, msg: (id: TLTranslationKey) => string, addToast: ToastsContextType['addToast'], onV1FileLoad?: () => void, forceDarkMode?: boolean): Promise<void>;
|
export function parseAndLoadDocument(editor: Editor, document: string, msg: (id: TLUiTranslationKey) => string, addToast: TLUiToastsContextType['addToast'], onV1FileLoad?: () => void, forceDarkMode?: boolean): Promise<void>;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export function parseTldrawJsonFile({ json, instanceId, store, }: {
|
export function parseTldrawJsonFile({ json, instanceId, store, }: {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
UnknownRecord,
|
UnknownRecord,
|
||||||
} from '@tldraw/tlstore'
|
} from '@tldraw/tlstore'
|
||||||
import { T } from '@tldraw/tlvalidate'
|
import { T } from '@tldraw/tlvalidate'
|
||||||
import { TLTranslationKey, ToastsContextType } from '@tldraw/ui'
|
import { TLUiToastsContextType, TLUiTranslationKey } from '@tldraw/ui'
|
||||||
import { exhaustiveSwitchError, Result } from '@tldraw/utils'
|
import { exhaustiveSwitchError, Result } from '@tldraw/utils'
|
||||||
import { buildFromV1Document } from './buildFromV1Document'
|
import { buildFromV1Document } from './buildFromV1Document'
|
||||||
|
|
||||||
|
@ -204,8 +204,8 @@ export async function serializeTldrawJsonBlob(store: TLStore): Promise<Blob> {
|
||||||
export async function parseAndLoadDocument(
|
export async function parseAndLoadDocument(
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
document: string,
|
document: string,
|
||||||
msg: (id: TLTranslationKey) => string,
|
msg: (id: TLUiTranslationKey) => string,
|
||||||
addToast: ToastsContextType['addToast'],
|
addToast: TLUiToastsContextType['addToast'],
|
||||||
onV1FileLoad?: () => void,
|
onV1FileLoad?: () => void,
|
||||||
forceDarkMode?: boolean
|
forceDarkMode?: boolean
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -364,7 +364,7 @@ export const geoShapeTypeValidator: T.Validator<TLGeoShape>;
|
||||||
export const geoValidator: T.Validator<"arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box">;
|
export const geoValidator: T.Validator<"arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "check-box" | "diamond" | "ellipse" | "hexagon" | "octagon" | "oval" | "pentagon" | "rectangle" | "rhombus-2" | "rhombus" | "star" | "trapezoid" | "triangle" | "x-box">;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export function getDefaultTranslationLocale(): TLTranslationLocale;
|
export function getDefaultTranslationLocale(): TLUiTranslationLocale;
|
||||||
|
|
||||||
// @public (undocumented)
|
// @public (undocumented)
|
||||||
export const groupShapeTypeMigrations: Migrations;
|
export const groupShapeTypeMigrations: Migrations;
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { LANGUAGES } from './languages'
|
import { LANGUAGES } from './languages'
|
||||||
|
|
||||||
type TLListedTranslation = {
|
/** @public */
|
||||||
|
export type TLUiLanguage = {
|
||||||
readonly locale: string
|
readonly locale: string
|
||||||
readonly label: string
|
readonly label: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type TLListedTranslations = TLListedTranslation[]
|
type TLUiTranslationLocale = TLUiLanguage['locale']
|
||||||
type TLTranslationLocale = TLListedTranslations[number]['locale']
|
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function getDefaultTranslationLocale(): TLTranslationLocale {
|
export function getDefaultTranslationLocale(): TLUiTranslationLocale {
|
||||||
const locales = typeof window !== 'undefined' ? window.navigator.languages ?? ['en'] : ['en']
|
const locales = typeof window !== 'undefined' ? window.navigator.languages ?? ['en'] : ['en']
|
||||||
return _getDefaultTranslationLocale(locales)
|
return _getDefaultTranslationLocale(locales)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function _getDefaultTranslationLocale(locales: readonly string[]): TLTranslationLocale {
|
export function _getDefaultTranslationLocale(locales: readonly string[]): TLUiTranslationLocale {
|
||||||
for (const locale of locales) {
|
for (const locale of locales) {
|
||||||
const supportedLocale = getSupportedLocale(locale)
|
const supportedLocale = getSupportedLocale(locale)
|
||||||
if (supportedLocale) {
|
if (supportedLocale) {
|
||||||
|
@ -26,7 +26,7 @@ export function _getDefaultTranslationLocale(locales: readonly string[]): TLTran
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
const DEFAULT_LOCALE_REGIONS: { [locale: string]: TLTranslationLocale } = {
|
const DEFAULT_LOCALE_REGIONS: { [locale: string]: TLUiTranslationLocale } = {
|
||||||
zh: 'zh-cn',
|
zh: 'zh-cn',
|
||||||
pt: 'pt-br',
|
pt: 'pt-br',
|
||||||
ko: 'ko-kr',
|
ko: 'ko-kr',
|
||||||
|
@ -34,7 +34,7 @@ const DEFAULT_LOCALE_REGIONS: { [locale: string]: TLTranslationLocale } = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
function getSupportedLocale(locale: string): TLTranslationLocale | null {
|
function getSupportedLocale(locale: string): TLUiTranslationLocale | null {
|
||||||
// If we have an exact match, return it!
|
// If we have an exact match, return it!
|
||||||
// (e.g. if the user has 'fr' and we have 'fr')
|
// (e.g. if the user has 'fr' and we have 'fr')
|
||||||
// (or if the user has 'pt-BR' and we have 'pt-br')
|
// (or if the user has 'pt-BR' and we have 'pt-br')
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,25 +1,16 @@
|
||||||
import * as Dialog from './lib/components/primitives/Dialog'
|
import * as Dialog from './lib/components/primitives/Dialog'
|
||||||
import * as DropdownMenu from './lib/components/primitives/DropdownMenu'
|
import * as DropdownMenu from './lib/components/primitives/DropdownMenu'
|
||||||
|
|
||||||
export { TldrawUi, TldrawUiContent, type TldrawUiProps } from './lib/TldrawUi'
|
export { TldrawUi, type TldrawUiProps } from './lib/TldrawUi'
|
||||||
export {
|
export {
|
||||||
TldrawUiContextProvider,
|
TldrawUiContextProvider,
|
||||||
type TldrawUiContextProviderProps,
|
type TldrawUiContextProviderProps,
|
||||||
} from './lib/TldrawUiContextProvider'
|
} from './lib/TldrawUiContextProvider'
|
||||||
export { setDefaultUiAssetUrls } from './lib/assetUrls'
|
export { setDefaultUiAssetUrls } from './lib/assetUrls'
|
||||||
export { ContextMenu, type ContextMenuProps } from './lib/components/ContextMenu'
|
export { ContextMenu, type TLUiContextMenuProps } from './lib/components/ContextMenu'
|
||||||
export { DebugPanel } from './lib/components/DebugPanel'
|
export { Button, type TLUiButtonProps } from './lib/components/primitives/Button'
|
||||||
export { HTMLCanvas } from './lib/components/HTMLCanvas'
|
export { Icon, type TLUiIconProps } from './lib/components/primitives/Icon'
|
||||||
export { HelpMenu, type HelpMenuProps } from './lib/components/HelpMenu'
|
export { Input, type TLUiInputProps } from './lib/components/primitives/Input'
|
||||||
export { NavigationZone } from './lib/components/NavigationZone/NavigationZone'
|
|
||||||
export { StylePanel } from './lib/components/StylePanel/StylePanel'
|
|
||||||
export { Button, type ButtonProps } from './lib/components/primitives/Button'
|
|
||||||
export { ButtonPicker, type ButtonPickerProps } from './lib/components/primitives/ButtonPicker'
|
|
||||||
export { Icon, type IconProps } from './lib/components/primitives/Icon'
|
|
||||||
export { Input, type InputProps } from './lib/components/primitives/Input'
|
|
||||||
export { Kbd, type KbdProps } from './lib/components/primitives/Kbd'
|
|
||||||
export { Slider, type SliderProps } from './lib/components/primitives/Slider'
|
|
||||||
export { BASE_URL, getBaseUrl, kbd, kbdStr, toStartCase } from './lib/components/primitives/shared'
|
|
||||||
export {
|
export {
|
||||||
compactMenuItems,
|
compactMenuItems,
|
||||||
findMenuItem,
|
findMenuItem,
|
||||||
|
@ -27,30 +18,21 @@ export {
|
||||||
menuGroup,
|
menuGroup,
|
||||||
menuItem,
|
menuItem,
|
||||||
menuSubmenu,
|
menuSubmenu,
|
||||||
useAllowGroup,
|
type TLUiCustomMenuItem,
|
||||||
useAllowUngroup,
|
type TLUiMenuChild,
|
||||||
useThreeStackableItems,
|
type TLUiMenuGroup,
|
||||||
type CustomMenuItem,
|
type TLUiMenuItem,
|
||||||
type MenuChild,
|
type TLUiMenuSchema,
|
||||||
type MenuGroup,
|
type TLUiSubMenu,
|
||||||
type MenuItem,
|
|
||||||
type MenuSchema,
|
|
||||||
type SubMenu,
|
|
||||||
} from './lib/hooks/menuHelpers'
|
} from './lib/hooks/menuHelpers'
|
||||||
export {
|
export {
|
||||||
ActionsContext,
|
|
||||||
ActionsProvider,
|
|
||||||
useActions,
|
useActions,
|
||||||
type ActionItem,
|
type TLUiActionItem,
|
||||||
type ActionsContextType,
|
type TLUiActionsContextType,
|
||||||
type ActionsProviderProps,
|
|
||||||
} from './lib/hooks/useActions'
|
} from './lib/hooks/useActions'
|
||||||
export {
|
export {
|
||||||
ActionsMenuSchemaContext,
|
|
||||||
ActionsMenuSchemaProvider,
|
|
||||||
useActionsMenuSchema,
|
useActionsMenuSchema,
|
||||||
type ActionsMenuSchemaContextType,
|
type TLUiActionsMenuSchemaContextType,
|
||||||
type ActionsMenuSchemaProviderProps,
|
|
||||||
} from './lib/hooks/useActionsMenuSchema'
|
} from './lib/hooks/useActionsMenuSchema'
|
||||||
export { AssetUrlsProvider, useAssetUrls } from './lib/hooks/useAssetUrls'
|
export { AssetUrlsProvider, useAssetUrls } from './lib/hooks/useAssetUrls'
|
||||||
export { BreakPointProvider, useBreakpoint } from './lib/hooks/useBreakpoint'
|
export { BreakPointProvider, useBreakpoint } from './lib/hooks/useBreakpoint'
|
||||||
|
@ -58,101 +40,65 @@ export { useCanRedo } from './lib/hooks/useCanRedo'
|
||||||
export { useCanUndo } from './lib/hooks/useCanUndo'
|
export { useCanUndo } from './lib/hooks/useCanUndo'
|
||||||
export { useMenuClipboardEvents, useNativeClipboardEvents } from './lib/hooks/useClipboardEvents'
|
export { useMenuClipboardEvents, useNativeClipboardEvents } from './lib/hooks/useClipboardEvents'
|
||||||
export {
|
export {
|
||||||
ContextMenuSchemaContext,
|
|
||||||
ContextMenuSchemaProvider,
|
|
||||||
useContextMenuSchema,
|
useContextMenuSchema,
|
||||||
type ContextMenuSchemaContextType,
|
type TLUiContextTTLUiMenuSchemaContextType,
|
||||||
type ContextMenuSchemaProviderProps,
|
|
||||||
} from './lib/hooks/useContextMenuSchema'
|
} from './lib/hooks/useContextMenuSchema'
|
||||||
export { useCopyAs } from './lib/hooks/useCopyAs'
|
export { useCopyAs } from './lib/hooks/useCopyAs'
|
||||||
export {
|
export {
|
||||||
DialogsContext,
|
|
||||||
DialogsProvider,
|
|
||||||
useDialogs,
|
useDialogs,
|
||||||
type DialogProps,
|
type TLUiDialog,
|
||||||
type DialogsContextType,
|
type TLUiDialogProps,
|
||||||
type DialogsProviderProps,
|
type TLUiDialogsContextType,
|
||||||
type TLDialog,
|
|
||||||
} from './lib/hooks/useDialogsProvider'
|
} from './lib/hooks/useDialogsProvider'
|
||||||
export { useEditorEvents } from './lib/hooks/useEditorEvents'
|
|
||||||
export {
|
export {
|
||||||
useEvents,
|
useEvents,
|
||||||
type EventsProviderProps,
|
type TLUiEventContextType,
|
||||||
type TLUiEventHandler,
|
type TLUiEventHandler,
|
||||||
type TLUiEventSource,
|
type TLUiEventSource,
|
||||||
} from './lib/hooks/useEventsProvider'
|
} from './lib/hooks/useEventsProvider'
|
||||||
export { useExportAs } from './lib/hooks/useExportAs'
|
export { useExportAs } from './lib/hooks/useExportAs'
|
||||||
export {
|
export {
|
||||||
HelpMenuSchemaContext,
|
|
||||||
HelpMenuSchemaProvider,
|
|
||||||
useHelpMenuSchema,
|
useHelpMenuSchema,
|
||||||
type HelpMenuSchemaProviderProps,
|
type TLUiHelpMenuSchemaContextType,
|
||||||
type HelpMenuSchemaProviderType,
|
|
||||||
} from './lib/hooks/useHelpMenuSchema'
|
} from './lib/hooks/useHelpMenuSchema'
|
||||||
export { useHighDpiCanvas } from './lib/hooks/useHighDpiCanvas'
|
|
||||||
export { useKeyboardShortcuts } from './lib/hooks/useKeyboardShortcuts'
|
export { useKeyboardShortcuts } from './lib/hooks/useKeyboardShortcuts'
|
||||||
export {
|
export {
|
||||||
KeyboardShortcutsSchemaContext,
|
|
||||||
KeyboardShortcutsSchemaProvider,
|
|
||||||
useKeyboardShortcutsSchema,
|
useKeyboardShortcutsSchema,
|
||||||
type KeyboardShortcutsSchemaContextType,
|
type TLUiKeyboardShortcutsSchemaContextType,
|
||||||
type KeyboardShortcutsSchemaProviderProps,
|
type TLUiKeyboardShortcutsSchemaProviderProps,
|
||||||
} from './lib/hooks/useKeyboardShortcutsSchema'
|
} from './lib/hooks/useKeyboardShortcutsSchema'
|
||||||
export { useLocalStorageState } from './lib/hooks/useLocalStorageState'
|
export { useLocalStorageState } from './lib/hooks/useLocalStorageState'
|
||||||
export { useMenuIsOpen } from './lib/hooks/useMenuIsOpen'
|
export { useMenuIsOpen } from './lib/hooks/useMenuIsOpen'
|
||||||
export {
|
export {
|
||||||
MenuSchemaContext,
|
|
||||||
MenuSchemaProvider,
|
|
||||||
useMenuSchema,
|
useMenuSchema,
|
||||||
type MenuSchemaContextType,
|
type TLUiMenuSchemaContextType,
|
||||||
type MenuSchemaProviderProps,
|
type TLUiMenuSchemaProviderProps,
|
||||||
} from './lib/hooks/useMenuSchema'
|
} from './lib/hooks/useMenuSchema'
|
||||||
export { usePrint } from './lib/hooks/usePrint'
|
|
||||||
export { useReadonly } from './lib/hooks/useReadonly'
|
export { useReadonly } from './lib/hooks/useReadonly'
|
||||||
export {
|
export {
|
||||||
ToastsContext,
|
|
||||||
ToastsProvider,
|
|
||||||
useToasts,
|
useToasts,
|
||||||
type TLToast,
|
type TLUiToast,
|
||||||
type TLToastAction,
|
type TLUiToastAction,
|
||||||
type ToastsContextType,
|
type TLUiToastsContextType,
|
||||||
type ToastsProviderProps,
|
|
||||||
} from './lib/hooks/useToastsProvider'
|
} from './lib/hooks/useToastsProvider'
|
||||||
export {
|
export {
|
||||||
ToolbarSchemaContext,
|
|
||||||
ToolbarSchemaProvider,
|
|
||||||
toolbarItem,
|
toolbarItem,
|
||||||
useToolbarSchema,
|
useToolbarSchema,
|
||||||
type ToolbarItem,
|
type TLUiToolbarItem,
|
||||||
type ToolbarSchemaContextType,
|
type TLUiToolbarSchemaContextType,
|
||||||
type ToolbarSchemaProviderProps,
|
|
||||||
} from './lib/hooks/useToolbarSchema'
|
} from './lib/hooks/useToolbarSchema'
|
||||||
export {
|
export {
|
||||||
ToolsContext,
|
|
||||||
ToolsProvider,
|
|
||||||
useTools,
|
useTools,
|
||||||
type ToolItem,
|
type TLUiToolItem,
|
||||||
type ToolsContextType,
|
type TLUiToolsContextType,
|
||||||
type ToolsProviderProps,
|
type TLUiToolsProviderProps,
|
||||||
} from './lib/hooks/useTools'
|
} from './lib/hooks/useTools'
|
||||||
export type { TLTranslationKey } from './lib/hooks/useTranslation/TLTranslationKey'
|
export { type TLUiTranslationKey } from './lib/hooks/useTranslation/TLUiTranslationKey'
|
||||||
|
export { type TLUiLanguage, type TLUiTranslation } from './lib/hooks/useTranslation/translations'
|
||||||
export {
|
export {
|
||||||
EN_TRANSLATION,
|
useTranslation as useTranslation,
|
||||||
fetchTranslation,
|
type TLUiTranslationContextType,
|
||||||
getTranslation,
|
|
||||||
type TLListedTranslation,
|
|
||||||
type TLListedTranslations,
|
|
||||||
type TLTranslation,
|
|
||||||
type TLTranslationLocale,
|
|
||||||
type TLTranslationMessages,
|
|
||||||
type TLTranslations,
|
|
||||||
} from './lib/hooks/useTranslation/translations'
|
|
||||||
export { useLanguages } from './lib/hooks/useTranslation/useLanguages'
|
|
||||||
export {
|
|
||||||
TranslationProvider,
|
|
||||||
useTranslation,
|
|
||||||
type TranslationProviderProps,
|
|
||||||
} from './lib/hooks/useTranslation/useTranslation'
|
} from './lib/hooks/useTranslation/useTranslation'
|
||||||
export { TLUiIconTypes, type TLUiIconType } from './lib/icon-types'
|
export { type TLUiIconType } from './lib/icon-types'
|
||||||
export { useDefaultHelpers, type TldrawUiOverrides } from './lib/overrides'
|
export { useDefaultHelpers, type TLUiOverrides } from './lib/overrides'
|
||||||
export { Dialog, DropdownMenu }
|
export { Dialog, DropdownMenu }
|
||||||
|
|
|
@ -85,8 +85,7 @@ const TldrawUiInner = React.memo(function TldrawUiInner({
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/** @public */
|
const TldrawUiContent = React.memo(function TldrawUI({
|
||||||
export const TldrawUiContent = React.memo(function TldrawUI({
|
|
||||||
shareZone,
|
shareZone,
|
||||||
topZone,
|
topZone,
|
||||||
renderDebugMenuItems,
|
renderDebugMenuItems,
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
import { defaultUiAssetUrls, UiAssetUrls } from './assetUrls'
|
import { defaultUiAssetUrls, TLUiAssetUrls } from './assetUrls'
|
||||||
import { ActionsProvider } from './hooks/useActions'
|
import { ActionsProvider } from './hooks/useActions'
|
||||||
import { ActionsMenuSchemaProvider } from './hooks/useActionsMenuSchema'
|
import { ActionsMenuSchemaProvider } from './hooks/useActionsMenuSchema'
|
||||||
import { AssetUrlsProvider } from './hooks/useAssetUrls'
|
import { AssetUrlsProvider } from './hooks/useAssetUrls'
|
||||||
import { BreakPointProvider } from './hooks/useBreakpoint'
|
import { BreakPointProvider } from './hooks/useBreakpoint'
|
||||||
import { ContextMenuSchemaProvider } from './hooks/useContextMenuSchema'
|
import { TLUiContextMenuSchemaProvider } from './hooks/useContextMenuSchema'
|
||||||
import { DialogsProvider } from './hooks/useDialogsProvider'
|
import { DialogsProvider } from './hooks/useDialogsProvider'
|
||||||
import { EventsProvider, TLUiEventHandler } from './hooks/useEventsProvider'
|
import { EventsProvider, TLUiEventHandler } from './hooks/useEventsProvider'
|
||||||
import { HelpMenuSchemaProvider } from './hooks/useHelpMenuSchema'
|
import { HelpMenuSchemaProvider } from './hooks/useHelpMenuSchema'
|
||||||
import { KeyboardShortcutsSchemaProvider } from './hooks/useKeyboardShortcutsSchema'
|
import { KeyboardShortcutsSchemaProvider } from './hooks/useKeyboardShortcutsSchema'
|
||||||
import { MenuSchemaProvider } from './hooks/useMenuSchema'
|
import { TLUiMenuSchemaProvider } from './hooks/useMenuSchema'
|
||||||
import { ToastsProvider } from './hooks/useToastsProvider'
|
import { ToastsProvider } from './hooks/useToastsProvider'
|
||||||
import { ToolbarSchemaProvider } from './hooks/useToolbarSchema'
|
import { ToolbarSchemaProvider } from './hooks/useToolbarSchema'
|
||||||
import { ToolsProvider } from './hooks/useTools'
|
import { ToolsProvider } from './hooks/useTools'
|
||||||
import { TranslationProvider } from './hooks/useTranslation/useTranslation'
|
import { TranslationProvider } from './hooks/useTranslation/useTranslation'
|
||||||
import { TldrawUiOverrides, useMergedOverrides, useMergedTranslationOverrides } from './overrides'
|
import { TLUiOverrides, useMergedOverrides, useMergedTranslationOverrides } from './overrides'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TldrawUiContextProviderProps {
|
export interface TldrawUiContextProviderProps {
|
||||||
assetUrls?: UiAssetUrls
|
assetUrls?: TLUiAssetUrls
|
||||||
overrides?: TldrawUiOverrides | TldrawUiOverrides[]
|
overrides?: TLUiOverrides | TLUiOverrides[]
|
||||||
onUiEvent?: TLUiEventHandler
|
onUiEvent?: TLUiEventHandler
|
||||||
children?: any
|
children?: any
|
||||||
}
|
}
|
||||||
|
@ -57,13 +57,13 @@ function InternalProviders({
|
||||||
<ToolbarSchemaProvider overrides={mergedOverrides.toolbar}>
|
<ToolbarSchemaProvider overrides={mergedOverrides.toolbar}>
|
||||||
<ActionsMenuSchemaProvider overrides={mergedOverrides.actionsMenu}>
|
<ActionsMenuSchemaProvider overrides={mergedOverrides.actionsMenu}>
|
||||||
<KeyboardShortcutsSchemaProvider overrides={mergedOverrides.keyboardShortcutsMenu}>
|
<KeyboardShortcutsSchemaProvider overrides={mergedOverrides.keyboardShortcutsMenu}>
|
||||||
<ContextMenuSchemaProvider overrides={mergedOverrides.contextMenu}>
|
<TLUiContextMenuSchemaProvider overrides={mergedOverrides.contextMenu}>
|
||||||
<HelpMenuSchemaProvider overrides={mergedOverrides.helpMenu}>
|
<HelpMenuSchemaProvider overrides={mergedOverrides.helpMenu}>
|
||||||
<MenuSchemaProvider overrides={mergedOverrides.menu}>
|
<TLUiMenuSchemaProvider overrides={mergedOverrides.menu}>
|
||||||
{children}
|
{children}
|
||||||
</MenuSchemaProvider>
|
</TLUiMenuSchemaProvider>
|
||||||
</HelpMenuSchemaProvider>
|
</HelpMenuSchemaProvider>
|
||||||
</ContextMenuSchemaProvider>
|
</TLUiContextMenuSchemaProvider>
|
||||||
</KeyboardShortcutsSchemaProvider>
|
</KeyboardShortcutsSchemaProvider>
|
||||||
</ActionsMenuSchemaProvider>
|
</ActionsMenuSchemaProvider>
|
||||||
</ToolbarSchemaProvider>
|
</ToolbarSchemaProvider>
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import { defaultEditorAssetUrls, EditorAssetUrls, EMBED_DEFINITIONS } from '@tldraw/editor'
|
import { defaultEditorAssetUrls, EditorAssetUrls, EMBED_DEFINITIONS } from '@tldraw/editor'
|
||||||
import { LANGUAGES } from './hooks/useTranslation/languages'
|
import { LANGUAGES } from './hooks/useTranslation/languages'
|
||||||
import { TLUiIconType, TLUiIconTypes } from './icon-types'
|
import { iconTypes, TLUiIconType } from './icon-types'
|
||||||
|
|
||||||
export type UiAssetUrls = EditorAssetUrls & {
|
export type TLUiAssetUrls = EditorAssetUrls & {
|
||||||
icons: Record<TLUiIconType, string>
|
icons: Record<TLUiIconType, string>
|
||||||
translations: Record<(typeof LANGUAGES)[number]['locale'], string>
|
translations: Record<(typeof LANGUAGES)[number]['locale'], string>
|
||||||
embedIcons: Record<(typeof EMBED_DEFINITIONS)[number]['type'], string>
|
embedIcons: Record<(typeof EMBED_DEFINITIONS)[number]['type'], string>
|
||||||
}
|
}
|
||||||
|
|
||||||
export let defaultUiAssetUrls: UiAssetUrls = {
|
export let defaultUiAssetUrls: TLUiAssetUrls = {
|
||||||
...defaultEditorAssetUrls,
|
...defaultEditorAssetUrls,
|
||||||
icons: Object.fromEntries(
|
icons: Object.fromEntries(iconTypes.map((name) => [name, `/icons/icon/${name}.svg`])) as Record<
|
||||||
TLUiIconTypes.map((name) => [name, `/icons/icon/${name}.svg`])
|
TLUiIconType,
|
||||||
) as Record<TLUiIconType, string>,
|
string
|
||||||
|
>,
|
||||||
translations: Object.fromEntries(
|
translations: Object.fromEntries(
|
||||||
LANGUAGES.map((lang) => [lang.locale, `/translations/${lang.locale}.json`])
|
LANGUAGES.map((lang) => [lang.locale, `/translations/${lang.locale}.json`])
|
||||||
) as Record<(typeof LANGUAGES)[number]['locale'], string>,
|
) as Record<(typeof LANGUAGES)[number]['locale'], string>,
|
||||||
|
@ -22,6 +23,6 @@ export let defaultUiAssetUrls: UiAssetUrls = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export function setDefaultUiAssetUrls(urls: UiAssetUrls) {
|
export function setDefaultUiAssetUrls(urls: TLUiAssetUrls) {
|
||||||
defaultUiAssetUrls = urls
|
defaultUiAssetUrls = urls
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as PopoverPrimitive from '@radix-ui/react-popover'
|
import * as PopoverPrimitive from '@radix-ui/react-popover'
|
||||||
import { useContainer } from '@tldraw/editor'
|
import { useContainer } from '@tldraw/editor'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
import { MenuChild } from '../hooks/menuHelpers'
|
import { TLUiMenuChild } from '../hooks/menuHelpers'
|
||||||
import { useActionsMenuSchema } from '../hooks/useActionsMenuSchema'
|
import { useActionsMenuSchema } from '../hooks/useActionsMenuSchema'
|
||||||
import { useReadonly } from '../hooks/useReadonly'
|
import { useReadonly } from '../hooks/useReadonly'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
|
@ -15,7 +15,7 @@ export const ActionsMenu = memo(function ActionsMenu() {
|
||||||
const menuSchema = useActionsMenuSchema()
|
const menuSchema = useActionsMenuSchema()
|
||||||
const isReadonly = useReadonly()
|
const isReadonly = useReadonly()
|
||||||
|
|
||||||
function getActionMenuItem(item: MenuChild) {
|
function getActionMenuItem(item: TLUiMenuChild) {
|
||||||
if (isReadonly && !item.readonlyOk) return null
|
if (isReadonly && !item.readonlyOk) return null
|
||||||
|
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { Editor, preventDefault, useContainer, useEditor } from '@tldraw/editor'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useValue } from 'signia-react'
|
import { useValue } from 'signia-react'
|
||||||
import { MenuChild } from '../hooks/menuHelpers'
|
import { TLUiMenuChild } from '../hooks/menuHelpers'
|
||||||
import { useBreakpoint } from '../hooks/useBreakpoint'
|
import { useBreakpoint } from '../hooks/useBreakpoint'
|
||||||
import { useContextMenuSchema } from '../hooks/useContextMenuSchema'
|
import { useContextMenuSchema } from '../hooks/useContextMenuSchema'
|
||||||
import { useMenuIsOpen } from '../hooks/useMenuIsOpen'
|
import { useMenuIsOpen } from '../hooks/useMenuIsOpen'
|
||||||
|
@ -15,7 +15,7 @@ import { Icon } from './primitives/Icon'
|
||||||
import { Kbd } from './primitives/Kbd'
|
import { Kbd } from './primitives/Kbd'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface ContextMenuProps {
|
export interface TLUiContextMenuProps {
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export interface ContextMenuProps {
|
||||||
export const ContextMenu = function ContextMenu({ children }: { children: any }) {
|
export const ContextMenu = function ContextMenu({ children }: { children: any }) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const contextMenuSchema = useContextMenuSchema()
|
const contextTLUiMenuSchema = useContextMenuSchema()
|
||||||
const cb = (isOpen: boolean) => {
|
const cb = (isOpen: boolean) => {
|
||||||
if (isOpen) return
|
if (isOpen) return
|
||||||
if (shouldDeselect(editor)) {
|
if (shouldDeselect(editor)) {
|
||||||
|
@ -37,8 +37,8 @@ export const ContextMenu = function ContextMenu({ children }: { children: any })
|
||||||
const isReadonly = useReadonly()
|
const isReadonly = useReadonly()
|
||||||
|
|
||||||
const noItemsToShow =
|
const noItemsToShow =
|
||||||
contextMenuSchema.length === 0 ||
|
contextTLUiMenuSchema.length === 0 ||
|
||||||
(isReadonly && contextMenuSchema.every((item) => !item.readonlyOk))
|
(isReadonly && contextTLUiMenuSchema.every((item) => !item.readonlyOk))
|
||||||
|
|
||||||
const selectToolActive = useValue('isSelectToolActive', () => editor.currentToolId === 'select', [
|
const selectToolActive = useValue('isSelectToolActive', () => editor.currentToolId === 'select', [
|
||||||
editor,
|
editor,
|
||||||
|
@ -80,8 +80,8 @@ function ContextMenuContent() {
|
||||||
|
|
||||||
function getContextMenuItem(
|
function getContextMenuItem(
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
item: MenuChild,
|
item: TLUiMenuChild,
|
||||||
parent: MenuChild | null,
|
parent: TLUiMenuChild | null,
|
||||||
depth: number
|
depth: number
|
||||||
) {
|
) {
|
||||||
if (isReadonly && !item.readonlyOk) return null
|
if (isReadonly && !item.readonlyOk) return null
|
||||||
|
|
|
@ -38,7 +38,7 @@ function createNShapes(editor: Editor, n: number) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const DebugPanel = React.memo(function DebugPanel({
|
export const DebugPanel = React.memo(function DebugPanel({
|
||||||
renderDebugMenuItems,
|
renderDebugMenuItems,
|
||||||
}: {
|
}: {
|
||||||
|
@ -96,7 +96,7 @@ const DebugMenuContent = track(function DebugMenuContent({
|
||||||
// icon?: string
|
// icon?: string
|
||||||
// title?: string
|
// title?: string
|
||||||
// description?: string
|
// description?: string
|
||||||
// actions?: TLToastAction[]
|
// actions?: TLUiToastAction[]
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import * as _Dialog from '@radix-ui/react-dialog'
|
import * as _Dialog from '@radix-ui/react-dialog'
|
||||||
import { useContainer } from '@tldraw/editor'
|
import { useContainer } from '@tldraw/editor'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
import { TLDialog, useDialogs } from '../hooks/useDialogsProvider'
|
import { TLUiDialog, useDialogs } from '../hooks/useDialogsProvider'
|
||||||
|
|
||||||
const Dialog = ({ id, component: ModalContent, onClose }: TLDialog) => {
|
const Dialog = ({ id, component: ModalContent, onClose }: TLUiDialog) => {
|
||||||
const { removeDialog } = useDialogs()
|
const { removeDialog } = useDialogs()
|
||||||
|
|
||||||
const container = useContainer()
|
const container = useContainer()
|
||||||
|
@ -42,7 +42,7 @@ function _Dialogs() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{dialogs.map((dialog: TLDialog) => (
|
{dialogs.map((dialog: TLUiDialog) => (
|
||||||
<Dialog key={dialog.id} {...dialog} />
|
<Dialog key={dialog.id} {...dialog} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { TLBaseShape, TLBookmarkUtil, useEditor } from '@tldraw/editor'
|
import { TLBaseShape, TLBookmarkUtil, useEditor } from '@tldraw/editor'
|
||||||
import { useCallback, useRef, useState } from 'react'
|
import { useCallback, useRef, useState } from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
import { DialogProps } from '../hooks/useDialogsProvider'
|
import { TLUiDialogProps } from '../hooks/useDialogsProvider'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
import { Button } from './primitives/Button'
|
import { Button } from './primitives/Button'
|
||||||
import * as Dialog from './primitives/Dialog'
|
import * as Dialog from './primitives/Dialog'
|
||||||
|
@ -21,7 +21,7 @@ function validateUrl(url: string) {
|
||||||
|
|
||||||
type ShapeWithUrl = TLBaseShape<string, { url: string }>
|
type ShapeWithUrl = TLBaseShape<string, { url: string }>
|
||||||
|
|
||||||
export const EditLinkDialog = track(function EditLinkDialog({ onClose }: DialogProps) {
|
export const EditLinkDialog = track(function EditLinkDialog({ onClose }: TLUiDialogProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const selectedShape = editor.onlySelectedShape
|
const selectedShape = editor.onlySelectedShape
|
||||||
|
@ -38,7 +38,7 @@ export const EditLinkDialog = track(function EditLinkDialog({ onClose }: DialogP
|
||||||
export const EditLinkDialogInner = track(function EditLinkDialogInner({
|
export const EditLinkDialogInner = track(function EditLinkDialogInner({
|
||||||
onClose,
|
onClose,
|
||||||
selectedShape,
|
selectedShape,
|
||||||
}: DialogProps & { selectedShape: ShapeWithUrl }) {
|
}: TLUiDialogProps & { selectedShape: ShapeWithUrl }) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ import { EMBED_DEFINITIONS, EmbedDefinition } from '@tldraw/tlschema'
|
||||||
import { useRef, useState } from 'react'
|
import { useRef, useState } from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
import { useAssetUrls } from '../hooks/useAssetUrls'
|
import { useAssetUrls } from '../hooks/useAssetUrls'
|
||||||
import { DialogProps } from '../hooks/useDialogsProvider'
|
import { TLUiDialogProps } from '../hooks/useDialogsProvider'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
import { Button } from './primitives/Button'
|
import { Button } from './primitives/Button'
|
||||||
import * as Dialog from './primitives/Dialog'
|
import * as Dialog from './primitives/Dialog'
|
||||||
import { Icon } from './primitives/Icon'
|
import { Icon } from './primitives/Icon'
|
||||||
import { Input } from './primitives/Input'
|
import { Input } from './primitives/Input'
|
||||||
|
|
||||||
export const EmbedDialog = track(function EmbedDialog({ onClose }: DialogProps) {
|
export const EmbedDialog = track(function EmbedDialog({ onClose }: TLUiDialogProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
const assetUrls = useAssetUrls()
|
const assetUrls = useAssetUrls()
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useEditor } from '@tldraw/editor'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const HTMLCanvas = track(function HTMLCanvas() {
|
export const HTMLCanvas = track(function HTMLCanvas() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const rCanvas = React.useRef<HTMLCanvasElement>(null)
|
const rCanvas = React.useRef<HTMLCanvasElement>(null)
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { Content, Portal, Root, Trigger } from '@radix-ui/react-dropdown-menu'
|
import { Content, Portal, Root, Trigger } from '@radix-ui/react-dropdown-menu'
|
||||||
import { useContainer } from '@tldraw/editor'
|
import { useContainer } from '@tldraw/editor'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { MenuChild } from '../hooks/menuHelpers'
|
import { TLUiMenuChild } from '../hooks/menuHelpers'
|
||||||
import { useHelpMenuSchema } from '../hooks/useHelpMenuSchema'
|
import { useHelpMenuSchema } from '../hooks/useHelpMenuSchema'
|
||||||
import { useMenuIsOpen } from '../hooks/useMenuIsOpen'
|
import { useMenuIsOpen } from '../hooks/useMenuIsOpen'
|
||||||
import { useReadonly } from '../hooks/useReadonly'
|
import { useReadonly } from '../hooks/useReadonly'
|
||||||
import { TLTranslationKey } from '../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../icon-types'
|
import { TLUiIconType } from '../icon-types'
|
||||||
import { LanguageMenu } from './LanguageMenu'
|
import { LanguageMenu } from './LanguageMenu'
|
||||||
|
@ -13,17 +13,17 @@ import * as M from './primitives/DropdownMenu'
|
||||||
import { Icon } from './primitives/Icon'
|
import { Icon } from './primitives/Icon'
|
||||||
|
|
||||||
interface HelpMenuLink {
|
interface HelpMenuLink {
|
||||||
label: TLTranslationKey
|
label: TLUiTranslationKey
|
||||||
icon: TLUiIconType
|
icon: TLUiIconType
|
||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export interface HelpMenuProps {
|
export interface HelpMenuProps {
|
||||||
links?: HelpMenuLink[]
|
links?: HelpMenuLink[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const HelpMenu = React.memo(function HelpMenu() {
|
export const HelpMenu = React.memo(function HelpMenu() {
|
||||||
const container = useContainer()
|
const container = useContainer()
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
|
@ -61,7 +61,7 @@ function HelpMenuContent() {
|
||||||
|
|
||||||
const isReadonly = useReadonly()
|
const isReadonly = useReadonly()
|
||||||
|
|
||||||
function getHelpMenuItem(item: MenuChild) {
|
function getHelpMenuItem(item: TLUiMenuChild) {
|
||||||
if (isReadonly && !item.readonlyOk) return null
|
if (isReadonly && !item.readonlyOk) return null
|
||||||
|
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { MenuChild } from '../hooks/menuHelpers'
|
import { TLUiMenuChild } from '../hooks/menuHelpers'
|
||||||
import { useKeyboardShortcutsSchema } from '../hooks/useKeyboardShortcutsSchema'
|
import { useKeyboardShortcutsSchema } from '../hooks/useKeyboardShortcutsSchema'
|
||||||
import { useReadonly } from '../hooks/useReadonly'
|
import { useReadonly } from '../hooks/useReadonly'
|
||||||
import { TLTranslationKey } from '../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
import * as Dialog from './primitives/Dialog'
|
import * as Dialog from './primitives/Dialog'
|
||||||
import { Kbd } from './primitives/Kbd'
|
import { Kbd } from './primitives/Kbd'
|
||||||
|
@ -11,7 +11,7 @@ export const KeyboardShortcutsDialog = () => {
|
||||||
const isReadonly = useReadonly()
|
const isReadonly = useReadonly()
|
||||||
const shortcutsItems = useKeyboardShortcutsSchema()
|
const shortcutsItems = useKeyboardShortcutsSchema()
|
||||||
|
|
||||||
function getKeyboardShortcutItem(item: MenuChild) {
|
function getKeyboardShortcutItem(item: TLUiMenuChild) {
|
||||||
if (isReadonly && !item.readonlyOk) return null
|
if (isReadonly && !item.readonlyOk) return null
|
||||||
|
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
|
@ -19,7 +19,7 @@ export const KeyboardShortcutsDialog = () => {
|
||||||
return (
|
return (
|
||||||
<div className="tlui-shortcuts-dialog__group" key={item.id}>
|
<div className="tlui-shortcuts-dialog__group" key={item.id}>
|
||||||
<h2 className="tlui-shortcuts-dialog__group__title">
|
<h2 className="tlui-shortcuts-dialog__group__title">
|
||||||
{msg(item.id as TLTranslationKey)}
|
{msg(item.id as TLUiTranslationKey)}
|
||||||
</h2>
|
</h2>
|
||||||
<div className="tlui-shortcuts-dialog__group__content">
|
<div className="tlui-shortcuts-dialog__group__content">
|
||||||
{item.children
|
{item.children
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useEditor } from '@tldraw/editor'
|
import { useEditor } from '@tldraw/editor'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { TLTranslationLocale } from '../hooks/useTranslation/translations'
|
import { TLUiTranslation } from '../hooks/useTranslation/translations'
|
||||||
import { useLanguages } from '../hooks/useTranslation/useLanguages'
|
import { useLanguages } from '../hooks/useTranslation/useLanguages'
|
||||||
import * as D from './primitives/DropdownMenu'
|
import * as D from './primitives/DropdownMenu'
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ export function LanguageMenu() {
|
||||||
const { languages, currentLanguage } = useLanguages()
|
const { languages, currentLanguage } = useLanguages()
|
||||||
|
|
||||||
const handleLanguageSelect = useCallback(
|
const handleLanguageSelect = useCallback(
|
||||||
(locale: TLTranslationLocale) => editor.setLocale(locale),
|
(locale: TLUiTranslation['locale']) => editor.setLocale(locale),
|
||||||
[editor]
|
[editor]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Editor, useEditor } from '@tldraw/editor'
|
import { Editor, useEditor } from '@tldraw/editor'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { MenuChild } from '../hooks/menuHelpers'
|
import { TLUiMenuChild } from '../hooks/menuHelpers'
|
||||||
import { useBreakpoint } from '../hooks/useBreakpoint'
|
import { useBreakpoint } from '../hooks/useBreakpoint'
|
||||||
import { useMenuSchema } from '../hooks/useMenuSchema'
|
import { useMenuSchema } from '../hooks/useMenuSchema'
|
||||||
import { useReadonly } from '../hooks/useReadonly'
|
import { useReadonly } from '../hooks/useReadonly'
|
||||||
|
@ -37,7 +37,12 @@ function MenuContent() {
|
||||||
const breakpoint = useBreakpoint()
|
const breakpoint = useBreakpoint()
|
||||||
const isReadonly = useReadonly()
|
const isReadonly = useReadonly()
|
||||||
|
|
||||||
function getMenuItem(editor: Editor, item: MenuChild, parent: MenuChild | null, depth: number) {
|
function getMenuItem(
|
||||||
|
editor: Editor,
|
||||||
|
item: TLUiMenuChild,
|
||||||
|
parent: TLUiMenuChild | null,
|
||||||
|
depth: number
|
||||||
|
) {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
case 'custom': {
|
case 'custom': {
|
||||||
if (isReadonly && !item.readonlyOk) return null
|
if (isReadonly && !item.readonlyOk) return null
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { Button } from '../primitives/Button'
|
||||||
import { kbdStr } from '../primitives/shared'
|
import { kbdStr } from '../primitives/shared'
|
||||||
import { ZoomMenu } from './ZoomMenu'
|
import { ZoomMenu } from './ZoomMenu'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const NavigationZone = memo(function NavigationZone() {
|
export const NavigationZone = memo(function NavigationZone() {
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Trigger } from '@radix-ui/react-dropdown-menu'
|
||||||
import { Editor, TLStyleItem, TLStyleType } from '@tldraw/editor'
|
import { Editor, TLStyleItem, TLStyleType } from '@tldraw/editor'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
import { Button } from '../primitives/Button'
|
import { Button } from '../primitives/Button'
|
||||||
|
@ -11,9 +11,9 @@ import * as DropdownMenu from '../primitives/DropdownMenu'
|
||||||
type AllStyles = typeof Editor.styles
|
type AllStyles = typeof Editor.styles
|
||||||
|
|
||||||
interface DoubleDropdownPickerProps<T extends AllStyles[keyof AllStyles][number]> {
|
interface DoubleDropdownPickerProps<T extends AllStyles[keyof AllStyles][number]> {
|
||||||
label: TLTranslationKey
|
label: TLUiTranslationKey
|
||||||
labelA: TLTranslationKey
|
labelA: TLUiTranslationKey
|
||||||
labelB: TLTranslationKey
|
labelB: TLUiTranslationKey
|
||||||
itemsA: T[]
|
itemsA: T[]
|
||||||
itemsB: T[]
|
itemsB: T[]
|
||||||
styleTypeA: TLStyleType
|
styleTypeA: TLStyleType
|
||||||
|
@ -69,7 +69,7 @@ export const DoubleDropdownPicker = React.memo(function DoubleDropdownPicker<
|
||||||
' — ' +
|
' — ' +
|
||||||
(valueA === null
|
(valueA === null
|
||||||
? msg('style-panel.mixed')
|
? msg('style-panel.mixed')
|
||||||
: msg(`${styleTypeA}-style.${valueA}` as TLTranslationKey))
|
: msg(`${styleTypeA}-style.${valueA}` as TLUiTranslationKey))
|
||||||
}
|
}
|
||||||
icon={iconA as any}
|
icon={iconA as any}
|
||||||
invertIcon
|
invertIcon
|
||||||
|
@ -88,7 +88,9 @@ export const DoubleDropdownPicker = React.memo(function DoubleDropdownPicker<
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="tlui-button-grid__button"
|
className="tlui-button-grid__button"
|
||||||
title={
|
title={
|
||||||
msg(labelA) + ' — ' + msg(`${styleTypeA}-style.${item.id}` as TLTranslationKey)
|
msg(labelA) +
|
||||||
|
' — ' +
|
||||||
|
msg(`${styleTypeA}-style.${item.id}` as TLUiTranslationKey)
|
||||||
}
|
}
|
||||||
data-testid={`${startWdPrefix}.${item.id}`}
|
data-testid={`${startWdPrefix}.${item.id}`}
|
||||||
key={item.id}
|
key={item.id}
|
||||||
|
@ -110,7 +112,7 @@ export const DoubleDropdownPicker = React.memo(function DoubleDropdownPicker<
|
||||||
' — ' +
|
' — ' +
|
||||||
(valueB === null
|
(valueB === null
|
||||||
? msg('style-panel.mixed')
|
? msg('style-panel.mixed')
|
||||||
: msg(`${styleTypeB}-style.${valueB}` as TLTranslationKey))
|
: msg(`${styleTypeB}-style.${valueB}` as TLUiTranslationKey))
|
||||||
}
|
}
|
||||||
icon={iconB as any}
|
icon={iconB as any}
|
||||||
smallIcon
|
smallIcon
|
||||||
|
@ -128,7 +130,9 @@ export const DoubleDropdownPicker = React.memo(function DoubleDropdownPicker<
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="tlui-button-grid__button"
|
className="tlui-button-grid__button"
|
||||||
title={
|
title={
|
||||||
msg(labelB) + ' — ' + msg(`${styleTypeB}-style.${item.id}` as TLTranslationKey)
|
msg(labelB) +
|
||||||
|
' — ' +
|
||||||
|
msg(`${styleTypeB}-style.${item.id}` as TLUiTranslationKey)
|
||||||
}
|
}
|
||||||
data-testid={`${endWdPrefix}.${item.id}`}
|
data-testid={`${endWdPrefix}.${item.id}`}
|
||||||
key={item.id}
|
key={item.id}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Trigger } from '@radix-ui/react-dropdown-menu'
|
||||||
import { Editor, TLStyleItem, TLStyleType } from '@tldraw/editor'
|
import { Editor, TLStyleItem, TLStyleType } from '@tldraw/editor'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
import { Button } from '../primitives/Button'
|
import { Button } from '../primitives/Button'
|
||||||
|
@ -12,7 +12,7 @@ type AllStyles = typeof Editor.styles
|
||||||
|
|
||||||
interface DropdownPickerProps<T extends AllStyles[keyof AllStyles][number]> {
|
interface DropdownPickerProps<T extends AllStyles[keyof AllStyles][number]> {
|
||||||
id: string
|
id: string
|
||||||
label?: TLTranslationKey
|
label?: TLUiTranslationKey
|
||||||
items: T[]
|
items: T[]
|
||||||
styleType: TLStyleType
|
styleType: TLStyleType
|
||||||
value: T['id'] | null
|
value: T['id'] | null
|
||||||
|
@ -43,7 +43,7 @@ export const DropdownPicker = React.memo(function DropdownPicker<
|
||||||
title={
|
title={
|
||||||
value === null
|
value === null
|
||||||
? msg('style-panel.mixed')
|
? msg('style-panel.mixed')
|
||||||
: msg(`${styleType}-style.${value}` as TLTranslationKey)
|
: msg(`${styleType}-style.${value}` as TLUiTranslationKey)
|
||||||
}
|
}
|
||||||
label={label}
|
label={label}
|
||||||
icon={(icon as TLUiIconType) ?? 'mixed'}
|
icon={(icon as TLUiIconType) ?? 'mixed'}
|
||||||
|
@ -62,7 +62,7 @@ export const DropdownPicker = React.memo(function DropdownPicker<
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
className="tlui-button-grid__button"
|
className="tlui-button-grid__button"
|
||||||
data-testid={`${testId}.${item.id}`}
|
data-testid={`${testId}.${item.id}`}
|
||||||
title={msg(`${styleType}-style.${item.id}` as TLTranslationKey)}
|
title={msg(`${styleType}-style.${item.id}` as TLUiTranslationKey)}
|
||||||
key={item.id}
|
key={item.id}
|
||||||
icon={item.icon as TLUiIconType}
|
icon={item.icon as TLUiIconType}
|
||||||
onClick={() => onValueChange(item as TLStyleItem, false)}
|
onClick={() => onValueChange(item as TLStyleItem, false)}
|
||||||
|
|
|
@ -13,7 +13,7 @@ interface StylePanelProps {
|
||||||
isMobile?: boolean
|
isMobile?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const StylePanel = function StylePanel({ isMobile }: StylePanelProps) {
|
export const StylePanel = function StylePanel({ isMobile }: StylePanelProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import * as T from '@radix-ui/react-toast'
|
import * as T from '@radix-ui/react-toast'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLToast, useToasts } from '../hooks/useToastsProvider'
|
import { TLUiToast, useToasts } from '../hooks/useToastsProvider'
|
||||||
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../icon-types'
|
import { TLUiIconType } from '../icon-types'
|
||||||
import { Button } from './primitives/Button'
|
import { Button } from './primitives/Button'
|
||||||
import { Icon } from './primitives/Icon'
|
import { Icon } from './primitives/Icon'
|
||||||
|
|
||||||
function Toast({ toast }: { toast: TLToast }) {
|
function Toast({ toast }: { toast: TLUiToast }) {
|
||||||
const { removeToast } = useToasts()
|
const { removeToast } = useToasts()
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import React from 'react'
|
||||||
import { track, useValue } from 'signia-react'
|
import { track, useValue } from 'signia-react'
|
||||||
import { useBreakpoint } from '../../hooks/useBreakpoint'
|
import { useBreakpoint } from '../../hooks/useBreakpoint'
|
||||||
import { useReadonly } from '../../hooks/useReadonly'
|
import { useReadonly } from '../../hooks/useReadonly'
|
||||||
import { ToolbarItem, useToolbarSchema } from '../../hooks/useToolbarSchema'
|
import { TLUiToolbarItem, useToolbarSchema } from '../../hooks/useToolbarSchema'
|
||||||
import { ToolItem } from '../../hooks/useTools'
|
import { TLUiToolItem } from '../../hooks/useTools'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { ActionsMenu } from '../ActionsMenu'
|
import { ActionsMenu } from '../ActionsMenu'
|
||||||
import { DuplicateButton } from '../DuplicateButton'
|
import { DuplicateButton } from '../DuplicateButton'
|
||||||
|
@ -24,7 +24,7 @@ export const Toolbar = function Toolbar() {
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
const breakpoint = useBreakpoint()
|
const breakpoint = useBreakpoint()
|
||||||
|
|
||||||
const rMostRecentlyActiveDropdownItem = React.useRef<ToolbarItem | undefined>(undefined)
|
const rMostRecentlyActiveDropdownItem = React.useRef<TLUiToolbarItem | undefined>(undefined)
|
||||||
|
|
||||||
const isReadOnly = useReadonly()
|
const isReadOnly = useReadonly()
|
||||||
const toolbarItems = useToolbarSchema()
|
const toolbarItems = useToolbarSchema()
|
||||||
|
@ -38,17 +38,17 @@ export const Toolbar = function Toolbar() {
|
||||||
const showEditingTools = !isReadOnly
|
const showEditingTools = !isReadOnly
|
||||||
const showExtraActions = !(isReadOnly || isHandTool)
|
const showExtraActions = !(isReadOnly || isHandTool)
|
||||||
|
|
||||||
const getTitle = (item: ToolItem) =>
|
const getTitle = (item: TLUiToolItem) =>
|
||||||
item.label ? `${msg(item.label)} ${item.kbd ? kbdStr(item.kbd) : ''}` : ''
|
item.label ? `${msg(item.label)} ${item.kbd ? kbdStr(item.kbd) : ''}` : ''
|
||||||
|
|
||||||
const activeToolbarItem = toolbarItems.find((item) => {
|
const activeTLUiToolbarItem = toolbarItems.find((item) => {
|
||||||
return isActiveToolItem(item.toolItem, activeToolId, geoState)
|
return isActiveTLUiToolItem(item.toolItem, activeToolId, geoState)
|
||||||
})
|
})
|
||||||
|
|
||||||
const { itemsInPanel, itemsInDropdown, dropdownFirstItem } = React.useMemo(() => {
|
const { itemsInPanel, itemsInDropdown, dropdownFirstItem } = React.useMemo(() => {
|
||||||
const itemsInPanel: ToolbarItem[] = []
|
const itemsInPanel: TLUiToolbarItem[] = []
|
||||||
const itemsInDropdown: ToolbarItem[] = []
|
const itemsInDropdown: TLUiToolbarItem[] = []
|
||||||
let dropdownFirstItem: ToolbarItem | undefined
|
let dropdownFirstItem: TLUiToolbarItem | undefined
|
||||||
|
|
||||||
const overflowIndex = Math.min(8, 5 + breakpoint)
|
const overflowIndex = Math.min(8, 5 + breakpoint)
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ export const Toolbar = function Toolbar() {
|
||||||
} else {
|
} else {
|
||||||
// Items above will be in the dropdown menu unless the item
|
// Items above will be in the dropdown menu unless the item
|
||||||
// is active (or was the most recently selected active item)
|
// is active (or was the most recently selected active item)
|
||||||
if (item === activeToolbarItem) {
|
if (item === activeTLUiToolbarItem) {
|
||||||
// If the dropdown item is active, make it the dropdownFirstItem
|
// If the dropdown item is active, make it the dropdownFirstItem
|
||||||
dropdownFirstItem = item
|
dropdownFirstItem = item
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ export const Toolbar = function Toolbar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
return { itemsInPanel, itemsInDropdown, dropdownFirstItem }
|
return { itemsInPanel, itemsInDropdown, dropdownFirstItem }
|
||||||
}, [toolbarItems, activeToolbarItem, breakpoint])
|
}, [toolbarItems, activeTLUiToolbarItem, breakpoint])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tlui-toolbar">
|
<div className="tlui-toolbar">
|
||||||
|
@ -139,7 +139,7 @@ export const Toolbar = function Toolbar() {
|
||||||
key={toolItem.id}
|
key={toolItem.id}
|
||||||
item={toolItem}
|
item={toolItem}
|
||||||
title={getTitle(toolItem)}
|
title={getTitle(toolItem)}
|
||||||
isSelected={isActiveToolItem(toolItem, activeToolId, geoState)}
|
isSelected={isActiveTLUiToolItem(toolItem, activeToolId, geoState)}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@ -148,7 +148,7 @@ export const Toolbar = function Toolbar() {
|
||||||
key={laserTool.toolItem.id}
|
key={laserTool.toolItem.id}
|
||||||
item={laserTool.toolItem}
|
item={laserTool.toolItem}
|
||||||
title={getTitle(laserTool.toolItem)}
|
title={getTitle(laserTool.toolItem)}
|
||||||
isSelected={isActiveToolItem(laserTool.toolItem, activeToolId, geoState)}
|
isSelected={isActiveTLUiToolItem(laserTool.toolItem, activeToolId, geoState)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{showEditingTools && (
|
{showEditingTools && (
|
||||||
|
@ -160,7 +160,7 @@ export const Toolbar = function Toolbar() {
|
||||||
key={toolItem.id}
|
key={toolItem.id}
|
||||||
item={toolItem}
|
item={toolItem}
|
||||||
title={getTitle(toolItem)}
|
title={getTitle(toolItem)}
|
||||||
isSelected={isActiveToolItem(toolItem, activeToolId, geoState)}
|
isSelected={isActiveTLUiToolItem(toolItem, activeToolId, geoState)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{/* Everything Else */}
|
{/* Everything Else */}
|
||||||
|
@ -170,7 +170,7 @@ export const Toolbar = function Toolbar() {
|
||||||
key={toolItem.id}
|
key={toolItem.id}
|
||||||
item={toolItem}
|
item={toolItem}
|
||||||
title={getTitle(toolItem)}
|
title={getTitle(toolItem)}
|
||||||
isSelected={isActiveToolItem(toolItem, activeToolId, geoState)}
|
isSelected={isActiveTLUiToolItem(toolItem, activeToolId, geoState)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
{/* Overflowing Shapes */}
|
{/* Overflowing Shapes */}
|
||||||
|
@ -181,7 +181,7 @@ export const Toolbar = function Toolbar() {
|
||||||
key={dropdownFirstItem.toolItem.id}
|
key={dropdownFirstItem.toolItem.id}
|
||||||
item={dropdownFirstItem.toolItem}
|
item={dropdownFirstItem.toolItem}
|
||||||
title={getTitle(dropdownFirstItem.toolItem)}
|
title={getTitle(dropdownFirstItem.toolItem)}
|
||||||
isSelected={isActiveToolItem(
|
isSelected={isActiveTLUiToolItem(
|
||||||
dropdownFirstItem.toolItem,
|
dropdownFirstItem.toolItem,
|
||||||
activeToolId,
|
activeToolId,
|
||||||
geoState
|
geoState
|
||||||
|
@ -220,7 +220,7 @@ export const Toolbar = function Toolbar() {
|
||||||
const OverflowToolsContent = track(function OverflowToolsContent({
|
const OverflowToolsContent = track(function OverflowToolsContent({
|
||||||
toolbarItems,
|
toolbarItems,
|
||||||
}: {
|
}: {
|
||||||
toolbarItems: ToolbarItem[]
|
toolbarItems: TLUiToolbarItem[]
|
||||||
}) {
|
}) {
|
||||||
const msg = useTranslation()
|
const msg = useTranslation()
|
||||||
|
|
||||||
|
@ -250,7 +250,7 @@ function ToolbarButton({
|
||||||
title,
|
title,
|
||||||
isSelected,
|
isSelected,
|
||||||
}: {
|
}: {
|
||||||
item: ToolItem
|
item: TLUiToolItem
|
||||||
title: string
|
title: string
|
||||||
isSelected: boolean
|
isSelected: boolean
|
||||||
}) {
|
}) {
|
||||||
|
@ -273,8 +273,8 @@ function ToolbarButton({
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isActiveToolItem = (
|
const isActiveTLUiToolItem = (
|
||||||
item: ToolItem,
|
item: TLUiToolItem,
|
||||||
activeToolId: string | undefined,
|
activeToolId: string | undefined,
|
||||||
geoState: string | null | undefined
|
geoState: string | null | undefined
|
||||||
) => {
|
) => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
import { Spinner } from '../Spinner'
|
import { Spinner } from '../Spinner'
|
||||||
|
@ -8,10 +8,10 @@ import { Icon } from './Icon'
|
||||||
import { Kbd } from './Kbd'
|
import { Kbd } from './Kbd'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
export interface TLUiButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||||
loading?: boolean // TODO: loading spinner
|
loading?: boolean // TODO: loading spinner
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
label?: TLTranslationKey
|
label?: TLUiTranslationKey
|
||||||
icon?: TLUiIconType
|
icon?: TLUiIconType
|
||||||
spinner?: boolean
|
spinner?: boolean
|
||||||
iconLeft?: TLUiIconType
|
iconLeft?: TLUiIconType
|
||||||
|
@ -23,7 +23,7 @@ export interface ButtonProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
export const Button = React.forwardRef<HTMLButtonElement, TLUiButtonProps>(function Button(
|
||||||
{
|
{
|
||||||
label,
|
label,
|
||||||
icon,
|
icon,
|
||||||
|
|
|
@ -3,12 +3,12 @@ import { clamp } from '@tldraw/primitives'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useRef } from 'react'
|
import { useRef } from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
import { Button } from './Button'
|
import { Button } from './Button'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export interface ButtonPickerProps<T extends TLStyleItem> {
|
export interface ButtonPickerProps<T extends TLStyleItem> {
|
||||||
title: string
|
title: string
|
||||||
items: T[]
|
items: T[]
|
||||||
|
@ -97,7 +97,7 @@ function _ButtonPicker<T extends TLStyleItem>(props: ButtonPickerProps<T>) {
|
||||||
data-testid={`${props['data-testid']}.${item.id}`}
|
data-testid={`${props['data-testid']}.${item.id}`}
|
||||||
aria-label={item.id}
|
aria-label={item.id}
|
||||||
data-state={value === item.id ? 'hinted' : undefined}
|
data-state={value === item.id ? 'hinted' : undefined}
|
||||||
title={title + ' — ' + msg(`${styleType}-style.${item.id}` as TLTranslationKey)}
|
title={title + ' — ' + msg(`${styleType}-style.${item.id}` as TLUiTranslationKey)}
|
||||||
className={classNames('tlui-button-grid__button')}
|
className={classNames('tlui-button-grid__button')}
|
||||||
style={item.type === 'color' ? { color: `var(--palette-${item.id})` } : undefined}
|
style={item.type === 'color' ? { color: `var(--palette-${item.id})` } : undefined}
|
||||||
onPointerEnter={handleButtonPointerEnter}
|
onPointerEnter={handleButtonPointerEnter}
|
||||||
|
@ -111,5 +111,5 @@ function _ButtonPicker<T extends TLStyleItem>(props: ButtonPickerProps<T>) {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ButtonPicker = React.memo(_ButtonPicker)
|
export const ButtonPicker = React.memo(_ButtonPicker)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import { preventDefault, useContainer } from '@tldraw/editor'
|
import { preventDefault, useContainer } from '@tldraw/editor'
|
||||||
import { useMenuIsOpen } from '../../hooks/useMenuIsOpen'
|
import { useMenuIsOpen } from '../../hooks/useMenuIsOpen'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { Button, ButtonProps } from './Button'
|
import { Button, TLUiButtonProps } from './Button'
|
||||||
import { Icon } from './Icon'
|
import { Icon } from './Icon'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
|
@ -88,7 +88,7 @@ export function SubTrigger({
|
||||||
'data-testid': testId,
|
'data-testid': testId,
|
||||||
'data-direction': dataDirection,
|
'data-direction': dataDirection,
|
||||||
}: {
|
}: {
|
||||||
label: TLTranslationKey
|
label: TLUiTranslationKey
|
||||||
'data-testid'?: string
|
'data-testid'?: string
|
||||||
'data-direction'?: 'left' | 'right'
|
'data-direction'?: 'left' | 'right'
|
||||||
}) {
|
}) {
|
||||||
|
@ -153,7 +153,7 @@ export function Indicator() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface DropdownMenuItemProps extends ButtonProps {
|
export interface DropdownMenuItemProps extends TLUiButtonProps {
|
||||||
noClose?: boolean
|
noClose?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { useAssetUrls } from '../../hooks/useAssetUrls'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface IconProps extends React.HTMLProps<HTMLDivElement> {
|
export interface TLUiIconProps extends React.HTMLProps<HTMLDivElement> {
|
||||||
icon: TLUiIconType
|
icon: TLUiIconType
|
||||||
small?: boolean
|
small?: boolean
|
||||||
color?: string
|
color?: string
|
||||||
|
@ -21,7 +21,7 @@ export const Icon = memo(function Icon({
|
||||||
color,
|
color,
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
}: IconProps) {
|
}: TLUiIconProps) {
|
||||||
const assetUrls = useAssetUrls()
|
const assetUrls = useAssetUrls()
|
||||||
const asset = assetUrls.icons[icon]
|
const asset = assetUrls.icons[icon]
|
||||||
const ref = useRef<HTMLDivElement>(null)
|
const ref = useRef<HTMLDivElement>(null)
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
import { TLUiIconType } from '../../icon-types'
|
import { TLUiIconType } from '../../icon-types'
|
||||||
import { Icon } from './Icon'
|
import { Icon } from './Icon'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface InputProps {
|
export interface TLUiInputProps {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
label?: TLTranslationKey
|
label?: TLUiTranslationKey
|
||||||
icon?: TLUiIconType
|
icon?: TLUiIconType
|
||||||
iconLeft?: TLUiIconType
|
iconLeft?: TLUiIconType
|
||||||
autofocus?: boolean
|
autofocus?: boolean
|
||||||
|
@ -34,7 +34,7 @@ export interface InputProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const Input = React.forwardRef<HTMLInputElement, InputProps>(function Input(
|
export const Input = React.forwardRef<HTMLInputElement, TLUiInputProps>(function Input(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
label,
|
label,
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { kbd } from './shared'
|
import { kbd } from './shared'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export interface KbdProps {
|
export interface KbdProps {
|
||||||
children: string
|
children: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function Kbd({ children }: KbdProps) {
|
export function Kbd({ children }: KbdProps) {
|
||||||
return (
|
return (
|
||||||
<kbd className="tlui-kbd">
|
<kbd className="tlui-kbd">
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { Range, Root, Thumb, Track } from '@radix-ui/react-slider'
|
import { Range, Root, Thumb, Track } from '@radix-ui/react-slider'
|
||||||
import { useEditor } from '@tldraw/editor'
|
import { useEditor } from '@tldraw/editor'
|
||||||
import { useCallback } from 'react'
|
import { useCallback } from 'react'
|
||||||
import { TLTranslationKey } from '../../hooks/useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from '../../hooks/useTranslation/TLUiTranslationKey'
|
||||||
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
import { useTranslation } from '../../hooks/useTranslation/useTranslation'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export interface SliderProps {
|
export interface SliderProps {
|
||||||
steps: number
|
steps: number
|
||||||
value: number | null
|
value: number | null
|
||||||
|
@ -14,7 +14,7 @@ export interface SliderProps {
|
||||||
'data-testid'?: string
|
'data-testid'?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function Slider(props: SliderProps) {
|
export function Slider(props: SliderProps) {
|
||||||
const { title, steps, value, label, onValueChange } = props
|
const { title, steps, value, label, onValueChange } = props
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
@ -50,7 +50,7 @@ export function Slider(props: SliderProps) {
|
||||||
onPointerDown={handlePointerDown}
|
onPointerDown={handlePointerDown}
|
||||||
onValueChange={handleValueChange}
|
onValueChange={handleValueChange}
|
||||||
onPointerUp={handlePointerUp}
|
onPointerUp={handlePointerUp}
|
||||||
title={title + ' — ' + msg(label as TLTranslationKey)}
|
title={title + ' — ' + msg(label as TLUiTranslationKey)}
|
||||||
>
|
>
|
||||||
<Track className="tlui-slider__track" dir="ltr">
|
<Track className="tlui-slider__track" dir="ltr">
|
||||||
{value !== null && <Range className="tlui-slider__range" dir="ltr" />}
|
{value !== null && <Range className="tlui-slider__range" dir="ltr" />}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function toStartCase(str: string) {
|
export function toStartCase(str: string) {
|
||||||
return str
|
return str
|
||||||
.split(' ')
|
.split(' ')
|
||||||
|
@ -13,7 +13,7 @@ const isDarwin =
|
||||||
const cmdKey = isDarwin ? '⌘' : 'Ctrl'
|
const cmdKey = isDarwin ? '⌘' : 'Ctrl'
|
||||||
const altKey = isDarwin ? '⌥' : 'Alt'
|
const altKey = isDarwin ? '⌥' : 'Alt'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function kbd(str: string) {
|
export function kbd(str: string) {
|
||||||
return str
|
return str
|
||||||
.split(',')[0]
|
.split(',')[0]
|
||||||
|
@ -24,7 +24,7 @@ export function kbd(str: string) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function kbdStr(str: string) {
|
export function kbdStr(str: string) {
|
||||||
return (
|
return (
|
||||||
'— ' +
|
'— ' +
|
||||||
|
@ -38,27 +38,3 @@ export function kbdStr(str: string) {
|
||||||
.join(' ')
|
.join(' ')
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export const getBaseUrl = () => {
|
|
||||||
if (typeof process === 'undefined') {
|
|
||||||
return 'http://localhost:5420'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
return 'http://localhost:3000'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NEXT_PUBLIC_VERCEL_ENV === 'production') {
|
|
||||||
return 'https://www.tldraw.com'
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process.env.NEXT_PUBLIC_VERCEL_ENV === 'preview') {
|
|
||||||
return `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'http://localhost:3000'
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export const BASE_URL = getBaseUrl()
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { Editor, TLArrowUtil, useEditor } from '@tldraw/editor'
|
import { Editor, TLArrowUtil, useEditor } from '@tldraw/editor'
|
||||||
import { assert, exhaustiveSwitchError } from '@tldraw/utils'
|
import { assert, exhaustiveSwitchError } from '@tldraw/utils'
|
||||||
import { useValue } from 'signia-react'
|
import { useValue } from 'signia-react'
|
||||||
import { ActionItem } from './useActions'
|
import { TLUiActionItem } from './useActions'
|
||||||
import { ToolItem } from './useTools'
|
import { TLUiToolItem } from './useTools'
|
||||||
import { TLTranslationKey } from './useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from './useTranslation/TLUiTranslationKey'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type MenuChild = MenuItem | SubMenu | MenuGroup | CustomMenuItem
|
export type TLUiMenuChild = TLUiMenuItem | TLUiSubMenu | TLUiMenuGroup | TLUiCustomMenuItem
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type CustomMenuItem = {
|
export type TLUiCustomMenuItem = {
|
||||||
id: string
|
id: string
|
||||||
type: 'custom'
|
type: 'custom'
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
|
@ -17,37 +17,37 @@ export type CustomMenuItem = {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type MenuItem = {
|
export type TLUiMenuItem = {
|
||||||
id: string
|
id: string
|
||||||
type: 'item'
|
type: 'item'
|
||||||
readonlyOk: boolean
|
readonlyOk: boolean
|
||||||
actionItem: ActionItem
|
actionItem: TLUiActionItem
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
checked: boolean
|
checked: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type MenuGroup = {
|
export type TLUiMenuGroup = {
|
||||||
id: string
|
id: string
|
||||||
type: 'group'
|
type: 'group'
|
||||||
checkbox: boolean
|
checkbox: boolean
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
readonlyOk: boolean
|
readonlyOk: boolean
|
||||||
children: MenuChild[]
|
children: TLUiMenuChild[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type SubMenu = {
|
export type TLUiSubMenu = {
|
||||||
id: string
|
id: string
|
||||||
type: 'submenu'
|
type: 'submenu'
|
||||||
label: TLTranslationKey
|
label: TLUiTranslationKey
|
||||||
disabled: boolean
|
disabled: boolean
|
||||||
readonlyOk: boolean
|
readonlyOk: boolean
|
||||||
children: MenuChild[]
|
children: TLUiMenuChild[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type MenuSchema = (MenuGroup | MenuItem | CustomMenuItem)[]
|
export type TLUiMenuSchema = (TLUiMenuGroup | TLUiMenuItem | TLUiCustomMenuItem)[]
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function compactMenuItems<T>(arr: T[]): Exclude<T, null | false | undefined>[] {
|
export function compactMenuItems<T>(arr: T[]): Exclude<T, null | false | undefined>[] {
|
||||||
|
@ -55,7 +55,10 @@ export function compactMenuItems<T>(arr: T[]): Exclude<T, null | false | undefin
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function menuGroup(id: string, ...children: (MenuChild | null | false)[]): MenuGroup | null {
|
export function menuGroup(
|
||||||
|
id: string,
|
||||||
|
...children: (TLUiMenuChild | null | false)[]
|
||||||
|
): TLUiMenuGroup | null {
|
||||||
const childItems = compactMenuItems(children)
|
const childItems = compactMenuItems(children)
|
||||||
|
|
||||||
if (childItems.length === 0) return null
|
if (childItems.length === 0) return null
|
||||||
|
@ -73,9 +76,9 @@ export function menuGroup(id: string, ...children: (MenuChild | null | false)[])
|
||||||
/** @public */
|
/** @public */
|
||||||
export function menuSubmenu(
|
export function menuSubmenu(
|
||||||
id: string,
|
id: string,
|
||||||
label: TLTranslationKey,
|
label: TLUiTranslationKey,
|
||||||
...children: (MenuChild | null | false)[]
|
...children: (TLUiMenuChild | null | false)[]
|
||||||
): SubMenu | null {
|
): TLUiSubMenu | null {
|
||||||
const childItems = compactMenuItems(children)
|
const childItems = compactMenuItems(children)
|
||||||
if (childItems.length === 0) return null
|
if (childItems.length === 0) return null
|
||||||
|
|
||||||
|
@ -105,9 +108,9 @@ export function menuCustom(
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function menuItem(
|
export function menuItem(
|
||||||
actionItem: ActionItem | ToolItem,
|
actionItem: TLUiActionItem | TLUiToolItem,
|
||||||
opts = {} as Partial<{ checked: boolean; disabled: boolean }>
|
opts = {} as Partial<{ checked: boolean; disabled: boolean }>
|
||||||
): MenuItem {
|
): TLUiMenuItem {
|
||||||
if (!actionItem) {
|
if (!actionItem) {
|
||||||
throw Error('No action item provided to menuItem')
|
throw Error('No action item provided to menuItem')
|
||||||
}
|
}
|
||||||
|
@ -146,19 +149,19 @@ function shapesWithUnboundArrows(editor: Editor) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const useThreeStackableItems = () => {
|
export const useThreeStackableItems = () => {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
return useValue('threeStackableItems', () => shapesWithUnboundArrows(editor).length > 2, [editor])
|
return useValue('threeStackableItems', () => shapesWithUnboundArrows(editor).length > 2, [editor])
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const useAllowGroup = () => {
|
export const useAllowGroup = () => {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
return useValue('allowGroup', () => shapesWithUnboundArrows(editor).length > 1, [editor])
|
return useValue('allowGroup', () => shapesWithUnboundArrows(editor).length > 1, [editor])
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const useAllowUngroup = () => {
|
export const useAllowUngroup = () => {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
return useValue(
|
return useValue(
|
||||||
|
@ -169,13 +172,16 @@ export const useAllowUngroup = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function findMenuItem(menu: MenuSchema, path: string[]) {
|
export function findMenuItem(menu: TLUiMenuSchema, path: string[]) {
|
||||||
const item = _findMenuItem(menu, path)
|
const item = _findMenuItem(menu, path)
|
||||||
assert(item, `Menu item ${path.join(' > ')} not found`)
|
assert(item, `Menu item ${path.join(' > ')} not found`)
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
function _findMenuItem(menu: MenuSchema | MenuChild[], path: string[]): MenuChild | null {
|
function _findMenuItem(
|
||||||
|
menu: TLUiMenuSchema | TLUiMenuChild[],
|
||||||
|
path: string[]
|
||||||
|
): TLUiMenuChild | null {
|
||||||
const [next, ...rest] = path
|
const [next, ...rest] = path
|
||||||
if (!next) return null
|
if (!next) return null
|
||||||
|
|
||||||
|
|
|
@ -27,44 +27,44 @@ import { useExportAs } from './useExportAs'
|
||||||
import { useInsertMedia } from './useInsertMedia'
|
import { useInsertMedia } from './useInsertMedia'
|
||||||
import { usePrint } from './usePrint'
|
import { usePrint } from './usePrint'
|
||||||
import { useToasts } from './useToastsProvider'
|
import { useToasts } from './useToastsProvider'
|
||||||
import { TLTranslationKey } from './useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from './useTranslation/TLUiTranslationKey'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface ActionItem {
|
export interface TLUiActionItem {
|
||||||
icon?: TLUiIconType
|
icon?: TLUiIconType
|
||||||
id: string
|
id: string
|
||||||
kbd?: string
|
kbd?: string
|
||||||
title?: string
|
title?: string
|
||||||
label?: TLTranslationKey
|
label?: TLUiTranslationKey
|
||||||
menuLabel?: TLTranslationKey
|
menuLabel?: TLUiTranslationKey
|
||||||
shortcutsLabel?: TLTranslationKey
|
shortcutsLabel?: TLUiTranslationKey
|
||||||
contextMenuLabel?: TLTranslationKey
|
contextMenuLabel?: TLUiTranslationKey
|
||||||
readonlyOk: boolean
|
readonlyOk: boolean
|
||||||
checkbox?: boolean
|
checkbox?: boolean
|
||||||
onSelect: (source: TLUiEventSource) => Promise<void> | void
|
onSelect: (source: TLUiEventSource) => Promise<void> | void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ActionsContextType = Record<string, ActionItem>
|
export type TLUiActionsContextType = Record<string, TLUiActionItem>
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ActionsContext = React.createContext<ActionsContextType>({})
|
export const ActionsContext = React.createContext<TLUiActionsContextType>({})
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ActionsProviderProps = {
|
export type ActionsProviderProps = {
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
actions: ActionsContextType,
|
actions: TLUiActionsContextType,
|
||||||
helpers: undefined
|
helpers: undefined
|
||||||
) => ActionsContextType
|
) => TLUiActionsContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeActions(actions: ActionItem[]) {
|
function makeActions(actions: TLUiActionItem[]) {
|
||||||
return Object.fromEntries(actions.map((action) => [action.id, action])) as ActionsContextType
|
return Object.fromEntries(actions.map((action) => [action.id, action])) as TLUiActionsContextType
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ export function ActionsProvider({ overrides, children }: ActionsProviderProps) {
|
||||||
const trackEvent = useEvents()
|
const trackEvent = useEvents()
|
||||||
|
|
||||||
// should this be a useMemo? looks like it doesn't actually deref any reactive values
|
// should this be a useMemo? looks like it doesn't actually deref any reactive values
|
||||||
const actions = React.useMemo<ActionsContextType>(() => {
|
const actions = React.useMemo<TLUiActionsContextType>(() => {
|
||||||
const actions = makeActions([
|
const actions = makeActions([
|
||||||
{
|
{
|
||||||
id: 'edit-link',
|
id: 'edit-link',
|
||||||
|
@ -976,6 +976,6 @@ export function useActions() {
|
||||||
return ctx
|
return ctx
|
||||||
}
|
}
|
||||||
|
|
||||||
function asActions<T extends Record<string, ActionItem>>(actions: T) {
|
function asActions<T extends Record<string, TLUiActionItem>>(actions: T) {
|
||||||
return actions as Record<keyof typeof actions, ActionItem>
|
return actions as Record<keyof typeof actions, TLUiActionItem>
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Editor, useEditor } from '@tldraw/editor'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
import {
|
import {
|
||||||
MenuSchema,
|
TLUiMenuSchema,
|
||||||
menuItem,
|
menuItem,
|
||||||
useAllowGroup,
|
useAllowGroup,
|
||||||
useAllowUngroup,
|
useAllowUngroup,
|
||||||
|
@ -13,27 +13,27 @@ import { useBreakpoint } from './useBreakpoint'
|
||||||
import { useHasLinkShapeSelected } from './useHasLinkShapeSelected'
|
import { useHasLinkShapeSelected } from './useHasLinkShapeSelected'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ActionsMenuSchemaContextType = MenuSchema
|
export type TLUiActionsMenuSchemaContextType = TLUiMenuSchema
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ActionsMenuSchemaContext = React.createContext({} as ActionsMenuSchemaContextType)
|
export const ActionsMenuSchemaContext = React.createContext({} as TLUiActionsMenuSchemaContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ActionsMenuSchemaProviderProps = {
|
export type ActionsMenuSchemaProviderProps = {
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: ActionsMenuSchemaContextType,
|
schema: TLUiActionsMenuSchemaContextType,
|
||||||
helpers: {
|
helpers: {
|
||||||
actions: ReturnType<typeof useActions>
|
actions: ReturnType<typeof useActions>
|
||||||
oneSelected: boolean
|
oneSelected: boolean
|
||||||
twoSelected: boolean
|
twoSelected: boolean
|
||||||
threeSelected: boolean
|
threeSelected: boolean
|
||||||
}
|
}
|
||||||
) => ActionsMenuSchemaContextType
|
) => TLUiActionsMenuSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ActionsMenuSchemaProvider = track(function ActionsMenuSchemaProvider({
|
export const ActionsMenuSchemaProvider = track(function ActionsMenuSchemaProvider({
|
||||||
overrides,
|
overrides,
|
||||||
children,
|
children,
|
||||||
|
@ -53,7 +53,7 @@ export const ActionsMenuSchemaProvider = track(function ActionsMenuSchemaProvide
|
||||||
const breakpoint = useBreakpoint()
|
const breakpoint = useBreakpoint()
|
||||||
const isZoomedTo100 = editor.zoomLevel === 1
|
const isZoomedTo100 = editor.zoomLevel === 1
|
||||||
|
|
||||||
const actionMenuSchema = useMemo<MenuSchema>(() => {
|
const actionTLUiMenuSchema = useMemo<TLUiMenuSchema>(() => {
|
||||||
const results = [
|
const results = [
|
||||||
menuItem(actions['align-left'], { disabled: !twoSelected }),
|
menuItem(actions['align-left'], { disabled: !twoSelected }),
|
||||||
menuItem(actions['align-center-horizontal'], { disabled: !twoSelected }),
|
menuItem(actions['align-center-horizontal'], { disabled: !twoSelected }),
|
||||||
|
@ -104,14 +104,14 @@ export const ActionsMenuSchemaProvider = track(function ActionsMenuSchemaProvide
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ActionsMenuSchemaContext.Provider value={actionMenuSchema}>
|
<ActionsMenuSchemaContext.Provider value={actionTLUiMenuSchema}>
|
||||||
{children}
|
{children}
|
||||||
</ActionsMenuSchemaContext.Provider>
|
</ActionsMenuSchemaContext.Provider>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useActionsMenuSchema(): MenuSchema {
|
export function useActionsMenuSchema(): TLUiMenuSchema {
|
||||||
const ctx = React.useContext(ActionsMenuSchemaContext)
|
const ctx = React.useContext(ActionsMenuSchemaContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
|
|
|
@ -1,20 +1,23 @@
|
||||||
import { createContext, useContext } from 'react'
|
import { createContext, useContext } from 'react'
|
||||||
import { UiAssetUrls } from '../assetUrls'
|
import { TLUiAssetUrls } from '../assetUrls'
|
||||||
|
|
||||||
const AssetUrlsContext = createContext<UiAssetUrls | null>(null)
|
/** @internal */
|
||||||
|
type UiAssetUrlsContextType = TLUiAssetUrls | null
|
||||||
|
|
||||||
/** @public */
|
const AssetUrlsContext = createContext<UiAssetUrlsContextType>(null)
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
export function AssetUrlsProvider({
|
export function AssetUrlsProvider({
|
||||||
assetUrls,
|
assetUrls,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
assetUrls: UiAssetUrls
|
assetUrls: TLUiAssetUrls
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}) {
|
}) {
|
||||||
return <AssetUrlsContext.Provider value={assetUrls}>{children}</AssetUrlsContext.Provider>
|
return <AssetUrlsContext.Provider value={assetUrls}>{children}</AssetUrlsContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function useAssetUrls() {
|
export function useAssetUrls() {
|
||||||
const assetUrls = useContext(AssetUrlsContext)
|
const assetUrls = useContext(AssetUrlsContext)
|
||||||
if (!assetUrls) {
|
if (!assetUrls) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Editor, TLBookmarkUtil, TLEmbedUtil, getEmbedInfo, useEditor } from '@t
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { track, useValue } from 'signia-react'
|
import { track, useValue } from 'signia-react'
|
||||||
import {
|
import {
|
||||||
MenuSchema,
|
TLUiMenuSchema,
|
||||||
compactMenuItems,
|
compactMenuItems,
|
||||||
menuCustom,
|
menuCustom,
|
||||||
menuGroup,
|
menuGroup,
|
||||||
|
@ -19,16 +19,18 @@ import { useOnlyFlippableShape } from './useOnlyFlippableShape'
|
||||||
import { useShowAutoSizeToggle } from './useShowAutoSizeToggle'
|
import { useShowAutoSizeToggle } from './useShowAutoSizeToggle'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ContextMenuSchemaContextType = MenuSchema
|
export type TLUiContextTTLUiMenuSchemaContextType = TLUiMenuSchema
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const TLUiContextMenuSchemaContext = React.createContext(
|
||||||
|
{} as TLUiContextTTLUiMenuSchemaContextType
|
||||||
|
)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const ContextMenuSchemaContext = React.createContext({} as ContextMenuSchemaContextType)
|
export type TLUiContextMenuSchemaProviderProps = {
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type ContextMenuSchemaProviderProps = {
|
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: ContextMenuSchemaContextType,
|
schema: TLUiContextTTLUiMenuSchemaContextType,
|
||||||
helpers: {
|
helpers: {
|
||||||
actions: ReturnType<typeof useActions>
|
actions: ReturnType<typeof useActions>
|
||||||
oneSelected: boolean
|
oneSelected: boolean
|
||||||
|
@ -38,15 +40,15 @@ export type ContextMenuSchemaProviderProps = {
|
||||||
showUngroup: boolean
|
showUngroup: boolean
|
||||||
onlyFlippableShapeSelected: boolean
|
onlyFlippableShapeSelected: boolean
|
||||||
}
|
}
|
||||||
) => ContextMenuSchemaContextType
|
) => TLUiContextTTLUiMenuSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ContextMenuSchemaProvider = track(function ContextMenuSchemaProvider({
|
export const TLUiContextMenuSchemaProvider = track(function TLUiContextMenuSchemaProvider({
|
||||||
overrides,
|
overrides,
|
||||||
children,
|
children,
|
||||||
}: ContextMenuSchemaProviderProps) {
|
}: TLUiContextMenuSchemaProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
|
|
||||||
|
@ -100,8 +102,8 @@ export const ContextMenuSchemaProvider = track(function ContextMenuSchemaProvide
|
||||||
const { onlySelectedShape } = editor
|
const { onlySelectedShape } = editor
|
||||||
const isShapeLocked = onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)
|
const isShapeLocked = onlySelectedShape && editor.isShapeOrAncestorLocked(onlySelectedShape)
|
||||||
|
|
||||||
const contextMenuSchema = useMemo<MenuSchema>(() => {
|
const contextTLUiMenuSchema = useMemo<TLUiMenuSchema>(() => {
|
||||||
let contextMenuSchema: ContextMenuSchemaContextType = compactMenuItems([
|
let contextTLUiMenuSchema: TLUiContextTTLUiMenuSchemaContextType = compactMenuItems([
|
||||||
menuGroup(
|
menuGroup(
|
||||||
'selection',
|
'selection',
|
||||||
oneEmbedSelected && menuItem(actions['open-embed-link']),
|
oneEmbedSelected && menuItem(actions['open-embed-link']),
|
||||||
|
@ -220,7 +222,7 @@ export const ContextMenuSchemaProvider = track(function ContextMenuSchemaProvide
|
||||||
])
|
])
|
||||||
|
|
||||||
if (overrides) {
|
if (overrides) {
|
||||||
contextMenuSchema = overrides(editor, contextMenuSchema, {
|
contextTLUiMenuSchema = overrides(editor, contextTLUiMenuSchema, {
|
||||||
actions,
|
actions,
|
||||||
oneSelected,
|
oneSelected,
|
||||||
twoSelected,
|
twoSelected,
|
||||||
|
@ -231,7 +233,7 @@ export const ContextMenuSchemaProvider = track(function ContextMenuSchemaProvide
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return contextMenuSchema
|
return contextTLUiMenuSchema
|
||||||
}, [
|
}, [
|
||||||
editor,
|
editor,
|
||||||
overrides,
|
overrides,
|
||||||
|
@ -254,18 +256,18 @@ export const ContextMenuSchemaProvider = track(function ContextMenuSchemaProvide
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuSchemaContext.Provider value={contextMenuSchema}>
|
<TLUiContextMenuSchemaContext.Provider value={contextTLUiMenuSchema}>
|
||||||
{children}
|
{children}
|
||||||
</ContextMenuSchemaContext.Provider>
|
</TLUiContextMenuSchemaContext.Provider>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useContextMenuSchema(): MenuSchema {
|
export function useContextMenuSchema(): TLUiMenuSchema {
|
||||||
const ctx = React.useContext(ContextMenuSchemaContext)
|
const ctx = React.useContext(TLUiContextMenuSchemaContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
throw new Error('useContextMenuSchema must be used inside of a ContextMenuSchemaProvider.')
|
throw new Error('useContextMenuSchema must be used inside of a TLUiContextMenuSchemaProvider.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
|
@ -3,44 +3,44 @@ import { createContext, useCallback, useContext, useState } from 'react'
|
||||||
import { useEvents } from './useEventsProvider'
|
import { useEvents } from './useEventsProvider'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface DialogProps {
|
export interface TLUiDialogProps {
|
||||||
onClose: () => void
|
onClose: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TLDialog {
|
export interface TLUiDialog {
|
||||||
id: string
|
id: string
|
||||||
onClose?: () => void
|
onClose?: () => void
|
||||||
component: (props: DialogProps) => any
|
component: (props: TLUiDialogProps) => any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type DialogsContextType = {
|
export type TLUiDialogsContextType = {
|
||||||
addDialog: (dialog: Omit<TLDialog, 'id'> & { id?: string }) => string
|
addDialog: (dialog: Omit<TLUiDialog, 'id'> & { id?: string }) => string
|
||||||
removeDialog: (id: string) => string
|
removeDialog: (id: string) => string
|
||||||
updateDialog: (id: string, newDialogData: Partial<TLDialog>) => string
|
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string
|
||||||
clearDialogs: () => void
|
clearDialogs: () => void
|
||||||
dialogs: TLDialog[]
|
dialogs: TLUiDialog[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const DialogsContext = createContext({} as DialogsContextType)
|
export const DialogsContext = createContext({} as TLUiDialogsContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export type DialogsProviderProps = {
|
export type DialogsProviderProps = {
|
||||||
overrides?: (editor: Editor) => DialogsContextType
|
overrides?: (editor: Editor) => TLUiDialogsContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function DialogsProvider({ children }: DialogsProviderProps) {
|
export function DialogsProvider({ children }: DialogsProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const trackEvent = useEvents()
|
const trackEvent = useEvents()
|
||||||
|
|
||||||
const [dialogs, setDialogs] = useState<TLDialog[]>([])
|
const [dialogs, setDialogs] = useState<TLUiDialog[]>([])
|
||||||
|
|
||||||
const addDialog = useCallback(
|
const addDialog = useCallback(
|
||||||
(dialog: Omit<TLDialog, 'id'> & { id?: string }) => {
|
(dialog: Omit<TLUiDialog, 'id'> & { id?: string }) => {
|
||||||
const id = dialog.id ?? uniqueId()
|
const id = dialog.id ?? uniqueId()
|
||||||
setDialogs((d) => {
|
setDialogs((d) => {
|
||||||
return [...d.filter((m) => m.id !== dialog.id), { ...dialog, id }]
|
return [...d.filter((m) => m.id !== dialog.id), { ...dialog, id }]
|
||||||
|
@ -55,7 +55,7 @@ export function DialogsProvider({ children }: DialogsProviderProps) {
|
||||||
)
|
)
|
||||||
|
|
||||||
const updateDialog = useCallback(
|
const updateDialog = useCallback(
|
||||||
(id: string, newDialogData: Partial<TLDialog>) => {
|
(id: string, newDialogData: Partial<TLUiDialog>) => {
|
||||||
setDialogs((d) =>
|
setDialogs((d) =>
|
||||||
d.map((m) => {
|
d.map((m) => {
|
||||||
if (m.id === id) {
|
if (m.id === id) {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { useEditor } from '@tldraw/editor'
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { useToasts } from './useToastsProvider'
|
import { useToasts } from './useToastsProvider'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function useEditorEvents() {
|
export function useEditorEvents() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const { addToast } = useToasts()
|
const { addToast } = useToasts()
|
||||||
|
|
|
@ -96,16 +96,19 @@ export type TLUiEventHandler<T extends keyof TLUiEventMap = keyof TLUiEventMap>
|
||||||
/** @internal */
|
/** @internal */
|
||||||
const defaultEventHandler: TLUiEventHandler = () => void null
|
const defaultEventHandler: TLUiEventHandler = () => void null
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
export const EventsContext = React.createContext({} as TLUiEventHandler)
|
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
|
export type TLUiEventContextType = TLUiEventHandler<keyof TLUiEventMap>
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const EventsContext = React.createContext<TLUiEventContextType>({} as TLUiEventContextType)
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
export type EventsProviderProps = {
|
export type EventsProviderProps = {
|
||||||
onEvent?: TLUiEventHandler
|
onEvent?: TLUiEventHandler
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function EventsProvider({ onEvent, children }: EventsProviderProps) {
|
export function EventsProvider({ onEvent, children }: EventsProviderProps) {
|
||||||
return (
|
return (
|
||||||
<EventsContext.Provider value={onEvent ?? defaultEventHandler}>
|
<EventsContext.Provider value={onEvent ?? defaultEventHandler}>
|
||||||
|
@ -115,6 +118,6 @@ export function EventsProvider({ onEvent, children }: EventsProviderProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useEvents(): TLUiEventHandler<keyof TLUiEventMap> {
|
export function useEvents() {
|
||||||
return React.useContext(EventsContext)
|
return React.useContext(EventsContext)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,41 +2,41 @@ import { Editor, useEditor } from '@tldraw/editor'
|
||||||
import { compact } from '@tldraw/utils'
|
import { compact } from '@tldraw/utils'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
|
import { TLUiLanguage } from '../..'
|
||||||
import { KeyboardShortcutsDialog } from '../components/KeyboardShortcutsDialog'
|
import { KeyboardShortcutsDialog } from '../components/KeyboardShortcutsDialog'
|
||||||
import { MenuSchema, menuCustom, menuGroup, menuItem } from './menuHelpers'
|
import { TLUiMenuSchema, menuCustom, menuGroup, menuItem } from './menuHelpers'
|
||||||
import { useActions } from './useActions'
|
import { useActions } from './useActions'
|
||||||
import { useDialogs } from './useDialogsProvider'
|
import { useDialogs } from './useDialogsProvider'
|
||||||
import { TLListedTranslations } from './useTranslation/translations'
|
|
||||||
import { useLanguages } from './useTranslation/useLanguages'
|
import { useLanguages } from './useTranslation/useLanguages'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type HelpMenuSchemaProviderType = MenuSchema
|
export type TLUiHelpMenuSchemaContextType = TLUiMenuSchema
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export const HelpMenuSchemaContext = React.createContext({} as HelpMenuSchemaProviderType)
|
export const HelpMenuSchemaContext = React.createContext({} as TLUiHelpMenuSchemaContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type HelpMenuSchemaProviderProps = {
|
export type TLUiHelpMenuSchemaProviderProps = {
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: HelpMenuSchemaProviderType,
|
schema: TLUiHelpMenuSchemaContextType,
|
||||||
helpers: {
|
helpers: {
|
||||||
actions: ReturnType<typeof useActions>
|
actions: ReturnType<typeof useActions>
|
||||||
languages: TLListedTranslations
|
languages: readonly TLUiLanguage[]
|
||||||
currentLanguage: string
|
currentLanguage: string
|
||||||
oneSelected: boolean
|
oneSelected: boolean
|
||||||
twoSelected: boolean
|
twoSelected: boolean
|
||||||
threeSelected: boolean
|
threeSelected: boolean
|
||||||
}
|
}
|
||||||
) => HelpMenuSchemaProviderType
|
) => TLUiHelpMenuSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
||||||
overrides,
|
overrides,
|
||||||
children,
|
children,
|
||||||
}: HelpMenuSchemaProviderProps) {
|
}: TLUiHelpMenuSchemaProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
|
|
||||||
|
@ -49,8 +49,8 @@ export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
||||||
const { languages, currentLanguage } = useLanguages()
|
const { languages, currentLanguage } = useLanguages()
|
||||||
const { addDialog } = useDialogs()
|
const { addDialog } = useDialogs()
|
||||||
|
|
||||||
const helpMenuSchema = useMemo<MenuSchema>(() => {
|
const helpTLUiMenuSchema = useMemo<TLUiMenuSchema>(() => {
|
||||||
const helpMenuSchema = compact([
|
const helpTLUiMenuSchema = compact([
|
||||||
menuGroup(
|
menuGroup(
|
||||||
'top',
|
'top',
|
||||||
menuCustom('LANGUAGE_MENU', { readonlyOk: true }),
|
menuCustom('LANGUAGE_MENU', { readonlyOk: true }),
|
||||||
|
@ -66,7 +66,7 @@ export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
||||||
])
|
])
|
||||||
|
|
||||||
if (overrides) {
|
if (overrides) {
|
||||||
return overrides(editor, helpMenuSchema, {
|
return overrides(editor, helpTLUiMenuSchema, {
|
||||||
actions,
|
actions,
|
||||||
currentLanguage,
|
currentLanguage,
|
||||||
languages,
|
languages,
|
||||||
|
@ -76,7 +76,7 @@ export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return helpMenuSchema
|
return helpTLUiMenuSchema
|
||||||
}, [
|
}, [
|
||||||
editor,
|
editor,
|
||||||
overrides,
|
overrides,
|
||||||
|
@ -90,18 +90,18 @@ export const HelpMenuSchemaProvider = track(function HelpMenuSchemaProvider({
|
||||||
])
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HelpMenuSchemaContext.Provider value={helpMenuSchema}>
|
<HelpMenuSchemaContext.Provider value={helpTLUiMenuSchema}>
|
||||||
{children}
|
{children}
|
||||||
</HelpMenuSchemaContext.Provider>
|
</HelpMenuSchemaContext.Provider>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useHelpMenuSchema(): MenuSchema {
|
export function useHelpMenuSchema(): TLUiMenuSchema {
|
||||||
const ctx = React.useContext(HelpMenuSchemaContext)
|
const ctx = React.useContext(HelpMenuSchemaContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
throw new Error('useHelpMenuSchema must be used inside of a helpMenuSchemaProvider.')
|
throw new Error('useHelpMenuSchema must be used inside of a helpTLUiMenuSchemaProvider.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useLayoutEffect } from 'react'
|
import { useLayoutEffect } from 'react'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function useHighDpiCanvas(ref: React.RefObject<HTMLCanvasElement>, dpr: number) {
|
export function useHighDpiCanvas(ref: React.RefObject<HTMLCanvasElement>, dpr: number) {
|
||||||
// Match the resolution of the client
|
// Match the resolution of the client
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
|
|
@ -2,38 +2,38 @@ import { Editor, useEditor } from '@tldraw/editor'
|
||||||
import { compact } from '@tldraw/utils'
|
import { compact } from '@tldraw/utils'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
import { MenuSchema, menuGroup, menuItem } from './menuHelpers'
|
import { TLUiMenuSchema, menuGroup, menuItem } from './menuHelpers'
|
||||||
import { ActionsContextType, useActions } from './useActions'
|
import { TLUiActionsContextType, useActions } from './useActions'
|
||||||
import { ToolsContextType, useTools } from './useTools'
|
import { TLUiToolsContextType, useTools } from './useTools'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type KeyboardShortcutsSchemaContextType = MenuSchema
|
export type TLUiKeyboardShortcutsSchemaContextType = TLUiMenuSchema
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const KeyboardShortcutsSchemaContext = React.createContext(
|
export const KeyboardShortcutsSchemaContext = React.createContext(
|
||||||
{} as KeyboardShortcutsSchemaContextType
|
{} as TLUiKeyboardShortcutsSchemaContextType
|
||||||
)
|
)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type KeyboardShortcutsSchemaProviderProps = {
|
export type TLUiKeyboardShortcutsSchemaProviderProps = {
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: KeyboardShortcutsSchemaContextType,
|
schema: TLUiKeyboardShortcutsSchemaContextType,
|
||||||
more: { tools: ToolsContextType; actions: ActionsContextType }
|
more: { tools: TLUiToolsContextType; actions: TLUiActionsContextType }
|
||||||
) => KeyboardShortcutsSchemaContextType
|
) => TLUiKeyboardShortcutsSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const KeyboardShortcutsSchemaProvider = track(function KeyboardShortcutsSchemaProvider({
|
export const KeyboardShortcutsSchemaProvider = track(function KeyboardShortcutsSchemaProvider({
|
||||||
overrides,
|
overrides,
|
||||||
children,
|
children,
|
||||||
}: KeyboardShortcutsSchemaProviderProps) {
|
}: TLUiKeyboardShortcutsSchemaProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const tools = useTools()
|
const tools = useTools()
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
|
|
||||||
const keyboardShortcutsSchema = useMemo<MenuSchema>(() => {
|
const keyboardShortcutsSchema = useMemo<TLUiMenuSchema>(() => {
|
||||||
const keyboardShortcutsSchema = compact([
|
const keyboardShortcutsSchema = compact([
|
||||||
menuGroup(
|
menuGroup(
|
||||||
'shortcuts-dialog.tools',
|
'shortcuts-dialog.tools',
|
||||||
|
@ -118,7 +118,7 @@ export const KeyboardShortcutsSchemaProvider = track(function KeyboardShortcutsS
|
||||||
})
|
})
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useKeyboardShortcutsSchema(): KeyboardShortcutsSchemaContextType {
|
export function useKeyboardShortcutsSchema(): TLUiKeyboardShortcutsSchemaContextType {
|
||||||
const ctx = React.useContext(KeyboardShortcutsSchemaContext)
|
const ctx = React.useContext(KeyboardShortcutsSchemaContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { compact } from '@tldraw/utils'
|
||||||
import React, { useMemo } from 'react'
|
import React, { useMemo } from 'react'
|
||||||
import { useValue } from 'signia-react'
|
import { useValue } from 'signia-react'
|
||||||
import {
|
import {
|
||||||
MenuSchema,
|
TLUiMenuSchema,
|
||||||
menuCustom,
|
menuCustom,
|
||||||
menuGroup,
|
menuGroup,
|
||||||
menuItem,
|
menuItem,
|
||||||
|
@ -20,16 +20,16 @@ import { useHasLinkShapeSelected } from './useHasLinkShapeSelected'
|
||||||
import { useShowAutoSizeToggle } from './useShowAutoSizeToggle'
|
import { useShowAutoSizeToggle } from './useShowAutoSizeToggle'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type MenuSchemaContextType = MenuSchema
|
export type TLUiMenuSchemaContextType = TLUiMenuSchema
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const TLUiMenuSchemaContext = React.createContext({} as TLUiMenuSchemaContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const MenuSchemaContext = React.createContext({} as MenuSchemaContextType)
|
export type TLUiMenuSchemaProviderProps = {
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type MenuSchemaProviderProps = {
|
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: MenuSchemaContextType,
|
schema: TLUiMenuSchemaContextType,
|
||||||
helpers: {
|
helpers: {
|
||||||
actions: ReturnType<typeof useActions>
|
actions: ReturnType<typeof useActions>
|
||||||
noneSelected: boolean
|
noneSelected: boolean
|
||||||
|
@ -37,12 +37,12 @@ export type MenuSchemaProviderProps = {
|
||||||
twoSelected: boolean
|
twoSelected: boolean
|
||||||
threeSelected: boolean
|
threeSelected: boolean
|
||||||
}
|
}
|
||||||
) => MenuSchemaContextType
|
) => TLUiMenuSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function MenuSchemaProvider({ overrides, children }: MenuSchemaProviderProps) {
|
export function TLUiMenuSchemaProvider({ overrides, children }: TLUiMenuSchemaProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const actions = useActions()
|
const actions = useActions()
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ export function MenuSchemaProvider({ overrides, children }: MenuSchemaProviderPr
|
||||||
const canRedo = useCanRedo()
|
const canRedo = useCanRedo()
|
||||||
const isZoomedTo100 = useValue('isZoomedTo100', () => editor.zoomLevel === 1, [editor])
|
const isZoomedTo100 = useValue('isZoomedTo100', () => editor.zoomLevel === 1, [editor])
|
||||||
|
|
||||||
const menuSchema = useMemo<MenuSchema>(() => {
|
const menuSchema = useMemo<TLUiMenuSchema>(() => {
|
||||||
const menuSchema = compact([
|
const menuSchema = compact([
|
||||||
menuGroup(
|
menuGroup(
|
||||||
'menu',
|
'menu',
|
||||||
|
@ -221,15 +221,17 @@ export function MenuSchemaProvider({ overrides, children }: MenuSchemaProviderPr
|
||||||
isZoomedTo100,
|
isZoomedTo100,
|
||||||
])
|
])
|
||||||
|
|
||||||
return <MenuSchemaContext.Provider value={menuSchema}>{children}</MenuSchemaContext.Provider>
|
return (
|
||||||
|
<TLUiMenuSchemaContext.Provider value={menuSchema}>{children}</TLUiMenuSchemaContext.Provider>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useMenuSchema(): MenuSchema {
|
export function useMenuSchema(): TLUiMenuSchema {
|
||||||
const ctx = React.useContext(MenuSchemaContext)
|
const ctx = React.useContext(TLUiMenuSchemaContext)
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
throw new Error('useMenuSchema must be used inside of a MenuSchemaProvider.')
|
throw new Error('useMenuSchema must be used inside of a TLUiMenuSchemaProvider.')
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { TLUiIconTypes } from '../icon-types'
|
import { iconTypes } from '../icon-types'
|
||||||
import { useAssetUrls } from './useAssetUrls'
|
import { useAssetUrls } from './useAssetUrls'
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
|
@ -16,7 +16,7 @@ export function usePreloadIcons(): boolean {
|
||||||
// all of the icons it can so that they're available when we need them.
|
// all of the icons it can so that they're available when we need them.
|
||||||
|
|
||||||
await Promise.allSettled(
|
await Promise.allSettled(
|
||||||
TLUiIconTypes.map((icon) => {
|
iconTypes.map((icon) => {
|
||||||
const image = new Image()
|
const image = new Image()
|
||||||
image.src = assetUrls.icons[icon]
|
image.src = assetUrls.icons[icon]
|
||||||
return image.decode()
|
return image.decode()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { uniqueId, useEditor } from '@tldraw/editor'
|
import { uniqueId, useEditor } from '@tldraw/editor'
|
||||||
import { useCallback, useRef } from 'react'
|
import { useCallback, useRef } from 'react'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function usePrint() {
|
export function usePrint() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const prevPrintEl = useRef<HTMLDivElement | null>(null)
|
const prevPrintEl = useRef<HTMLDivElement | null>(null)
|
||||||
|
|
|
@ -2,45 +2,45 @@ import { Editor, uniqueId } from '@tldraw/editor'
|
||||||
import { createContext, useCallback, useContext, useState } from 'react'
|
import { createContext, useCallback, useContext, useState } from 'react'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TLToast {
|
export interface TLUiToast {
|
||||||
id: string
|
id: string
|
||||||
icon?: string
|
icon?: string
|
||||||
title?: string
|
title?: string
|
||||||
description?: string
|
description?: string
|
||||||
actions?: TLToastAction[]
|
actions?: TLUiToastAction[]
|
||||||
keepOpen?: boolean
|
keepOpen?: boolean
|
||||||
closeLabel?: string
|
closeLabel?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TLToastAction {
|
export interface TLUiToastAction {
|
||||||
type: 'primary' | 'secondary' | 'warn'
|
type: 'primary' | 'secondary' | 'warn'
|
||||||
label: string
|
label: string
|
||||||
onClick: () => void
|
onClick: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ToastsContextType = {
|
export type TLUiToastsContextType = {
|
||||||
addToast: (toast: Omit<TLToast, 'id'> & { id?: string }) => string
|
addToast: (toast: Omit<TLUiToast, 'id'> & { id?: string }) => string
|
||||||
removeToast: (id: TLToast['id']) => string
|
removeToast: (id: TLUiToast['id']) => string
|
||||||
clearToasts: () => void
|
clearToasts: () => void
|
||||||
toasts: TLToast[]
|
toasts: TLUiToast[]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export const ToastsContext = createContext({} as ToastsContextType)
|
export const ToastsContext = createContext({} as TLUiToastsContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export type ToastsProviderProps = {
|
export type ToastsProviderProps = {
|
||||||
overrides?: (editor: Editor) => ToastsContextType
|
overrides?: (editor: Editor) => TLUiToastsContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function ToastsProvider({ children }: ToastsProviderProps) {
|
export function ToastsProvider({ children }: ToastsProviderProps) {
|
||||||
const [toasts, setToasts] = useState<TLToast[]>([])
|
const [toasts, setToasts] = useState<TLUiToast[]>([])
|
||||||
|
|
||||||
const addToast = useCallback((toast: Omit<TLToast, 'id'> & { id?: string }) => {
|
const addToast = useCallback((toast: Omit<TLUiToast, 'id'> & { id?: string }) => {
|
||||||
const id = toast.id ?? uniqueId()
|
const id = toast.id ?? uniqueId()
|
||||||
setToasts((d) => [...d.filter((m) => m.id !== toast.id), { ...toast, id }])
|
setToasts((d) => [...d.filter((m) => m.id !== toast.id), { ...toast, id }])
|
||||||
return id
|
return id
|
||||||
|
|
|
@ -2,18 +2,18 @@ import { Editor, featureFlags, useEditor } from '@tldraw/editor'
|
||||||
import { compact } from '@tldraw/utils'
|
import { compact } from '@tldraw/utils'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { useValue } from 'signia-react'
|
import { useValue } from 'signia-react'
|
||||||
import { ToolItem, ToolsContextType, useTools } from './useTools'
|
import { TLUiToolItem, TLUiToolsContextType, useTools } from './useTools'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ToolbarItem = {
|
export type TLUiToolbarItem = {
|
||||||
id: string
|
id: string
|
||||||
type: 'item'
|
type: 'item'
|
||||||
readonlyOk: boolean
|
readonlyOk: boolean
|
||||||
toolItem: ToolItem
|
toolItem: TLUiToolItem
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function toolbarItem(toolItem: ToolItem): ToolbarItem {
|
export function toolbarItem(toolItem: TLUiToolItem): TLUiToolbarItem {
|
||||||
return {
|
return {
|
||||||
id: toolItem.id,
|
id: toolItem.id,
|
||||||
type: 'item',
|
type: 'item',
|
||||||
|
@ -23,30 +23,30 @@ export function toolbarItem(toolItem: ToolItem): ToolbarItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ToolbarSchemaContextType = ToolbarItem[]
|
export type TLUiToolbarSchemaContextType = TLUiToolbarItem[]
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const ToolbarSchemaContext = React.createContext([] as TLUiToolbarSchemaContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const ToolbarSchemaContext = React.createContext([] as ToolbarSchemaContextType)
|
export type TLUiToolbarSchemaProviderProps = {
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type ToolbarSchemaProviderProps = {
|
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
schema: ToolbarSchemaContextType,
|
schema: TLUiToolbarSchemaContextType,
|
||||||
more: { tools: ToolsContextType }
|
more: { tools: TLUiToolsContextType }
|
||||||
) => ToolbarSchemaContextType
|
) => TLUiToolbarSchemaContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function ToolbarSchemaProvider({ overrides, children }: ToolbarSchemaProviderProps) {
|
export function ToolbarSchemaProvider({ overrides, children }: TLUiToolbarSchemaProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
|
|
||||||
const tools = useTools()
|
const tools = useTools()
|
||||||
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
||||||
|
|
||||||
const toolbarSchema = React.useMemo<ToolbarSchemaContextType>(() => {
|
const toolbarSchema = React.useMemo<TLUiToolbarSchemaContextType>(() => {
|
||||||
const schema: ToolbarSchemaContextType = compact([
|
const schema: TLUiToolbarSchemaContextType = compact([
|
||||||
toolbarItem(tools.select),
|
toolbarItem(tools.select),
|
||||||
toolbarItem(tools.hand),
|
toolbarItem(tools.hand),
|
||||||
toolbarItem(tools.draw),
|
toolbarItem(tools.draw),
|
||||||
|
|
|
@ -6,13 +6,13 @@ import { TLUiIconType } from '../icon-types'
|
||||||
import { useDialogs } from './useDialogsProvider'
|
import { useDialogs } from './useDialogsProvider'
|
||||||
import { TLUiEventSource, useEvents } from './useEventsProvider'
|
import { TLUiEventSource, useEvents } from './useEventsProvider'
|
||||||
import { useInsertMedia } from './useInsertMedia'
|
import { useInsertMedia } from './useInsertMedia'
|
||||||
import { TLTranslationKey } from './useTranslation/TLTranslationKey'
|
import { TLUiTranslationKey } from './useTranslation/TLUiTranslationKey'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface ToolItem {
|
export interface TLUiToolItem {
|
||||||
id: string
|
id: string
|
||||||
label: TLTranslationKey
|
label: TLUiTranslationKey
|
||||||
shortcutsLabel?: TLTranslationKey
|
shortcutsLabel?: TLUiTranslationKey
|
||||||
icon: TLUiIconType
|
icon: TLUiIconType
|
||||||
onSelect: (source: TLUiEventSource) => void
|
onSelect: (source: TLUiEventSource) => void
|
||||||
kbd?: string
|
kbd?: string
|
||||||
|
@ -23,23 +23,23 @@ export interface ToolItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type ToolsContextType = Record<string, ToolItem>
|
export type TLUiToolsContextType = Record<string, TLUiToolItem>
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const ToolsContext = React.createContext({} as TLUiToolsContextType)
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const ToolsContext = React.createContext({} as ToolsContextType)
|
export type TLUiToolsProviderProps = {
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type ToolsProviderProps = {
|
|
||||||
overrides?: (
|
overrides?: (
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
tools: ToolsContextType,
|
tools: TLUiToolsContextType,
|
||||||
helpers: { insertMedia: () => void }
|
helpers: { insertMedia: () => void }
|
||||||
) => ToolsContextType
|
) => TLUiToolsContextType
|
||||||
children: any
|
children: any
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function ToolsProvider({ overrides, children }: ToolsProviderProps) {
|
export function ToolsProvider({ overrides, children }: TLUiToolsProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const trackEvent = useEvents()
|
const trackEvent = useEvents()
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ export function ToolsProvider({ overrides, children }: ToolsProviderProps) {
|
||||||
|
|
||||||
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
const highlighterEnabled = useValue(featureFlags.highlighterTool)
|
||||||
|
|
||||||
const tools = React.useMemo<ToolsContextType>(() => {
|
const tools = React.useMemo<TLUiToolsContextType>(() => {
|
||||||
const toolsArray: ToolItem[] = [
|
const toolsArray: TLUiToolItem[] = [
|
||||||
{
|
{
|
||||||
id: 'select',
|
id: 'select',
|
||||||
label: 'tool.select',
|
label: 'tool.select',
|
||||||
|
@ -96,7 +96,7 @@ export function ToolsProvider({ overrides, children }: ToolsProviderProps) {
|
||||||
},
|
},
|
||||||
...[...TL_GEO_TYPES].map((id) => ({
|
...[...TL_GEO_TYPES].map((id) => ({
|
||||||
id,
|
id,
|
||||||
label: `tool.${id}` as TLTranslationKey,
|
label: `tool.${id}` as TLUiTranslationKey,
|
||||||
readonlyOk: false,
|
readonlyOk: false,
|
||||||
meta: {
|
meta: {
|
||||||
geo: id,
|
geo: id,
|
||||||
|
@ -218,7 +218,7 @@ export function ToolsProvider({ overrides, children }: ToolsProviderProps) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const tools = makeTools(toolsArray)
|
const tools = Object.fromEntries(toolsArray.map((t) => [t.id, t]))
|
||||||
|
|
||||||
if (overrides) {
|
if (overrides) {
|
||||||
return overrides(editor, tools, { insertMedia })
|
return overrides(editor, tools, { insertMedia })
|
||||||
|
@ -230,10 +230,6 @@ export function ToolsProvider({ overrides, children }: ToolsProviderProps) {
|
||||||
return <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>
|
return <ToolsContext.Provider value={tools}>{children}</ToolsContext.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeTools(tools: ToolItem[]) {
|
|
||||||
return Object.fromEntries(tools.map((t) => [t.id, t]))
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useTools() {
|
export function useTools() {
|
||||||
const ctx = React.useContext(ToolsContext)
|
const ctx = React.useContext(ToolsContext)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Do not edit manually.
|
// Do not edit manually.
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type TLTranslationKey =
|
export type TLUiTranslationKey =
|
||||||
| 'action.convert-to-bookmark'
|
| 'action.convert-to-bookmark'
|
||||||
| 'action.convert-to-embed'
|
| 'action.convert-to-embed'
|
||||||
| 'action.open-embed-link'
|
| 'action.open-embed-link'
|
|
@ -1,7 +1,7 @@
|
||||||
import { UiAssetUrls } from '../../assetUrls'
|
import { TLUiAssetUrls } from '../../assetUrls'
|
||||||
|
import { TLUiTranslationKey } from './TLUiTranslationKey'
|
||||||
import { DEFAULT_TRANSLATION } from './defaultTranslation'
|
import { DEFAULT_TRANSLATION } from './defaultTranslation'
|
||||||
import { LANGUAGES } from './languages'
|
import { LANGUAGES } from './languages'
|
||||||
import { TLTranslationKey } from './TLTranslationKey'
|
|
||||||
|
|
||||||
// The default language (english) must have a value for every message.
|
// The default language (english) must have a value for every message.
|
||||||
// Other languages may have missing messages. If the application finds
|
// Other languages may have missing messages. If the application finds
|
||||||
|
@ -11,42 +11,29 @@ import { TLTranslationKey } from './TLTranslationKey'
|
||||||
/* ----------------- (do not change) ---------------- */
|
/* ----------------- (do not change) ---------------- */
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type TLListedTranslation = {
|
export type TLUiLanguage = {
|
||||||
readonly locale: string
|
readonly locale: string
|
||||||
readonly label: string
|
readonly label: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export type TLListedTranslations = readonly TLListedTranslation[]
|
export type TLUiTranslation = {
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type TLTranslationMessages = Record<TLTranslationKey, string>
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type TLTranslation = {
|
|
||||||
readonly locale: string
|
readonly locale: string
|
||||||
readonly label: string
|
readonly label: string
|
||||||
readonly messages: TLTranslationMessages
|
readonly messages: Record<TLUiTranslationKey, string>
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
const EN_TRANSLATION: TLUiTranslation = {
|
||||||
export type TLTranslations = TLTranslation[]
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export type TLTranslationLocale = TLTranslations[number]['locale']
|
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export const EN_TRANSLATION: TLTranslation = {
|
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
label: 'English',
|
label: 'English',
|
||||||
messages: DEFAULT_TRANSLATION as TLTranslationMessages,
|
messages: DEFAULT_TRANSLATION as TLUiTranslation['messages'],
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export async function fetchTranslation(
|
export async function fetchTranslation(
|
||||||
locale: TLTranslationLocale,
|
locale: TLUiTranslation['locale'],
|
||||||
assetUrls: UiAssetUrls
|
assetUrls: TLUiAssetUrls
|
||||||
): Promise<TLTranslation> {
|
): Promise<TLUiTranslation> {
|
||||||
const mainRes = await fetch(assetUrls.translations.en)
|
const mainRes = await fetch(assetUrls.translations.en)
|
||||||
|
|
||||||
if (!mainRes.ok) {
|
if (!mainRes.ok) {
|
||||||
|
@ -66,7 +53,7 @@ export async function fetchTranslation(
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetch(assetUrls.translations[language.locale])
|
const res = await fetch(assetUrls.translations[language.locale])
|
||||||
const messages: TLTranslationMessages = await res.json()
|
const messages: TLUiTranslation['messages'] = await res.json()
|
||||||
|
|
||||||
if (!messages) {
|
if (!messages) {
|
||||||
console.warn(`No messages found for locale ${locale}`)
|
console.warn(`No messages found for locale ${locale}`)
|
||||||
|
@ -76,7 +63,7 @@ export async function fetchTranslation(
|
||||||
const missing: string[] = []
|
const missing: string[] = []
|
||||||
|
|
||||||
for (const key in EN_TRANSLATION) {
|
for (const key in EN_TRANSLATION) {
|
||||||
if (!messages[key as TLTranslationKey]) {
|
if (!messages[key as TLUiTranslationKey]) {
|
||||||
missing.push(key)
|
missing.push(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,11 +78,3 @@ export async function fetchTranslation(
|
||||||
messages: { ...EN_TRANSLATION.messages, ...messages },
|
messages: { ...EN_TRANSLATION.messages, ...messages },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @public */
|
|
||||||
export async function getTranslation(
|
|
||||||
locale: TLTranslationLocale,
|
|
||||||
assetUrls: UiAssetUrls
|
|
||||||
): Promise<TLTranslation> {
|
|
||||||
return await fetchTranslation(locale, assetUrls)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
import { useEditor } from '@tldraw/editor'
|
import { useEditor } from '@tldraw/editor'
|
||||||
import { LANGUAGES } from './languages'
|
import { LANGUAGES } from './languages'
|
||||||
|
import { TLUiLanguage } from './translations'
|
||||||
|
|
||||||
/** @public */
|
/** @internal */
|
||||||
export function useLanguages() {
|
export function useLanguages() {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
return { languages: LANGUAGES, currentLanguage: editor.locale }
|
return {
|
||||||
|
languages: LANGUAGES as readonly TLUiLanguage[],
|
||||||
|
currentLanguage: editor.locale,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,12 @@ import { useEditor } from '@tldraw/editor'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { track } from 'signia-react'
|
import { track } from 'signia-react'
|
||||||
import { useAssetUrls } from '../useAssetUrls'
|
import { useAssetUrls } from '../useAssetUrls'
|
||||||
import { TLTranslationKey } from './TLTranslationKey'
|
import { TLUiTranslationKey } from './TLUiTranslationKey'
|
||||||
import { DEFAULT_TRANSLATION } from './defaultTranslation'
|
import { DEFAULT_TRANSLATION } from './defaultTranslation'
|
||||||
import { TLTranslation, getTranslation } from './translations'
|
import { TLUiTranslation, fetchTranslation } from './translations'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TranslationProviderProps {
|
export interface TLUiTranslationProviderProps {
|
||||||
children: any
|
children: any
|
||||||
/**
|
/**
|
||||||
* (optional) A collection of overrides different locales.
|
* (optional) A collection of overrides different locales.
|
||||||
|
@ -21,24 +21,29 @@ export interface TranslationProviderProps {
|
||||||
overrides?: Record<string, Record<string, string>>
|
overrides?: Record<string, Record<string, string>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const TranslationsContext = React.createContext<TLTranslation>({} as TLTranslation)
|
/** @public */
|
||||||
|
export type TLUiTranslationContextType = TLUiTranslation
|
||||||
|
|
||||||
|
const TranslationsContext = React.createContext<TLUiTranslationContextType>(
|
||||||
|
{} as TLUiTranslationContextType
|
||||||
|
)
|
||||||
|
|
||||||
const useCurrentTranslation = () => React.useContext(TranslationsContext)
|
const useCurrentTranslation = () => React.useContext(TranslationsContext)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a translation context to the editor.
|
* Provides a translation context to the editor.
|
||||||
*
|
*
|
||||||
* @public
|
* @internal
|
||||||
*/
|
*/
|
||||||
export const TranslationProvider = track(function TranslationProvider({
|
export const TranslationProvider = track(function TranslationProvider({
|
||||||
overrides,
|
overrides,
|
||||||
children,
|
children,
|
||||||
}: TranslationProviderProps) {
|
}: TLUiTranslationProviderProps) {
|
||||||
const editor = useEditor()
|
const editor = useEditor()
|
||||||
const locale = editor.locale
|
const locale = editor.locale
|
||||||
const getAssetUrl = useAssetUrls()
|
const getAssetUrl = useAssetUrls()
|
||||||
|
|
||||||
const [currentTranslation, setCurrentTranslation] = React.useState<TLTranslation>(() => {
|
const [currentTranslation, setCurrentTranslation] = React.useState<TLUiTranslation>(() => {
|
||||||
if (overrides && overrides['en']) {
|
if (overrides && overrides['en']) {
|
||||||
return {
|
return {
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
|
@ -58,7 +63,7 @@ export const TranslationProvider = track(function TranslationProvider({
|
||||||
let isCancelled = false
|
let isCancelled = false
|
||||||
|
|
||||||
async function loadTranslation() {
|
async function loadTranslation() {
|
||||||
const translation = await getTranslation(locale, getAssetUrl)
|
const translation = await fetchTranslation(locale, getAssetUrl)
|
||||||
|
|
||||||
if (translation && !isCancelled) {
|
if (translation && !isCancelled) {
|
||||||
if (overrides && overrides[locale]) {
|
if (overrides && overrides[locale]) {
|
||||||
|
@ -101,7 +106,7 @@ export const TranslationProvider = track(function TranslationProvider({
|
||||||
export function useTranslation() {
|
export function useTranslation() {
|
||||||
const translation = useCurrentTranslation()
|
const translation = useCurrentTranslation()
|
||||||
return React.useCallback(
|
return React.useCallback(
|
||||||
function msg(id: TLTranslationKey) {
|
function msg(id: TLUiTranslationKey) {
|
||||||
return translation.messages[id] ?? id
|
return translation.messages[id] ?? id
|
||||||
},
|
},
|
||||||
[translation]
|
[translation]
|
||||||
|
|
|
@ -166,7 +166,7 @@ export type TLUiIconType =
|
||||||
| 'zoom-out'
|
| 'zoom-out'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const TLUiIconTypes = [
|
export const iconTypes = [
|
||||||
'align-bottom-center',
|
'align-bottom-center',
|
||||||
'align-bottom-left',
|
'align-bottom-left',
|
||||||
'align-bottom-right',
|
'align-bottom-right',
|
||||||
|
|
|
@ -4,15 +4,15 @@ import { useMemo } from 'react'
|
||||||
import { ActionsProviderProps } from './hooks/useActions'
|
import { ActionsProviderProps } from './hooks/useActions'
|
||||||
import { ActionsMenuSchemaProviderProps } from './hooks/useActionsMenuSchema'
|
import { ActionsMenuSchemaProviderProps } from './hooks/useActionsMenuSchema'
|
||||||
import { useBreakpoint } from './hooks/useBreakpoint'
|
import { useBreakpoint } from './hooks/useBreakpoint'
|
||||||
import { ContextMenuSchemaProviderProps } from './hooks/useContextMenuSchema'
|
import { TLUiContextMenuSchemaProviderProps } from './hooks/useContextMenuSchema'
|
||||||
import { useDialogs } from './hooks/useDialogsProvider'
|
import { useDialogs } from './hooks/useDialogsProvider'
|
||||||
import { HelpMenuSchemaProviderProps } from './hooks/useHelpMenuSchema'
|
import { TLUiHelpMenuSchemaProviderProps } from './hooks/useHelpMenuSchema'
|
||||||
import { KeyboardShortcutsSchemaProviderProps } from './hooks/useKeyboardShortcutsSchema'
|
import { TLUiKeyboardShortcutsSchemaProviderProps } from './hooks/useKeyboardShortcutsSchema'
|
||||||
import { MenuSchemaProviderProps } from './hooks/useMenuSchema'
|
import { TLUiMenuSchemaProviderProps } from './hooks/useMenuSchema'
|
||||||
import { useToasts } from './hooks/useToastsProvider'
|
import { useToasts } from './hooks/useToastsProvider'
|
||||||
import { ToolbarSchemaProviderProps } from './hooks/useToolbarSchema'
|
import { TLUiToolbarSchemaProviderProps } from './hooks/useToolbarSchema'
|
||||||
import { ToolsProviderProps } from './hooks/useTools'
|
import { TLUiToolsProviderProps } from './hooks/useTools'
|
||||||
import { TranslationProviderProps, useTranslation } from './hooks/useTranslation/useTranslation'
|
import { TLUiTranslationProviderProps, useTranslation } from './hooks/useTranslation/useTranslation'
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export function useDefaultHelpers() {
|
export function useDefaultHelpers() {
|
||||||
|
@ -49,51 +49,47 @@ export function useDefaultHelpers() {
|
||||||
|
|
||||||
type DefaultHelpers = ReturnType<typeof useDefaultHelpers>
|
type DefaultHelpers = ReturnType<typeof useDefaultHelpers>
|
||||||
|
|
||||||
export type TldrawUiOverride<Type, Helpers> = (
|
export type TLUiOverride<Type, Helpers> = (editor: Editor, schema: Type, helpers: Helpers) => Type
|
||||||
editor: Editor,
|
|
||||||
schema: Type,
|
|
||||||
helpers: Helpers
|
|
||||||
) => Type
|
|
||||||
|
|
||||||
type WithDefaultHelpers<T extends TldrawUiOverride<any, any>> = T extends TldrawUiOverride<
|
type WithDefaultHelpers<T extends TLUiOverride<any, any>> = T extends TLUiOverride<
|
||||||
infer Type,
|
infer Type,
|
||||||
infer Helpers
|
infer Helpers
|
||||||
>
|
>
|
||||||
? TldrawUiOverride<Type, Helpers extends undefined ? DefaultHelpers : Helpers & DefaultHelpers>
|
? TLUiOverride<Type, Helpers extends undefined ? DefaultHelpers : Helpers & DefaultHelpers>
|
||||||
: never
|
: never
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export interface TldrawUiOverrides {
|
export interface TLUiOverrides {
|
||||||
actionsMenu?: WithDefaultHelpers<NonNullable<ActionsMenuSchemaProviderProps['overrides']>>
|
actionsMenu?: WithDefaultHelpers<NonNullable<ActionsMenuSchemaProviderProps['overrides']>>
|
||||||
actions?: WithDefaultHelpers<NonNullable<ActionsProviderProps['overrides']>>
|
actions?: WithDefaultHelpers<NonNullable<ActionsProviderProps['overrides']>>
|
||||||
contextMenu?: WithDefaultHelpers<NonNullable<ContextMenuSchemaProviderProps['overrides']>>
|
contextMenu?: WithDefaultHelpers<NonNullable<TLUiContextMenuSchemaProviderProps['overrides']>>
|
||||||
helpMenu?: WithDefaultHelpers<NonNullable<HelpMenuSchemaProviderProps['overrides']>>
|
helpMenu?: WithDefaultHelpers<NonNullable<TLUiHelpMenuSchemaProviderProps['overrides']>>
|
||||||
menu?: WithDefaultHelpers<NonNullable<MenuSchemaProviderProps['overrides']>>
|
menu?: WithDefaultHelpers<NonNullable<TLUiMenuSchemaProviderProps['overrides']>>
|
||||||
toolbar?: WithDefaultHelpers<NonNullable<ToolbarSchemaProviderProps['overrides']>>
|
toolbar?: WithDefaultHelpers<NonNullable<TLUiToolbarSchemaProviderProps['overrides']>>
|
||||||
keyboardShortcutsMenu?: WithDefaultHelpers<
|
keyboardShortcutsMenu?: WithDefaultHelpers<
|
||||||
NonNullable<KeyboardShortcutsSchemaProviderProps['overrides']>
|
NonNullable<TLUiKeyboardShortcutsSchemaProviderProps['overrides']>
|
||||||
>
|
>
|
||||||
tools?: WithDefaultHelpers<NonNullable<ToolsProviderProps['overrides']>>
|
tools?: WithDefaultHelpers<NonNullable<TLUiToolsProviderProps['overrides']>>
|
||||||
translations?: TranslationProviderProps['overrides']
|
translations?: TLUiTranslationProviderProps['overrides']
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TldrawUiOverridesWithoutDefaults {
|
export interface TLUiOverridesWithoutDefaults {
|
||||||
actionsMenu?: ActionsMenuSchemaProviderProps['overrides']
|
actionsMenu?: ActionsMenuSchemaProviderProps['overrides']
|
||||||
actions?: ActionsProviderProps['overrides']
|
actions?: ActionsProviderProps['overrides']
|
||||||
contextMenu?: ContextMenuSchemaProviderProps['overrides']
|
contextMenu?: TLUiContextMenuSchemaProviderProps['overrides']
|
||||||
helpMenu?: HelpMenuSchemaProviderProps['overrides']
|
helpMenu?: TLUiHelpMenuSchemaProviderProps['overrides']
|
||||||
menu?: MenuSchemaProviderProps['overrides']
|
menu?: TLUiMenuSchemaProviderProps['overrides']
|
||||||
toolbar?: ToolbarSchemaProviderProps['overrides']
|
toolbar?: TLUiToolbarSchemaProviderProps['overrides']
|
||||||
keyboardShortcutsMenu?: KeyboardShortcutsSchemaProviderProps['overrides']
|
keyboardShortcutsMenu?: TLUiKeyboardShortcutsSchemaProviderProps['overrides']
|
||||||
tools?: ToolsProviderProps['overrides']
|
tools?: TLUiToolsProviderProps['overrides']
|
||||||
translations?: TranslationProviderProps['overrides']
|
translations?: TLUiTranslationProviderProps['overrides']
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mergeOverrides(
|
export function mergeOverrides(
|
||||||
overrides: TldrawUiOverrides[],
|
overrides: TLUiOverrides[],
|
||||||
defaultHelpers: DefaultHelpers
|
defaultHelpers: DefaultHelpers
|
||||||
): TldrawUiOverridesWithoutDefaults {
|
): TLUiOverridesWithoutDefaults {
|
||||||
const mergedTranslations: TranslationProviderProps['overrides'] = {}
|
const mergedTranslations: TLUiTranslationProviderProps['overrides'] = {}
|
||||||
for (const override of overrides) {
|
for (const override of overrides) {
|
||||||
if (override.translations) {
|
if (override.translations) {
|
||||||
for (const [key, value] of objectMapEntries(override.translations)) {
|
for (const [key, value] of objectMapEntries(override.translations)) {
|
||||||
|
@ -180,13 +176,13 @@ function useShallowArrayEquality<T extends unknown[]>(array: T): T {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useMergedTranslationOverrides(
|
export function useMergedTranslationOverrides(
|
||||||
overrides?: TldrawUiOverrides[] | TldrawUiOverrides
|
overrides?: TLUiOverrides[] | TLUiOverrides
|
||||||
): NonNullable<TranslationProviderProps['overrides']> {
|
): NonNullable<TLUiTranslationProviderProps['overrides']> {
|
||||||
const overridesArray = useShallowArrayEquality(
|
const overridesArray = useShallowArrayEquality(
|
||||||
overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
|
overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
|
||||||
)
|
)
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
const mergedTranslations: TranslationProviderProps['overrides'] = {}
|
const mergedTranslations: TLUiTranslationProviderProps['overrides'] = {}
|
||||||
for (const override of overridesArray) {
|
for (const override of overridesArray) {
|
||||||
if (override.translations) {
|
if (override.translations) {
|
||||||
for (const [key, value] of objectMapEntries(override.translations)) {
|
for (const [key, value] of objectMapEntries(override.translations)) {
|
||||||
|
@ -203,8 +199,8 @@ export function useMergedTranslationOverrides(
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useMergedOverrides(
|
export function useMergedOverrides(
|
||||||
overrides?: TldrawUiOverrides[] | TldrawUiOverrides
|
overrides?: TLUiOverrides[] | TLUiOverrides
|
||||||
): TldrawUiOverridesWithoutDefaults {
|
): TLUiOverridesWithoutDefaults {
|
||||||
const defaultHelpers = useDefaultHelpers()
|
const defaultHelpers = useDefaultHelpers()
|
||||||
const overridesArray = useShallowArrayEquality(
|
const overridesArray = useShallowArrayEquality(
|
||||||
overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
|
overrides == null ? [] : Array.isArray(overrides) ? overrides : [overrides]
|
||||||
|
|
|
@ -85,7 +85,7 @@ async function copyIcons() {
|
||||||
${icons.map((icon) => JSON.stringify(icon.replace('.svg', ''))).join(' | ')}
|
${icons.map((icon) => JSON.stringify(icon.replace('.svg', ''))).join(' | ')}
|
||||||
|
|
||||||
/** @public */
|
/** @public */
|
||||||
export const TLUiIconTypes = [
|
export const iconTypes = [
|
||||||
${icons.map((icon) => JSON.stringify(icon.replace('.svg', ''))).join(', ')}
|
${icons.map((icon) => JSON.stringify(icon.replace('.svg', ''))).join(', ')}
|
||||||
] as const`
|
] as const`
|
||||||
|
|
||||||
|
@ -239,10 +239,10 @@ async function copyTranslations() {
|
||||||
// translationKeys.ts
|
// translationKeys.ts
|
||||||
|
|
||||||
const translationKeys = Object.keys(defaultTranslation).map((key) => `'${key}'`)
|
const translationKeys = Object.keys(defaultTranslation).map((key) => `'${key}'`)
|
||||||
const translationKeysFilePath = join(uiPath, 'TLTranslationKey.ts')
|
const translationKeysFilePath = join(uiPath, 'TLUiTranslationKey.ts')
|
||||||
const translationKeysFile = `
|
const translationKeysFile = `
|
||||||
/** @public */
|
/** @public */
|
||||||
export type TLTranslationKey = ${translationKeys.join(' | ')}
|
export type TLUiTranslationKey = ${translationKeys.join(' | ')}
|
||||||
`
|
`
|
||||||
await writeCodeFile(
|
await writeCodeFile(
|
||||||
'scripts/refresh-assets.ts',
|
'scripts/refresh-assets.ts',
|
||||||
|
|
Loading…
Reference in a new issue