docs: rework docs site to have different sections (#2686)
This PR starts putting in place the high-level changes we want to make to the docs site. - It makes separate sections for Reference and Examples and Community. - Gets rid of the secondary sidebar and integrates it into the main sidebar. - Groups the reference articles by type. - Pulls in the examples alongside code and a live playground so people don't have to visit examples.tldraw.com separately. <img width="1458" alt="Screenshot 2024-01-30 at 09 43 46" src="https://github.com/tldraw/tldraw/assets/469604/4f5aa339-3a69-4d9b-9b9f-dfdddea623e8"> Again, this is the top-level changes and there's more to be done for the next PR(s): - create quick start page - clean up installation page - add accordion to Examples page prbly - put fun stuff in header (from footer) - landing page - something for landing page of API - search cmd-k and border - cleanup _sidebarReferenceContentLinks - external links _blank - address potential skew issue with code examples - have a link to other examples (next.js, etc.) ### Change Type - [x] `documentation` — Changes to the documentation only[^2] ### Test Plan 1. Make sure examples work! ### Release Notes - Rework our docs site to pull together the examples app and reference section more cohesively. --------- Co-authored-by: Taha <98838967+Taha-Hassan-Git@users.noreply.github.com> Co-authored-by: Steve Ruiz <steveruizok@gmail.com> Co-authored-by: Mitja Bezenšek <mitja.bezensek@gmail.com> Co-authored-by: alex <alex@dytry.ch> Co-authored-by: Lu Wilson <l2wilson94@gmail.com> Co-authored-by: Dan Groshev <git@dgroshev.com>
This commit is contained in:
parent
a43b172b64
commit
3ae48af67c
68 changed files with 94415 additions and 92577 deletions
2
apps/docs/.gitignore
vendored
2
apps/docs/.gitignore
vendored
|
@ -1,4 +1,4 @@
|
|||
content/gen
|
||||
content/reference
|
||||
api-content.json
|
||||
content.db
|
||||
.env
|
||||
|
|
|
@ -2,5 +2,4 @@
|
|||
.lazy/*
|
||||
content.db
|
||||
node_modules
|
||||
utils/vector-db/index.json
|
||||
**/*.api.json
|
||||
utils/vector-db/index.json
|
|
@ -25,8 +25,7 @@ The files are also provided in this repo.
|
|||
|
||||
You can build the markdown and API content using the following scripts:
|
||||
|
||||
- `yarn refresh-all` to reset the database, generate the markdown from the API docs, and populate the database with articles from both the regular content and the generated API content
|
||||
- `yarn refresh-api-content` to refresh just the API content
|
||||
- `yarn refresh-everything` to reset the database, generate the markdown from the API docs, and populate the database with articles from both the regular content and the generated API content
|
||||
- `yarn refresh-content` to generate just the regular content
|
||||
|
||||
# Content
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
|
@ -80,12 +80,12 @@ export async function GET(req: NextRequest) {
|
|||
const { category, section, article, heading, score } = result
|
||||
const isUncategorized = category.id === section.id + '_ucg'
|
||||
if (BANNED_HEADINGS.some((h) => heading.slug.endsWith(h))) continue
|
||||
results[section.id === 'gen' ? 'apiDocs' : 'articles'].push({
|
||||
results[section.id === 'reference' ? 'apiDocs' : 'articles'].push({
|
||||
id: result.id,
|
||||
type: 'heading',
|
||||
subtitle: isUncategorized ? section.title : `${section.title} / ${category.title}`,
|
||||
title:
|
||||
section.id === 'gen'
|
||||
section.id === 'reference'
|
||||
? article.title + '.' + heading.title
|
||||
: article.title + ': ' + heading.title,
|
||||
url: isUncategorized
|
||||
|
@ -115,7 +115,7 @@ export async function GET(req: NextRequest) {
|
|||
article.sectionId
|
||||
)
|
||||
const isUncategorized = category.id === section.id + '_ucg'
|
||||
results[section.id === 'gen' ? 'apiDocs' : 'articles'].push({
|
||||
results[section.id === 'reference' ? 'apiDocs' : 'articles'].push({
|
||||
id: article.id,
|
||||
type: 'article',
|
||||
subtitle: isUncategorized ? section.title : `${section.title} / ${category.title}`,
|
||||
|
|
|
@ -61,7 +61,7 @@ export async function GET(req: NextRequest) {
|
|||
|
||||
await searchForArticle.all(query).then(async (queryResults) => {
|
||||
for (const article of queryResults) {
|
||||
const isApiDoc = article.sectionId === 'gen'
|
||||
const isApiDoc = article.sectionId === 'reference'
|
||||
const section = await db.getSection(article.sectionId)
|
||||
const category = await db.getCategory(article.categoryId)
|
||||
const isUncategorized = category.id === section.id + '_ucg'
|
||||
|
@ -95,7 +95,7 @@ export async function GET(req: NextRequest) {
|
|||
if (BANNED_HEADINGS.some((h) => heading.slug.endsWith(h))) continue
|
||||
const article = await db.getArticle(heading.articleId)
|
||||
|
||||
const isApiDoc = article.sectionId === 'gen'
|
||||
const isApiDoc = article.sectionId === 'reference'
|
||||
const section = await db.getSection(article.sectionId)
|
||||
const category = await db.getCategory(article.categoryId)
|
||||
const isUncategorized = category.id === section.id + '_ucg'
|
||||
|
@ -105,7 +105,7 @@ export async function GET(req: NextRequest) {
|
|||
type: 'heading',
|
||||
subtitle: isUncategorized ? section.title : `${section.title} / ${category.title}`,
|
||||
title:
|
||||
section.id === 'gen'
|
||||
section.id === 'reference'
|
||||
? article.title + '.' + heading.title
|
||||
: article.title + ': ' + heading.title,
|
||||
url: isUncategorized
|
||||
|
|
|
@ -8,7 +8,7 @@ export default async function ClaPage() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={null} />
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<div className="page-header">
|
||||
|
|
|
@ -8,7 +8,7 @@ export default async function LicensePage() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={null} />
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<div className="page-header">
|
||||
|
|
|
@ -8,7 +8,7 @@ export default async function NotFound() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={null} />
|
||||
<Header />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<div className="page-header">
|
||||
|
|
|
@ -4,7 +4,7 @@ import { notFound } from 'next/navigation'
|
|||
|
||||
export default async function HomePage() {
|
||||
const db = await getDb()
|
||||
const article = await db.db.get(`SELECT * FROM articles WHERE articles.path = ?`, `/introduction`)
|
||||
const article = await db.db.get(`SELECT * FROM articles WHERE articles.path = ?`, `/quick-start`)
|
||||
if (article) return <ArticleDocsPage article={article} />
|
||||
throw notFound()
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ export default async function SearchResultsPage({
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={null} searchQuery={query} searchType={type} />
|
||||
<Sidebar {...sidebar} />
|
||||
<Header searchQuery={query} searchType={type} />
|
||||
<Sidebar {...sidebar} searchQuery={query} searchType={type} />
|
||||
<main className="article list">
|
||||
<div className="page-header">
|
||||
<h2>{`Found ${
|
||||
|
|
|
@ -3,8 +3,8 @@ import { getDb } from '@/utils/ContentDatabase'
|
|||
import { ArticleDetails } from './ArticleDetails'
|
||||
import { ArticleNavLinks } from './ArticleNavLinks'
|
||||
import { Breadcrumb } from './Breadcrumb'
|
||||
import ExampleCodeBlock from './ExampleCodeBlock'
|
||||
import { Header } from './Header'
|
||||
import { HeadingLinks } from './HeadingLinks'
|
||||
import { Mdx } from './Mdx'
|
||||
import { Sidebar } from './Sidebar'
|
||||
import { Image } from './mdx-components/generic'
|
||||
|
@ -21,23 +21,34 @@ export async function ArticleDocsPage({ article }: { article: Article }) {
|
|||
articleId: article.id,
|
||||
})
|
||||
|
||||
const isGenerated = article.sectionId === 'gen'
|
||||
const isGenerated = article.sectionId === 'reference'
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={article.id} />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className={`article${isGenerated ? ' article__api-docs' : ''}`}>
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar headings={headings} {...sidebar} />
|
||||
<main
|
||||
className={`article${isGenerated ? ' article__api-docs' : ''}${article.componentCode ? ' article__example' : ''}`}
|
||||
>
|
||||
<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} />}
|
||||
{article.componentCode && (
|
||||
<ExampleCodeBlock
|
||||
articleId={article.id}
|
||||
files={{
|
||||
'App.tsx': article.componentCode,
|
||||
...(article.componentCodeFiles ? JSON.parse(article.componentCodeFiles) : null),
|
||||
}}
|
||||
activeFile={'App.tsx'}
|
||||
/>
|
||||
)}
|
||||
{isGenerated ? null : <ArticleDetails article={article} />}
|
||||
{links && <ArticleNavLinks links={links} />}
|
||||
</main>
|
||||
{headings.length > 0 ? <HeadingLinks article={article} headingLinks={headings} /> : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ export async function CategoryDocsPage({ category }: { category: Category }) {
|
|||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={category.id} />
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className={'article'}>
|
||||
<div className="page-header">
|
||||
|
@ -23,9 +23,11 @@ export async function CategoryDocsPage({ category }: { category: Category }) {
|
|||
{articles.length > 0 && (
|
||||
<ul>
|
||||
{articles.map((article) => (
|
||||
<Link key={article.id} href={`/${section.id}/${category.id}/${article.id}`}>
|
||||
<li>{article.title}</li>
|
||||
</Link>
|
||||
<li>
|
||||
<Link key={article.id} href={`/${section.id}/${category.id}/${article.id}`}>
|
||||
{article.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
|
|
52
apps/docs/components/ExampleCodeBlock.tsx
Normal file
52
apps/docs/components/ExampleCodeBlock.tsx
Normal file
|
@ -0,0 +1,52 @@
|
|||
'use client'
|
||||
|
||||
import { SandpackCodeEditor, SandpackFiles, SandpackProvider } from '@codesandbox/sandpack-react'
|
||||
import { useTheme } from 'next-themes'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function ExampleCodeBlock({
|
||||
articleId,
|
||||
files = {},
|
||||
activeFile,
|
||||
}: {
|
||||
articleId: string
|
||||
activeFile: string
|
||||
files: SandpackFiles
|
||||
}) {
|
||||
const [isClientSide, setIsClientSide] = useState(false)
|
||||
const { theme } = useTheme()
|
||||
useEffect(() => setIsClientSide(true), [])
|
||||
const SERVER =
|
||||
process.env.NODE_ENV === 'development' ? 'http://localhost:5420' : 'https://examples.tldraw.com'
|
||||
|
||||
// This is to avoid hydration mismatch between the server and the client because of the useTheme.
|
||||
if (!isClientSide) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<iframe
|
||||
src={`${SERVER}/${articleId}/full`}
|
||||
style={{ border: 0, height: '50vh', width: '100%' }}
|
||||
/>
|
||||
<SandpackProvider
|
||||
key={`sandpack-${theme}-${activeFile}`}
|
||||
template="react-ts"
|
||||
options={{ activeFile }}
|
||||
customSetup={{
|
||||
dependencies: {
|
||||
'@tldraw/assets': 'latest',
|
||||
'@tldraw/tldraw': 'latest',
|
||||
},
|
||||
}}
|
||||
files={{
|
||||
...files,
|
||||
}}
|
||||
theme={theme === 'dark' ? 'dark' : 'light'}
|
||||
>
|
||||
<SandpackCodeEditor readOnly />
|
||||
</SandpackProvider>
|
||||
</>
|
||||
)
|
||||
}
|
|
@ -15,7 +15,7 @@ export function Footer() {
|
|||
WebkitMask: `url(/tldraw-icon.svg) center 100% / 100% no-repeat`,
|
||||
}}
|
||||
/>
|
||||
<p>tldraw © 2024</p>
|
||||
<p>tldraw © {new Date().getFullYear()}</p>
|
||||
</a>
|
||||
<div className="footer__socials">
|
||||
<a
|
||||
|
|
|
@ -1,20 +1,24 @@
|
|||
'use client'
|
||||
|
||||
import * as NavigationMenu from '@radix-ui/react-navigation-menu'
|
||||
import Link from 'next/link'
|
||||
import { Icon } from './Icon'
|
||||
import { Chevron } from './Icons'
|
||||
import { Search } from './Search'
|
||||
import { ThemeSwitcher } from './ThemeSwitcher'
|
||||
|
||||
export function Header({
|
||||
activeId,
|
||||
searchQuery,
|
||||
searchType,
|
||||
sectionId,
|
||||
}: {
|
||||
activeId: string | null
|
||||
searchQuery?: string
|
||||
searchType?: string
|
||||
sectionId?: string
|
||||
}) {
|
||||
return (
|
||||
<div className="layout__header">
|
||||
<Link href="/">
|
||||
<Link href="/quick-start">
|
||||
<div
|
||||
className="lockup"
|
||||
style={{
|
||||
|
@ -23,14 +27,16 @@ export function Header({
|
|||
}}
|
||||
/>
|
||||
</Link>
|
||||
<Search activeId={activeId} prevQuery={searchQuery} prevType={searchType} />
|
||||
<div className="layout__header__socials">
|
||||
<Search prevQuery={searchQuery} prevType={searchType} />
|
||||
<div className="layout__header__sections_and_socials">
|
||||
<SectionLinks sectionId={sectionId} />
|
||||
<ThemeSwitcher />
|
||||
<a
|
||||
href="https://twitter.com/tldraw"
|
||||
href="https://discord.com/invite/SBBEVCA4PG"
|
||||
className="sidebar__button icon-button"
|
||||
title="twitter"
|
||||
title="discord"
|
||||
>
|
||||
<Icon icon="twitter" />
|
||||
<Icon icon="discord" />
|
||||
</a>
|
||||
<a
|
||||
href="https://github.com/tldraw/tldraw"
|
||||
|
@ -39,15 +45,84 @@ export function Header({
|
|||
>
|
||||
<Icon icon="github" />
|
||||
</a>
|
||||
<a
|
||||
href="https://discord.com/invite/SBBEVCA4PG"
|
||||
className="sidebar__button icon-button"
|
||||
title="discord"
|
||||
>
|
||||
<Icon icon="discord" />
|
||||
</a>
|
||||
<ThemeSwitcher />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function SectionLinks({ sectionId }: { sectionId?: string | null }) {
|
||||
return (
|
||||
<>
|
||||
<a
|
||||
href="/quick-start"
|
||||
title="Learn"
|
||||
data-active={!['reference', 'examples'].includes(sectionId || '')}
|
||||
className="layout_header__section"
|
||||
>
|
||||
Learn
|
||||
</a>
|
||||
<a
|
||||
href="/reference/editor/Editor"
|
||||
title="Reference"
|
||||
data-active={sectionId === 'reference'}
|
||||
className="layout_header__section"
|
||||
>
|
||||
Reference
|
||||
</a>
|
||||
<a
|
||||
href="/examples/basic/develop"
|
||||
title="Examples"
|
||||
data-active={sectionId === 'examples'}
|
||||
className="layout_header__section"
|
||||
>
|
||||
Examples
|
||||
</a>
|
||||
|
||||
<NavigationMenu.Root className="NavigationMenuRoot">
|
||||
<NavigationMenu.List className="NavigationMenuList">
|
||||
<NavigationMenu.Item>
|
||||
<NavigationMenu.Trigger
|
||||
className="NavigationMenuTrigger"
|
||||
onPointerMove={(event) => event.preventDefault()}
|
||||
onPointerLeave={(event) => event.preventDefault()}
|
||||
>
|
||||
<span>
|
||||
Community <Chevron className="CaretDown" aria-hidden />
|
||||
</span>
|
||||
</NavigationMenu.Trigger>
|
||||
<NavigationMenu.Content
|
||||
className="NavigationMenuContent"
|
||||
onPointerMove={(event) => event.preventDefault()}
|
||||
onPointerLeave={(event) => event.preventDefault()}
|
||||
>
|
||||
<ul>
|
||||
<li>
|
||||
<NavigationMenu.Link asChild>
|
||||
<a href="/community/contributing">Contributing</a>
|
||||
</NavigationMenu.Link>
|
||||
</li>
|
||||
<li>
|
||||
<NavigationMenu.Link asChild>
|
||||
<a href="/community/translations">Translations</a>
|
||||
</NavigationMenu.Link>
|
||||
</li>
|
||||
<li>
|
||||
<NavigationMenu.Link asChild>
|
||||
<a href="/community/license">License</a>
|
||||
</NavigationMenu.Link>
|
||||
</li>
|
||||
<li>
|
||||
<NavigationMenu.Link asChild>
|
||||
<a href="https://discord.com/invite/SBBEVCA4PG" target="_blank">
|
||||
Discord
|
||||
</a>
|
||||
</NavigationMenu.Link>
|
||||
</li>
|
||||
</ul>
|
||||
</NavigationMenu.Content>
|
||||
</NavigationMenu.Item>
|
||||
</NavigationMenu.List>
|
||||
</NavigationMenu.Root>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/* eslint-disable no-useless-escape */
|
||||
import { Article, ArticleHeadings } from '@/types/content-types'
|
||||
import Link from 'next/link'
|
||||
|
||||
export function HeadingLinks({
|
||||
article,
|
||||
headingLinks,
|
||||
}: {
|
||||
article: Article
|
||||
headingLinks: ArticleHeadings
|
||||
}) {
|
||||
return (
|
||||
<nav className="layout__headings">
|
||||
<ul className="sidebar__list sidebar__sections__list" key={article.id}>
|
||||
<li className="sidebar__section">
|
||||
<div className="sidebar__section__title" data-active={false}>
|
||||
On this page
|
||||
</div>
|
||||
<ul className="sidebar__list">
|
||||
{headingLinks
|
||||
.filter((heading) => heading.level < 4)
|
||||
.map((heading) => (
|
||||
<li className="sidebar__article" key={heading.slug}>
|
||||
<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>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
22
apps/docs/components/Icons.tsx
Normal file
22
apps/docs/components/Icons.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import classNames from 'classnames'
|
||||
|
||||
export function Chevron({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={classNames('accordion__trigger__chevron', className)}
|
||||
>
|
||||
<path
|
||||
d="M4 6L8 10L12 6"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
|
@ -9,7 +9,6 @@ export function Search({
|
|||
prevType = 'n',
|
||||
prevQuery = '',
|
||||
}: {
|
||||
activeId: string | null
|
||||
prevType?: string
|
||||
prevQuery?: string
|
||||
}) {
|
||||
|
|
|
@ -1,65 +1,21 @@
|
|||
import { Article, Category, Section } from '@/types/content-types'
|
||||
import { Section } from '@/types/content-types'
|
||||
import { getDb } from '@/utils/ContentDatabase'
|
||||
import Link from 'next/link'
|
||||
import { Header } from './Header'
|
||||
import { Sidebar } from './Sidebar'
|
||||
|
||||
export async function SectionDocsPage({ section }: { section: Section }) {
|
||||
const db = await getDb()
|
||||
|
||||
const sidebar = await db.getSidebarContentList({ sectionId: section.id })
|
||||
|
||||
const categories = [] as Category[]
|
||||
const articles: Article[] = []
|
||||
|
||||
const sectionCategories = await db.getCategoriesForSection(section.id)
|
||||
|
||||
for (const category of sectionCategories) {
|
||||
if (category.id === section.id + '_ucg') {
|
||||
const categoryArticles = await db.getCategoryArticles(section.id, category.id)
|
||||
for (const article of categoryArticles) {
|
||||
articles.push(article)
|
||||
}
|
||||
} else {
|
||||
// If the count of articles for this category is greater than zero...
|
||||
const articleCount = await db.getCategoryArticlesCount(section.id, category.id)
|
||||
|
||||
if (articleCount > 0) {
|
||||
categories.push(category)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header activeId={section.id} />
|
||||
<Header sectionId={section.id} />
|
||||
<Sidebar {...sidebar} />
|
||||
<main className="article">
|
||||
<div className="page-header">
|
||||
<h1>{section.title}</h1>
|
||||
</div>
|
||||
{articles.length > 0 && (
|
||||
<ul>
|
||||
{articles.map((articleLink) => {
|
||||
return (
|
||||
<Link key={articleLink.id} href={articleLink.path!}>
|
||||
<li>{articleLink.title}</li>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
)}
|
||||
{categories.length > 0 && (
|
||||
<ul>
|
||||
{categories.map((category) =>
|
||||
category.id === 'ucg' ? null : (
|
||||
<Link key={category.id} href={`/${section.id}/${category.id}`}>
|
||||
{category.id === 'ucg' ? null : <li>{category.title}</li>}
|
||||
</Link>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
)}
|
||||
Choose your adventure on the left.
|
||||
</main>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -1,65 +1,97 @@
|
|||
'use client'
|
||||
|
||||
import {
|
||||
ArticleHeadings,
|
||||
SidebarContentArticleLink,
|
||||
SidebarContentCategoryLink,
|
||||
SidebarContentLink,
|
||||
SidebarContentList,
|
||||
SidebarContentSectionLink,
|
||||
} from '@/types/content-types'
|
||||
import * as Accordion from '@radix-ui/react-accordion'
|
||||
import Link from 'next/link'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { createContext, useContext, useEffect } from 'react'
|
||||
import { SectionLinks } from './Header'
|
||||
import { Chevron } from './Icons'
|
||||
import { Search } from './Search'
|
||||
import { SidebarCloseButton } from './SidebarCloseButton'
|
||||
import { ToggleMenuButton } from './ToggleMenuButton'
|
||||
|
||||
type SidebarProps = SidebarContentList
|
||||
|
||||
const activeLinkContext = createContext<string | null>(null)
|
||||
const linkContext = createContext<{
|
||||
activeId: string | null
|
||||
articleId: string | null
|
||||
categoryId: string | null
|
||||
sectionId: string | null
|
||||
} | null>(null)
|
||||
|
||||
export function Sidebar({ links, sectionId, categoryId, articleId }: SidebarProps) {
|
||||
export function Sidebar({
|
||||
headings,
|
||||
links,
|
||||
sectionId,
|
||||
categoryId,
|
||||
articleId,
|
||||
searchQuery,
|
||||
searchType,
|
||||
}: SidebarProps) {
|
||||
const activeId = articleId ?? categoryId ?? sectionId
|
||||
|
||||
const pathName = usePathname()
|
||||
|
||||
useEffect(() => {
|
||||
document.body.classList.remove('sidebar-open')
|
||||
|
||||
document.querySelector('.sidebar [data-active=true]')?.scrollIntoView({ block: 'center' })
|
||||
|
||||
// XXX(mime): scrolling the sidebar into position also scrolls the page to the wrong
|
||||
// spot. this compensates for that but, ugh.
|
||||
document.documentElement.scrollTop = 0
|
||||
}, [pathName])
|
||||
|
||||
return (
|
||||
<>
|
||||
<activeLinkContext.Provider value={activeId}>
|
||||
<linkContext.Provider value={{ activeId, articleId, categoryId, sectionId }}>
|
||||
<div className="sidebar" onScroll={(e) => e.stopPropagation()}>
|
||||
<Search activeId={activeId} />
|
||||
<SidebarLinks links={links} />
|
||||
<Search prevQuery={searchQuery} prevType={searchType} />
|
||||
<div className="sidebar__section__links">
|
||||
<SectionLinks sectionId={sectionId} />
|
||||
</div>
|
||||
<SidebarLinks headings={headings} links={links} />
|
||||
<SidebarCloseButton />
|
||||
</div>
|
||||
<ToggleMenuButton />
|
||||
</activeLinkContext.Provider>
|
||||
</linkContext.Provider>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function SidebarLinks({ links }: { links: SidebarContentLink[] }) {
|
||||
export function SidebarLinks({
|
||||
headings,
|
||||
links,
|
||||
}: {
|
||||
headings?: ArticleHeadings
|
||||
links: SidebarContentLink[]
|
||||
}) {
|
||||
return (
|
||||
<nav className="sidebar__nav">
|
||||
<ul className="sidebar__list sidebar__sections__list">
|
||||
{links.map((link) => (
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
<SidebarLink key={link.url} headings={headings} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
function SidebarLink(props: SidebarContentLink) {
|
||||
function SidebarLink({ headings, ...props }: SidebarContentLink & { headings?: ArticleHeadings }) {
|
||||
switch (props.type) {
|
||||
case 'section': {
|
||||
return <SidebarSection {...props} />
|
||||
return <SidebarSection headings={headings} {...props} />
|
||||
}
|
||||
case 'article': {
|
||||
return <SidebarArticle {...props} />
|
||||
return <SidebarArticle headings={headings} {...props} />
|
||||
}
|
||||
case 'category': {
|
||||
return <SidebarCategory {...props} />
|
||||
|
@ -67,19 +99,19 @@ function SidebarLink(props: SidebarContentLink) {
|
|||
}
|
||||
}
|
||||
|
||||
function SidebarSection({ title, children }: SidebarContentSectionLink) {
|
||||
function SidebarSection({
|
||||
title,
|
||||
children,
|
||||
headings,
|
||||
}: SidebarContentSectionLink & { headings?: ArticleHeadings }) {
|
||||
if (children.length === 0) return null
|
||||
|
||||
return (
|
||||
<li className="sidebar__section">
|
||||
{title && (
|
||||
<Link href={children[0].url} title={title} className="sidebar__section__title">
|
||||
{title}
|
||||
</Link>
|
||||
)}
|
||||
{title && <span className="sidebar__section__title">{title}</span>}
|
||||
<ul className="sidebar__list">
|
||||
{children.map((link) => (
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
<SidebarLink key={link.url} headings={headings} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -87,33 +119,102 @@ function SidebarSection({ title, children }: SidebarContentSectionLink) {
|
|||
}
|
||||
|
||||
function SidebarCategory({ title, children }: SidebarContentCategoryLink) {
|
||||
const linkCtx = useContext(linkContext)
|
||||
if (children.length === 0) return null
|
||||
const hasGroups = children.some((child) => !!(child as SidebarContentArticleLink).groupId)
|
||||
const activeArticle = children.find(
|
||||
(child) => (child as SidebarContentArticleLink).articleId === linkCtx?.articleId
|
||||
)
|
||||
const activeGroup = activeArticle && (activeArticle as SidebarContentArticleLink).groupId
|
||||
const groups = ['Class', 'Function', 'Variable', 'Interface', 'Enum', 'TypeAlias', 'Namespace']
|
||||
|
||||
return (
|
||||
<li className="sidebar__category">
|
||||
<Link href={children[0].url} title={title} className="sidebar__link">
|
||||
{title}
|
||||
</Link>
|
||||
<ul className="sidebar__list">
|
||||
{children.map((link) => (
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
{hasGroups ? (
|
||||
<>
|
||||
<span className="sidebar__link">{title}</span>
|
||||
<Accordion.Root
|
||||
type="multiple"
|
||||
defaultValue={[`${linkCtx?.categoryId}-${activeGroup}-${linkCtx?.articleId}`]}
|
||||
>
|
||||
{groups.map((group) => {
|
||||
const articles = children.filter(
|
||||
(child) => (child as SidebarContentArticleLink).groupId === group
|
||||
)
|
||||
if (articles.length === 0) return null
|
||||
|
||||
return (
|
||||
<Accordion.Item
|
||||
key={group}
|
||||
value={`${linkCtx?.categoryId}-${group}-${linkCtx?.articleId}`}
|
||||
>
|
||||
<Accordion.Trigger
|
||||
className="sidebar__section__group__title"
|
||||
style={{ marginLeft: '8px', paddingRight: '8px' }}
|
||||
>
|
||||
{group}
|
||||
<Chevron />
|
||||
</Accordion.Trigger>
|
||||
<Accordion.Content>
|
||||
<ul className="sidebar__list" style={{ paddingLeft: '8px' }}>
|
||||
{articles.map((link) => (
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</Accordion.Content>
|
||||
</Accordion.Item>
|
||||
)
|
||||
})}
|
||||
</Accordion.Root>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Link href={children[0].url} title={title} className="sidebar__link">
|
||||
{title}
|
||||
</Link>
|
||||
<ul className="sidebar__list">
|
||||
{children.map((link) => (
|
||||
<SidebarLink key={link.url} {...link} />
|
||||
))}
|
||||
</ul>
|
||||
</>
|
||||
)}
|
||||
<hr />
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
function SidebarArticle({ title, url, articleId }: SidebarContentArticleLink) {
|
||||
const isActive = useContext(activeLinkContext) === articleId
|
||||
function SidebarArticle({
|
||||
title,
|
||||
url,
|
||||
articleId,
|
||||
headings,
|
||||
}: SidebarContentArticleLink & { headings?: ArticleHeadings }) {
|
||||
const isActive = useContext(linkContext)?.activeId === articleId
|
||||
|
||||
return (
|
||||
<li className="sidebar__article">
|
||||
<Link href={url}>
|
||||
<div className="sidebar__link" data-active={isActive}>
|
||||
{title}
|
||||
</div>
|
||||
<Link href={url} className="sidebar__link" data-active={isActive}>
|
||||
{title}
|
||||
</Link>
|
||||
|
||||
{isActive && (
|
||||
<ul className="sidebar__list">
|
||||
{headings
|
||||
?.filter((heading) => heading.level < 3)
|
||||
.map((heading) => (
|
||||
<li key={heading.slug}>
|
||||
<Link href={`#${heading.slug}`} className="sidebar__link">
|
||||
{heading.isCode ? (
|
||||
<code>{heading.title.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')}</code>
|
||||
) : (
|
||||
heading.title.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
||||
)}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
---
|
||||
title: Examples
|
||||
status: published
|
||||
author: steveruizok
|
||||
date: 10/11/2023
|
||||
order: 3
|
||||
---
|
||||
|
||||
Here's a [very simple sandbox](https://codesandbox.io/s/tldraw-example-canary-2lrzmy) showing the tldraw component.
|
||||
|
||||
<Embed src="https://codesandbox.io/embed/2lrzmy?view=Editor+%2B+Preview&module=%2Fsrc%2Fapp.tsx" />
|
||||
|
||||
You can also find simple [framework-specific examples](https://github.com/tldraw/examples). For a multiplayer example using a collaboration backend, see our [Yjs example](https://github.com/tldraw/tldraw-yjs-example).
|
||||
|
||||
For more specific examples of how to use the tldraw component, check out the [tldraw repository's examples app](https://github.com/tldraw/tldraw/blob/main/apps/examples/src). The [tldraw repo](https://github.com/tldraw/tldraw) has more information about running the examples locally.
|
|
@ -31,3 +31,169 @@ yarn add @tldraw/tldraw@canary
|
|||
```bash
|
||||
npm install @tldraw/tldraw@canary
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
You can use the [Tldraw](?) component inside of any React component.
|
||||
|
||||
```tsx
|
||||
import { Tldraw } from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<div style={{ position: 'fixed', inset: 0 }}>
|
||||
<Tldraw />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Wrapper
|
||||
|
||||
It's important that the [Tldraw](?) component is wrapped in a parent container that has an explicit size. Its height and width are set to `100%`, so it will fill its parent container.
|
||||
|
||||
### CSS
|
||||
|
||||
In addition to the [Tldraw](?) component itself, you should also import the `tldraw.css` file from the `@tldraw/tldraw` package.
|
||||
|
||||
```ts
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
```
|
||||
|
||||
You can alternatively import this file inside of another CSS file using the `@import` syntax.
|
||||
|
||||
```css
|
||||
@import url('@tldraw/tldraw/tldraw.css');
|
||||
```
|
||||
|
||||
If you'd like to deeply change the way that tldraw looks, you can copy the `tldraw.css` file into a new CSS file, make your changes, and import that instead.
|
||||
|
||||
### Fonts
|
||||
|
||||
We also use Inter as the default tldraw font. You can import this font however you like (or use a different font!) but here's the CSS import from Google fonts that we use:
|
||||
|
||||
```css
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
If you're using the [Tldraw](?) component in a full-screen app, you probably also want to update your `index.html`'s meta viewport element as shown below.
|
||||
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
```
|
||||
|
||||
This may not be critical to [Tldraw](?) performing correctly, however some features (such as safe area positioning) will only work correctly if these viewport options are set.
|
||||
|
||||
## Server Rendering
|
||||
|
||||
The [Tldraw](?) component can't be server-rendered. If you're using the component in a server-rendered framework (such as Next.js) then you need to import it dynamically.
|
||||
|
||||
```tsx
|
||||
const Tldraw = dynamic(async () => (await import('@tldraw/tldraw')).Tldraw, { ssr: false })
|
||||
```
|
||||
|
||||
### Using a bundler
|
||||
|
||||
If you're using a bundler like webpack or rollup, you can import the assets directly from the `@tldraw/assets` package. Here you can use `getAssetUrlsByMetaUrl` helper function:
|
||||
|
||||
```javascript
|
||||
import { getAssetUrlsByMetaUrl } from '@tldraw/assets/urls'
|
||||
|
||||
const assetUrls = getAssetUrlsByMetaUrl()
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
## Usage in Frameworks
|
||||
|
||||
Visit our [framework examples repository](https://github.com/tldraw/examples) to see examples of tldraw being used in various frameworks.
|
||||
|
||||
## Static Assets
|
||||
|
||||
In order to use the [Tldraw](?) component, the app must be able to find certain assets. These are contained in the `embed-icons`, `fonts`, `icons`, and `translations` folders. We offer a few different ways of making these assets available to your app.
|
||||
|
||||
### Using a public CDN
|
||||
|
||||
By default we serve these assets from a [public CDN called unpkg](https://unpkg.com/browse/@tldraw/assets@2.0.0-alpha.12/), so everything should work out of the box and is a good way to get started.
|
||||
|
||||
If you would like to customize some of the assets you can pass the customizations to our [Tldraw](?) component. For example, to use a custom icon for the `hand` tool you can do the following:
|
||||
|
||||
```javascript
|
||||
const assetUrls = {
|
||||
icons: {
|
||||
'tool-hand': './custom-tool-hand.svg',
|
||||
},
|
||||
}
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
This will use the custom icon for the `hand` tool and the default assets for everything else.
|
||||
|
||||
### Self-hosting static assets
|
||||
|
||||
If you want more flexibility you can also host these assets yourself:
|
||||
|
||||
1. Download the `embed-icons`, `fonts`, `icons`, and `translations` folders from the [assets folder](https://github.com/tldraw/tldraw/tree/main/assets) of the tldraw repository.
|
||||
2. Place the folders in your project's public path.
|
||||
3. Pass `assetUrls` prop to our `<Tldraw/>` component to let the component know where the assets live.
|
||||
|
||||
You can use our `getAssetUrls` helper function from the `@tldraw/assets` package to generate these urls for you.
|
||||
|
||||
```javascript
|
||||
import { getAssetUrls } from '@tldraw/assets/selfHosted'
|
||||
|
||||
const assetUrls = getAssetUrls()
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
While these files must be available, you can overwrite the individual files: for example, by placing different icons under the same name or modifying / adding translations.
|
||||
|
||||
If you use a CDN for hosting these files you can specify the base url of your assets. To recreate the above option of serving the assets from unpkg you would do the following:
|
||||
|
||||
```javascript
|
||||
const assetUrls = getAssetUrls({
|
||||
baseUrl: 'https://unpkg.com/@tldraw/assets@2.0.0-alpha.12/',
|
||||
})
|
||||
```
|
||||
|
||||
## Subcomponents
|
||||
|
||||
The [Tldraw](?) component combines two lower-level components: [TldrawEditor](?) and [TldrawUi](?). If you want to have more granular control, you can use those lower-level components directly. See [this example](https://github.com/tldraw/tldraw/blob/main/apps/examples/src/examples/ExplodedExample.tsx) for reference.
|
||||
|
||||
### Customize the default components
|
||||
|
||||
You can customize the appearance of the tldraw editor using the [Tldraw](?) (or [TldrawEditor](?) component's `components` prop.
|
||||
|
||||
```ts
|
||||
<Tldraw
|
||||
components={{
|
||||
Background: YourCustomBackground,
|
||||
SvgDefs: YourCustomSvgDefs,
|
||||
Brush: YourCustomBrush,
|
||||
ZoomBrush: YourCustomBrush,
|
||||
CollaboratorBrush: YourCustomBrush,
|
||||
Cursor: YourCustomCursor,
|
||||
CollaboratorCursor: YourCustomCursor,
|
||||
CollaboratorHint: YourCustomCollaboratorHint,
|
||||
CollaboratorShapeIndicator: YourCustomdicator,
|
||||
Grid: YourCustomGrid,
|
||||
Scribble: YourCustomScribble,
|
||||
SnapLine: YourCustomSnapLine,
|
||||
Handles: YourCustomHandles,
|
||||
Handle: YourCustomHandle,
|
||||
CollaboratorScribble: YourCustomScribble,
|
||||
ErrorFallback: YourCustomErrorFallback,
|
||||
ShapeErrorFallback: YourCustomShapeErrorFallback,
|
||||
ShapeIndicatorErrorFallback: YourCustomShapeIndicatorErrorFallback,
|
||||
Spinner: YourCustomSpinner,
|
||||
SelectionBackground: YourCustomSelectionBackground,
|
||||
SelectionForeground: YourCustomSelectionForeground,
|
||||
HoveredShapeIndicator: YourCustomHoveredShapeIndicator,
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
|
|
@ -6,7 +6,7 @@ date: 3/22/2023
|
|||
order: 0
|
||||
---
|
||||
|
||||
Welcome to the developer docs for tldraw, a React library for creating whiteboards and other infinite canvas experiences. These docs are for the 2.0 version which is currently in alpha.
|
||||
Welcome to the developer docs for tldraw, a React library for creating whiteboards and other infinite canvas experiences. These docs are for the 2.0 version which is currently in beta.
|
||||
|
||||
<a className="hero__images" href="https://examples.tldraw.com">
|
||||
<img src={'/images/hero_light.png'} alt="tldraw demo" className="article__image hero__light" />
|
||||
|
@ -31,7 +31,7 @@ If you want to go even deeper, you can use the [TldrawEditor](?) component as a
|
|||
|
||||
In addition to the docs on this website, we provide [many examples](https://github.com/tldraw/tldraw/tree/main/apps/examples/src/examples) in the tldraw repo that demonstrate different ways of using the tldraw library. You can view them running [here](https://examples.tldraw.com/); or else you can clone the tldraw repo and start a local development server to see them in action.
|
||||
|
||||
You can ask questions and get help on our [Discord](https://discord.gg/JMbeb96jsh) channel or in our Github [issues](https://github.com/tldraw/tldraw/issues).
|
||||
You can ask questions and get help on our [Discord](https://discord.com/invite/SBBEVCA4PG) channel or in our Github [issues](https://github.com/tldraw/tldraw/issues).
|
||||
|
||||
## Community
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
---
|
||||
title: Usage
|
||||
status: published
|
||||
author: steveruizok
|
||||
date: 3/22/2023
|
||||
order: 2
|
||||
---
|
||||
|
||||
You can use the [Tldraw](?) component inside of any React component.
|
||||
|
||||
```tsx
|
||||
import { Tldraw } from '@tldraw/tldraw'
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
|
||||
export default function () {
|
||||
return (
|
||||
<div style={{ position: 'fixed', inset: 0 }}>
|
||||
<Tldraw />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Wrapper
|
||||
|
||||
It's important that the [Tldraw](?) component is wrapped in a parent container that has an explicit size. Its height and width are set to `100%`, so it will fill its parent container.
|
||||
|
||||
### CSS
|
||||
|
||||
In addition to the [Tldraw](?) component itself, you should also import the `tldraw.css` file from the `@tldraw/tldraw` package.
|
||||
|
||||
```ts
|
||||
import '@tldraw/tldraw/tldraw.css'
|
||||
```
|
||||
|
||||
You can alternatively import this file inside of another CSS file using the `@import` syntax.
|
||||
|
||||
```css
|
||||
@import url('@tldraw/tldraw/tldraw.css');
|
||||
```
|
||||
|
||||
If you'd like to deeply change the way that tldraw looks, you can copy the `tldraw.css` file into a new CSS file, make your changes, and import that instead.
|
||||
|
||||
### Fonts
|
||||
|
||||
We also use Inter as the default tldraw font. You can import this font however you like (or use a different font!) but here's the CSS import from Google fonts that we use:
|
||||
|
||||
```css
|
||||
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
|
||||
```
|
||||
|
||||
### HTML
|
||||
|
||||
If you're using the [Tldraw](?) component in a full-screen app, you probably also want to update your `index.html`'s meta viewport element as shown below.
|
||||
|
||||
```html
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||
```
|
||||
|
||||
This may not be critical to [Tldraw](?) performing correctly, however some features (such as safe area positioning) will only work correctly if these viewport options are set.
|
||||
|
||||
## Server Rendering
|
||||
|
||||
The [Tldraw](?) component can't be server-rendered. If you're using the component in a server-rendered framework (such as Next.js) then you need to import it dynamically.
|
||||
|
||||
```tsx
|
||||
const Tldraw = dynamic(async () => (await import('@tldraw/tldraw')).Tldraw, { ssr: false })
|
||||
```
|
||||
|
||||
### Using a bundler
|
||||
|
||||
If you're using a bundler like webpack or rollup, you can import the assets directly from the `@tldraw/assets` package. Here you can use `getAssetUrlsByMetaUrl` helper function:
|
||||
|
||||
```javascript
|
||||
import { getAssetUrlsByMetaUrl } from '@tldraw/assets/urls'
|
||||
|
||||
const assetUrls = getAssetUrlsByMetaUrl()
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
## Usage in Frameworks
|
||||
|
||||
Visit our [framework examples repository](https://github.com/tldraw/examples) to see examples of tldraw being used in various frameworks.
|
||||
|
||||
## Static Assets
|
||||
|
||||
In order to use the [Tldraw](?) component, the app must be able to find certain assets. These are contained in the `embed-icons`, `fonts`, `icons`, and `translations` folders. We offer a few different ways of making these assets available to your app.
|
||||
|
||||
### Using a public CDN
|
||||
|
||||
By default we serve these assets from a [public CDN called unpkg](https://unpkg.com/browse/@tldraw/assets@2.0.0-alpha.12/), so everything should work out of the box and is a good way to get started.
|
||||
|
||||
If you would like to customize some of the assets you can pass the customizations to our [Tldraw](?) component. For example, to use a custom icon for the `hand` tool you can do the following:
|
||||
|
||||
```javascript
|
||||
const assetUrls = {
|
||||
icons: {
|
||||
'tool-hand': './custom-tool-hand.svg',
|
||||
},
|
||||
}
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
This will use the custom icon for the `hand` tool and the default assets for everything else.
|
||||
|
||||
### Self-hosting static assets
|
||||
|
||||
If you want more flexibility you can also host these assets yourself:
|
||||
|
||||
1. Download the `embed-icons`, `fonts`, `icons`, and `translations` folders from the [assets folder](https://github.com/tldraw/tldraw/tree/main/assets) of the tldraw repository.
|
||||
2. Place the folders in your project's public path.
|
||||
3. Pass `assetUrls` prop to our `<Tldraw/>` component to let the component know where the assets live.
|
||||
|
||||
You can use our `getAssetUrls` helper function from the `@tldraw/assets` package to generate these urls for you.
|
||||
|
||||
```javascript
|
||||
import { getAssetUrls } from '@tldraw/assets/selfHosted'
|
||||
|
||||
const assetUrls = getAssetUrls()
|
||||
|
||||
<Tldraw assetUrls={assetUrls} />
|
||||
```
|
||||
|
||||
While these files must be available, you can overwrite the individual files: for example, by placing different icons under the same name or modifying / adding translations.
|
||||
|
||||
If you use a CDN for hosting these files you can specify the base url of your assets. To recreate the above option of serving the assets from unpkg you would do the following:
|
||||
|
||||
```javascript
|
||||
const assetUrls = getAssetUrls({
|
||||
baseUrl: 'https://unpkg.com/@tldraw/assets@2.0.0-alpha.12/',
|
||||
})
|
||||
```
|
||||
|
||||
## Subcomponents
|
||||
|
||||
The [Tldraw](?) component combines two lower-level components: [TldrawEditor](?) and [TldrawUi](?). If you want to have more granular control, you can use those lower-level components directly. See [this example](https://github.com/tldraw/tldraw/blob/main/apps/examples/src/examples/ExplodedExample.tsx) for reference.
|
||||
|
||||
### Customize the default components
|
||||
|
||||
You can customize the appearance of the tldraw editor using the [Tldraw](?) (or [TldrawEditor](?) component's `components` prop.
|
||||
|
||||
```ts
|
||||
<Tldraw
|
||||
components={{
|
||||
Background: YourCustomBackground,
|
||||
SvgDefs: YourCustomSvgDefs,
|
||||
Brush: YourCustomBrush,
|
||||
ZoomBrush: YourCustomBrush,
|
||||
CollaboratorBrush: YourCustomBrush,
|
||||
Cursor: YourCustomCursor,
|
||||
CollaboratorCursor: YourCustomCursor,
|
||||
CollaboratorHint: YourCustomCollaboratorHint,
|
||||
CollaboratorShapeIndicator: YourCustomdicator,
|
||||
Grid: YourCustomGrid,
|
||||
Scribble: YourCustomScribble,
|
||||
SnapLine: YourCustomSnapLine,
|
||||
Handles: YourCustomHandles,
|
||||
Handle: YourCustomHandle,
|
||||
CollaboratorScribble: YourCustomScribble,
|
||||
ErrorFallback: YourCustomErrorFallback,
|
||||
ShapeErrorFallback: YourCustomShapeErrorFallback,
|
||||
ShapeIndicatorErrorFallback: YourCustomShapeIndicatorErrorFallback,
|
||||
Spinner: YourCustomSpinner,
|
||||
SelectionBackground: YourCustomSelectionBackground,
|
||||
SelectionForeground: YourCustomSelectionForeground,
|
||||
HoveredShapeIndicator: YourCustomHoveredShapeIndicator,
|
||||
}}
|
||||
/>
|
||||
```
|
|
@ -8,3 +8,4 @@ status: published
|
|||
---
|
||||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.12)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.14)
|
||||
|
||||
|
||||
#### Disable styles panel button on mobile when using the laser tool. ([#1704](https://github.com/tldraw/tldraw/pull/1704))
|
||||
|
||||
- Disable the styles panel button for laser tool on mobile.
|
||||
|
@ -111,4 +112,4 @@ status: published
|
|||
- David Sheldrick ([@ds300](https://github.com/ds300))
|
||||
- Lu Wilson ([@TodePond](https://github.com/TodePond))
|
||||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.15)
|
||||
|
||||
|
||||
#### frame label fix ([#2016](https://github.com/tldraw/tldraw/pull/2016))
|
||||
|
||||
- Add a brief release note for your PR here.
|
||||
|
@ -35,14 +36,8 @@ This pr add the custom defined shapes that's being passed to Tldraw
|
|||
|
||||
Before/After
|
||||
|
||||
<img
|
||||
width="300"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/91ea55c8-0fcc-4f73-b61e-565829a5f25e"
|
||||
/>
|
||||
<img
|
||||
width="300"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/ee4070fe-e236-4818-8fb4-43520210102b"
|
||||
/>
|
||||
<img width="300" src="https://github.com/tldraw/tldraw/assets/98838967/91ea55c8-0fcc-4f73-b61e-565829a5f25e" />
|
||||
<img width="300" src="https://github.com/tldraw/tldraw/assets/98838967/ee4070fe-e236-4818-8fb4-43520210102b" />
|
||||
|
||||
#### [fix] pinch events ([#1979](https://github.com/tldraw/tldraw/pull/1979))
|
||||
|
||||
|
@ -54,14 +49,8 @@ Before/After
|
|||
|
||||
Before/After
|
||||
|
||||
<image
|
||||
width="350"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/320171b4-61e0-4a41-b8d3-830bd90bea65"
|
||||
/>
|
||||
<image
|
||||
width="350"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/b42d7156-0ce9-4894-9692-9338dc931b79"
|
||||
/>
|
||||
<image width="350" src="https://github.com/tldraw/tldraw/assets/98838967/320171b4-61e0-4a41-b8d3-830bd90bea65" />
|
||||
<image width="350" src="https://github.com/tldraw/tldraw/assets/98838967/b42d7156-0ce9-4894-9692-9338dc931b79" />
|
||||
|
||||
#### Remove focus management ([#1953](https://github.com/tldraw/tldraw/pull/1953))
|
||||
|
||||
|
@ -82,14 +71,8 @@ Before/After
|
|||
|
||||
Before & After:
|
||||
|
||||
<image
|
||||
width="250"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/e0ca7d54-506f-4014-b65a-6b61a98e3665"
|
||||
/>
|
||||
<image
|
||||
width="250"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/90c9fa12-1bcb-430d-80c7-97e1faacea16"
|
||||
/>
|
||||
<image width="250" src="https://github.com/tldraw/tldraw/assets/98838967/e0ca7d54-506f-4014-b65a-6b61a98e3665" />
|
||||
<image width="250" src="https://github.com/tldraw/tldraw/assets/98838967/90c9fa12-1bcb-430d-80c7-97e1faacea16" />
|
||||
|
||||
#### Allow right clicking selection backgrounds ([#1968](https://github.com/tldraw/tldraw/pull/1968))
|
||||
|
||||
|
@ -105,7 +88,7 @@ Before & After:
|
|||
|
||||
#### Lokalise: Translations update ([#1964](https://github.com/tldraw/tldraw/pull/1964))
|
||||
|
||||
- Updated community translations for German and Galician
|
||||
* Updated community translations for German and Galician
|
||||
|
||||
#### [improvement] improve arrows (for real) ([#1957](https://github.com/tldraw/tldraw/pull/1957))
|
||||
|
||||
|
@ -149,7 +132,7 @@ Before & After:
|
|||
|
||||
#### :recycle: fix: editing is not terminated after the conversion is confirmed. ([#1885](https://github.com/tldraw/tldraw/pull/1885))
|
||||
|
||||
- fix: editing is not terminated after the conversion is confirmed.
|
||||
- fix: editing is not terminated after the conversion is confirmed.
|
||||
|
||||
#### Update community translations ([#1889](https://github.com/tldraw/tldraw/pull/1889))
|
||||
|
||||
|
@ -467,17 +450,10 @@ Removed a feature to reset the viewport back to a shape that is being edited.
|
|||
- `@tldraw/editor`, `@tldraw/store`, `@tldraw/tldraw`, `@tldraw/tlschema`
|
||||
- Migrate snapshot [#1843](https://github.com/tldraw/tldraw/pull/1843) ([@steveruizok](https://github.com/steveruizok))
|
||||
- `@tldraw/tldraw`
|
||||
|
||||
- export asset stuff [#1829](https://github.com/tldraw/tldraw/pull/1829) ([@steveruizok](https://github.com/steveruizok)
|
||||
|
||||
)
|
||||
|
||||
- export asset stuff [#1829](https://github.com/tldraw/tldraw/pull/1829) ([@steveruizok](https://github.com/steveruizok))
|
||||
- [feature] Asset props [#1824](https://github.com/tldraw/tldraw/pull/1824) ([@steveruizok](https://github.com/steveruizok))
|
||||
- [feature] unlock all action [#1820](https://github.com/tldraw/tldraw/pull/1820) ([@steveruizok](https://github.com/steveruizok))
|
||||
- export `UiEventsProvider` [#1774](https://github.com/tldraw/tldraw/pull/1774) ([@steveruizok](https://github.com/steveruizok)
|
||||
|
||||
)
|
||||
|
||||
- export `UiEventsProvider` [#1774](https://github.com/tldraw/tldraw/pull/1774) ([@steveruizok](https://github.com/steveruizok))
|
||||
- `@tldraw/editor`
|
||||
- Add className as prop to Canvas [#1827](https://github.com/tldraw/tldraw/pull/1827) ([@steveruizok](https://github.com/steveruizok))
|
||||
- refactor `parentsToChildrenWithIndexes` [#1764](https://github.com/tldraw/tldraw/pull/1764) ([@steveruizok](https://github.com/steveruizok))
|
||||
|
@ -658,4 +634,4 @@ Removed a feature to reset the viewport back to a shape that is being edited.
|
|||
- Ricardo Crespo ([@ricardo-crespo](https://github.com/ricardo-crespo))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Takuto Mori Gump ([@mr04vv](https://github.com/mr04vv))
|
||||
- Takuto Mori Gump ([@mr04vv](https://github.com/mr04vv))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.16)
|
||||
|
||||
|
||||
#### Fix shape opacity when erasing ([#2055](https://github.com/tldraw/tldraw/pull/2055))
|
||||
|
||||
- Fixes opacity of shapes while erasing in a group or frame.
|
||||
|
@ -23,15 +24,9 @@ status: published
|
|||
|
||||
Before/after:
|
||||
|
||||
<image
|
||||
width="250"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/763a93eb-ffaa-405c-9255-e68ba88ed9a2"
|
||||
/>
|
||||
<image width="250" src="https://github.com/tldraw/tldraw/assets/98838967/763a93eb-ffaa-405c-9255-e68ba88ed9a2" />
|
||||
|
||||
<image
|
||||
width="250"
|
||||
src="https://github.com/tldraw/tldraw/assets/98838967/dc9d3f77-c1c5-40f2-a9fe-10c723b6a21c"
|
||||
/>
|
||||
<image width="250" src="https://github.com/tldraw/tldraw/assets/98838967/dc9d3f77-c1c5-40f2-a9fe-10c723b6a21c" />
|
||||
|
||||
#### fix: proper label for opacity tooltip on hover ([#2044](https://github.com/tldraw/tldraw/pull/2044))
|
||||
|
||||
|
@ -102,4 +97,4 @@ Before/after:
|
|||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Prince Mendiratta ([@Prince-Mendiratta](https://github.com/Prince-Mendiratta))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.17)
|
||||
|
||||
|
||||
#### Firefox, Touch: Fix not being able to open style dropdowns ([#2092](https://github.com/tldraw/tldraw/pull/2092))
|
||||
|
||||
- Firefox Mobile: Fixed a bug where you couldn't open some style dropdown options.
|
||||
|
@ -48,8 +49,8 @@ status: published
|
|||
#### [fix] locked shape of opacity problem with eraser.pointing ([#2073](https://github.com/tldraw/tldraw/pull/2073))
|
||||
|
||||
- locked shape of opacity problem with eraser.pointing
|
||||
Before/after:
|
||||
![A](https://github.com/tldraw/tldraw/assets/59823089/7483506c-72ac-45cc-93aa-f2a794ea8ff0) ![B](https://github.com/tldraw/tldraw/assets/59823089/ef0f988c-83f5-46a2-b891-0a391bca2f87)
|
||||
Before/after:
|
||||
![A](https://github.com/tldraw/tldraw/assets/59823089/7483506c-72ac-45cc-93aa-f2a794ea8ff0) ![B](https://github.com/tldraw/tldraw/assets/59823089/ef0f988c-83f5-46a2-b891-0a391bca2f87)
|
||||
|
||||
---
|
||||
|
||||
|
@ -106,4 +107,4 @@ status: published
|
|||
- Lu Wilson ([@TodePond](https://github.com/TodePond))
|
||||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.18)
|
||||
|
||||
|
||||
#### Fix an error when using context menu. ([#2186](https://github.com/tldraw/tldraw/pull/2186))
|
||||
|
||||
- Fixes the console error when opening the context menu for the first time.
|
||||
|
@ -183,4 +184,4 @@ status: published
|
|||
- Lu Wilson ([@TodePond](https://github.com/TodePond))
|
||||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-alpha.19)
|
||||
|
||||
|
||||
#### zoom to affected shapes after undo/redo ([#2293](https://github.com/tldraw/tldraw/pull/2293))
|
||||
|
||||
- Make sure affected shapes are visible after undo/redo
|
||||
|
@ -247,4 +248,4 @@ status: published
|
|||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Sugit ([@sugitlab](https://github.com/sugitlab))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-beta.1)
|
||||
|
||||
|
||||
#### add speech bubble example ([#2362](https://github.com/tldraw/tldraw/pull/2362))
|
||||
|
||||
- Add an example for making a custom shape with handles, this one is a speech bubble with a movable tail.
|
||||
|
@ -148,4 +149,4 @@ Updated translations for German, Korean, Russian, Ukrainian, Traditional Chinese
|
|||
- MinhoPark ([@Lennon57](https://github.com/Lennon57))
|
||||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -9,6 +9,7 @@ status: published
|
|||
|
||||
[View on GitHub](https://github.com/tldraw/tldraw/releases/tag/v2.0.0-beta.2)
|
||||
|
||||
|
||||
#### Fix validation when pasting images. ([#2436](https://github.com/tldraw/tldraw/pull/2436))
|
||||
|
||||
- Fixes url validations.
|
||||
|
@ -163,4 +164,4 @@ status: published
|
|||
- Mitja Bezenšek ([@MitjaBezensek](https://github.com/MitjaBezensek))
|
||||
- Stan Flint ([@StanFlint](https://github.com/StanFlint))
|
||||
- Steve Ruiz ([@steveruizok](https://github.com/steveruizok))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
||||
- Taha ([@Taha-Hassan-Git](https://github.com/Taha-Hassan-Git))
|
|
@ -1,14 +1,14 @@
|
|||
[
|
||||
{
|
||||
"id": "getting-started",
|
||||
"title": "Getting Started",
|
||||
"title": "Get Started",
|
||||
"description": "Introduction articles for tldraw.",
|
||||
"categories": [],
|
||||
"sidebar_behavior": "show-links"
|
||||
},
|
||||
{
|
||||
"id": "docs",
|
||||
"title": "Documentation",
|
||||
"title": "Learn tldraw",
|
||||
"description": "Developer documentation for tldraw.",
|
||||
"categories": [],
|
||||
"sidebar_behavior": "show-links"
|
||||
|
@ -18,10 +18,10 @@
|
|||
"title": "Community",
|
||||
"description": "Guides for contributing to tldraw's open source project.",
|
||||
"categories": [],
|
||||
"sidebar_behavior": "show-links"
|
||||
"sidebar_behavior": "hidden"
|
||||
},
|
||||
{
|
||||
"id": "gen",
|
||||
"id": "reference",
|
||||
"title": "API Reference",
|
||||
"description": "Reference for the tldraw package's APIs (generated).",
|
||||
"categories": [
|
||||
|
@ -201,6 +201,6 @@
|
|||
]
|
||||
}
|
||||
],
|
||||
"sidebar_behavior": "show-title"
|
||||
"sidebar_behavior": "reference"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -16,7 +16,13 @@ const nextConfig = {
|
|||
{
|
||||
// For reverse compatibility with old links
|
||||
source: '/docs/introduction',
|
||||
destination: '/introduction',
|
||||
destination: '/quick-start',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// For reverse compatibility with old links
|
||||
source: '/introduction',
|
||||
destination: '/quick-start',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
|
@ -31,30 +37,6 @@ const nextConfig = {
|
|||
destination: '/usage',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// For reverse compatibility with old links
|
||||
source: '/docs/introduction',
|
||||
destination: '/introduction',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// For reverse compatibility with old links
|
||||
source: '/docs/installation',
|
||||
destination: '/installation',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// For reverse compatibility with old links
|
||||
source: '/docs/usage',
|
||||
destination: '/usage',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// To reflect that these are at the top level of the sidebar
|
||||
source: '/getting-started/:childId',
|
||||
destination: '/:childId',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
// To reflect that these are at the top level of the sidebar
|
||||
source: '/getting-started/:childId',
|
||||
|
|
|
@ -37,19 +37,24 @@
|
|||
"create-api-markdown": "yarn run -T tsx --tsconfig ./tsconfig.content.json ./scripts/create-api-markdown.ts",
|
||||
"refresh-content": "yarn run -T tsx --tsconfig ./tsconfig.content.json ./scripts/refresh-content.ts",
|
||||
"refresh-embeddings": "yarn run -T tsx --tsconfig ./tsconfig.content.json ./scripts/refresh-embeddings.ts",
|
||||
"refresh-everything": "yarn fetch-api-source && yarn fetch-releases && yarn create-api-markdown && yarn refresh-content && yarn refresh-embeddings",
|
||||
"refresh-everything": "yarn fetch-api-source && yarn fetch-releases && yarn create-api-markdown && yarn refresh-content && yarn refresh-embeddings && yarn format",
|
||||
"clean": "rm -rf node_modules .yarn",
|
||||
"format": "yarn run -T prettier --write .",
|
||||
"watch-content": "tsx ./watcher.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codesandbox/sandpack-react": "^2.11.3",
|
||||
"@microsoft/api-extractor-model": "^7.26.4",
|
||||
"@microsoft/tsdoc": "^0.14.2",
|
||||
"@radix-ui/react-accordion": "^1.1.2",
|
||||
"@radix-ui/react-navigation-menu": "^1.1.4",
|
||||
"@types/broken-link-checker": "^0.7.1",
|
||||
"@types/node": "^18.7.3",
|
||||
"@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",
|
||||
"eslint": "^8.37.0",
|
||||
|
|
|
@ -65,6 +65,8 @@ export async function connect(opts = {} as { reset?: boolean }) {
|
|||
status TEXT NOT NULL,
|
||||
date TEXT,
|
||||
sourceUrl TEXT,
|
||||
componentCode TEXT,
|
||||
componentCodeFiles TEXT,
|
||||
keywords TEXT,
|
||||
content TEXT NOT NULL,
|
||||
path TEXT,
|
||||
|
|
|
@ -8,17 +8,17 @@ import { getApiMarkdown } from './getApiMarkdown'
|
|||
|
||||
export async function createApiMarkdown() {
|
||||
const apiInputSection: InputSection = {
|
||||
id: 'gen' as string,
|
||||
id: 'reference' as string,
|
||||
title: 'API Reference',
|
||||
description: "Reference for the tldraw package's APIs (generated).",
|
||||
categories: [],
|
||||
sidebar_behavior: 'show-title',
|
||||
sidebar_behavior: 'reference',
|
||||
}
|
||||
|
||||
const addedCategories = new Set<string>()
|
||||
|
||||
const INPUT_DIR = path.join(process.cwd(), 'api')
|
||||
const OUTPUT_DIR = path.join(CONTENT_DIR, 'gen')
|
||||
const OUTPUT_DIR = path.join(CONTENT_DIR, 'reference')
|
||||
|
||||
if (fs.existsSync(OUTPUT_DIR)) {
|
||||
fs.rmSync(OUTPUT_DIR, { recursive: true })
|
||||
|
@ -85,7 +85,7 @@ export async function createApiMarkdown() {
|
|||
const sectionsJsonPath = path.join(CONTENT_DIR, 'sections.json')
|
||||
const sectionsJson = JSON.parse(fs.readFileSync(sectionsJsonPath, 'utf8')) as InputSection[]
|
||||
sectionsJson.splice(
|
||||
sectionsJson.findIndex((s) => s.id === 'gen'),
|
||||
sectionsJson.findIndex((s) => s.id === 'reference'),
|
||||
1
|
||||
)
|
||||
sectionsJson.push(apiInputSection)
|
||||
|
|
|
@ -11,8 +11,8 @@ export async function generateApiContent(): Promise<GeneratedContent> {
|
|||
const sections = require(path.join(CONTENT_DIRECTORY, 'sections.json')) as InputSection[]
|
||||
|
||||
try {
|
||||
const inputApiSection = sections.find((s) => s.id === 'gen')
|
||||
if (!inputApiSection) throw new Error(`Could not find section with id 'gen'`)
|
||||
const inputApiSection = sections.find((s) => s.id === 'reference')
|
||||
if (!inputApiSection) throw new Error(`Could not find section with id 'reference'`)
|
||||
const outputApiSection = generateSection(inputApiSection, articles, 999999) // always at the end!
|
||||
const contentComplete = { sections: [outputApiSection], articles }
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ export async function generateContent() {
|
|||
}
|
||||
|
||||
for (let i = 0; i < sections.length; i++) {
|
||||
if (sections[i].id === 'gen') continue
|
||||
if (sections[i].id === 'reference') continue
|
||||
result.sections.push(generateSection(sections[i], result.articles, i))
|
||||
}
|
||||
|
||||
|
|
34
apps/docs/scripts/functions/generateExamplesContent.ts
Normal file
34
apps/docs/scripts/functions/generateExamplesContent.ts
Normal file
|
@ -0,0 +1,34 @@
|
|||
import { Articles, GeneratedContent, InputSection } from '../../types/content-types'
|
||||
import { generateSection } from './generateSection'
|
||||
|
||||
const { log: nicelog } = console
|
||||
|
||||
const section: InputSection = {
|
||||
id: 'examples',
|
||||
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: [] },
|
||||
],
|
||||
sidebar_behavior: 'show-links',
|
||||
}
|
||||
|
||||
export async function generateExamplesContent(): Promise<GeneratedContent> {
|
||||
const articles: Articles = {}
|
||||
|
||||
try {
|
||||
const outputExamplesSection = generateSection(section, articles, 0)
|
||||
const contentComplete = { sections: [outputExamplesSection], articles }
|
||||
|
||||
return contentComplete
|
||||
} catch (error) {
|
||||
nicelog(`x Could not generate Examples content`)
|
||||
|
||||
throw error
|
||||
}
|
||||
}
|
|
@ -21,21 +21,29 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
)
|
||||
|
||||
// The file directory for this section
|
||||
const dir = path.join(CONTENT_DIR, section.id)
|
||||
const isExamples = section.id === 'examples'
|
||||
const dir = isExamples
|
||||
? path.join(process.cwd(), '..', 'examples', 'src', 'examples')
|
||||
: path.join(CONTENT_DIR, section.id)
|
||||
const files = fs.readdirSync(dir, { withFileTypes: false })
|
||||
|
||||
const isGenerated = section.id === 'gen'
|
||||
const isGenerated = section.id === 'reference'
|
||||
|
||||
for (const file of files) {
|
||||
const filename = file.toString()
|
||||
const fileContent = fs.readFileSync(path.join(dir, filename)).toString()
|
||||
const pathname = isExamples ? path.join(dir, filename, 'README.md') : path.join(dir, filename)
|
||||
const fileContent = fs.readFileSync(pathname).toString()
|
||||
const extension = path.extname(filename)
|
||||
const articleId = filename.replace(extension, '')
|
||||
|
||||
const parsed = matter({ content: fileContent }, {})
|
||||
|
||||
// If we're in prod and the article isn't published, skip it
|
||||
if (process.env.NODE_ENV !== 'development' && parsed.data.status !== 'published') {
|
||||
if (
|
||||
process.env.NODE_ENV !== 'development' &&
|
||||
!isExamples &&
|
||||
parsed.data.status !== 'published'
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@ -48,6 +56,38 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
|
||||
const isUncategorized = categoryId === section.id + '_ucg'
|
||||
const isIndex = articleId === section.id
|
||||
const componentCode = parsed.data.component
|
||||
? fs
|
||||
.readFileSync(
|
||||
path.join(
|
||||
dir,
|
||||
filename,
|
||||
`${parsed.data.component}${parsed.data.component.endsWith('.tsx') ? '' : '.tsx'}`
|
||||
)
|
||||
)
|
||||
.toString()
|
||||
: null
|
||||
const componentCodeFiles: { [key: string]: string } = {}
|
||||
if (parsed.data.component) {
|
||||
const exampleParentDirectory = path.join(dir, filename)
|
||||
const codeFilenames = fs.readdirSync(exampleParentDirectory, {
|
||||
withFileTypes: true,
|
||||
recursive: true,
|
||||
})
|
||||
codeFilenames
|
||||
.filter(
|
||||
(file) =>
|
||||
!file.isDirectory() &&
|
||||
file.name !== 'README.md' &&
|
||||
file.name.replace('.tsx', '') !==
|
||||
parsed.data.component.replace('./', '').replace('.tsx', '')
|
||||
)
|
||||
.forEach((file) => {
|
||||
componentCodeFiles[file.name] = fs
|
||||
.readFileSync(path.join(file.path, file.name))
|
||||
.toString()
|
||||
})
|
||||
}
|
||||
|
||||
const article: Article = {
|
||||
id: articleId,
|
||||
|
@ -55,7 +95,7 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
sectionIndex: 0,
|
||||
groupIndex: -1,
|
||||
groupId: parsed.data.group ?? null,
|
||||
categoryIndex: parsed.data.order ?? -1,
|
||||
categoryIndex: parsed.data.order ?? parsed.data.priority ?? -1,
|
||||
sectionId: section.id,
|
||||
author,
|
||||
categoryId,
|
||||
|
@ -68,6 +108,8 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
sourceUrl: isGenerated // if it's a generated API doc, then we don't have a link
|
||||
? parsed.data.sourceUrl ?? null
|
||||
: `${section.id}/${articleId}${extension}`,
|
||||
componentCode,
|
||||
componentCodeFiles: componentCode ? JSON.stringify(componentCodeFiles) : null,
|
||||
content: parsed.content,
|
||||
path:
|
||||
section.id === 'getting-started'
|
||||
|
@ -166,14 +208,10 @@ export function generateSection(section: InputSection, articles: Articles, index
|
|||
}
|
||||
|
||||
const sortArticles = (articleA: Article, articleB: Article) => {
|
||||
const { categoryIndex: categoryIndexA, date: dateA = '01/01/1970' } = articleA
|
||||
const { categoryIndex: categoryIndexB, date: dateB = '01/01/1970' } = articleB
|
||||
const { categoryIndex: categoryIndexA, title: titleA } = articleA
|
||||
const { categoryIndex: categoryIndexB, title: titleB } = articleB
|
||||
|
||||
return categoryIndexA === categoryIndexB
|
||||
? new Date(dateB!).getTime() > new Date(dateA!).getTime()
|
||||
? 1
|
||||
: -1
|
||||
: categoryIndexA < categoryIndexB
|
||||
? -1
|
||||
: 1
|
||||
? titleA.localeCompare(titleB)
|
||||
: categoryIndexA - categoryIndexB
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import { nicelog } from '@/utils/nicelog'
|
|||
import { connect } from './connect'
|
||||
import { generateApiContent } from './generateApiContent'
|
||||
import { generateContent } from './generateContent'
|
||||
import { generateExamplesContent } from './generateExamplesContent'
|
||||
|
||||
export async function refreshContent(opts = {} as { silent: boolean }) {
|
||||
if (!opts.silent) nicelog('◦ Resetting database...')
|
||||
|
@ -16,6 +17,9 @@ export async function refreshContent(opts = {} as { silent: boolean }) {
|
|||
if (!opts.silent) nicelog('◦ Generating / adding regular content to db...')
|
||||
await addContentToDb(db, await generateContent())
|
||||
|
||||
if (!opts.silent) nicelog('◦ Generating / adding Examples content to db...')
|
||||
await addContentToDb(db, await generateExamplesContent())
|
||||
|
||||
if (!opts.silent) nicelog('◦ Generating / adding API content to db...')
|
||||
await addContentToDb(db, await generateApiContent())
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
/* Light theme */
|
||||
--color-text: #1d1d1d;
|
||||
--color-text-secondary: #999;
|
||||
--color-background: #ffffff;
|
||||
--color-contrast: #ffffff;
|
||||
--color-accent: #2f80ed;
|
||||
|
@ -46,6 +47,7 @@
|
|||
[data-theme='dark'] {
|
||||
/* Dark theme */
|
||||
--color-text: #fafafa;
|
||||
--color-text-secondary: #999;
|
||||
--color-background: hsl(240, 5%, 8%);
|
||||
--color-contrast: #000;
|
||||
--color-accent: #74b0ff;
|
||||
|
@ -129,7 +131,7 @@ body {
|
|||
top: 0px;
|
||||
display: grid;
|
||||
padding: 16px;
|
||||
grid-template-columns: 264px 1fr auto;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
gap: 16px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
@ -145,12 +147,34 @@ body {
|
|||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.layout__header__socials {
|
||||
.layout__header__sections_and_socials {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.layout_header__section {
|
||||
text-decoration: none;
|
||||
margin: 0 4px;
|
||||
padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
color: var(--color-text);
|
||||
background-color: transparent;
|
||||
transition: background-color 0.12s ease-in-out;
|
||||
transition-delay: 0.1s;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.layout_header__section[data-active='true'] {
|
||||
background-color: var(--color-tint-1);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.layout_header__section:not([data-active='true']):hover {
|
||||
background-color: var(--color-tint-1);
|
||||
}
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
display: block;
|
||||
position: relative;
|
||||
|
@ -170,7 +194,7 @@ body {
|
|||
position: absolute;
|
||||
display: block;
|
||||
content: '';
|
||||
inset: 4px;
|
||||
inset: 0;
|
||||
background-color: var(--bg);
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.1s ease-in-out;
|
||||
|
@ -209,7 +233,7 @@ body {
|
|||
justify-self: center;
|
||||
width: 100%;
|
||||
min-height: calc(100vh - 64px);
|
||||
padding: 24px 0px 96px 0px;
|
||||
padding: 0px 0px 96px 0px;
|
||||
font-weight: 400;
|
||||
overflow-x: hidden;
|
||||
overflow-y: visible;
|
||||
|
@ -444,6 +468,10 @@ body {
|
|||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.article.article__example pre {
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
.article__api-docs pre {
|
||||
margin: 24px 0px;
|
||||
}
|
||||
|
@ -491,6 +519,10 @@ body {
|
|||
border: none;
|
||||
}
|
||||
|
||||
.article.article__example hr {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.article table {
|
||||
margin: 20px 0px;
|
||||
border-radius: 4px;
|
||||
|
@ -734,7 +766,7 @@ body {
|
|||
align-self: start;
|
||||
top: 72px;
|
||||
margin-left: -12px;
|
||||
padding: 24px 12px 120px 28px;
|
||||
padding: 0px 12px 120px 28px;
|
||||
width: calc(100% + 24px);
|
||||
max-height: calc(100vh);
|
||||
z-index: 800;
|
||||
|
@ -742,10 +774,10 @@ body {
|
|||
font-size: 14px;
|
||||
}
|
||||
|
||||
.sidebar a {
|
||||
color: inherit;
|
||||
.sidebar a,
|
||||
.sidebar .sidebar__link {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sidebar hr {
|
||||
|
@ -757,22 +789,32 @@ body {
|
|||
border: none;
|
||||
}
|
||||
|
||||
.sidebar__section__links {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar__list {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.sidebar__list li .sidebar__article {
|
||||
height: 44px;
|
||||
.sidebar__list li .sidebar__article,
|
||||
.sidebar__list li .sidebar__article li {
|
||||
margin-top: -6px;
|
||||
margin-bottom: -6px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar__list li .sidebar__category li a,
|
||||
.sidebar__list li .sidebar__article li a {
|
||||
padding-left: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.sidebar__link {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
padding: 6px 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
@ -815,33 +857,51 @@ body {
|
|||
|
||||
.sidebar__section__title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: var(--color-text);
|
||||
font-weight: normal;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
color: var(--color-text);
|
||||
color: var(--color-text-secondary);
|
||||
text-transform: uppercase;
|
||||
--bg: transparent;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.sidebar__sections__list > *:nth-last-of-type(n + 2) .sidebar__list {
|
||||
.sidebar__section__group__title {
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
margin-bottom: 4px;
|
||||
position: relative;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: var(--color-text-secondary);
|
||||
white-space: nowrap;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.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) {
|
||||
.sidebar__link:hover {
|
||||
a.sidebar__link:hover {
|
||||
cursor: pointer;
|
||||
color: var(--color-text);
|
||||
transition: background-color 0.12s ease-in-out;
|
||||
transition-delay: 0.1s;
|
||||
}
|
||||
|
||||
.sidebar__link:not([data-active='true']):hover {
|
||||
a.sidebar__link:not([data-active='true']):hover {
|
||||
--bg: var(--color-tint-1);
|
||||
}
|
||||
}
|
||||
|
@ -1073,6 +1133,23 @@ body {
|
|||
grid-gap: 40px;
|
||||
}
|
||||
|
||||
.layout__header .layout__header__sections_and_socials .layout_header__section,
|
||||
.layout__header .layout__header__sections_and_socials .NavigationMenuRoot {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.sidebar__section__links {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 16px 0;
|
||||
border-top: 1px solid var(--color-accent);
|
||||
border-bottom: 1px solid var(--color-accent);
|
||||
}
|
||||
|
||||
.NavigationMenuTrigger {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.menu__button {
|
||||
display: flex;
|
||||
pointer-events: all;
|
||||
|
@ -1257,3 +1334,93 @@ html[data-theme='light'] .hero__dark {
|
|||
margin: 0px -16px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------- Menus ------------------ */
|
||||
|
||||
.NavigationMenuRoot {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.NavigationMenuList {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.NavigationMenuTrigger {
|
||||
outline: none;
|
||||
user-select: none;
|
||||
border: 0;
|
||||
background: none;
|
||||
background-color: transparent;
|
||||
transition: background-color 0.12s ease-in-out;
|
||||
transition-delay: 0.1s;
|
||||
border-radius: 4px;
|
||||
margin: 0 4px;
|
||||
padding: 8px 12px;
|
||||
height: 44px;
|
||||
line-height: 22px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.NavigationMenuTrigger span {
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.NavigationMenuTrigger:hover {
|
||||
background-color: var(--color-tint-1);
|
||||
}
|
||||
}
|
||||
|
||||
.NavigationMenuContent {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: calc(100% + 4px);
|
||||
left: 4px;
|
||||
overflow: hidden;
|
||||
border-radius: 4px;
|
||||
background-color: var(--color-background);
|
||||
box-shadow: var(--shadow-small);
|
||||
}
|
||||
|
||||
.NavigationMenuContent li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.NavigationMenuContent li a {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
color: var(--color-text);
|
||||
font-size: 14px;
|
||||
padding: 8px 12px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.NavigationMenuContent li a:hover {
|
||||
background-color: var(--color-tint-1);
|
||||
}
|
||||
}
|
||||
|
||||
.NavigationMenuViewport {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: var(--radix-navigation-menu-viewport-height);
|
||||
}
|
||||
@media only screen and (min-width: 600px) {
|
||||
.NavigationMenuViewport {
|
||||
width: var(--radix-navigation-menu-viewport-width);
|
||||
}
|
||||
}
|
||||
|
||||
.CaretDown {
|
||||
position: relative;
|
||||
top: 3px;
|
||||
transition: transform 250ms ease;
|
||||
}
|
||||
[data-state='open'] > .CaretDown {
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export type InputSection = {
|
|||
title: string
|
||||
description: string
|
||||
categories: InputCategory[]
|
||||
sidebar_behavior: 'show-links' | 'show-title'
|
||||
sidebar_behavior: 'show-links' | 'show-title' | 'hidden' | 'reference'
|
||||
}
|
||||
|
||||
export type InputGroup = {
|
||||
|
@ -55,7 +55,7 @@ export interface Section extends ContentPage {
|
|||
/** An array of this section's categories. */
|
||||
categories: Category[]
|
||||
/** How the section should appear in the sidebar. */
|
||||
sidebar_behavior: 'show-links' | 'show-title'
|
||||
sidebar_behavior: 'show-links' | 'show-title' | 'hidden' | 'reference'
|
||||
}
|
||||
|
||||
export interface Category extends ContentPage {
|
||||
|
@ -104,6 +104,10 @@ export interface Article extends ContentPage {
|
|||
keywords: string[]
|
||||
/** The URL where the article's source can be found. */
|
||||
sourceUrl: string | null
|
||||
/** The article's code example (optional). */
|
||||
componentCode: string | null
|
||||
/** The article's code example files, JSON stringified (optional). */
|
||||
componentCodeFiles: string | null
|
||||
}
|
||||
|
||||
export enum ArticleStatus {
|
||||
|
@ -155,7 +159,8 @@ export interface SidebarContentCategoryLink extends BaseSidebarLink {
|
|||
|
||||
export interface SidebarContentArticleLink extends BaseSidebarLink {
|
||||
type: 'article'
|
||||
articleId: string
|
||||
articleId: string | null
|
||||
groupId: string | null
|
||||
}
|
||||
|
||||
export type SidebarContentLink =
|
||||
|
@ -164,10 +169,14 @@ export type SidebarContentLink =
|
|||
| SidebarContentArticleLink
|
||||
|
||||
export type SidebarContentList = {
|
||||
headings?: ArticleHeadings
|
||||
sectionId: string | null
|
||||
categoryId: string | null
|
||||
articleId: string | null
|
||||
links: SidebarContentLink[]
|
||||
activeId?: string | null
|
||||
searchQuery?: string
|
||||
searchType?: string
|
||||
}
|
||||
|
||||
/* ---------- Finished / generated content ---------- */
|
||||
|
|
|
@ -141,7 +141,10 @@ export class ContentDatabase {
|
|||
return { prev: prev ?? null, next: next ?? null }
|
||||
}
|
||||
|
||||
// TODO(mime): make this more generic, not per docs area
|
||||
private _sidebarContentLinks: SidebarContentLink[] | undefined
|
||||
private _sidebarReferenceContentLinks: SidebarContentLink[] | undefined
|
||||
private _sidebarExamplesContentLinks: SidebarContentLink[] | undefined
|
||||
|
||||
async getSidebarContentList({
|
||||
sectionId,
|
||||
|
@ -154,9 +157,15 @@ export class ContentDatabase {
|
|||
}): Promise<SidebarContentList> {
|
||||
let links: SidebarContentLink[]
|
||||
|
||||
if (this._sidebarContentLinks && process.env.NODE_ENV !== 'development') {
|
||||
const cachedLinks =
|
||||
sectionId === 'examples'
|
||||
? this._sidebarExamplesContentLinks
|
||||
: sectionId === 'reference'
|
||||
? this._sidebarReferenceContentLinks
|
||||
: this._sidebarContentLinks
|
||||
if (cachedLinks && process.env.NODE_ENV !== 'development') {
|
||||
// Use the previously cached sidebar links
|
||||
links = this._sidebarContentLinks
|
||||
links = cachedLinks
|
||||
} else {
|
||||
// Generate sidebar links and cache them
|
||||
links = []
|
||||
|
@ -168,12 +177,31 @@ export class ContentDatabase {
|
|||
|
||||
const children: SidebarContentLink[] = []
|
||||
|
||||
if (section.sidebar_behavior === 'hidden') {
|
||||
continue
|
||||
}
|
||||
|
||||
if (
|
||||
(sectionId === 'reference' && section.id !== 'reference') ||
|
||||
(sectionId !== 'reference' && section.id === 'reference')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (
|
||||
(sectionId === 'examples' && section.id !== 'examples') ||
|
||||
(sectionId !== 'examples' && section.id === 'examples')
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (section.sidebar_behavior === 'show-title') {
|
||||
links.push({
|
||||
type: 'article',
|
||||
title: section.title,
|
||||
url: section.path,
|
||||
articleId: section.id,
|
||||
groupId: null,
|
||||
})
|
||||
continue
|
||||
}
|
||||
|
@ -204,6 +232,7 @@ export class ContentDatabase {
|
|||
articleId: article.id,
|
||||
title: article.title,
|
||||
url: article.path,
|
||||
groupId: article.groupId,
|
||||
}
|
||||
|
||||
ucg.push(sidebarArticleLink)
|
||||
|
@ -228,6 +257,7 @@ export class ContentDatabase {
|
|||
const sidebarArticleLink: SidebarContentArticleLink = {
|
||||
type: 'article' as const,
|
||||
articleId: article.id,
|
||||
groupId: article.groupId,
|
||||
title: article.title,
|
||||
url: article.path,
|
||||
}
|
||||
|
@ -244,7 +274,14 @@ export class ContentDatabase {
|
|||
links.push({ type: 'section', title: section.title, url: section.path, children })
|
||||
|
||||
// Cache the links structure for next time
|
||||
this._sidebarContentLinks = links
|
||||
if (sectionId === 'examples') {
|
||||
this._sidebarExamplesContentLinks = links
|
||||
}
|
||||
if (sectionId === 'reference') {
|
||||
this._sidebarReferenceContentLinks = links
|
||||
} else {
|
||||
this._sidebarContentLinks = links
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ export class ContentVectorDatabase {
|
|||
// This is the content that we'll create the embedding for
|
||||
let contentToVectorize: string
|
||||
|
||||
if (article.sectionId === 'gen') {
|
||||
if (article.sectionId === 'reference') {
|
||||
// For API docs, we'll just use the title, description, and members as the content.
|
||||
// We'll also add a note that the content was generated from the API docs, hopefully
|
||||
// so that the embedding better reflects searches for api docs.
|
||||
|
@ -217,8 +217,8 @@ export async function getVectorDb(
|
|||
INCLUDE_API_CONTENT && INCLUDE_CONTENT
|
||||
? await db.all('SELECT * FROM articles')
|
||||
: INCLUDE_API_CONTENT
|
||||
? await db.all('SELECT * FROM articles WHERE articles.sectionId = ?', 'gen')
|
||||
: await db.all('SELECT * FROM articles WHERE articles.sectionId != ?', 'gen')
|
||||
? await db.all('SELECT * FROM articles WHERE articles.sectionId = ?', 'reference')
|
||||
: await db.all('SELECT * FROM articles WHERE articles.sectionId != ?', 'reference')
|
||||
|
||||
nicelog(`Adding articles to index`)
|
||||
const max = Math.min(articles.length, MAX_ARTICLES)
|
||||
|
|
|
@ -35,10 +35,12 @@ export async function addContentToDb(
|
|||
status,
|
||||
date,
|
||||
sourceUrl,
|
||||
componentCode,
|
||||
componentCodeFiles,
|
||||
keywords,
|
||||
content,
|
||||
path
|
||||
) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
) VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
|
||||
)
|
||||
|
||||
for (let i = 0; i < content.sections.length; i++) {
|
||||
|
@ -46,7 +48,7 @@ export async function addContentToDb(
|
|||
try {
|
||||
await sectionInsert.run(
|
||||
section.id,
|
||||
section.id === 'gen' ? 99999 : i,
|
||||
section.id === 'reference' ? 99999 : i,
|
||||
section.title,
|
||||
section.description,
|
||||
section.path,
|
||||
|
@ -92,6 +94,8 @@ export async function addContentToDb(
|
|||
article.status,
|
||||
article.date,
|
||||
article.sourceUrl,
|
||||
article.componentCode,
|
||||
article.componentCodeFiles,
|
||||
article.keywords.join(', '),
|
||||
article.content,
|
||||
article.path
|
||||
|
|
|
@ -6,7 +6,10 @@ import sqlite3 from 'sqlite3'
|
|||
export async function autoLinkDocs(db: Database<sqlite3.Database, sqlite3.Statement>) {
|
||||
// replace [TLEditor](?) with [TLEditor](/gen/editor/TLEditor)?
|
||||
// not sure how we would get there but finding an article with the same title
|
||||
const articles = await db.all('SELECT id, content FROM articles WHERE sectionId != ?', 'gen')
|
||||
const articles = await db.all(
|
||||
'SELECT id, content FROM articles WHERE sectionId != ?',
|
||||
'reference'
|
||||
)
|
||||
await Promise.all(articles.map((a) => autoLinkDocsForArticle(db, a)))
|
||||
}
|
||||
|
||||
|
@ -30,7 +33,7 @@ export async function autoLinkDocsForArticle(
|
|||
const article = await db.get(
|
||||
'SELECT id, sectionId, categoryId FROM articles WHERE title = ? AND sectionId = ?',
|
||||
title,
|
||||
'gen'
|
||||
'reference'
|
||||
)
|
||||
|
||||
if (!article) throw Error(`Could not find article for ${_title} (${title})`)
|
||||
|
|
|
@ -13,7 +13,7 @@ export type Example = {
|
|||
loadComponent: () => Promise<ComponentType>
|
||||
}
|
||||
|
||||
type Category = 'basic' | 'editor' | 'ui' | 'collaboration' | 'data/assets' | 'shapes/tools'
|
||||
type Category = 'basic' | 'editor-api' | 'ui' | 'collaboration' | 'data/assets' | 'shapes/tools'
|
||||
|
||||
const getExamplesForCategory = (category: Category) =>
|
||||
(Object.values(import.meta.glob('./examples/*/README.md', { eager: true })) as Example[])
|
||||
|
@ -28,7 +28,7 @@ const categories: Record<Category, string> = {
|
|||
ui: 'UI/Theming',
|
||||
'shapes/tools': 'Shapes & Tools',
|
||||
'data/assets': 'Data & Assets',
|
||||
editor: 'Editor API',
|
||||
'editor-api': 'Editor API',
|
||||
collaboration: 'Collaboration',
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Editor API
|
||||
component: ./APIExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 1
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Canvas events
|
||||
component: ./CanvasEventsExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 2
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Context Toolbar
|
||||
component: ./ContextToolbar.tsx
|
||||
category: UI
|
||||
category: ui
|
||||
priority: 2
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Sublibraries
|
||||
component: ./ExplodedExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 3
|
||||
---
|
||||
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
title: Floaty window
|
||||
hide: true
|
||||
component: ./FloatyExample.tsx
|
||||
category: UI
|
||||
category: ui
|
||||
priority: 3
|
||||
---
|
||||
|
|
|
@ -5,4 +5,4 @@ category: basic
|
|||
priority: 3
|
||||
---
|
||||
|
||||
Use multiple <Tldraw/> components on the same page.
|
||||
Use multiple `<Tldraw/>` components on the same page.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Minimal
|
||||
component: ./OnlyEditor.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 3
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Snapshots
|
||||
component: ./SnapshotExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 1
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: Store events
|
||||
component: ./StoreEventsExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 2
|
||||
---
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
title: UI events
|
||||
component: ./UiEventsExample.tsx
|
||||
category: editor
|
||||
category: editor-api
|
||||
priority: 2
|
||||
---
|
||||
|
||||
|
|
12
apps/examples/src/examples/yjs/README.md
Normal file
12
apps/examples/src/examples/yjs/README.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
title: YJS
|
||||
component: ./YjsExample.tsx
|
||||
category: collaboration
|
||||
priority: 2
|
||||
---
|
||||
|
||||
TODOTODO
|
||||
|
||||
---
|
||||
|
||||
TODOTODO
|
497
yarn.lock
497
yarn.lock
|
@ -2356,6 +2356,177 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/autocomplete@npm:^6.0.0, @codemirror/autocomplete@npm:^6.4.0":
|
||||
version: 6.12.0
|
||||
resolution: "@codemirror/autocomplete@npm:6.12.0"
|
||||
dependencies:
|
||||
"@codemirror/language": "npm:^6.0.0"
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.17.0"
|
||||
"@lezer/common": "npm:^1.0.0"
|
||||
peerDependencies:
|
||||
"@codemirror/language": ^6.0.0
|
||||
"@codemirror/state": ^6.0.0
|
||||
"@codemirror/view": ^6.0.0
|
||||
"@lezer/common": ^1.0.0
|
||||
checksum: d01fa7e5b965285e7c26116c716c2f85d8fc4810f69abb9432dd97d60bf3a05cac547fe9dc6eaf8c7723a8621c017ff41a0b5df0e635c5a7cc37b041c7676ce8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/commands@npm:^6.1.3":
|
||||
version: 6.3.3
|
||||
resolution: "@codemirror/commands@npm:6.3.3"
|
||||
dependencies:
|
||||
"@codemirror/language": "npm:^6.0.0"
|
||||
"@codemirror/state": "npm:^6.4.0"
|
||||
"@codemirror/view": "npm:^6.0.0"
|
||||
"@lezer/common": "npm:^1.1.0"
|
||||
checksum: 4b398b102d6afcbf0e0018b426287a7458867497811c9155790a3cc679b880765cd756bdb96bf35abc28fecb85c0938e618d39469ce8bc0724d4dea5d88f6ac2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/lang-css@npm:^6.0.0, @codemirror/lang-css@npm:^6.0.1":
|
||||
version: 6.2.1
|
||||
resolution: "@codemirror/lang-css@npm:6.2.1"
|
||||
dependencies:
|
||||
"@codemirror/autocomplete": "npm:^6.0.0"
|
||||
"@codemirror/language": "npm:^6.0.0"
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@lezer/common": "npm:^1.0.2"
|
||||
"@lezer/css": "npm:^1.0.0"
|
||||
checksum: 03c9111904850127ad69658e5e6f5d61bacc0d56e080aab17bedbc99fced10810f9930454aee812f138767ee9e65efae246301c49db55294c2a67ccf75b28731
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/lang-html@npm:^6.4.0":
|
||||
version: 6.4.8
|
||||
resolution: "@codemirror/lang-html@npm:6.4.8"
|
||||
dependencies:
|
||||
"@codemirror/autocomplete": "npm:^6.0.0"
|
||||
"@codemirror/lang-css": "npm:^6.0.0"
|
||||
"@codemirror/lang-javascript": "npm:^6.0.0"
|
||||
"@codemirror/language": "npm:^6.4.0"
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.17.0"
|
||||
"@lezer/common": "npm:^1.0.0"
|
||||
"@lezer/css": "npm:^1.1.0"
|
||||
"@lezer/html": "npm:^1.3.0"
|
||||
checksum: 92928806ee7d2ff570b279a6527b65fa61be44fd1b409529aead08d9d2bed0c2408efaaeb2638929ecbcd5894868312a870d24da46679bab3d136342b25a8f93
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/lang-javascript@npm:^6.0.0, @codemirror/lang-javascript@npm:^6.1.2":
|
||||
version: 6.2.1
|
||||
resolution: "@codemirror/lang-javascript@npm:6.2.1"
|
||||
dependencies:
|
||||
"@codemirror/autocomplete": "npm:^6.0.0"
|
||||
"@codemirror/language": "npm:^6.6.0"
|
||||
"@codemirror/lint": "npm:^6.0.0"
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.17.0"
|
||||
"@lezer/common": "npm:^1.0.0"
|
||||
"@lezer/javascript": "npm:^1.0.0"
|
||||
checksum: edc874d7c0563aeb50c720e3c9cb4928f08263ae2b26f72e49d58c57ed75cfbd2f4ef9f704f15747087989b37d249cbb17e9833c5281d992ab33120bd910887b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/language@npm:^6.0.0, @codemirror/language@npm:^6.3.2, @codemirror/language@npm:^6.4.0, @codemirror/language@npm:^6.6.0":
|
||||
version: 6.10.0
|
||||
resolution: "@codemirror/language@npm:6.10.0"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.23.0"
|
||||
"@lezer/common": "npm:^1.1.0"
|
||||
"@lezer/highlight": "npm:^1.0.0"
|
||||
"@lezer/lr": "npm:^1.0.0"
|
||||
style-mod: "npm:^4.0.0"
|
||||
checksum: 674f87a5f7cae19a5e0cbdd0e06beade7f3694809cc30b31939aa04790dd43008942e3cd3b537ba5729fd14fed81c8ff62b7dcf51800db815cbf8d19d1d6a763
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/lint@npm:^6.0.0":
|
||||
version: 6.4.2
|
||||
resolution: "@codemirror/lint@npm:6.4.2"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.0.0"
|
||||
"@codemirror/view": "npm:^6.0.0"
|
||||
crelt: "npm:^1.0.5"
|
||||
checksum: 5e48e4f654c0890fe226fd84dca7fcea716dc72939eb2583151cc8cb6342187a0744b8bffc10b14ad8d8e67d96549c32b054926411c3a5b65de107388cb7ff6b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/state@npm:^6.0.0, @codemirror/state@npm:^6.2.0, @codemirror/state@npm:^6.4.0":
|
||||
version: 6.4.0
|
||||
resolution: "@codemirror/state@npm:6.4.0"
|
||||
checksum: d9129c456d1589ca376594620bad10c51d3dcdb57950f34637cea0e2ea073a695d426dc1cfc9b909b07365c236a6312da1eaf740c384c853009742493b8c9935
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codemirror/view@npm:^6.0.0, @codemirror/view@npm:^6.17.0, @codemirror/view@npm:^6.23.0, @codemirror/view@npm:^6.7.1":
|
||||
version: 6.23.1
|
||||
resolution: "@codemirror/view@npm:6.23.1"
|
||||
dependencies:
|
||||
"@codemirror/state": "npm:^6.4.0"
|
||||
style-mod: "npm:^4.1.0"
|
||||
w3c-keyname: "npm:^2.2.4"
|
||||
checksum: 42e6b73bcad6bf5d2e9578c54d166c63c4b1c7c7c7806b6f6b4bead8683dc7fcca52201a02a1f9b8ccf120a4ad87e7dcd68f09d9d3e416304dad41a75e20da82
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codesandbox/nodebox@npm:0.1.8":
|
||||
version: 0.1.8
|
||||
resolution: "@codesandbox/nodebox@npm:0.1.8"
|
||||
dependencies:
|
||||
outvariant: "npm:^1.4.0"
|
||||
strict-event-emitter: "npm:^0.4.3"
|
||||
checksum: 3de00d306ae0236524c436b8640c442a4541f0eb696820aa5f6fc66018dc66431d8d78edd9305986aa2877befca292a3906bb4c6af2ecba5f15dbd587d1c916d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codesandbox/sandpack-client@npm:^2.11.2":
|
||||
version: 2.11.2
|
||||
resolution: "@codesandbox/sandpack-client@npm:2.11.2"
|
||||
dependencies:
|
||||
"@codesandbox/nodebox": "npm:0.1.8"
|
||||
buffer: "npm:^6.0.3"
|
||||
dequal: "npm:^2.0.2"
|
||||
outvariant: "npm:1.4.0"
|
||||
static-browser-server: "npm:1.0.3"
|
||||
checksum: 70f97d27414755b564e929c3a824a4811f3664c268f54f98ea5e003f4ffc8f36111d79d819e77390a5c1d43805ae5779e8100df2fa5f7c900c40e2882890e888
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@codesandbox/sandpack-react@npm:^2.11.3":
|
||||
version: 2.11.3
|
||||
resolution: "@codesandbox/sandpack-react@npm:2.11.3"
|
||||
dependencies:
|
||||
"@codemirror/autocomplete": "npm:^6.4.0"
|
||||
"@codemirror/commands": "npm:^6.1.3"
|
||||
"@codemirror/lang-css": "npm:^6.0.1"
|
||||
"@codemirror/lang-html": "npm:^6.4.0"
|
||||
"@codemirror/lang-javascript": "npm:^6.1.2"
|
||||
"@codemirror/language": "npm:^6.3.2"
|
||||
"@codemirror/state": "npm:^6.2.0"
|
||||
"@codemirror/view": "npm:^6.7.1"
|
||||
"@codesandbox/sandpack-client": "npm:^2.11.2"
|
||||
"@lezer/highlight": "npm:^1.1.3"
|
||||
"@react-hook/intersection-observer": "npm:^3.1.1"
|
||||
"@stitches/core": "npm:^1.2.6"
|
||||
anser: "npm:^2.1.1"
|
||||
clean-set: "npm:^1.1.2"
|
||||
codesandbox-import-util-types: "npm:^2.2.3"
|
||||
dequal: "npm:^2.0.2"
|
||||
escape-carriage: "npm:^1.3.1"
|
||||
lz-string: "npm:^1.4.4"
|
||||
react-devtools-inline: "npm:4.4.0"
|
||||
react-is: "npm:^17.0.2"
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17 || ^18
|
||||
react-dom: ^16.8.0 || ^17 || ^18
|
||||
checksum: c78fb334a003df1c2398c04ae988259a61626865ac25f3bf2c1f46ac72d83f03d01aa6e2adcf2ab81ff781b8bf1caa8551f1a2c2ceca53f2eb78bb4f3604ea3c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@cspotcode/source-map-support@npm:^0.8.0":
|
||||
version: 0.8.1
|
||||
resolution: "@cspotcode/source-map-support@npm:0.8.1"
|
||||
|
@ -3761,6 +3932,64 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/common@npm:^1.0.0, @lezer/common@npm:^1.0.2, @lezer/common@npm:^1.1.0, @lezer/common@npm:^1.2.0":
|
||||
version: 1.2.1
|
||||
resolution: "@lezer/common@npm:1.2.1"
|
||||
checksum: b362ed2e97664e4b36b3dbff49b52d1bfc5accc0152b577fefd46e585d012ff685d1fd336d75d80066e01c0505b1135d4cf69be5e330b5bfec2e2650c437bcae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/css@npm:^1.0.0, @lezer/css@npm:^1.1.0":
|
||||
version: 1.1.7
|
||||
resolution: "@lezer/css@npm:1.1.7"
|
||||
dependencies:
|
||||
"@lezer/common": "npm:^1.2.0"
|
||||
"@lezer/highlight": "npm:^1.0.0"
|
||||
"@lezer/lr": "npm:^1.0.0"
|
||||
checksum: cffa5f0c65c622af3df294d6697d88ee1b5ce445250b0b95576b7c1c9dfaa1513ca34fde514507662c7d6fb9a17a33f5372d01685fe0925ea3021d86da5fa222
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/highlight@npm:^1.0.0, @lezer/highlight@npm:^1.1.3":
|
||||
version: 1.2.0
|
||||
resolution: "@lezer/highlight@npm:1.2.0"
|
||||
dependencies:
|
||||
"@lezer/common": "npm:^1.0.0"
|
||||
checksum: 14a80cbfb0cd1ce716decb4f3a045d42e7146f539cfd483b62ce46c4586a26d2f4fbdc35ace1cad81645304be4d30eafb95a2b057c34dfd471d56c7fbd82df3a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/html@npm:^1.3.0":
|
||||
version: 1.3.8
|
||||
resolution: "@lezer/html@npm:1.3.8"
|
||||
dependencies:
|
||||
"@lezer/common": "npm:^1.2.0"
|
||||
"@lezer/highlight": "npm:^1.0.0"
|
||||
"@lezer/lr": "npm:^1.0.0"
|
||||
checksum: 34eb58de4bf8fba49f84d8552fd6487bd981be5f8abd702cda517acdd89dee3dd33fec5a34349431d9357fe72512d4385bdec7617079a0c748b92c2e68b66e94
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/javascript@npm:^1.0.0":
|
||||
version: 1.4.13
|
||||
resolution: "@lezer/javascript@npm:1.4.13"
|
||||
dependencies:
|
||||
"@lezer/common": "npm:^1.2.0"
|
||||
"@lezer/highlight": "npm:^1.1.3"
|
||||
"@lezer/lr": "npm:^1.3.0"
|
||||
checksum: 2ebdfae4968e7d0ff1a6b21b13b511cfcc78ee08f548de0133d5dc6fa4e45f089ef35368ff82ab4370f22881768958e70d3d2d5c662784add0170a0fc48c9be0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@lezer/lr@npm:^1.0.0, @lezer/lr@npm:^1.3.0":
|
||||
version: 1.4.0
|
||||
resolution: "@lezer/lr@npm:1.4.0"
|
||||
dependencies:
|
||||
"@lezer/common": "npm:^1.0.0"
|
||||
checksum: 7391d0d08e54cd9e4f4d46e6ee6aa81fbaf079b22ed9c13d01fc9928e0ffd16d0c2d21b2cedd55675ad6c687277db28349ea8db81c9c69222cd7e7c40edd026e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@mapbox/node-pre-gyp@npm:^1.0.5":
|
||||
version: 1.0.11
|
||||
resolution: "@mapbox/node-pre-gyp@npm:1.0.11"
|
||||
|
@ -4521,6 +4750,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@open-draft/deferred-promise@npm:^2.1.0":
|
||||
version: 2.2.0
|
||||
resolution: "@open-draft/deferred-promise@npm:2.2.0"
|
||||
checksum: bc3bb1668a555bb87b33383cafcf207d9561e17d2ca0d9e61b7ce88e82b66e36a333d3676c1d39eb5848022c03c8145331fcdc828ba297f88cb1de9c5cef6c19
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@peculiar/asn1-schema@npm:^2.3.6":
|
||||
version: 2.3.8
|
||||
resolution: "@peculiar/asn1-schema@npm:2.3.8"
|
||||
|
@ -5002,6 +5238,39 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-navigation-menu@npm:^1.1.4":
|
||||
version: 1.1.4
|
||||
resolution: "@radix-ui/react-navigation-menu@npm:1.1.4"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.13.10"
|
||||
"@radix-ui/primitive": "npm:1.0.1"
|
||||
"@radix-ui/react-collection": "npm:1.0.3"
|
||||
"@radix-ui/react-compose-refs": "npm:1.0.1"
|
||||
"@radix-ui/react-context": "npm:1.0.1"
|
||||
"@radix-ui/react-direction": "npm:1.0.1"
|
||||
"@radix-ui/react-dismissable-layer": "npm:1.0.5"
|
||||
"@radix-ui/react-id": "npm:1.0.1"
|
||||
"@radix-ui/react-presence": "npm:1.0.1"
|
||||
"@radix-ui/react-primitive": "npm:1.0.3"
|
||||
"@radix-ui/react-use-callback-ref": "npm:1.0.1"
|
||||
"@radix-ui/react-use-controllable-state": "npm:1.0.1"
|
||||
"@radix-ui/react-use-layout-effect": "npm:1.0.1"
|
||||
"@radix-ui/react-use-previous": "npm:1.0.1"
|
||||
"@radix-ui/react-visually-hidden": "npm:1.0.3"
|
||||
peerDependencies:
|
||||
"@types/react": "*"
|
||||
"@types/react-dom": "*"
|
||||
react: ^16.8 || ^17.0 || ^18.0
|
||||
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||
peerDependenciesMeta:
|
||||
"@types/react":
|
||||
optional: true
|
||||
"@types/react-dom":
|
||||
optional: true
|
||||
checksum: ae502c3757a1a0417209a76def7fd43088d3414658b8acc2010a1c68c3f737fdd20f601eed384ddc0fdb55404f6299ae1dd23e1ae28b7e902595d98b97699825
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@radix-ui/react-popover@npm:^1.0.7":
|
||||
version: 1.0.7
|
||||
resolution: "@radix-ui/react-popover@npm:1.0.7"
|
||||
|
@ -5458,6 +5727,27 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-hook/intersection-observer@npm:^3.1.1":
|
||||
version: 3.1.1
|
||||
resolution: "@react-hook/intersection-observer@npm:3.1.1"
|
||||
dependencies:
|
||||
"@react-hook/passive-layout-effect": "npm:^1.2.0"
|
||||
intersection-observer: "npm:^0.10.0"
|
||||
peerDependencies:
|
||||
react: ">=16.8"
|
||||
checksum: dc11695baa03765d53a23753c261f74dd0f226b9abd5bf3019d87c4f5e43da1919d81b8b902cd03d08f21f6484eb66a64139307bc84b379a95b2e3b9947e935f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-hook/passive-layout-effect@npm:^1.2.0":
|
||||
version: 1.2.1
|
||||
resolution: "@react-hook/passive-layout-effect@npm:1.2.1"
|
||||
peerDependencies:
|
||||
react: ">=16.8"
|
||||
checksum: 217cb8aa90fb8e677672319a9a466d7752890cf4357c76df000b207696e9cc717cf2ee88080671cc9dae238a82f92093ab4f61ab2f6032d2a8db958fc7d99b5d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@remix-run/dev@npm:@vercel/remix-run-dev@1.15.0":
|
||||
version: 1.15.0
|
||||
resolution: "@vercel/remix-run-dev@npm:1.15.0"
|
||||
|
@ -6611,6 +6901,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@stitches/core@npm:^1.2.6":
|
||||
version: 1.2.8
|
||||
resolution: "@stitches/core@npm:1.2.8"
|
||||
checksum: bdee1772f033b20bfb1081a3bb8c3e85f2a44f381379d4c2ae21408336025e2d2578f79eec74db26824b852ebcc72de3edfc8c51418608f189aa5ffc26df667a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@supabase/auth-helpers-remix@npm:^0.2.2":
|
||||
version: 0.2.6
|
||||
resolution: "@supabase/auth-helpers-remix@npm:0.2.6"
|
||||
|
@ -6939,14 +7236,18 @@ __metadata:
|
|||
version: 0.0.0-use.local
|
||||
resolution: "@tldraw/docs@workspace:apps/docs"
|
||||
dependencies:
|
||||
"@codesandbox/sandpack-react": "npm:^2.11.3"
|
||||
"@microsoft/api-extractor-model": "npm:^7.26.4"
|
||||
"@microsoft/tsdoc": "npm:^0.14.2"
|
||||
"@radix-ui/react-accordion": "npm:^1.1.2"
|
||||
"@radix-ui/react-navigation-menu": "npm:^1.1.4"
|
||||
"@types/broken-link-checker": "npm:^0.7.1"
|
||||
"@types/node": "npm:^18.7.3"
|
||||
"@types/sqlite3": "npm:^3.1.9"
|
||||
"@types/ws": "npm:^8.5.9"
|
||||
"@vercel/analytics": "npm:^1.1.1"
|
||||
broken-link-checker: "npm:^0.7.8"
|
||||
classnames: "npm:^2.3.2"
|
||||
concurrently: "npm:^8.2.2"
|
||||
dotenv: "npm:^16.3.1"
|
||||
eslint: "npm:^8.37.0"
|
||||
|
@ -8964,6 +9265,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"anser@npm:^2.1.1":
|
||||
version: 2.1.1
|
||||
resolution: "anser@npm:2.1.1"
|
||||
checksum: 7cf63f2ac34a77a410da37bd7748f9d4f1b077763b51e5eadf7b355211050e12cabbb405268cc033f6351e1e60cc00ca18431a240053ffc94c12f0c758e1e66d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ansi-colors@npm:4.1.1":
|
||||
version: 4.1.1
|
||||
resolution: "ansi-colors@npm:4.1.1"
|
||||
|
@ -9988,6 +10296,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"buffer@npm:^6.0.3":
|
||||
version: 6.0.3
|
||||
resolution: "buffer@npm:6.0.3"
|
||||
dependencies:
|
||||
base64-js: "npm:^1.3.1"
|
||||
ieee754: "npm:^1.2.1"
|
||||
checksum: b6bc68237ebf29bdacae48ce60e5e28fc53ae886301f2ad9496618efac49427ed79096750033e7eab1897a4f26ae374ace49106a5758f38fb70c78c9fda2c3b1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"busboy@npm:1.6.0":
|
||||
version: 1.6.0
|
||||
resolution: "busboy@npm:1.6.0"
|
||||
|
@ -10403,6 +10721,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clean-set@npm:^1.1.2":
|
||||
version: 1.1.2
|
||||
resolution: "clean-set@npm:1.1.2"
|
||||
checksum: b460b59c82a11945052b59efa1d51405c0ba11d227f2c2140e9f7803d702b4a36354bfee0077d46a758979891aa4322211ce392c86961f11bf57e2ff774d5506
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clean-stack@npm:^2.0.0":
|
||||
version: 2.2.0
|
||||
resolution: "clean-stack@npm:2.2.0"
|
||||
|
@ -10542,6 +10867,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"codesandbox-import-util-types@npm:^2.2.3":
|
||||
version: 2.3.0
|
||||
resolution: "codesandbox-import-util-types@npm:2.3.0"
|
||||
checksum: 6cbb7050fb8bd822b4bf101792052a0d8a602bb2f85bb6f9422f9b1d11d170926c44af6f73e98fbb259792a45908ff4dc122123bec86d58176f6dadfc2f01f03
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"collect-v8-coverage@npm:^1.0.0":
|
||||
version: 1.0.2
|
||||
resolution: "collect-v8-coverage@npm:1.0.2"
|
||||
|
@ -10911,6 +11243,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"crelt@npm:^1.0.5":
|
||||
version: 1.0.6
|
||||
resolution: "crelt@npm:1.0.6"
|
||||
checksum: 5ed326ca6bd243b1dba6b943f665b21c2c04be03271824bc48f20dba324b0f8233e221f8c67312526d24af2b1243c023dc05a41bd8bd05d1a479fd2c72fb39c3
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-env@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-env@npm:7.0.3"
|
||||
|
@ -11061,6 +11400,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"d@npm:1, d@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "d@npm:1.0.1"
|
||||
dependencies:
|
||||
es5-ext: "npm:^0.10.50"
|
||||
type: "npm:^1.0.1"
|
||||
checksum: 1296e3f92e646895681c1cb564abd0eb23c29db7d62c5120a279e84e98915499a477808e9580760f09e3744c0ed7ac8f7cff98d096ba9770754f6ef0f1c97983
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"damerau-levenshtein@npm:^1.0.8":
|
||||
version: 1.0.8
|
||||
resolution: "damerau-levenshtein@npm:1.0.8"
|
||||
|
@ -11350,7 +11699,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dequal@npm:^2.0.0, dequal@npm:^2.0.3":
|
||||
"dequal@npm:^2.0.0, dequal@npm:^2.0.2, dequal@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "dequal@npm:2.0.3"
|
||||
checksum: 6ff05a7561f33603df87c45e389c9ac0a95e3c056be3da1a0c4702149e3a7f6fe5ffbb294478687ba51a9e95f3a60e8b6b9005993acd79c292c7d15f71964b6b
|
||||
|
@ -11626,10 +11975,10 @@ __metadata:
|
|||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"dotenv@npm:^16.0.0, dotenv@npm:^16.3.1":
|
||||
version: 16.3.1
|
||||
resolution: "dotenv@npm:16.3.1"
|
||||
checksum: dbb778237ef8750e9e3cd1473d3c8eaa9cc3600e33a75c0e36415d0fa0848197f56c3800f77924c70e7828f0b03896818cd52f785b07b9ad4d88dba73fbba83f
|
||||
"dotenv@npm:^16.0.0, dotenv@npm:^16.0.3, dotenv@npm:^16.3.1":
|
||||
version: 16.4.1
|
||||
resolution: "dotenv@npm:16.4.1"
|
||||
checksum: 8da20250633703686961004df3ea81b1f81e16fbe873372050676f54ca4053172d0589aae902e683eb575884d56b6bc89fe48bbac5e1e0bef606a061389ca33c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -12038,6 +12387,38 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"es5-ext@npm:^0.10.35, es5-ext@npm:^0.10.50":
|
||||
version: 0.10.62
|
||||
resolution: "es5-ext@npm:0.10.62"
|
||||
dependencies:
|
||||
es6-iterator: "npm:^2.0.3"
|
||||
es6-symbol: "npm:^3.1.3"
|
||||
next-tick: "npm:^1.1.0"
|
||||
checksum: 3f6a3bcdb7ff82aaf65265799729828023c687a2645da04005b8f1dc6676a0c41fd06571b2517f89dcf143e0268d3d9ef0fdfd536ab74580083204c688d6fb45
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"es6-iterator@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "es6-iterator@npm:2.0.3"
|
||||
dependencies:
|
||||
d: "npm:1"
|
||||
es5-ext: "npm:^0.10.35"
|
||||
es6-symbol: "npm:^3.1.1"
|
||||
checksum: dbadecf3d0e467692815c2b438dfa99e5a97cbbecf4a58720adcb467a04220e0e36282399ba297911fd472c50ae4158fffba7ed0b7d4273fe322b69d03f9e3a5
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"es6-symbol@npm:^3, es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3":
|
||||
version: 3.1.3
|
||||
resolution: "es6-symbol@npm:3.1.3"
|
||||
dependencies:
|
||||
d: "npm:^1.0.1"
|
||||
ext: "npm:^1.1.2"
|
||||
checksum: b404e5ecae1a076058aa2ba2568d87e2cb4490cb1130784b84e7b4c09c570b487d4f58ed685a08db8d350bd4916500dd3d623b26e6b3520841d30d2ebb152f8d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"esbuild-android-64@npm:0.14.47":
|
||||
version: 0.14.47
|
||||
resolution: "esbuild-android-64@npm:0.14.47"
|
||||
|
@ -12644,6 +13025,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"escape-carriage@npm:^1.3.1":
|
||||
version: 1.3.1
|
||||
resolution: "escape-carriage@npm:1.3.1"
|
||||
checksum: 6d7613a5875977b04eb4651f3fa14eb8f54c72aa198b603c823502fcfef9f5969afc4c76d27b2f2fc008d88764fbf4c3a6e04d549d6134e2ff7f705c99e3ddb9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"escape-html@npm:~1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "escape-html@npm:1.0.3"
|
||||
|
@ -13325,6 +13713,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ext@npm:^1.1.2":
|
||||
version: 1.7.0
|
||||
resolution: "ext@npm:1.7.0"
|
||||
dependencies:
|
||||
type: "npm:^2.7.2"
|
||||
checksum: 666a135980b002df0e75c8ac6c389140cdc59ac953db62770479ee2856d58ce69d2f845e5f2586716350b725400f6945e51e9159573158c39f369984c72dcd84
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"extend-shallow@npm:^2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "extend-shallow@npm:2.0.1"
|
||||
|
@ -15020,7 +15417,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4":
|
||||
"ieee754@npm:^1.1.13, ieee754@npm:^1.1.4, ieee754@npm:^1.2.1":
|
||||
version: 1.2.1
|
||||
resolution: "ieee754@npm:1.2.1"
|
||||
checksum: d9f2557a59036f16c282aaeb107832dc957a93d73397d89bbad4eb1130560560eb695060145e8e6b3b498b15ab95510226649a0b8f52ae06583575419fe10fc4
|
||||
|
@ -15181,6 +15578,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"intersection-observer@npm:^0.10.0":
|
||||
version: 0.10.0
|
||||
resolution: "intersection-observer@npm:0.10.0"
|
||||
checksum: d9ffce291459a2c4ada9e45f23ef805361691f93e9a41a2afe801d29e6c9b1d0054f7faddafd79ecc341d7008e1f921a2e67cadeae9692d9831af903f23fc644
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"invariant@npm:^2.2.4":
|
||||
version: 2.2.4
|
||||
resolution: "invariant@npm:2.2.4"
|
||||
|
@ -18405,7 +18809,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"mime-db@npm:1.52.0":
|
||||
"mime-db@npm:1.52.0, mime-db@npm:^1.52.0":
|
||||
version: 1.52.0
|
||||
resolution: "mime-db@npm:1.52.0"
|
||||
checksum: 54bb60bf39e6f8689f6622784e668a3d7f8bed6b0d886f5c3c446cb3284be28b30bf707ed05d0fe44a036f8469976b2629bbea182684977b084de9da274694d7
|
||||
|
@ -18902,6 +19306,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"next-tick@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "next-tick@npm:1.1.0"
|
||||
checksum: 83b5cf36027a53ee6d8b7f9c0782f2ba87f4858d977342bfc3c20c21629290a2111f8374d13a81221179603ffc4364f38374b5655d17b6a8f8a8c77bdea4fe8b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"next@npm:^14.0.4":
|
||||
version: 14.0.4
|
||||
resolution: "next@npm:14.0.4"
|
||||
|
@ -19530,6 +19941,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"outvariant@npm:1.4.0":
|
||||
version: 1.4.0
|
||||
resolution: "outvariant@npm:1.4.0"
|
||||
checksum: 07b9bcb9b3a2ff1b3db02af6b07d70e663082b30ddc08ff475d7c85fc623fdcc4433a4ab5b88f6902b62dbb284eef1be386aa537e14cef0519fad887ec483054
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"outvariant@npm:^1.3.0, outvariant@npm:^1.4.0":
|
||||
version: 1.4.2
|
||||
resolution: "outvariant@npm:1.4.2"
|
||||
checksum: f16ba035fb65d1cbe7d2e06693dd42183c46bc8456713d9ddb5182d067defa7d78217edab0a2d3e173d3bacd627b2bd692195c7087c225b82548fbf52c677b38
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"p-cancelable@npm:^2.0.0":
|
||||
version: 2.1.1
|
||||
resolution: "p-cancelable@npm:2.1.1"
|
||||
|
@ -20638,6 +21063,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-devtools-inline@npm:4.4.0":
|
||||
version: 4.4.0
|
||||
resolution: "react-devtools-inline@npm:4.4.0"
|
||||
dependencies:
|
||||
es6-symbol: "npm:^3"
|
||||
checksum: 316a03bd21eb34f511e74e4e969e6a7d75d299800a4158ff59081457f024dc3aebc0c471938fd7e1c4676823fdcb546ca0d7c2d7ab74e34a9c1bdac31f2284b2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-dom@npm:^18.2.0":
|
||||
version: 18.2.0
|
||||
resolution: "react-dom@npm:18.2.0"
|
||||
|
@ -20697,7 +21131,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-is@npm:^17.0.1":
|
||||
"react-is@npm:^17.0.1, react-is@npm:^17.0.2":
|
||||
version: 17.0.2
|
||||
resolution: "react-is@npm:17.0.2"
|
||||
checksum: 73b36281e58eeb27c9cc6031301b6ae19ecdc9f18ae2d518bdb39b0ac564e65c5779405d623f1df9abf378a13858b79442480244bd579968afc1faf9a2ce5e05
|
||||
|
@ -22421,6 +22855,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"static-browser-server@npm:1.0.3":
|
||||
version: 1.0.3
|
||||
resolution: "static-browser-server@npm:1.0.3"
|
||||
dependencies:
|
||||
"@open-draft/deferred-promise": "npm:^2.1.0"
|
||||
dotenv: "npm:^16.0.3"
|
||||
mime-db: "npm:^1.52.0"
|
||||
outvariant: "npm:^1.3.0"
|
||||
checksum: d047c6c8a667a054db23c3d9770cf5e9d558694f052be81886f606ccc1c6dab034eb1fc5b35d1e3bf23a8dc6ca6f9cd7e4349bfb7b5cad1c2af13058c32dea86
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"statuses@npm:2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "statuses@npm:2.0.1"
|
||||
|
@ -22494,6 +22940,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strict-event-emitter@npm:^0.4.3":
|
||||
version: 0.4.6
|
||||
resolution: "strict-event-emitter@npm:0.4.6"
|
||||
checksum: abdbf59b6c45b599cc2f227fa473765d1510d155ebd22533e8ecb06110dfacb2ff07aece7fd528dde2b4f9e379d60f2687eee8af3fa2877c3ed88ee5b7ed2707
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"string-argv@npm:0.3.2, string-argv@npm:~0.3.1":
|
||||
version: 0.3.2
|
||||
resolution: "string-argv@npm:0.3.2"
|
||||
|
@ -22759,6 +23212,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"style-mod@npm:^4.0.0, style-mod@npm:^4.1.0":
|
||||
version: 4.1.0
|
||||
resolution: "style-mod@npm:4.1.0"
|
||||
checksum: e0bf199d699f15d382c31ae7f18b1508f426b35346002dd1b9072db2cd32fdb0ba3ce7a4629e2fa867a79ffe4830ebf11cb9bce6500815f6a0534fac763e94f4
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"style-to-object@npm:^0.4.1":
|
||||
version: 0.4.4
|
||||
resolution: "style-to-object@npm:0.4.4"
|
||||
|
@ -23585,6 +24045,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type@npm:^1.0.1":
|
||||
version: 1.2.0
|
||||
resolution: "type@npm:1.2.0"
|
||||
checksum: b4d4b27d1926028be45fc5baaca205896e2a1fe9e5d24dc892046256efbe88de6acd0149e7353cd24dad596e1483e48ec60b0912aa47ca078d68cdd198b09885
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"type@npm:^2.7.2":
|
||||
version: 2.7.2
|
||||
resolution: "type@npm:2.7.2"
|
||||
checksum: 602f1b369fba60687fa4d0af6fcfb814075bcaf9ed3a87637fb384d9ff849e2ad15bc244a431f341374562e51a76c159527ffdb1f1f24b0f1f988f35a301c41d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typed-array-buffer@npm:^1.0.0":
|
||||
version: 1.0.0
|
||||
resolution: "typed-array-buffer@npm:1.0.0"
|
||||
|
@ -24601,6 +25075,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"w3c-keyname@npm:^2.2.4":
|
||||
version: 2.2.8
|
||||
resolution: "w3c-keyname@npm:2.2.8"
|
||||
checksum: 95bafa4c04fa2f685a86ca1000069c1ec43ace1f8776c10f226a73296caeddd83f893db885c2c220ebeb6c52d424e3b54d7c0c1e963bbf204038ff1a944fbb07
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"w3c-xmlserializer@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "w3c-xmlserializer@npm:4.0.0"
|
||||
|
|
Loading…
Reference in a new issue