[docs] design shuffle (#2951)
This PR incorporates design tweaks from #2922 without the home page or content changes. These are: - Replacing all `hello@tldraw.com` with `sales@tldraw.com` - Fix mailto links. - Showing the first item in a section on direct routes to the section - Splitting the article page for human-written content from article page for generated content - Splitting the layout for the landing page from the rest of the site (temporarily identical to the regular content) - Removing headings from left sidebar - Restoring headings in right sidebar for human-written pages with > 1 heading link - Styling block quote - Adjusting section link appearance / layout in header / menu - Changing the order of search results to preference docs over examples - Updating copy on events - Removing copy on user interface menus - Adding hero as prop to all articles - Updated icon - Fixing a few broken links - Replaces the sandpack code blocks with hljs code blocks, except in examples. ### Change Type - [x] `documentation` — Changes to the documentation only[^2]
This commit is contained in:
parent
3f5803729d
commit
9a6f4e8c4b
47 changed files with 1587 additions and 1299 deletions
|
@ -138,7 +138,7 @@ Please see our [contributing guide](https://github.com/tldraw/tldraw/blob/main/C
|
|||
|
||||
The tldraw source code and its distributions are provided under the [tldraw license](https://github.com/tldraw/tldraw/blob/master/LICENSE.md). This license does not permit commercial use.
|
||||
|
||||
If you wish to use this project in commercial product, you need to purchase a commercial license. matPlease contact us at [hello@tldraw.com](mailto:hello@tldraw.com) for more inforion about obtaining a commercial license.
|
||||
If you wish to use this project in commercial product, you need to purchase a commercial license. matPlease contact us at [sales@tldraw.com](mailto:sales@tldraw.com) for more inforion about obtaining a commercial license.
|
||||
|
||||
## Trademarks
|
||||
|
||||
|
@ -146,4 +146,4 @@ Copyright (c) 2023-present tldraw Inc. The tldraw name and logo are trademarks o
|
|||
|
||||
## Contact
|
||||
|
||||
Find us on Twitter at [@tldraw](https://twitter.com/tldraw) or email [hello@tldraw.com](mailto://hello@tldraw.com). You can also [join our discord](https://discord.gg/rhsyWMUJxd) for quick help and support.
|
||||
Find us on Twitter at [@tldraw](https://twitter.com/tldraw) or email [sales@tldraw.com](mailto://sales@tldraw.com). You can also [join our discord](https://discord.gg/rhsyWMUJxd) for quick help and support.
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,12 +1,20 @@
|
|||
import { ArticleDocsPage } from '@/components/ArticleDocsPage'
|
||||
import { ArticleReferenceDocsPage } from '@/components/ArticleReferenceDocsPage'
|
||||
import { CategoryDocsPage } from '@/components/CategoryDocsPage'
|
||||
import { ExampleDocsPage } from '@/components/ExampleDocsPage'
|
||||
import { SectionDocsPage } from '@/components/SectionDocsPage'
|
||||
import { Article, Category, Section } from '@/types/content-types'
|
||||
import { getDb } from '@/utils/ContentDatabase'
|
||||
import { Metadata } from 'next'
|
||||
import { notFound } from 'next/navigation'
|
||||
|
||||
async function getContentForPath(path: string) {
|
||||
async function getContentForPath(
|
||||
path: string
|
||||
): Promise<
|
||||
| { type: 'section'; section: Section }
|
||||
| { type: 'category'; category: Category }
|
||||
| { type: 'article'; article: Article }
|
||||
> {
|
||||
const db = await getDb()
|
||||
|
||||
const section = await db.db.get(`SELECT * FROM sections WHERE sections.path = ?`, path)
|
||||
|
@ -105,6 +113,28 @@ export default async function ContentPage({ params }: { params: { id: string | s
|
|||
|
||||
switch (content.type) {
|
||||
case 'section': {
|
||||
const db = await getDb()
|
||||
let firstArticleInSection: Article | undefined
|
||||
|
||||
const categories = await db.getCategoriesForSection(content.section.id)
|
||||
|
||||
for (const category of categories) {
|
||||
const articles = await db.getCategoryArticles(content.section.id, category.id)
|
||||
const article = articles[0]
|
||||
if (article) {
|
||||
firstArticleInSection = article
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (firstArticleInSection) {
|
||||
const article = await db.getArticle(firstArticleInSection.id)
|
||||
if (article?.componentCode) {
|
||||
return <ExampleDocsPage article={article} />
|
||||
}
|
||||
return <ArticleDocsPage article={article} />
|
||||
}
|
||||
|
||||
return <SectionDocsPage section={content.section} />
|
||||
}
|
||||
case 'category': {
|
||||
|
@ -114,6 +144,11 @@ export default async function ContentPage({ params }: { params: { id: string | s
|
|||
if (content.article.componentCode) {
|
||||
return <ExampleDocsPage article={content.article} />
|
||||
}
|
||||
|
||||
if (content.article.sectionId === 'reference') {
|
||||
return <ArticleReferenceDocsPage article={content.article} />
|
||||
}
|
||||
|
||||
return <ArticleDocsPage article={content.article} />
|
||||
}
|
||||
default: {
|
|
@ -10,7 +10,7 @@ export default async function ClaPage() {
|
|||
<>
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<main className="main-content article">
|
||||
<div className="page-header">
|
||||
<h1>Contributor License Agreement</h1>
|
||||
</div>
|
10
apps/docs/app/(content)/layout.tsx
Normal file
10
apps/docs/app/(content)/layout.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { Footer } from '@/components/Footer'
|
||||
|
||||
export default async function ContentLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="wrapper">
|
||||
<div className="layout">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
10
apps/docs/app/(landing)/layout.tsx
Normal file
10
apps/docs/app/(landing)/layout.tsx
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { Footer } from '@/components/Footer'
|
||||
|
||||
export default async function ContentLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div className="wrapper">
|
||||
<div className="layout">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
import { Footer } from '@/components/Footer'
|
||||
import { Analytics } from '@vercel/analytics/react'
|
||||
import { Metadata, Viewport } from 'next'
|
||||
import AutoRefresh from '../components/AutoRefresh'
|
||||
|
@ -7,9 +6,9 @@ import '../styles/hljs.css'
|
|||
import '../styles/parameters-table.css'
|
||||
import { Providers } from './providers'
|
||||
|
||||
const TITLE = 'tldraw docs'
|
||||
const TITLE = 'tldraw SDK'
|
||||
const DESCRIPTION =
|
||||
'Developer documentation for tldraw. Build infinite canvas experiences for the web.'
|
||||
'Infinite canvas SDK from tldraw. Build whiteboards, design tools, and canvas experiences for the web.'
|
||||
const TWITTER_HANDLE = '@tldraw'
|
||||
const TWITTER_CARD = 'social-twitter.png'
|
||||
const FACEBOOK_CARD = 'social-og.png'
|
||||
|
@ -70,10 +69,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
|
|||
<html suppressHydrationWarning>
|
||||
<body>
|
||||
<Providers>
|
||||
<div className="wrapper">
|
||||
<div className="layout">{children}</div>
|
||||
<Footer />
|
||||
</div>
|
||||
{children}
|
||||
<Analytics />
|
||||
</Providers>
|
||||
</body>
|
||||
|
|
|
@ -7,15 +7,17 @@ export default async function NotFound() {
|
|||
const sidebar = await db.getSidebarContentList({})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<div className="page-header">
|
||||
<h1>Not found.</h1>
|
||||
</div>
|
||||
<p>There's nothing here. :(</p>
|
||||
</main>
|
||||
</>
|
||||
<div className="wrapper">
|
||||
<div className="layout">
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="main-content article">
|
||||
<div className="page-header">
|
||||
<h1>Not found.</h1>
|
||||
</div>
|
||||
<p>There's nothing here. :(</p>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,5 +3,5 @@
|
|||
import { ThemeProvider } from 'next-themes'
|
||||
|
||||
export function Providers({ children }: { children: any }) {
|
||||
return <ThemeProvider>{children}</ThemeProvider>
|
||||
return <ThemeProvider enableSystem>{children}</ThemeProvider>
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Article } from '@/types/content-types'
|
||||
import { getDb } from '@/utils/ContentDatabase'
|
||||
import { ArticleDetails } from './ArticleDetails'
|
||||
import { ArticleHeadingLinks } from './ArticleHeadingLinks'
|
||||
import { ArticleNavLinks } from './ArticleNavLinks'
|
||||
import { Breadcrumb } from './Breadcrumb'
|
||||
import { Header } from './Header'
|
||||
import { Mdx } from './Mdx'
|
||||
import { Sidebar } from './Sidebar'
|
||||
|
@ -20,22 +20,20 @@ export async function ArticleDocsPage({ article }: { article: Article }) {
|
|||
articleId: article.id,
|
||||
})
|
||||
|
||||
const isGenerated = article.sectionId === 'reference'
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar headings={headings} {...sidebar} />
|
||||
<main className={`article${isGenerated ? ' article__api-docs' : ''}`}>
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="main-content article">
|
||||
<div className="page-header">
|
||||
<Breadcrumb section={section} category={category} />
|
||||
<h1>{article.title}</h1>
|
||||
</div>
|
||||
{article.hero && <Image alt="hero" title={article.title} src={`images/${article.hero}`} />}
|
||||
{article.content && <Mdx content={article.content} />}
|
||||
{isGenerated ? null : <ArticleDetails article={article} />}
|
||||
<ArticleDetails article={article} />
|
||||
{links && <ArticleNavLinks links={links} />}
|
||||
</main>
|
||||
<ArticleHeadingLinks article={article} headingLinks={headings} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
46
apps/docs/components/ArticleHeadingLinks.tsx
Normal file
46
apps/docs/components/ArticleHeadingLinks.tsx
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* eslint-disable no-useless-escape */
|
||||
import { Article, ArticleHeading, ArticleHeadings } from '@/types/content-types'
|
||||
import Link from 'next/link'
|
||||
|
||||
export function ArticleHeadingLinks({
|
||||
headingLinks,
|
||||
}: {
|
||||
article: Article
|
||||
headingLinks: ArticleHeadings
|
||||
}) {
|
||||
const linksToShow = headingLinks.filter((heading) => heading.level < 4)
|
||||
|
||||
if (linksToShow.length <= 1) return null
|
||||
|
||||
return (
|
||||
<nav className="layout__headings">
|
||||
<ul className="sidebar__list sidebar__sections__list">
|
||||
<li className="sidebar__section">
|
||||
<div className="sidebar__section__title uppercase_title">On this page</div>
|
||||
<ul className="sidebar__list">
|
||||
{linksToShow.map((heading) => (
|
||||
<HeaderLink key={heading.slug} heading={heading} />
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
function HeaderLink({ heading }: { heading: ArticleHeading }) {
|
||||
return (
|
||||
<li className="sidebar__article">
|
||||
<Link href={`#${heading.slug}`} className="sidebar__link">
|
||||
{heading.level > 2 ? <span className="sidebar__link__indent">{'–'}</span> : null}
|
||||
<span className="sidebar__link__title">
|
||||
{heading.isCode ? (
|
||||
<code>{heading.title.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')}</code>
|
||||
) : (
|
||||
heading.title.replace(/\[([^\]]+)\]\([^\)]+\)/g, '$1')
|
||||
)}
|
||||
</span>
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
}
|
36
apps/docs/components/ArticleReferenceDocsPage.tsx
Normal file
36
apps/docs/components/ArticleReferenceDocsPage.tsx
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { Article } from '@/types/content-types'
|
||||
import { getDb } from '@/utils/ContentDatabase'
|
||||
import { ArticleNavLinks } from './ArticleNavLinks'
|
||||
import { Breadcrumb } from './Breadcrumb'
|
||||
import { Header } from './Header'
|
||||
import { Mdx } from './Mdx'
|
||||
import { Sidebar } from './Sidebar'
|
||||
import { Image } from './mdx-components/generic'
|
||||
|
||||
export async function ArticleReferenceDocsPage({ article }: { article: Article }) {
|
||||
const db = await getDb()
|
||||
const section = await db.getSection(article.sectionId)
|
||||
const category = await db.getCategory(article.categoryId)
|
||||
const links = await db.getArticleLinks(article)
|
||||
const sidebar = await db.getSidebarContentList({
|
||||
sectionId: section.id,
|
||||
categoryId: category.id,
|
||||
articleId: article.id,
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="main-content article article__api-docs">
|
||||
<div className="page-header">
|
||||
<Breadcrumb section={section} category={category} />
|
||||
<h1>{article.title}</h1>
|
||||
</div>
|
||||
{article.hero && <Image alt="hero" title={article.title} src={`images/${article.hero}`} />}
|
||||
{article.content && <Mdx content={article.content} />}
|
||||
{links && <ArticleNavLinks links={links} />}
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -23,10 +23,8 @@ export async function CategoryDocsPage({ category }: { category: Category }) {
|
|||
{articles.length > 0 && (
|
||||
<ul>
|
||||
{articles.map((article) => (
|
||||
<li>
|
||||
<Link key={article.id} href={`/${section.id}/${category.id}/${article.id}`}>
|
||||
{article.title}
|
||||
</Link>
|
||||
<li key={article.id}>
|
||||
<Link href={`/${section.id}/${category.id}/${article.id}`}>{article.title}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
import { Article } from '@/types/content-types'
|
||||
import { getDb } from '@/utils/ContentDatabase'
|
||||
import { ArticleNavLinks } from './ArticleNavLinks'
|
||||
import { Breadcrumb } from './Breadcrumb'
|
||||
import ExampleCodeBlock from './ExampleCodeBlock'
|
||||
import { Header } from './Header'
|
||||
import { Mdx } from './Mdx'
|
||||
import { Sidebar } from './Sidebar'
|
||||
import { Image } from './mdx-components/generic'
|
||||
|
||||
export async function ExampleDocsPage({ article }: { article: Article }) {
|
||||
const db = await getDb()
|
||||
const section = await db.getSection(article.sectionId)
|
||||
const category = await db.getCategory(article.categoryId)
|
||||
const headings = await db.getArticleHeadings(article.id)
|
||||
const links = await db.getArticleLinks(article)
|
||||
const sidebar = await db.getSidebarContentList({
|
||||
sectionId: section.id,
|
||||
|
@ -23,25 +20,21 @@ export async function ExampleDocsPage({ article }: { article: Article }) {
|
|||
return (
|
||||
<>
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar headings={headings} {...sidebar} />
|
||||
<main className={`article article__example`}>
|
||||
<Sidebar {...sidebar} />
|
||||
<main className={`main-content article article__example`}>
|
||||
<div className="page-header">
|
||||
<Breadcrumb section={section} category={category} />
|
||||
<h1>{article.title}</h1>
|
||||
{article.description && <p>{article.description}</p>}
|
||||
</div>
|
||||
{article.hero && <Image alt="hero" title={article.title} src={`images/${article.hero}`} />}
|
||||
{article.content && <Mdx content={article.content} />}
|
||||
{article.componentCode && (
|
||||
<ExampleCodeBlock
|
||||
articleId={article.id}
|
||||
files={{
|
||||
'App.tsx': article.componentCode,
|
||||
...(article.componentCodeFiles ? JSON.parse(article.componentCodeFiles) : null),
|
||||
}}
|
||||
activeFile={'App.tsx'}
|
||||
/>
|
||||
)}
|
||||
<ExampleCodeBlock
|
||||
articleId={article.id}
|
||||
files={{
|
||||
'App.tsx': article.componentCode,
|
||||
...(article.componentCodeFiles ? JSON.parse(article.componentCodeFiles) : null),
|
||||
}}
|
||||
activeFile={'App.tsx'}
|
||||
/>
|
||||
{links && <ArticleNavLinks links={links} />}
|
||||
</main>
|
||||
</>
|
||||
|
|
|
@ -1,44 +1,43 @@
|
|||
'use client'
|
||||
|
||||
import { debounce } from '@/utils/debounce'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useRef } from 'react'
|
||||
|
||||
export default function FancyBox() {
|
||||
const rContainer = useRef<HTMLDivElement>(null)
|
||||
const [items, setItems] = useState<number[]>([])
|
||||
// const [items, setItems] = useState<number[]>([])
|
||||
|
||||
useEffect(() => {
|
||||
const populate = debounce(() => {
|
||||
const elm = rContainer.current
|
||||
if (!elm) return
|
||||
// useEffect(() => {
|
||||
// const populate = debounce(() => {
|
||||
// const elm = rContainer.current
|
||||
// if (!elm) return
|
||||
|
||||
const width = elm.clientWidth
|
||||
const height = elm.clientHeight
|
||||
// const width = elm.clientWidth
|
||||
// const height = elm.clientHeight
|
||||
|
||||
const SIZE = 32
|
||||
// const SIZE = 32
|
||||
|
||||
const cols = Math.ceil(width / SIZE)
|
||||
const rows = Math.ceil(height / SIZE)
|
||||
// const cols = Math.ceil(width / SIZE)
|
||||
// const rows = Math.ceil(height / SIZE)
|
||||
|
||||
const items = Array.from(Array(cols * rows)).map((_, i) => i)
|
||||
// const items = Array.from(Array(cols * rows)).map((_, i) => i)
|
||||
|
||||
setItems(items)
|
||||
}, 100)
|
||||
// setItems(items)
|
||||
// }, 100)
|
||||
|
||||
populate()
|
||||
// populate()
|
||||
|
||||
window.addEventListener('resize', populate)
|
||||
return () => {
|
||||
window.removeEventListener('resize', populate)
|
||||
}
|
||||
}, [])
|
||||
// window.addEventListener('resize', populate)
|
||||
// return () => {
|
||||
// window.removeEventListener('resize', populate)
|
||||
// }
|
||||
// }, [])
|
||||
|
||||
return (
|
||||
<div className="footer__fancybox" ref={rContainer}>
|
||||
{items.map((i) => {
|
||||
{/* {items.map((i) => {
|
||||
const c = 1 + (i % 7)
|
||||
return <div key={i} className="footer__fancybox__item" data-c={c} />
|
||||
})}
|
||||
})} */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -18,11 +18,7 @@ export function Footer() {
|
|||
<p>tldraw © {new Date().getFullYear()}</p>
|
||||
</a>
|
||||
<div className="footer__socials">
|
||||
<a
|
||||
href="https://twitter.com/tldraw"
|
||||
className="sidebar__button icon-button"
|
||||
title="twitter"
|
||||
>
|
||||
<a href="https://x.com/tldraw" className="sidebar__button icon-button" title="x">
|
||||
<Icon icon="twitter" />
|
||||
</a>
|
||||
<a
|
||||
|
|
|
@ -10,43 +10,42 @@ export function Header({ sectionId }: { sectionId?: string }) {
|
|||
<div className="layout__header">
|
||||
<div className="layout__header__left">
|
||||
<Link href="/quick-start">
|
||||
<div
|
||||
className="lockup"
|
||||
style={{
|
||||
mask: `url(/lockup.svg) center 100% / 100% no-repeat`,
|
||||
WebkitMask: `url(/lockup.svg) center 100% / 100% no-repeat`,
|
||||
}}
|
||||
/>
|
||||
<img className="logo-dark" src="/tldraw_dev_dark.png" />
|
||||
<img className="logo-light" src="/tldraw_dev_light.png" />
|
||||
</Link>
|
||||
</div>
|
||||
<Search />
|
||||
<div className="layout__header__sections_and_socials">
|
||||
<SectionLinks sectionId={sectionId} />
|
||||
<a
|
||||
href="https://x.com/tldraw/"
|
||||
className="sidebar__button icon-button"
|
||||
title="twitter"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="twitter" />
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.com/invite/SBBEVCA4PG"
|
||||
className="sidebar__button icon-button"
|
||||
title="discord"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="discord" />
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/tldraw/tldraw"
|
||||
className="sidebar__button icon-button"
|
||||
title="github"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="github" />
|
||||
</a>
|
||||
<ThemeSwitcher />
|
||||
<div className="layout__header__links">
|
||||
<div className="layout__header__sections">
|
||||
<SectionLinks sectionId={sectionId} />
|
||||
</div>
|
||||
<div className="layout__header__socials">
|
||||
<a
|
||||
href="https://x.com/tldraw/"
|
||||
className="sidebar__button icon-button"
|
||||
title="twitter"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="twitter" />
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.com/invite/SBBEVCA4PG"
|
||||
className="sidebar__button icon-button"
|
||||
title="discord"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="discord" />
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/tldraw/tldraw"
|
||||
className="sidebar__button icon-button"
|
||||
title="github"
|
||||
target="_blank"
|
||||
>
|
||||
<Icon icon="github" />
|
||||
</a>
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -13,7 +13,7 @@ export function Chevron({ className }: { className?: string }) {
|
|||
<path
|
||||
d="M4 6L8 10L12 6"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { MDXRemote } from 'next-mdx-remote/rsc'
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||
import rehypeHighlight from 'rehype-highlight'
|
||||
import rehypeSlug from 'rehype-slug-custom-id'
|
||||
import { components } from './mdx-components'
|
||||
// import rehypeHighlight from 'rehype-highlight'
|
||||
|
||||
interface MdxProps {
|
||||
content: string
|
||||
|
@ -17,7 +17,7 @@ export function Mdx({ content }: MdxProps) {
|
|||
mdxOptions: {
|
||||
// remarkPlugins: [remarkGfm, {}],
|
||||
rehypePlugins: [
|
||||
// [rehypeHighlight as any, {}],
|
||||
[rehypeHighlight as any, {}],
|
||||
[rehypeAutolinkHeadings, {}],
|
||||
[rehypeSlug, { enableCustomId: true, maintainCase: true, removeAccents: true }],
|
||||
],
|
||||
|
|
|
@ -102,7 +102,7 @@ export function Search() {
|
|||
// {searchType === SEARCH_TYPE.NORMAL ? '✨ Search using AI' : '⭐ Search without AI'}
|
||||
// </button>
|
||||
// }
|
||||
groups={['examples', 'docs', 'reference']}
|
||||
groups={['docs', 'examples', 'reference']}
|
||||
groupsToLabel={{ examples: 'Examples', docs: 'Articles', reference: 'Reference' }}
|
||||
options={searchResults}
|
||||
isLoading={isLoading}
|
||||
|
|
|
@ -11,7 +11,7 @@ export async function SectionDocsPage({ section }: { section: Section }) {
|
|||
<>
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<main className="main-content article">
|
||||
<div className="page-header">
|
||||
<h1>{section.title}</h1>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@ const linkContext = createContext<{
|
|||
// it keeps re-rendering.
|
||||
let scrollPosition = 0
|
||||
|
||||
export function Sidebar({ headings, links, sectionId, categoryId, articleId }: SidebarProps) {
|
||||
export function Sidebar({ links, sectionId, categoryId, articleId }: SidebarProps) {
|
||||
const activeId = articleId ?? categoryId ?? sectionId
|
||||
const sidebarRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
|
@ -72,7 +72,7 @@ export function Sidebar({ headings, links, sectionId, categoryId, articleId }: S
|
|||
<div className="sidebar__section__links">
|
||||
<SectionLinks sectionId={sectionId} />
|
||||
</div>
|
||||
<SidebarLinks headings={headings} links={links} />
|
||||
<SidebarLinks links={links} />
|
||||
<SidebarCloseButton />
|
||||
</div>
|
||||
<ToggleMenuButton />
|
||||
|
@ -81,62 +81,48 @@ export function Sidebar({ headings, links, sectionId, categoryId, articleId }: S
|
|||
)
|
||||
}
|
||||
|
||||
export function SidebarLinks({
|
||||
headings,
|
||||
links,
|
||||
}: {
|
||||
headings?: ArticleHeadings
|
||||
links: SidebarContentLink[]
|
||||
}) {
|
||||
export function SidebarLinks({ links }: { links: SidebarContentLink[] }) {
|
||||
return (
|
||||
<nav className="sidebar__nav">
|
||||
<ul className="sidebar__list sidebar__sections__list">
|
||||
{links.map((link) => (
|
||||
<SidebarLink key={link.url} headings={headings} {...link} />
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
function SidebarLink({ headings, ...props }: SidebarContentLink & { headings?: ArticleHeadings }) {
|
||||
function SidebarLink(props: SidebarContentLink) {
|
||||
switch (props.type) {
|
||||
case 'section': {
|
||||
return <SidebarSection headings={headings} {...props} />
|
||||
return <SidebarSection {...props} />
|
||||
}
|
||||
case 'article': {
|
||||
return <SidebarArticle headings={headings} {...props} />
|
||||
return <SidebarArticle {...props} />
|
||||
}
|
||||
case 'category': {
|
||||
return <SidebarCategory headings={headings} {...props} />
|
||||
return <SidebarCategory {...props} />
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function SidebarSection({
|
||||
title,
|
||||
children,
|
||||
headings,
|
||||
}: SidebarContentSectionLink & { headings?: ArticleHeadings }) {
|
||||
function SidebarSection({ title, children }: SidebarContentSectionLink) {
|
||||
if (children.length === 0) return null
|
||||
|
||||
return (
|
||||
<li className="sidebar__section">
|
||||
{title && <span className="sidebar__section__title">{title}</span>}
|
||||
{title && <span className="sidebar__section__title uppercase_title">{title}</span>}
|
||||
<ul className="sidebar__list">
|
||||
{children.map((link) => (
|
||||
<SidebarLink key={link.url} headings={headings} {...link} />
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
function SidebarCategory({
|
||||
title,
|
||||
children,
|
||||
headings,
|
||||
}: SidebarContentCategoryLink & { headings?: ArticleHeadings }) {
|
||||
function SidebarCategory({ title, children }: SidebarContentCategoryLink) {
|
||||
const linkCtx = useContext(linkContext)
|
||||
if (children.length === 0) return null
|
||||
const hasGroups = children.some((child) => !!(child as SidebarContentArticleLink).groupId)
|
||||
|
@ -171,7 +157,7 @@ function SidebarCategory({
|
|||
<Accordion.Content>
|
||||
<ul className="sidebar__list sidebar__group">
|
||||
{articles.map((link) => (
|
||||
<SidebarLink key={link.url} headings={headings} {...link} />
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
|
|
|
@ -5,12 +5,7 @@ import { useTheme } from 'next-themes'
|
|||
import { useEffect, useState } from 'react'
|
||||
|
||||
export const Code = (props: any) => {
|
||||
if (!props.className) {
|
||||
return <code {...props} />
|
||||
}
|
||||
|
||||
const language = props.className.replace('language-', '')
|
||||
return <CodeBlock code={{ [`App.${language}`]: props.children.trim() }} />
|
||||
return <code {...props} />
|
||||
}
|
||||
|
||||
export function CodeBlock({ code }: { code: SandpackFiles }) {
|
||||
|
|
|
@ -150,7 +150,7 @@ export const Footnotes = (props: any) => {
|
|||
/* -------------------- API docs -------------------- */
|
||||
|
||||
export const ApiHeading = (props: any) => {
|
||||
return <div {...props} />
|
||||
return <div className="article__api-heading uppercase_title" {...props} />
|
||||
}
|
||||
|
||||
export const Embed = (props: any) => {
|
||||
|
@ -161,3 +161,14 @@ export const Embed = (props: any) => {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
/* -------------------- Callouts -------------------- */
|
||||
|
||||
export const Callout = ({ icon, children }: any) => {
|
||||
return (
|
||||
<div className="article__callout">
|
||||
<span>{icon}</span>
|
||||
<p>{children}</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import {
|
|||
A,
|
||||
ApiHeading,
|
||||
Blockquote,
|
||||
Callout,
|
||||
Divider,
|
||||
Embed,
|
||||
Heading1,
|
||||
|
@ -56,6 +57,7 @@ export const components = {
|
|||
Image,
|
||||
Small: Small,
|
||||
Video,
|
||||
Callout,
|
||||
...customComponents,
|
||||
...apiComponents,
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
{
|
||||
"id": "tldraw",
|
||||
"name": "tldraw",
|
||||
"email": "hello@tldraw.com",
|
||||
"email": "sales@tldraw.com",
|
||||
"twitter": "tldraw",
|
||||
"image": "tldraw.jpg"
|
||||
},
|
||||
{
|
||||
"id": "api",
|
||||
"name": "API",
|
||||
"email": "hello@tldraw.com",
|
||||
"email": "sales@tldraw.com",
|
||||
"twitter": "tldraw",
|
||||
"image": "api.jpg"
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ tldraw uses a dual licensing model to support the development of the project.
|
|||
|
||||
The project's source code, libraries, and distributions are provided under the [tldraw licence](https://github.com/tldraw/tldraw/blob/master/LICENSE.md).
|
||||
|
||||
This license does not permit commercial use. If you wish to use this project in commercial product or enterprise, you need to purchase a commercial license.
|
||||
This license does not permit commercial use. If you wish to use this project in a commercial product or enterprise, you need to purchase a commercial license.
|
||||
|
||||
To purchase a commercial license, or for more information, please contact us at [sales@tldraw.com](mailto:sales@tldraw.com).
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: User Interface
|
||||
title: User interface
|
||||
status: published
|
||||
author: steveruizok
|
||||
date: 3/22/2023
|
||||
|
@ -39,6 +39,27 @@ All of our user interface works by controlling the editor via its `Editor` metho
|
|||
|
||||
The source for these examples are available in the [tldraw repository](https://github.com/tldraw/tldraw/blob/main/apps/examples/src) or in a [sandbox here](https://stackblitz.com/github/tldraw/tldraw/tree/examples?file=src%2Findex.tsx).
|
||||
|
||||
## Events
|
||||
|
||||
The [Tldraw](?) component has a prop, `onUiEvent`, that the user interface will call when certain events occur.
|
||||
|
||||
```tsx
|
||||
function Example() {
|
||||
function handleEvent(name, data) {
|
||||
// do something with the event
|
||||
}
|
||||
|
||||
return <Tldraw onUiEvent={handleEvent} />
|
||||
}
|
||||
```
|
||||
|
||||
The `onUiEvent` callback is called with the name of the event as a string and an object with information about the event's source (e.g. `menu` or `context-menu`) and possibly other data specific to each event, such as the direction in an `align-shapes` event.
|
||||
|
||||
Note that `onUiEvent` is only called when interacting with the user interface. It is not called when running commands manually against the app, e.g. calling [Editor#alignShapes](?) will not call `onUiEvent`.
|
||||
|
||||
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface.
|
||||
|
||||
|
||||
## Overrides
|
||||
|
||||
The content of tldraw's menus can be controlled via the `overrides` prop. This prop accepts a [TLUiOverrides](/reference/tldraw/TLUiOverrides) object, which has methods for each part of the user interface, such as the `toolbar` or `keyboardShortcutsMenu`.
|
||||
|
@ -99,70 +120,6 @@ const myOverrides: TLUiOverrides = {
|
|||
|
||||
The `tools` object is a map of [TLUiToolItem](/reference/tldraw/TLUiToolItem)s, with each item keyed under its `id`.
|
||||
|
||||
### Toolbar and Menus
|
||||
|
||||
The remaining overrides are for toolbar and the various menus: the main menu, actions menu, context menu, help menu, and the keyboard shortcuts menu.
|
||||
|
||||
Each of these overrides accepts a method that receives the default menu schema and returns a mutated version of that schema.
|
||||
|
||||
```ts
|
||||
const myOverrides: TLUiOverrides = {
|
||||
actions(editor, actions) {
|
||||
// Create a new action or replace an existing one
|
||||
actions['my-new-action'] = {
|
||||
id: 'my-new-action',
|
||||
label: 'My new action',
|
||||
readonlyOk: true,
|
||||
kbd: '$u',
|
||||
onSelect(source: any) {
|
||||
window.alert('My new action just happened!')
|
||||
},
|
||||
}
|
||||
return actions
|
||||
},
|
||||
contextMenu(editor, contextMenu, { actions }) {
|
||||
const newMenuItem = menuItem(actions['my-new-action'])
|
||||
const newMenuGroup = menuGroup('my-items', newMenuItem)
|
||||
contextMenu.unshift(newMenuItem)
|
||||
return contextMenu
|
||||
},
|
||||
menu(editor, menu, { actions }) {
|
||||
// using the findMenuItem helper
|
||||
const fileMenu = findMenuItem(menu, ['menu', 'file'])
|
||||
if (fileMenu.type === 'submenu') {
|
||||
// add the new item to the file menu's children
|
||||
const newMenuItem = menuItem(actions['my-new-action'])
|
||||
fileMenu.children.unshift(newMenuItem)
|
||||
}
|
||||
return menu
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
A menu schema is an array of either [submenus](/reference/tldraw/TLUiSubMenu), [groups](/reference/tldraw/TLUiMenuGroup), [items](/reference/tldraw/TLUiMenuItem), or [custom items](/reference/tldraw/TLUiCustomMenuItem). Each group or submenu may include any of the other types as its children.
|
||||
|
||||
The menu schema is stateful. Referencing atomic properties (such as computed values in the editor) will cause the menu to update when those values change. If you wish for a menu item to disappear from the menu, you can return `null` from the menu method. You can also provide additional options for each item, `disabled` or `checked`.
|
||||
|
||||
```ts
|
||||
const myOverrides: TLUiOverrides = {
|
||||
menu(editor, menu, { actions }) {
|
||||
const selectedShapes = editor.getSelectedShapeIds().length
|
||||
|
||||
const newMenuGroup = menuGroup(
|
||||
'my-actions',
|
||||
selectedShapes > 0 ? menuItem(actions['action-a']) : null,
|
||||
menuItem(actions['action-b'], { disabled: selectedShapes < 3 })
|
||||
)
|
||||
|
||||
menu.unshift(newMenuGroup)
|
||||
|
||||
return menu
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
It's recommmended to explore the [default menu schema](https://github.com/tldraw/tldraw/blob/main/packages/tldraw/src/lib/ui/hooks/useMenuSchema.tsx) in order to understand how menu items work.
|
||||
|
||||
### Translations
|
||||
|
||||
The `translations` method accepts a table of new translations. For example, if you wanted a tool to reference a key `"tools.card"`, then you should at minimum provide an english translation for this key.
|
||||
|
@ -176,23 +133,3 @@ const myOverrides: TLUiOverrides = {
|
|||
},
|
||||
}
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
The [Tldraw](?) component has a prop, `onUiEvent`, that the user interface will call when certain events occur.
|
||||
|
||||
```tsx
|
||||
function Example() {
|
||||
function handleEvent(name, data) {
|
||||
// do something with the event
|
||||
}
|
||||
|
||||
return <Tldraw onUiEvent={handleEvent} />
|
||||
}
|
||||
```
|
||||
|
||||
The `onUiEvent` callback is called with the name of the event as a string and an object with information about the event's source (e.g. `menu` or `context-menu`) and possibly other data specific to each event, such as the direction in an `align-shapes` event.
|
||||
|
||||
Note that `onUiEvent` is only called when interacting with the user interface. It is not called when running commands manually against the app, e.g. calling [Editor#alignShapes](?) will not call `onUiEvent`.
|
||||
|
||||
See the [tldraw repository](https://github.com/tldraw/tldraw/tree/main/apps/examples) for an example of how to customize tldraw's user interface.
|
||||
|
|
|
@ -12,71 +12,64 @@ The tldraw SDK provides a really simple way to craft infinite canvas experiences
|
|||
|
||||
By the end of this guide you will have made something that looks like this:
|
||||
|
||||
<Embed className="article__embed--quickstart" src="https://vite-template-five.vercel.app/" />
|
||||
<Embed className="article__embed--quickstart" src="https://examples.tldraw.com/develop" />
|
||||
|
||||
### 1. Installation
|
||||
|
||||
<hr />
|
||||
<ol className="ordered-list__quickstart">
|
||||
<li>
|
||||
### Installation
|
||||
- Set up a React project however you normally do. [We recommend Vite](https://vitejs.dev/guide/#scaffolding-your-first-vite-project).
|
||||
- Install the tldraw library using this command:
|
||||
|
||||
- Set up a React project however you normally do. [We recommend Vite](https://vitejs.dev/guide/#scaffolding-your-first-vite-project).
|
||||
- Install the tldraw library using this command:
|
||||
```bash
|
||||
npm install @tldraw/tldraw@beta
|
||||
```
|
||||
|
||||
```bash
|
||||
npm install tldraw@beta
|
||||
```
|
||||
</li>
|
||||
<li>
|
||||
### Import Styles
|
||||
<br />
|
||||
To import fonts and CSS for tldraw:
|
||||
### 2. Import Styles
|
||||
|
||||
- Create or edit a css file called `index.css`
|
||||
- Copy and paste this into the file:
|
||||
```CSS
|
||||
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Roboto+Mono:wght@400;700&display=swap");
|
||||
@import url("tldraw/tldraw.css");
|
||||
To import fonts and CSS for tldraw:
|
||||
|
||||
body {
|
||||
font-family: "Inter";
|
||||
}
|
||||
```
|
||||
</li>
|
||||
<li>
|
||||
### Render Tldraw Component
|
||||
<br />
|
||||
To render the Tldraw component
|
||||
- Create or edit a css file called `index.css`
|
||||
- Copy and paste this into the file:
|
||||
|
||||
- Import the `<Tldraw />` component from `tldraw`
|
||||
- Import the `index.css` CSS file from earlier
|
||||
- Wrap the Tldraw component in a `<div>` element with the style attribute set to: `{ position: 'fixed', inset: 0 }`
|
||||
```CSS
|
||||
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@500;700;&display=swap");
|
||||
@import url("@tldraw/tldraw/tldraw.css");
|
||||
|
||||
<p className="">This will render a full screen canvas:</p>
|
||||
body {
|
||||
font-family: "Inter";
|
||||
}
|
||||
```
|
||||
|
||||
```javascript
|
||||
import { Tldraw } from "tldraw";
|
||||
import "./index.css";
|
||||
### 3. Render Tldraw Component
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<div style={{ position: 'fixed', inset: 0 }}>
|
||||
<Tldraw />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</li>
|
||||
</ol>
|
||||
To render the Tldraw component
|
||||
|
||||
<hr />
|
||||
- Import the `<Tldraw />` component from `@tldraw/tldraw`
|
||||
- Import the `index.css` CSS file from earlier
|
||||
- Wrap the Tldraw component in a `<div>` element with the style attribute set to: `{ position: 'fixed', inset: 0 }`
|
||||
|
||||
### Next Steps
|
||||
This will render a full screen canvas:
|
||||
|
||||
You did it! Now that you have your canvas working, you may be wondering: what next? You can try:
|
||||
```javascript
|
||||
import { Tldraw } from "@tldraw/tldraw";
|
||||
import "./index.css";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<div style={{ position: 'fixed', inset: 0 }}>
|
||||
<Tldraw />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Now that you have your canvas working, you may be wondering: what next?
|
||||
|
||||
You can try:
|
||||
|
||||
- Giving the editor a makeover by [customizing the UI](/docs/user-interface)
|
||||
- Adding your own [shapes](/docs/shapes) and [tools](/docs/tools)
|
||||
- Providing collaboration using [multiplayer](https://github.com/tldraw/tldraw-yjs-example)
|
||||
|
||||
We provide the above examples and more in our [examples section](/examples/basic/develop). Go build something creative and please do share it with us in our [#show-and-tell](https://discord.com/invite/SBBEVCA4PG) channel on Discord!
|
||||
We provide the above examples and more in our [examples section](/examples). Go build something creative and please do share it with us in our [#show-and-tell](https://discord.com/invite/SBBEVCA4PG) channel on Discord!
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
{
|
||||
"id": "docs",
|
||||
"title": "Learn tldraw",
|
||||
"description": "Developer documentation for tldraw.",
|
||||
"description": "Learn to use the tldraw SDK.",
|
||||
"categories": [],
|
||||
"sidebar_behavior": "show-links"
|
||||
},
|
||||
|
@ -58,7 +58,8 @@
|
|||
"id": "Namespace",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
],
|
||||
"hero": null
|
||||
},
|
||||
{
|
||||
"id": "store",
|
||||
|
@ -93,7 +94,8 @@
|
|||
"id": "Namespace",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
],
|
||||
"hero": null
|
||||
},
|
||||
{
|
||||
"id": "tldraw",
|
||||
|
@ -128,7 +130,8 @@
|
|||
"id": "Namespace",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
],
|
||||
"hero": null
|
||||
},
|
||||
{
|
||||
"id": "tlschema",
|
||||
|
@ -163,7 +166,8 @@
|
|||
"id": "Namespace",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
],
|
||||
"hero": null
|
||||
},
|
||||
{
|
||||
"id": "validate",
|
||||
|
@ -198,9 +202,11 @@
|
|||
"id": "Namespace",
|
||||
"path": null
|
||||
}
|
||||
]
|
||||
],
|
||||
"hero": null
|
||||
}
|
||||
],
|
||||
"sidebar_behavior": "reference"
|
||||
"sidebar_behavior": "reference",
|
||||
"hero": null
|
||||
}
|
||||
]
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
"dev": "concurrently \"NODE_ENV=development next dev --port=3001\" \"tsx ./watcher.ts\" --kill-others",
|
||||
"next-dev": "next dev",
|
||||
"lint": "yarn run -T tsx ../../scripts/lint.ts",
|
||||
"build": "yarn create-api-markdown && yarn refresh-content && next build",
|
||||
"build": "yarn create-api-markdown && yarn refresh-content && next build && yarn check-links",
|
||||
"start": "yarn create-api-markdown && yarn refresh-content && next start",
|
||||
"fetch-api-source": "yarn run -T tsx --tsconfig ./tsconfig.content.json ./scripts/fetch-api-source.ts",
|
||||
"fetch-releases": "yarn run -T tsx --tsconfig ./tsconfig.content.json ./scripts/fetch-releases.ts",
|
||||
|
@ -54,7 +54,6 @@
|
|||
"@types/sqlite3": "^3.1.9",
|
||||
"@types/ws": "^8.5.9",
|
||||
"@vercel/analytics": "^1.1.1",
|
||||
"broken-link-checker": "^0.7.8",
|
||||
"classnames": "^2.3.2",
|
||||
"concurrently": "^8.2.2",
|
||||
"dotenv": "^16.3.1",
|
||||
|
@ -87,5 +86,8 @@
|
|||
"unist-util-visit": "^5.0.0",
|
||||
"vectra": "^0.4.4",
|
||||
"ws": "^8.16.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"linkinator": "^6.0.4"
|
||||
}
|
||||
}
|
||||
|
|
BIN
apps/docs/public/tldraw_dev_dark.png
Normal file
BIN
apps/docs/public/tldraw_dev_dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
BIN
apps/docs/public/tldraw_dev_light.png
Normal file
BIN
apps/docs/public/tldraw_dev_light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -1,29 +1,25 @@
|
|||
import { nicelog } from '@/utils/nicelog'
|
||||
import blc from 'broken-link-checker'
|
||||
|
||||
const IGNORED_URLS = ['https://twitter.com/tldraw', 'https://tldraw.com']
|
||||
import { check } from 'linkinator'
|
||||
|
||||
export async function checkBrokenLinks() {
|
||||
nicelog('Checking broken links...')
|
||||
const checked = new Set<string>()
|
||||
const checker = new blc.SiteChecker(
|
||||
{
|
||||
filterLevel: 1,
|
||||
},
|
||||
{
|
||||
link(result) {
|
||||
if (IGNORED_URLS.includes(result.url.original)) return
|
||||
if (checked.has(result.url.resolved)) return
|
||||
// nicelog('Checking', result.url.resolved.replace('http://localhost:3001', ''))
|
||||
if (result.broken) {
|
||||
nicelog(`BROKEN: ${result.url.resolved} on page ${result.base.resolved}`)
|
||||
}
|
||||
checked.add(result.url.resolved)
|
||||
},
|
||||
end() {
|
||||
nicelog('done')
|
||||
},
|
||||
}
|
||||
const results = await check({
|
||||
path: 'http://localhost:3001',
|
||||
recurse: true,
|
||||
})
|
||||
|
||||
// All good
|
||||
if (results.passed) return
|
||||
|
||||
// There seems to be a porblem
|
||||
nicelog(
|
||||
`𐄂 Broken links detected!\n\n` +
|
||||
results.links
|
||||
.filter((result) => result.state !== 'OK')
|
||||
.map(
|
||||
(result, i) =>
|
||||
`${i + 1}.\t${result.url}\n\tFrom: ${result.parent}\n\tStatus: ${result.status}`
|
||||
)
|
||||
.join('\n\n') +
|
||||
'\n\n'
|
||||
)
|
||||
checker.enqueue('http://localhost:3001/docs/assets', null)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ export async function createApiMarkdown() {
|
|||
description: "Reference for the tldraw package's APIs (generated).",
|
||||
categories: [],
|
||||
sidebar_behavior: 'reference',
|
||||
hero: null,
|
||||
}
|
||||
|
||||
const addedCategories = new Set<string>()
|
||||
|
@ -55,6 +56,7 @@ export async function createApiMarkdown() {
|
|||
id: title,
|
||||
path: null,
|
||||
})),
|
||||
hero: null,
|
||||
})
|
||||
addedCategories.add(categoryName)
|
||||
}
|
||||
|
|
|
@ -8,13 +8,14 @@ const section: InputSection = {
|
|||
title: 'Examples',
|
||||
description: 'Code recipes for bending tldraw to your will.',
|
||||
categories: [
|
||||
{ id: 'basic', title: 'Getting Started', description: '', groups: [] },
|
||||
{ id: 'ui', title: 'UI & Theming', description: '', groups: [] },
|
||||
{ id: 'shapes/tools', title: 'Shapes & Tools', description: '', groups: [] },
|
||||
{ id: 'data/assets', title: 'Data & Assets', description: '', groups: [] },
|
||||
{ id: 'editor-api', title: 'Editor API', description: '', groups: [] },
|
||||
{ id: 'collaboration', title: 'Collaboration', description: '', groups: [] },
|
||||
{ id: 'basic', title: 'Getting Started', description: '', groups: [], hero: null },
|
||||
{ id: 'ui', title: 'UI & Theming', description: '', groups: [], hero: null },
|
||||
{ id: 'shapes/tools', title: 'Shapes & Tools', description: '', groups: [], hero: null },
|
||||
{ id: 'data/assets', title: 'Data & Assets', description: '', groups: [], hero: null },
|
||||
{ id: 'editor-api', title: 'Editor API', description: '', groups: [], hero: null },
|
||||
{ id: 'collaboration', title: 'Collaboration', description: '', groups: [], hero: null },
|
||||
],
|
||||
hero: null,
|
||||
sidebar_behavior: 'show-links',
|
||||
}
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
groups: [],
|
||||
path: `/${section.id}/ucg`,
|
||||
content: null,
|
||||
hero: null,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -188,6 +189,7 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
index: i + 1,
|
||||
path: `/${section.id}/${inputCategory.id}`,
|
||||
content: null,
|
||||
hero: null,
|
||||
groups: inputCategory.groups.map(({ id }, i) => ({
|
||||
id,
|
||||
title: id,
|
||||
|
@ -210,6 +212,7 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
index,
|
||||
categories,
|
||||
content: '',
|
||||
hero: section.hero ?? null,
|
||||
path: `/${section.id}`,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ async function addDocComment(result: Result, member: ApiItem) {
|
|||
|
||||
if (exampleBlocks.length) {
|
||||
result.markdown += `\n\n`
|
||||
result.markdown += `##### Example\n\n`
|
||||
result.markdown += `<ApiHeading>Example</ApiHeading>\n\n`
|
||||
for (const example of exampleBlocks) {
|
||||
result.markdown += await MarkdownWriter.docNodeToMarkdown(member, example.content)
|
||||
}
|
||||
|
@ -393,7 +393,7 @@ function addTags(result: Result, member: ApiItem) {
|
|||
tags.push('readonly')
|
||||
}
|
||||
tags.push(member.kind.toLowerCase())
|
||||
result.markdown += `<Small>${tags.join(' ')}</Small>\n\n`
|
||||
result.markdown += `<Small>${tags.filter((t) => t.toLowerCase() !== 'none').join(' ')}</Small>\n\n`
|
||||
}
|
||||
|
||||
function addReferences(result: Result, member: ApiItem) {
|
||||
|
|
|
@ -19,13 +19,15 @@
|
|||
--color-tint-5: rgb(144, 144, 144);
|
||||
--color-tint-6: rgb(81, 81, 81);
|
||||
|
||||
--color-blockquote: rgb(242, 247, 255);
|
||||
|
||||
/* Light theme */
|
||||
--color-text: #1d1d1d;
|
||||
--color-text-secondary: #666;
|
||||
--color-background: #ffffff;
|
||||
--color-contrast: #ffffff;
|
||||
--color-accent: #2f80ed;
|
||||
--color-footer-background: #212529;
|
||||
--color-footer-background: hsl(240, 5%, 8%);
|
||||
--color-footer-text: #fafafa;
|
||||
|
||||
--shadow-small: 0px 0px 16px -2px rgba(0, 0, 0, 0.12), 0px 0px 4px 0px rgba(0, 0, 0, 0.12);
|
||||
|
@ -47,7 +49,8 @@
|
|||
--border-radius-menu: 4px;
|
||||
|
||||
/* Sizes */
|
||||
--header-height: 72px;
|
||||
--header-height: 80px;
|
||||
--header-padding: 24px;
|
||||
}
|
||||
|
||||
[data-theme='dark'] {
|
||||
|
@ -57,7 +60,7 @@
|
|||
--color-background: hsl(240, 5%, 8%);
|
||||
--color-contrast: #000;
|
||||
--color-accent: #74b0ff;
|
||||
--color-footer-background: #0d0d0d;
|
||||
--color-footer-background: hsl(240, 5%, 8%);
|
||||
--color-footer-text: #ccc;
|
||||
|
||||
--shadow-small: 0px 0px 16px -2px rgba(0, 0, 0, 0.52), 0px 0px 4px 0px rgba(0, 0, 0, 0.62);
|
||||
|
@ -71,6 +74,8 @@
|
|||
--color-tint-5: rgb(144, 144, 144);
|
||||
--color-tint-6: rgb(186, 186, 186);
|
||||
|
||||
--color-blockquote: rgb(34, 47, 55);
|
||||
|
||||
/* Code colors */
|
||||
--hl: #c8c5f1;
|
||||
--hl-0: #5c6370;
|
||||
|
@ -93,7 +98,7 @@
|
|||
html {
|
||||
background-color: #000;
|
||||
border-bottom: none;
|
||||
scroll-padding-top: var(--header-height);
|
||||
scroll-padding-top: calc(var(--header-height) + var(--header-padding));
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -137,7 +142,7 @@ body {
|
|||
z-index: 900;
|
||||
top: 0px;
|
||||
display: grid;
|
||||
padding: 16px;
|
||||
padding: 0px 16px;
|
||||
grid-template-columns: 250px 1fr auto;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
|
@ -145,24 +150,31 @@ body {
|
|||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.layout__header .lockup {
|
||||
position: relative;
|
||||
width: calc(71px * (30 / 18));
|
||||
height: calc(18px * (30 / 18));
|
||||
background: currentColor;
|
||||
color: var(--color-text);
|
||||
margin-bottom: 8px;
|
||||
.layout__header__left img {
|
||||
width: calc(136px);
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.layout__header__sections_and_socials {
|
||||
.layout__header__links {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.layout__header__sections {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layout__header__socials {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.layout_header__section {
|
||||
text-decoration: none;
|
||||
padding: 8px 12px;
|
||||
padding: 13px 12px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text);
|
||||
position: relative;
|
||||
|
@ -172,7 +184,7 @@ body {
|
|||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
inset: 7px 1px;
|
||||
inset: 7px 2px;
|
||||
background-color: var(--bg);
|
||||
border-radius: var(--border-radius-menu);
|
||||
}
|
||||
|
@ -241,11 +253,11 @@ body {
|
|||
background-color: currentColor;
|
||||
}
|
||||
|
||||
.article {
|
||||
.main-content {
|
||||
justify-self: center;
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 64px);
|
||||
padding: 0px 0px 96px 0px;
|
||||
padding: var(--header-padding) 0px 96px 0px;
|
||||
font-weight: 400;
|
||||
overflow-x: hidden;
|
||||
overflow-y: visible;
|
||||
|
@ -354,7 +366,7 @@ body {
|
|||
}
|
||||
|
||||
.article > h2 {
|
||||
margin-top: 16px;
|
||||
margin-top: 48px;
|
||||
}
|
||||
|
||||
.article > p + h2 {
|
||||
|
@ -468,9 +480,10 @@ body {
|
|||
|
||||
.article > blockquote {
|
||||
max-width: 100%;
|
||||
margin: 20px 0px;
|
||||
padding-left: 16px;
|
||||
border-left: 2px solid var(--color-tint-2);
|
||||
margin: 32px 0px;
|
||||
padding: 16px;
|
||||
border-radius: var(--border-radius-menu);
|
||||
background-color: var(--color-blockquote);
|
||||
}
|
||||
|
||||
.article pre {
|
||||
|
@ -517,8 +530,7 @@ body {
|
|||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.article ol h3,
|
||||
.article ol li::marker {
|
||||
.article ol h3 {
|
||||
font-size: 1.17em;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
@ -551,7 +563,6 @@ body {
|
|||
|
||||
.page-header > p {
|
||||
margin-top: 1rem;
|
||||
|
||||
}
|
||||
|
||||
.article table {
|
||||
|
@ -624,6 +635,7 @@ body {
|
|||
.article__embed--quickstart {
|
||||
aspect-ratio: 16 / 9;
|
||||
min-height: 405px;
|
||||
margin: 32px 0px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 520px) {
|
||||
|
@ -649,8 +661,8 @@ body {
|
|||
.breadcrumb {
|
||||
font-size: 14px;
|
||||
color: var(--color-text);
|
||||
font-weight: 600;
|
||||
height: 40px;
|
||||
font-weight: 500;
|
||||
padding-bottom: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
|
@ -675,7 +687,6 @@ body {
|
|||
font-size: 12px;
|
||||
gap: 24px;
|
||||
color: var(--color-footer-text);
|
||||
border-top: 1px solid rgba(144, 144, 144, 0.28);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
@ -781,7 +792,7 @@ body {
|
|||
align-self: start;
|
||||
top: var(--header-height);
|
||||
margin-left: -12px;
|
||||
padding: 24px 28px 120px 12px;
|
||||
padding: var(--header-padding) 28px 120px 12px;
|
||||
max-height: calc(100vh);
|
||||
width: 290px;
|
||||
z-index: 800;
|
||||
|
@ -815,7 +826,7 @@ body {
|
|||
align-self: start;
|
||||
top: var(--header-height);
|
||||
margin-left: -12px;
|
||||
padding: 0px 12px 120px 28px;
|
||||
padding: var(--header-padding) 12px 120px 28px;
|
||||
width: calc(100% + 24px);
|
||||
max-height: calc(100vh);
|
||||
z-index: 800;
|
||||
|
@ -934,18 +945,21 @@ body {
|
|||
transition-delay: 0s;
|
||||
}
|
||||
|
||||
.sidebar__section__title {
|
||||
.uppercase_title {
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.5px;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.sidebar__section__title {
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
letter-spacing: 0.5px;
|
||||
height: 40px;
|
||||
padding-bottom: 4px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: var(--color-text-secondary);
|
||||
text-transform: uppercase;
|
||||
--bg: transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
@ -958,7 +972,6 @@ body {
|
|||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--color-text-secondary);
|
||||
white-space: nowrap;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
|
@ -971,7 +984,6 @@ body {
|
|||
.sidebar__sections__list > *:nth-last-of-type(n + 2) > .sidebar__list {
|
||||
padding-bottom: 12px;
|
||||
margin-bottom: 12px;
|
||||
border-bottom: 1px solid var(--color-tint-2);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
|
@ -1113,8 +1125,7 @@ body {
|
|||
grid-gap: 40px;
|
||||
}
|
||||
|
||||
.layout__header .layout__header__sections_and_socials .layout_header__section,
|
||||
.layout__header .layout__header__sections_and_socials .NavigationMenuRoot {
|
||||
.layout__header .NavigationMenuRoot {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -1122,10 +1133,10 @@ body {
|
|||
position: relative;
|
||||
z-index: 1;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid var(--color-accent);
|
||||
border-bottom: 1px solid var(--color-accent);
|
||||
padding: 12px 0px;
|
||||
border-bottom: 1px solid var(--color-tint-2);
|
||||
margin-bottom: 12px;
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
.NavigationMenuTrigger {
|
||||
|
@ -1142,7 +1153,7 @@ body {
|
|||
}
|
||||
|
||||
.layout__header {
|
||||
grid-template-columns: auto auto;
|
||||
grid-template-columns: auto 1fr;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
|
@ -1227,7 +1238,7 @@ body {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.article {
|
||||
.main-content {
|
||||
padding: 24px 16px 16px 16px;
|
||||
}
|
||||
|
||||
|
@ -1288,6 +1299,14 @@ body {
|
|||
display: none;
|
||||
}
|
||||
|
||||
.layout__header__links {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.layout__header__sections {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.article__links__prev {
|
||||
border: none;
|
||||
grid-row: 2;
|
||||
|
@ -1327,6 +1346,7 @@ html[data-theme='light'] .hero__dark {
|
|||
}
|
||||
|
||||
.code-example .sandpack {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
|
@ -1358,12 +1378,12 @@ html[data-theme='light'] .hero__dark {
|
|||
|
||||
/* ------------------- Hero images ------------------ */
|
||||
|
||||
.hero__images {
|
||||
margin: 32px 0px;
|
||||
.hero__images__wrapper {
|
||||
padding-bottom: 24px;
|
||||
}
|
||||
|
||||
.hero_images > a {
|
||||
margin: 0px;
|
||||
.hero__images {
|
||||
margin: 32px 0px;
|
||||
}
|
||||
|
||||
.article__image {
|
||||
|
@ -1496,3 +1516,83 @@ html[data-theme='light'] .hero__dark {
|
|||
.scroll-light::-webkit-scrollbar-thumb:hover {
|
||||
background-color: rgba(144, 144, 144);
|
||||
}
|
||||
|
||||
/* ------------------ Landing page ------------------ */
|
||||
|
||||
.landing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.landing__inner {
|
||||
width: fit-content;
|
||||
max-width: 960px;
|
||||
height: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.landing__logo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.landing__logo img {
|
||||
width: 200px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
[data-theme='dark'] .logo-light {
|
||||
display: none;
|
||||
}
|
||||
|
||||
[data-theme='light'] .logo-dark {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.landing__blurb {
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
margin: 12px 0 16px 0;
|
||||
}
|
||||
|
||||
.landing__links {
|
||||
list-style-type: none;
|
||||
display: flex;
|
||||
gap: 0px;
|
||||
}
|
||||
|
||||
.landing__links a {
|
||||
text-decoration: none;
|
||||
color: var(--color-text);
|
||||
padding: 16px 16px;
|
||||
position: relative;
|
||||
font-size: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.landing__links a::after {
|
||||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
left: 1px;
|
||||
right: 1px;
|
||||
background-color: var(--color-tint-1);
|
||||
border-radius: var(--border-radius-menu);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.landing__links a:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
.article__api-heading {
|
||||
text-transform: uppercase;
|
||||
color: var(--color-tint-5);
|
||||
letter-spacing: 0.07em;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.article__parameters-table {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ export type InputCategory = {
|
|||
title: string
|
||||
description: string
|
||||
groups: InputGroup[]
|
||||
hero: string | null
|
||||
}
|
||||
|
||||
export type InputSection = {
|
||||
|
@ -10,6 +11,7 @@ export type InputSection = {
|
|||
title: string
|
||||
description: string
|
||||
categories: InputCategory[]
|
||||
hero: string | null
|
||||
sidebar_behavior: 'show-links' | 'show-title' | 'hidden' | 'reference'
|
||||
}
|
||||
|
||||
|
@ -56,6 +58,8 @@ export interface Section extends ContentPage {
|
|||
categories: Category[]
|
||||
/** How the section should appear in the sidebar. */
|
||||
sidebar_behavior: 'show-links' | 'show-title' | 'hidden' | 'reference'
|
||||
/** The section's hero image (optional). */
|
||||
hero: string | null
|
||||
}
|
||||
|
||||
export interface Category extends ContentPage {
|
||||
|
@ -66,6 +70,8 @@ export interface Category extends ContentPage {
|
|||
index: number
|
||||
/** The category's groups */
|
||||
groups: Group[]
|
||||
/** The category's hero image (optional). */
|
||||
hero: string | null
|
||||
}
|
||||
|
||||
export interface Group extends ContentPage {
|
||||
|
@ -179,7 +185,6 @@ export type SidebarContentLink =
|
|||
| SidebarContentArticleLink
|
||||
|
||||
export type SidebarContentList = {
|
||||
headings?: ArticleHeadings
|
||||
sectionId: string | null
|
||||
categoryId: string | null
|
||||
articleId: string | null
|
||||
|
|
|
@ -1400,7 +1400,136 @@ export const TldrawSelectionBackground: ({ bounds, rotation }: TLSelectionBackgr
|
|||
export const TldrawSelectionForeground: MemoExoticComponent<({ bounds, rotation, }: TLSelectionForegroundProps) => JSX_2.Element | null>;
|
||||
|
||||
// @public (undocumented)
|
||||
export const TldrawUi: React_2.NamedExoticComponent<TldrawUiProps>;
|
||||
export const TldrawUi: React_2.NamedExoticComponent<{
|
||||
children?: any;
|
||||
hideUi?: boolean | undefined;
|
||||
components?: Partial<{
|
||||
ContextMenu: null | React_2.ComponentType<TLUiContextMenuProps>;
|
||||
ActionsMenu: null | React_2.ComponentType<TLUiActionsMenuProps>;
|
||||
HelpMenu: null | React_2.ComponentType<TLUiHelpMenuProps>;
|
||||
ZoomMenu: null | React_2.ComponentType<TLUiZoomMenuProps>;
|
||||
MainMenu: null | React_2.ComponentType<TLUiMainMenuProps>;
|
||||
Minimap: null | React_2.ComponentType;
|
||||
StylePanel: null | React_2.ComponentType<TLUiStylePanelProps>;
|
||||
PageMenu: null | React_2.ComponentType;
|
||||
NavigationPanel: null | React_2.ComponentType;
|
||||
Toolbar: null | React_2.ComponentType;
|
||||
KeyboardShortcutsDialog: null | React_2.ComponentType<TLUiKeyboardShortcutsDialogProps>;
|
||||
QuickActions: null | React_2.ComponentType<TLUiQuickActionsProps>;
|
||||
HelperButtons: null | React_2.ComponentType<TLUiHelperButtonsProps>;
|
||||
DebugMenu: null | React_2.ComponentType;
|
||||
MenuPanel: null | React_2.ComponentType;
|
||||
TopPanel: null | React_2.ComponentType;
|
||||
SharePanel: null | React_2.ComponentType;
|
||||
}> | undefined;
|
||||
renderDebugMenuItems?: (() => React_2.ReactNode) | undefined;
|
||||
assetUrls?: (RecursivePartial<TLUiAssetUrls> & RecursivePartial<TLUiAssetUrls>) | undefined;
|
||||
overrides?: Partial<{
|
||||
actions: TLUiOverride<TLUiActionsContextType, {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
toolbar: TLUiOverride<TLUiToolbarSchemaContextType, {
|
||||
tools: TLUiToolsContextType;
|
||||
} & {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
tools: TLUiOverride<TLUiToolsContextType, {
|
||||
insertMedia: () => void;
|
||||
} & {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
translations: Record<string, Record<string, string>> | undefined;
|
||||
}> | Partial<{
|
||||
actions: TLUiOverride<TLUiActionsContextType, {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
toolbar: TLUiOverride<TLUiToolbarSchemaContextType, {
|
||||
tools: TLUiToolsContextType;
|
||||
} & {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
tools: TLUiOverride<TLUiToolsContextType, {
|
||||
insertMedia: () => void;
|
||||
} & {
|
||||
addToast: (toast: Omit<TLUiToast, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
removeToast: (id: string) => string;
|
||||
clearToasts: () => void;
|
||||
addDialog: (dialog: Omit<TLUiDialog, "id"> & {
|
||||
id?: string | undefined;
|
||||
}) => string;
|
||||
clearDialogs: () => void;
|
||||
removeDialog: (id: string) => string;
|
||||
updateDialog: (id: string, newDialogData: Partial<TLUiDialog>) => string;
|
||||
msg: (id?: string | undefined) => string;
|
||||
isMobile: boolean;
|
||||
}>;
|
||||
translations: Record<string, Record<string, string>> | undefined;
|
||||
}>[] | undefined;
|
||||
onUiEvent?: TLUiEventHandler | undefined;
|
||||
forceMobile?: boolean | undefined;
|
||||
}>;
|
||||
|
||||
// @public
|
||||
export interface TldrawUiBaseProps {
|
||||
|
@ -1518,7 +1647,7 @@ export function TldrawUiPopoverContent({ side, children, align, sideOffset, alig
|
|||
export function TldrawUiPopoverTrigger({ children }: TLUiPopoverTriggerProps): JSX_2.Element;
|
||||
|
||||
// @public
|
||||
export type TldrawUiProps = TldrawUiBaseProps & TldrawUiContextProviderProps;
|
||||
export type TldrawUiProps = Expand<TldrawUiBaseProps & TldrawUiContextProviderProps>;
|
||||
|
||||
// @internal (undocumented)
|
||||
export const TldrawUiSlider: NamedExoticComponent<TLUiSliderProps>;
|
||||
|
|
|
@ -16204,16 +16204,808 @@
|
|||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<"
|
||||
"text": "<{\n children?: any;\n hideUi?: boolean | undefined;\n components?: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TldrawUiProps",
|
||||
"canonicalReference": "tldraw!TldrawUiProps:type"
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">"
|
||||
"text": "<{\n ContextMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiContextMenuProps",
|
||||
"canonicalReference": "tldraw!TLUiContextMenuProps:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n ActionsMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiActionsMenuProps",
|
||||
"canonicalReference": "tldraw!TLUiActionsMenuProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n HelpMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiHelpMenuProps",
|
||||
"canonicalReference": "tldraw!TLUiHelpMenuProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n ZoomMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiZoomMenuProps",
|
||||
"canonicalReference": "tldraw!TLUiZoomMenuProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n MainMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiMainMenuProps",
|
||||
"canonicalReference": "tldraw!TLUiMainMenuProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n Minimap: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n StylePanel: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiStylePanelProps",
|
||||
"canonicalReference": "tldraw!TLUiStylePanelProps:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n PageMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n NavigationPanel: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n Toolbar: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n KeyboardShortcutsDialog: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiKeyboardShortcutsDialogProps",
|
||||
"canonicalReference": "tldraw!TLUiKeyboardShortcutsDialogProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n QuickActions: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiQuickActionsProps",
|
||||
"canonicalReference": "tldraw!TLUiQuickActionsProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n HelperButtons: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"../..\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiHelperButtonsProps",
|
||||
"canonicalReference": "tldraw!TLUiHelperButtonsProps:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">;\n DebugMenu: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n MenuPanel: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n TopPanel: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n SharePanel: null | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ComponentType",
|
||||
"canonicalReference": "@types/react!React.ComponentType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n }> | undefined;\n renderDebugMenuItems?: (() => "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "React.ReactNode",
|
||||
"canonicalReference": "@types/react!React.ReactNode:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ") | undefined;\n assetUrls?: (import(\"@tldraw/editor\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "RecursivePartial",
|
||||
"canonicalReference": "@tldraw/utils!RecursivePartial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./assetUrls\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiAssetUrls",
|
||||
"canonicalReference": "tldraw!~TLUiAssetUrls:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "> & import(\"@tldraw/editor\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "RecursivePartial",
|
||||
"canonicalReference": "@tldraw/utils!RecursivePartial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./assetUrls\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiAssetUrls",
|
||||
"canonicalReference": "tldraw!~TLUiAssetUrls:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) | undefined;\n overrides?: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<{\n actions: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/actions\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiActionsContextType",
|
||||
"canonicalReference": "tldraw!TLUiActionsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n toolbar: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./hooks/useToolbarSchema\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolbarSchemaContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolbarSchemaContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n tools: import(\"./hooks/useTools\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolsContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n } & {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n tools: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./hooks/useTools\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolsContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n insertMedia: () => void;\n } & {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n translations: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Record",
|
||||
"canonicalReference": "!Record:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<string, "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Record",
|
||||
"canonicalReference": "!Record:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<string, string>> | undefined;\n }> | "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<{\n actions: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/actions\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiActionsContextType",
|
||||
"canonicalReference": "tldraw!TLUiActionsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n toolbar: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./hooks/useToolbarSchema\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolbarSchemaContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolbarSchemaContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n tools: import(\"./hooks/useTools\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolsContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";\n } & {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n tools: import(\"./overrides\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiOverride",
|
||||
"canonicalReference": "tldraw!~TLUiOverride:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./hooks/useTools\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToolsContextType",
|
||||
"canonicalReference": "tldraw!TLUiToolsContextType:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", {\n insertMedia: () => void;\n } & {\n addToast: (toast: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/toasts\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiToast",
|
||||
"canonicalReference": "tldraw!TLUiToast:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n removeToast: (id: string) => string;\n clearToasts: () => void;\n addDialog: (dialog: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Omit",
|
||||
"canonicalReference": "!Omit:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ", \"id\"> & {\n id?: string | undefined;\n }) => string;\n clearDialogs: () => void;\n removeDialog: (id: string) => string;\n updateDialog: (id: string, newDialogData: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Partial",
|
||||
"canonicalReference": "!Partial:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<import(\"./context/dialogs\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiDialog",
|
||||
"canonicalReference": "tldraw!TLUiDialog:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">) => string;\n msg: (id?: string | undefined) => string;\n isMobile: boolean;\n }>;\n translations: "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Record",
|
||||
"canonicalReference": "!Record:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<string, "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Record",
|
||||
"canonicalReference": "!Record:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<string, string>> | undefined;\n }>[] | undefined;\n onUiEvent?: import(\"./context/events\")."
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TLUiEventHandler",
|
||||
"canonicalReference": "tldraw!TLUiEventHandler:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": " | undefined;\n forceMobile?: boolean | undefined;\n}>"
|
||||
}
|
||||
],
|
||||
"fileUrlPath": "packages/tldraw/src/lib/ui/TldrawUi.tsx",
|
||||
|
@ -16222,7 +17014,7 @@
|
|||
"name": "TldrawUi",
|
||||
"variableTypeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 5
|
||||
"endIndex": 181
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -18325,12 +19117,21 @@
|
|||
{
|
||||
"kind": "TypeAlias",
|
||||
"canonicalReference": "tldraw!TldrawUiProps:type",
|
||||
"docComment": "/**\n * Props for the {@link tldraw#Tldraw} and {@link TldrawUi} components.\n *\n * @public\n */\n",
|
||||
"docComment": "/**\n * Props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawUi} components.\n *\n * @public\n */\n",
|
||||
"excerptTokens": [
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "export type TldrawUiProps = "
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "Expand",
|
||||
"canonicalReference": "@tldraw/utils!Expand:type"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": "<"
|
||||
},
|
||||
{
|
||||
"kind": "Reference",
|
||||
"text": "TldrawUiBaseProps",
|
||||
|
@ -18345,6 +19146,10 @@
|
|||
"text": "TldrawUiContextProviderProps",
|
||||
"canonicalReference": "tldraw!TldrawUiContextProviderProps:interface"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ">"
|
||||
},
|
||||
{
|
||||
"kind": "Content",
|
||||
"text": ";"
|
||||
|
@ -18355,7 +19160,7 @@
|
|||
"name": "TldrawUiProps",
|
||||
"typeTokenRange": {
|
||||
"startIndex": 1,
|
||||
"endIndex": 4
|
||||
"endIndex": 7
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { ToastProvider } from '@radix-ui/react-toast'
|
||||
import { useEditor, useValue } from '@tldraw/editor'
|
||||
import { Expand, useEditor, useValue } from '@tldraw/editor'
|
||||
import classNames from 'classnames'
|
||||
import React, { ReactNode } from 'react'
|
||||
import { TLUiAssetUrlOverrides } from './assetUrls'
|
||||
|
@ -23,13 +23,6 @@ import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts'
|
|||
import { useReadonly } from './hooks/useReadonly'
|
||||
import { useTranslation } from './hooks/useTranslation/useTranslation'
|
||||
|
||||
/**
|
||||
* Props for the {@link tldraw#Tldraw} and {@link TldrawUi} components.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TldrawUiProps = TldrawUiBaseProps & TldrawUiContextProviderProps
|
||||
|
||||
/**
|
||||
* Base props for the {@link tldraw#Tldraw} and {@link TldrawUi} components.
|
||||
*
|
||||
|
@ -60,6 +53,13 @@ export interface TldrawUiBaseProps {
|
|||
assetUrls?: TLUiAssetUrlOverrides
|
||||
}
|
||||
|
||||
/**
|
||||
* Props for the {@link @tldraw/tldraw#Tldraw} and {@link TldrawUi} components.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type TldrawUiProps = Expand<TldrawUiBaseProps & TldrawUiContextProviderProps>
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue