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
88 lines
2.3 KiB
TypeScript
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,
|
|
}
|
|
}
|