Files
upstream-tldraw/packages/tlschema/src/misc/TLRichText.ts
upstream-mirror a774ac673a
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
2026-09-23 16:12:52 +05:00

88 lines
2.3 KiB
TypeScript

import { T } from '@tldraw/validate'
/**
* Validator for TLRichText objects that ensures they have the correct structure
* for document-based rich text content. Validates a document with a type field
* and an array of content blocks.
*
* @public
* @example
* ```ts
* const richText = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] }] }
* const isValid = richTextValidator.check(richText) // true
* ```
*/
export const richTextValidator = T.object({
type: T.string,
content: T.arrayOf(T.unknown),
attrs: T.any.optional(),
})
/**
* Type representing rich text content in tldraw. Rich text follows a document-based
* structure with a root document containing an array of content blocks (paragraphs,
* text nodes, etc.). This enables formatted text with support for multiple paragraphs,
* styling, and other rich content.
*
* @public
* @example
* ```ts
* const richText: TLRichText = {
* type: 'doc',
* content: [
* {
* type: 'paragraph',
* content: [{ type: 'text', text: 'Hello world!' }]
* }
* ]
* }
* ```
*/
export type TLRichText = T.TypeOf<typeof richTextValidator>
/**
* Converts a plain text string into a TLRichText object. Each line of the input
* text becomes a separate paragraph in the rich text document. Empty lines are
* preserved as empty paragraphs to maintain the original text structure.
*
* @param text - The plain text string to convert to rich text
* @returns A TLRichText object with the text content structured as paragraphs
* @public
* @example
* ```ts
* const richText = toRichText('Hello\nWorld')
* // Returns:
* // {
* // type: 'doc',
* // content: [
* // { type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] },
* // { type: 'paragraph', content: [{ type: 'text', text: 'World' }] }
* // ]
* // }
*
* const emptyLine = toRichText('Line 1\n\nLine 3')
* // Creates three paragraphs, with the middle one being empty
* ```
*/
export function toRichText(text: string): TLRichText {
const lines = text.split('\n')
const content = lines.map((text) => {
if (!text) {
return {
type: 'paragraph',
}
}
return {
type: 'paragraph',
content: [{ type: 'text', text }],
}
})
return {
type: 'doc',
content,
}
}