UI components round two (#2847)
This PR: - replaces the `shareZone` prop with `SharePanel` component - replaces the `topZone` prop with `TopPanel` components - replaces the `Button` component with `TldrawUiButton` and subcomponents - adds `TldrawUi` prefix to our primitives - fixes a couple of bugs with the components ### Change Type - [x] `major` — Breaking change
This commit is contained in:
parent
5d87804a76
commit
7ece89a357
83 changed files with 3122 additions and 2826 deletions
|
@ -67,6 +67,13 @@ const components: TLComponents = {
|
|||
</DefaultDebugMenu>
|
||||
)
|
||||
},
|
||||
SharePanel: () => {
|
||||
return (
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<ShareMenu />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export function LocalEditor() {
|
||||
|
@ -88,11 +95,6 @@ export function LocalEditor() {
|
|||
overrides={[sharingUiOverrides, fileSystemUiOverrides]}
|
||||
onUiEvent={handleUiEvent}
|
||||
components={components}
|
||||
shareZone={
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<ShareMenu />
|
||||
</div>
|
||||
}
|
||||
inferDarkMode
|
||||
>
|
||||
<LocalMigration />
|
||||
|
|
|
@ -13,8 +13,10 @@ import {
|
|||
Tldraw,
|
||||
TldrawUiMenuGroup,
|
||||
TldrawUiMenuItem,
|
||||
atom,
|
||||
lns,
|
||||
useActions,
|
||||
useValue,
|
||||
} from '@tldraw/tldraw'
|
||||
import { useCallback, useEffect } from 'react'
|
||||
import { useRemoteSyncClient } from '../hooks/useRemoteSyncClient'
|
||||
|
@ -39,6 +41,8 @@ import { SneakyOnDropOverride } from './SneakyOnDropOverride'
|
|||
import { StoreErrorScreen } from './StoreErrorScreen'
|
||||
import { ThemeUpdater } from './ThemeUpdater/ThemeUpdater'
|
||||
|
||||
const shittyOfflineAtom = atom('shitty offline atom', false)
|
||||
|
||||
const components: TLComponents = {
|
||||
ErrorFallback: ({ error }) => {
|
||||
throw error
|
||||
|
@ -78,6 +82,19 @@ const components: TLComponents = {
|
|||
</DefaultKeyboardShortcutsDialog>
|
||||
)
|
||||
},
|
||||
TopPanel: () => {
|
||||
const isOffline = useValue('offline', () => shittyOfflineAtom.get(), [])
|
||||
if (!isOffline) return null
|
||||
return <OfflineIndicator />
|
||||
},
|
||||
SharePanel: () => {
|
||||
return (
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<PeopleMenu />
|
||||
<ShareMenu />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
export function MultiplayerEditor({
|
||||
|
@ -96,6 +113,12 @@ export function MultiplayerEditor({
|
|||
roomId,
|
||||
})
|
||||
|
||||
const isOffline =
|
||||
storeWithStatus.status === 'synced-remote' && storeWithStatus.connectionStatus === 'offline'
|
||||
useEffect(() => {
|
||||
shittyOfflineAtom.set(isOffline)
|
||||
}, [isOffline])
|
||||
|
||||
const isEmbedded = useIsEmbedded(roomSlug)
|
||||
const sharingUiOverrides = useSharing()
|
||||
const fileSystemUiOverrides = useFileSystem({ isMultiplayer: true })
|
||||
|
@ -118,9 +141,6 @@ export function MultiplayerEditor({
|
|||
return <EmbeddedInIFrameWarning />
|
||||
}
|
||||
|
||||
const isOffline =
|
||||
storeWithStatus.status === 'synced-remote' && storeWithStatus.connectionStatus === 'offline'
|
||||
|
||||
return (
|
||||
<div className="tldraw__editor">
|
||||
<Tldraw
|
||||
|
@ -131,13 +151,6 @@ export function MultiplayerEditor({
|
|||
initialState={isReadOnly ? 'hand' : 'select'}
|
||||
onUiEvent={handleUiEvent}
|
||||
components={components}
|
||||
topZone={isOffline && <OfflineIndicator />}
|
||||
shareZone={
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<PeopleMenu />
|
||||
<ShareMenu />
|
||||
</div>
|
||||
}
|
||||
autoFocus
|
||||
inferDarkMode
|
||||
>
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import * as Popover from '@radix-ui/react-popover'
|
||||
import {
|
||||
Button,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonIcon,
|
||||
TldrawUiButtonLabel,
|
||||
track,
|
||||
useContainer,
|
||||
useEditor,
|
||||
|
@ -73,13 +75,16 @@ export const PeopleMenu = track(function PeopleMenu({
|
|||
)}
|
||||
{!hideShareMenu && (
|
||||
<div className="tlui-people-menu__section">
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="menu"
|
||||
data-wd="people-menu.invite"
|
||||
label={'people-menu.invite'}
|
||||
icon="plus"
|
||||
data-testid="people-menu.invite"
|
||||
onClick={() => editor.addOpenMenu('share menu')}
|
||||
/>
|
||||
>
|
||||
<TldrawUiButtonLabel>
|
||||
{msg('people-menu.invite')}
|
||||
<TldrawUiButtonIcon icon="plus" />
|
||||
</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
Button,
|
||||
Icon,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonIcon,
|
||||
TldrawUiIcon,
|
||||
track,
|
||||
useEditor,
|
||||
usePresence,
|
||||
|
@ -34,16 +35,16 @@ export const PeopleMenuItem = track(function PeopleMenuItem({ userId }: { userId
|
|||
|
||||
return (
|
||||
<div className="tlui-people-menu__item tlui-buttons__horizontal">
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="menu"
|
||||
className="tlui-people-menu__item__button"
|
||||
onClick={() => editor.animateToUser(userId)}
|
||||
onDoubleClick={handleFollowClick}
|
||||
>
|
||||
<Icon icon="color" color={presence.color} />
|
||||
<TldrawUiIcon icon="color" color={presence.color} />
|
||||
<div className="tlui-people-menu__name">{presence.userName ?? 'New User'}</div>
|
||||
</Button>
|
||||
<Button
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton
|
||||
type="icon"
|
||||
className="tlui-people-menu__item__follow"
|
||||
title={
|
||||
|
@ -53,11 +54,14 @@ export const PeopleMenuItem = track(function PeopleMenuItem({ userId }: { userId
|
|||
? msg('people-menu.following')
|
||||
: msg('people-menu.follow')
|
||||
}
|
||||
icon={theyAreFollowingYou ? 'leading' : youAreFollowingThem ? 'following' : 'follow'}
|
||||
onClick={handleFollowClick}
|
||||
disabled={theyAreFollowingYou}
|
||||
data-active={youAreFollowingThem || theyAreFollowingYou}
|
||||
/>
|
||||
>
|
||||
<TldrawUiButtonIcon
|
||||
icon={theyAreFollowingYou ? 'leading' : youAreFollowingThem ? 'following' : 'follow'}
|
||||
/>
|
||||
</TldrawUiButton>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as Popover from '@radix-ui/react-popover'
|
||||
import {
|
||||
Button,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonIcon,
|
||||
USER_COLORS,
|
||||
track,
|
||||
useContainer,
|
||||
|
@ -88,13 +89,14 @@ export const UserPresenceColorPicker = track(function UserPresenceColorPicker()
|
|||
return (
|
||||
<Popover.Root onOpenChange={handleOpenChange} open={isOpen}>
|
||||
<Popover.Trigger dir="ltr" asChild>
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="icon"
|
||||
className="tlui-people-menu__user__color"
|
||||
icon="color"
|
||||
style={{ color: editor.user.getColor() }}
|
||||
title={msg('people-menu.change-color')}
|
||||
/>
|
||||
>
|
||||
<TldrawUiButtonIcon icon="color" />
|
||||
</TldrawUiButton>
|
||||
</Popover.Trigger>
|
||||
<Popover.Portal container={container}>
|
||||
<Popover.Content
|
||||
|
@ -106,11 +108,11 @@ export const UserPresenceColorPicker = track(function UserPresenceColorPicker()
|
|||
>
|
||||
<div className={'tlui-buttons__grid'}>
|
||||
{USER_COLORS.map((item: string) => (
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="icon"
|
||||
key={item}
|
||||
data-id={item}
|
||||
data-wd={item}
|
||||
data-testid={item}
|
||||
aria-label={item}
|
||||
data-state={value === item ? 'hinted' : undefined}
|
||||
title={item}
|
||||
|
@ -120,8 +122,9 @@ export const UserPresenceColorPicker = track(function UserPresenceColorPicker()
|
|||
onPointerDown={handleButtonPointerDown}
|
||||
onPointerUp={handleButtonPointerUp}
|
||||
onClick={handleButtonClick}
|
||||
icon={'color'}
|
||||
/>
|
||||
>
|
||||
<TldrawUiButtonIcon icon="color" />
|
||||
</TldrawUiButton>
|
||||
))}
|
||||
</div>
|
||||
</Popover.Content>
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import { Button, Input, useEditor, useTranslation, useUiEvents, useValue } from '@tldraw/tldraw'
|
||||
import {
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonIcon,
|
||||
TldrawUiInput,
|
||||
useEditor,
|
||||
useTranslation,
|
||||
useUiEvents,
|
||||
useValue,
|
||||
} from '@tldraw/tldraw'
|
||||
import { useCallback, useRef, useState } from 'react'
|
||||
import { UI_OVERRIDE_TODO_EVENT } from '../../utils/useHandleUiEvent'
|
||||
import { UserPresenceColorPicker } from './UserPresenceColorPicker'
|
||||
|
@ -36,7 +44,7 @@ export function UserPresenceEditor() {
|
|||
<div className="tlui-people-menu__user">
|
||||
<UserPresenceColorPicker />
|
||||
{isEditingName ? (
|
||||
<Input
|
||||
<TldrawUiInput
|
||||
className="tlui-people-menu__user__input"
|
||||
defaultValue={userName}
|
||||
onValueChange={handleValueChange}
|
||||
|
@ -62,14 +70,15 @@ export function UserPresenceEditor() {
|
|||
) : null}
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="icon"
|
||||
className="tlui-people-menu__user__edit"
|
||||
data-wd="people-menu.change-name"
|
||||
data-testid="people-menu.change-name"
|
||||
title={msg('people-menu.change-name')}
|
||||
icon={isEditingName ? 'check' : 'edit'}
|
||||
onClick={toggleEditingName}
|
||||
/>
|
||||
>
|
||||
<TldrawUiButtonIcon icon={isEditingName ? 'check' : 'edit'} />
|
||||
</TldrawUiButton>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -54,6 +54,13 @@ const components: TLComponents = {
|
|||
</DefaultKeyboardShortcutsDialog>
|
||||
)
|
||||
},
|
||||
SharePanel: () => {
|
||||
return (
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<ExportMenu />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
type SnapshotEditorProps = {
|
||||
|
@ -79,11 +86,6 @@ export function SnapshotsEditor(props: SnapshotEditorProps) {
|
|||
editor.updateInstanceState({ isReadonly: true })
|
||||
}}
|
||||
components={components}
|
||||
shareZone={
|
||||
<div className="tlui-share-zone" draggable={false}>
|
||||
<ExportMenu />
|
||||
</div>
|
||||
}
|
||||
renderDebugMenuItems={() => <DebugMenuItems />}
|
||||
autoFocus
|
||||
inferDarkMode
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
import { Button, LegacyTldrawDocument, useEditor, useValue } from '@tldraw/tldraw'
|
||||
import {
|
||||
LegacyTldrawDocument,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonLabel,
|
||||
useEditor,
|
||||
useValue,
|
||||
} from '@tldraw/tldraw'
|
||||
|
||||
export function MigrationAnnouncement({
|
||||
onClose,
|
||||
|
@ -107,16 +113,16 @@ export function MigrationAnnouncement({
|
|||
marginTop: 8,
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="normal"
|
||||
style={{ fontSize: 14, marginRight: 'auto' }}
|
||||
onClick={downloadFile}
|
||||
>
|
||||
Download original
|
||||
</Button>
|
||||
<Button style={{ fontSize: 14 }} type="primary" onClick={onClose}>
|
||||
Continue
|
||||
</Button>
|
||||
<TldrawUiButtonLabel>Download original</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton style={{ fontSize: 14 }} type="primary" onClick={onClose}>
|
||||
<TldrawUiButtonLabel>Continue</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import {
|
||||
Button,
|
||||
DialogBody,
|
||||
DialogCloseButton,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
TLUiDialogsContextType,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonCheck,
|
||||
TldrawUiButtonLabel,
|
||||
TldrawUiDialogBody,
|
||||
TldrawUiDialogCloseButton,
|
||||
TldrawUiDialogFooter,
|
||||
TldrawUiDialogHeader,
|
||||
TldrawUiDialogTitle,
|
||||
useTranslation,
|
||||
} from '@tldraw/tldraw'
|
||||
import { useState } from 'react'
|
||||
|
@ -49,26 +51,28 @@ function ConfirmClearDialog({
|
|||
const [dontShowAgain, setDontShowAgain] = useState(false)
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{msg('file-system.confirm-clear.title')}</DialogTitle>
|
||||
<DialogCloseButton />
|
||||
</DialogHeader>
|
||||
<DialogBody style={{ maxWidth: 350 }}>
|
||||
<TldrawUiDialogHeader>
|
||||
<TldrawUiDialogTitle>{msg('file-system.confirm-clear.title')}</TldrawUiDialogTitle>
|
||||
<TldrawUiDialogCloseButton />
|
||||
</TldrawUiDialogHeader>
|
||||
<TldrawUiDialogBody style={{ maxWidth: 350 }}>
|
||||
{msg('file-system.confirm-clear.description')}
|
||||
</DialogBody>
|
||||
<DialogFooter className="tlui-dialog__footer__actions">
|
||||
<Button
|
||||
</TldrawUiDialogBody>
|
||||
<TldrawUiDialogFooter className="tlui-dialog__footer__actions">
|
||||
<TldrawUiButton
|
||||
type="normal"
|
||||
onClick={() => setDontShowAgain(!dontShowAgain)}
|
||||
iconLeft={dontShowAgain ? 'checkbox-checked' : 'checkbox-empty'}
|
||||
style={{ marginRight: 'auto' }}
|
||||
>
|
||||
{msg('file-system.confirm-clear.dont-show-again')}
|
||||
</Button>
|
||||
<Button type="normal" onClick={onCancel}>
|
||||
{msg('file-system.confirm-clear.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
<TldrawUiButtonCheck checked={dontShowAgain} />
|
||||
<TldrawUiButtonLabel>
|
||||
{msg('file-system.confirm-clear.dont-show-again')}
|
||||
</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton type="normal" onClick={onCancel}>
|
||||
<TldrawUiButtonLabel>{msg('file-system.confirm-clear.cancel')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
if (dontShowAgain) {
|
||||
|
@ -77,9 +81,9 @@ function ConfirmClearDialog({
|
|||
onContinue()
|
||||
}}
|
||||
>
|
||||
{msg('file-system.confirm-clear.continue')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
<TldrawUiButtonLabel>{msg('file-system.confirm-clear.continue')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</TldrawUiDialogFooter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import {
|
||||
Button,
|
||||
DialogBody,
|
||||
DialogCloseButton,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
TLUiDialogsContextType,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonCheck,
|
||||
TldrawUiButtonLabel,
|
||||
TldrawUiDialogBody,
|
||||
TldrawUiDialogCloseButton,
|
||||
TldrawUiDialogFooter,
|
||||
TldrawUiDialogHeader,
|
||||
TldrawUiDialogTitle,
|
||||
useLocalStorageState,
|
||||
useTranslation,
|
||||
} from '@tldraw/tldraw'
|
||||
|
@ -50,24 +52,26 @@ function ConfirmLeaveDialog({
|
|||
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{msg('sharing.confirm-leave.title')}</DialogTitle>
|
||||
<DialogCloseButton />
|
||||
</DialogHeader>
|
||||
<DialogBody style={{ maxWidth: 350 }}>{msg('sharing.confirm-leave.description')}</DialogBody>
|
||||
<DialogFooter className="tlui-dialog__footer__actions">
|
||||
<Button
|
||||
<TldrawUiDialogHeader>
|
||||
<TldrawUiDialogTitle>{msg('sharing.confirm-leave.title')}</TldrawUiDialogTitle>
|
||||
<TldrawUiDialogCloseButton />
|
||||
</TldrawUiDialogHeader>
|
||||
<TldrawUiDialogBody style={{ maxWidth: 350 }}>
|
||||
{msg('sharing.confirm-leave.description')}
|
||||
</TldrawUiDialogBody>
|
||||
<TldrawUiDialogFooter className="tlui-dialog__footer__actions">
|
||||
<TldrawUiButton
|
||||
type="normal"
|
||||
onClick={() => setDontShowAgain(!dontShowAgain)}
|
||||
iconLeft={dontShowAgain ? 'checkbox-checked' : 'checkbox-empty'}
|
||||
style={{ marginRight: 'auto' }}
|
||||
onClick={() => setDontShowAgain(!dontShowAgain)}
|
||||
>
|
||||
{msg('sharing.confirm-leave.dont-show-again')}
|
||||
</Button>
|
||||
<Button type="normal" onClick={onCancel}>
|
||||
{msg('sharing.confirm-leave.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
<TldrawUiButtonCheck checked={dontShowAgain} />
|
||||
<TldrawUiButtonLabel>{msg('sharing.confirm-leave.dont-show-again')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton type="normal" onClick={onCancel}>
|
||||
<TldrawUiButtonLabel>{msg('sharing.confirm-leave.cancel')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
if (dontShowAgain) {
|
||||
|
@ -76,9 +80,9 @@ function ConfirmLeaveDialog({
|
|||
onContinue()
|
||||
}}
|
||||
>
|
||||
{msg('sharing.confirm-leave.leave')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
<TldrawUiButtonLabel>{msg('sharing.confirm-leave.leave')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</TldrawUiDialogFooter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import {
|
||||
Button,
|
||||
DialogBody,
|
||||
DialogCloseButton,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
TLUiDialogsContextType,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonCheck,
|
||||
TldrawUiButtonLabel,
|
||||
TldrawUiDialogBody,
|
||||
TldrawUiDialogCloseButton,
|
||||
TldrawUiDialogFooter,
|
||||
TldrawUiDialogHeader,
|
||||
TldrawUiDialogTitle,
|
||||
useTranslation,
|
||||
} from '@tldraw/tldraw'
|
||||
import { useState } from 'react'
|
||||
|
@ -49,26 +51,28 @@ function ConfirmOpenDialog({
|
|||
const [dontShowAgain, setDontShowAgain] = useState(false)
|
||||
return (
|
||||
<>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{msg('file-system.confirm-open.title')}</DialogTitle>
|
||||
<DialogCloseButton />
|
||||
</DialogHeader>
|
||||
<DialogBody style={{ maxWidth: 350 }}>
|
||||
<TldrawUiDialogHeader>
|
||||
<TldrawUiDialogTitle>{msg('file-system.confirm-open.title')}</TldrawUiDialogTitle>
|
||||
<TldrawUiDialogCloseButton />
|
||||
</TldrawUiDialogHeader>
|
||||
<TldrawUiDialogBody style={{ maxWidth: 350 }}>
|
||||
{msg('file-system.confirm-open.description')}
|
||||
</DialogBody>
|
||||
<DialogFooter className="tlui-dialog__footer__actions">
|
||||
<Button
|
||||
</TldrawUiDialogBody>
|
||||
<TldrawUiDialogFooter className="tlui-dialog__footer__actions">
|
||||
<TldrawUiButton
|
||||
type="normal"
|
||||
onClick={() => setDontShowAgain(!dontShowAgain)}
|
||||
iconLeft={dontShowAgain ? 'checkbox-checked' : 'checkbox-empty'}
|
||||
style={{ marginRight: 'auto' }}
|
||||
>
|
||||
{msg('file-system.confirm-open.dont-show-again')}
|
||||
</Button>
|
||||
<Button type="normal" onClick={onCancel}>
|
||||
{msg('file-system.confirm-open.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
<TldrawUiButtonCheck checked={dontShowAgain} />
|
||||
<TldrawUiButtonLabel>
|
||||
{msg('file-system.confirm-open.dont-show-again')}
|
||||
</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton type="normal" onClick={onCancel}>
|
||||
<TldrawUiButtonLabel>{msg('file-system.confirm-open.cancel')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton
|
||||
type="primary"
|
||||
onClick={async () => {
|
||||
if (dontShowAgain) {
|
||||
|
@ -77,9 +81,9 @@ function ConfirmOpenDialog({
|
|||
onContinue()
|
||||
}}
|
||||
>
|
||||
{msg('file-system.confirm-open.open')}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
<TldrawUiButtonLabel>{msg('file-system.confirm-open.open')}</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
</TldrawUiDialogFooter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import {
|
||||
DefaultSizeStyle,
|
||||
Icon,
|
||||
SharedStyleMap,
|
||||
Tldraw,
|
||||
TldrawUiIcon,
|
||||
TLEditorComponents,
|
||||
track,
|
||||
useEditor,
|
||||
|
@ -85,7 +85,7 @@ const ContextToolbarComponent = track(() => {
|
|||
editor.setStyleForSelectedShapes(DefaultSizeStyle, value, { squashing: false })
|
||||
}
|
||||
>
|
||||
<Icon icon={icon} />
|
||||
<TldrawUiIcon icon={icon} />
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {
|
||||
Button,
|
||||
DefaultQuickActions,
|
||||
DefaultQuickActionsContent,
|
||||
TLComponents,
|
||||
Tldraw,
|
||||
TldrawUiMenuItem,
|
||||
} from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
||||
|
@ -11,7 +11,7 @@ function CustomQuickActions() {
|
|||
return (
|
||||
<DefaultQuickActions>
|
||||
<DefaultQuickActionsContent />
|
||||
<Button type="icon" icon="code" smallIcon />
|
||||
<TldrawUiMenuItem id="code" icon="code" onSelect={() => window.alert('code')} />
|
||||
</DefaultQuickActions>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import {
|
||||
Button,
|
||||
DefaultColorStyle,
|
||||
DefaultStylePanel,
|
||||
DefaultStylePanelContent,
|
||||
TLComponents,
|
||||
TLUiStylePanelProps,
|
||||
Tldraw,
|
||||
TldrawUiButton,
|
||||
TldrawUiButtonLabel,
|
||||
useEditor,
|
||||
} from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
@ -17,22 +18,22 @@ function CustomStylePanel(props: TLUiStylePanelProps) {
|
|||
|
||||
return (
|
||||
<DefaultStylePanel {...props}>
|
||||
<Button
|
||||
<TldrawUiButton
|
||||
type="menu"
|
||||
onClick={() => {
|
||||
editor.setStyleForSelectedShapes(DefaultColorStyle, 'red', { squashing: true })
|
||||
}}
|
||||
>
|
||||
Red
|
||||
</Button>
|
||||
<Button
|
||||
<TldrawUiButtonLabel>Red</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<TldrawUiButton
|
||||
type="menu"
|
||||
onClick={() => {
|
||||
editor.setStyleForSelectedShapes(DefaultColorStyle, 'green', { squashing: true })
|
||||
}}
|
||||
>
|
||||
Green
|
||||
</Button>
|
||||
<TldrawUiButtonLabel>Green</TldrawUiButtonLabel>
|
||||
</TldrawUiButton>
|
||||
<DefaultStylePanelContent relevantStyles={props.relevantStyles} />
|
||||
</DefaultStylePanel>
|
||||
)
|
||||
|
|
|
@ -17,6 +17,9 @@ const components: Required<TLUiComponents> = {
|
|||
QuickActions: null,
|
||||
HelperButtons: null,
|
||||
DebugMenu: null,
|
||||
SharePanel: null,
|
||||
MenuPanel: null,
|
||||
TopPanel: null,
|
||||
}
|
||||
|
||||
export default function UiComponentsHiddenExample() {
|
||||
|
|
|
@ -1,13 +1,18 @@
|
|||
import { Tldraw } from '@tldraw/tldraw'
|
||||
import { TLComponents, Tldraw } from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
||||
// There's a guide at the bottom of this file!
|
||||
|
||||
const components: TLComponents = {
|
||||
SharePanel: CustomShareZone,
|
||||
TopPanel: CustomTopZone,
|
||||
}
|
||||
|
||||
// [1]
|
||||
export default function Example() {
|
||||
return (
|
||||
<div className="tldraw__editor">
|
||||
<Tldraw topZone={<CustomTopZone />} shareZone={<CustomShareZone />} />
|
||||
<Tldraw components={components} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -46,8 +51,8 @@ function CustomShareZone() {
|
|||
}
|
||||
|
||||
/*
|
||||
This example shows how to pass in a custom component to the share zone and top zone.
|
||||
The share zone is in the top right corner above the style menu, the top zone is in
|
||||
This example shows how to pass in a custom component to the share panel and top panel.
|
||||
The share panel is in the top right corner above the style menu, the top panel is in
|
||||
the top center.
|
||||
|
||||
[1]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue