Skip to content

QuadnucYard/ourchat-typ

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

27 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Ourchat

Universe

GitHub

Create chat interfaces in Typst with ease

Ourchat is a Typst package for building chat UI mockups. It helps you document software features, create presentations, or prototype chat interfaces with themes for popular platforms like WeChat, Discord, and QQ.

typst-frame

#let yau = wechat.default-user(name: [ไธ˜ๆˆๆก๏ผˆๅ›ฏๅ…ง๏ผ‰]) #wechat.chat( theme: "dark", ..oc.with-side-user( left, yau, oc.time[5ๆœˆ16ๆ—ฅ ไธŠๅˆ10:23], oc.free-message[ ๅทฒ็ถ“ๅˆฐไบ†็„กๆฅ็š„ๅœฐๆญฅใ€‚ ], oc.time[6ๆœˆ18ๆ—ฅ ๅ‡Œๆ™จ00:06], oc.free-message[ ๆˆ‘ๅฎฃๅธƒไป–ๅทฒ็ถ“ไธๆ˜ฏๆˆ‘็š„ๅญธ็”Ÿไบ† ], oc.time[14:00], oc.free-message[ ้€™็จฎๆˆ็ธพ๏ผŒไฝฟไบบๆฑ—้ก๏ผๅฆ‚ๆญคๆˆ็ธพ๏ผŒๅฆ‚ไฝ•ๆ‹›็”Ÿ๏ผŸ ], ), oc.message(right, yau)[ ๆˆ‘ๆฒ’ๆœ‰่ชฌ้Ž้€™็จฎ่ฉฑ๏ผ โ€”โ€”็™ผ่‡ชๆˆ‘็š„ๆ‰‹ๆฉŸ ], )

Features

  • Out-of-the-box themes: WeChat, Discord, QQNT theme support
  • Simple API: Easy-to-use, declarative interface
  • Customizable styling: Colors, avatars, layouts, and typography
  • Just do it: Write anything inside messagesโ€”Code blocks, tables, mathematical equationsโ€ฆ

Quick Start

First, import the package in your Typst document:

#import "@preview/ourchat:0.2.1" as oc #import oc.themes: *

Then create your first chat:

#let alice = wechat.user(name: [Alice], avatar: circle(fill: blue, text(white)[A])) #let bob = wechat.user(name: [Bob], avatar: circle(fill: green, text(white)[B])) #wechat.chat( oc.time[Today 14:30], oc.message(left, alice)[ Hey! How's the new project going? ], oc.message(right, bob)[ Great! Just finished the API integration. The performance improvements are impressive! ๐Ÿš€ ], )

typst-frame

Builtin Themes

WeChat Theme

#let user1 = wechat.user(name: [Alice], avatar: circle(fill: blue, text(white)[A])) #let user2 = wechat.user(name: [Bob], avatar: circle(fill: green, text(white)[B])) #wechat.chat( theme: "light", // or "dark" layout: ( bubble-radius: 8pt, ), width: 400pt, oc.time[Monday 9:00 AM], oc.message(left, user1)[Hello world!], oc.message(right, user2)[Hi there! ๐Ÿ‘‹], )

typst-frame

Discord Theme

#set text(font: ("gg sans", "IBM Plex Sans SC")) #let developer = discord.user( name: [Dev], avatar: circle(fill: purple, text(white)[D]) ) #let admin = discord.user( name: [Admin], avatar: circle(fill: red, text(white)[A]) ) #discord.chat( oc.time[Today at 2:14 PM], oc.message(left, developer)[ ```python def optimize_query():  return cache_strategy.redis_cluster() ``` What do you think about this approach? @admin ], oc.message(right, admin)[ @developer Looks good! The Redis cluster should handle the load well. ], )

typst-frame

QQNT Theme

#let student = qqnt.user( name: [Student], avatar: circle(fill: orange, text(white)[S]) ) #let expert = qqnt.user( name: [Expert], avatar: circle(fill: teal, text(white)[E]) ) #qqnt.chat( theme: ( inherit: "light", bubble-left: rgb("#F0F8FF"), bubble-right: rgb("#E8F5E8"), text-right: rgb("#111111"), ), oc.message(left, student)[ Can someone explain Rust ownership? ], oc.message(right, expert)[ Sure! Ownership prevents data races at compile time... ], )

typst-frame

Advanced Usage

Convenience Functions

For multiple messages from the same user, use with-side-user to avoid repetition:

#set text(font: ("gg sans", "IBM Plex Sans SC")) #let admin = oc.user( name: [System Admin], avatar: circle(fill: red.darken(20%), text(white, weight: "bold")[โšก]) ) #discord.chat( oc.time[Today at 3:45 PM], // Instead of repeating the user for each message: // oc.message(left, admin)[Server maintenance scheduled], // oc.message(left, admin)[Downtime: 30 minutes max], // oc.message(left, admin)[Please save your work], // Use with-side-user for cleaner code: ..oc.with-side-user( left, admin, oc.free-message[๐Ÿšจ *URGENT: Server Maintenance Alert*], oc.free-message[Scheduled downtime: Tonight 11 PM - 11:30 PM], oc.free-message[All services will be temporarily unavailable], oc.free-message[Please save your work and plan accordingly], ), )

typst-frame

Custom User Avatars

Create distinctive user profiles:

#let ceo = oc.user( name: [Sarah Chen], badge: qqnt.badge(text-color: purple, bg-color: purple.transparentize(80%))[#text(stroke: 0.05em + purple)[CEO]], avatar: rect( fill: blue.darken(20%), radius: 4pt, inset: 6pt, text(white, weight: "bold")[SC] ) ) #qqnt.chat( oc.message(left, ceo)[ Hi team! Ready for the quarterly review? ], )

typst-frame

Rich Content Support

Include tables, code blocks, and visual elements:

#let analyst = wechat.user( name: [Data Analyst], avatar: circle(fill: green.darken(10%), text(white)[๐Ÿ“Š]) ) #wechat.chat( oc.message(left, analyst)[ Here's our performance analysis: #table( columns: (auto, auto, auto), [*Metric*], [*Before*], [*After*], [Response Time], [250ms], [120ms], [Throughput], [1000 RPS], [2500 RPS], ) The optimization yielded 58% improvement! ๐Ÿ“Š ] )

typst-frame

Theme Customization

Modify existing themes or create your own:

#let custom_theme = ( inherit: "light", background: rgb("#F5F5F5"), bubble-left: rgb("#E3F2FD"), bubble-right: rgb("#C8E6C9"), text-primary: rgb("#212121"), text-secondary: rgb("#757575"), ) #wechat.chat(theme: custom_theme, ...)

Layout Control

Fine-tune spacing and dimensions:

#wechat.chat( layout: ( content-width: 350pt, message-spacing: 0.8em, avatar-size: 32pt, bubble-padding: 12pt, ), ... )

Examples Gallery

Explore our comprehensive example collection: https://quadnucyard.github.io/ourchat-typ

The source codes for these example are located at ./examples.

Architecture & Design

API Design Philosophy

Ourchat follows a unified component architecture where oc provides the core building blocks:

  • oc.message(), oc.user(), oc.time() - Universal components that work across all themes
  • Built-in themes (wechat, discord, qqnt) import all common components but may override them for platform-specific features
    • For example, qqnt.user() extends the base user component with badge support for role badges
  • Uses chat as the rendering function of messages, which is defined in individual themes. Styling is decided here.
// Universal approach - works with any theme #let user = oc.user(name: [Alice]) // Theme-specific approach - leverages extended features #let qqnt_user = qqnt.user( name: [Alice], badge: qqnt.badge()[Admin] // QQNT specific feature )

Theme Customization Scope

Built-in themes provide a solid foundation but donโ€™t cover every possible customization. Youโ€™re encouraged to:

  • Extend existing themes for minor modifications using theme and layout parameters.
  • Create entirely new themes for different platforms or unique designs with basic blocks. Refer to the source code of built-in themes as implementation guides

API Reference

Here only lists exported functions and variables. Please refer to the documentation comments of each function for details

Common Components

  • oc.user(name, avatar, badge): Create universal user profiles
  • oc.message(side, user, body, time, merge): Add chat messages (left or right)
  • oc.time(body): Insert timestamp dividers
  • oc.with-side-user(side, user, ..messages): Convenience for multiple messages from same user
  • oc.free-message(body, time, merge): Create message without specific user or side
  • oc.plain(side, user, body): Create plain item without padding

Note: These are just helper functions for data wrapping. You can directly create data structures if you like.

Theme Collections

oc.themes.wechat

WeChat layout and color schemes (light, dark)

  • wechat.chat(theme, layout, width, validate, ..messages): WeChat-style interface
  • wechat.default-user: Pre-configured user with WeChat avatar

oc.themes.qqnt

QQNT layout and color schemes (light, dark)

  • qqnt.chat(theme, layout, width, validate, ..messages): QQNT-style interface
  • qqnt.user (uses oc.user with badge support): QQNT user with role support
  • qqnt.badge(body, text-color, bg-color): Create role badges

oc.themes.discord

Discord layout and color schemes

  • discord.newbie-user: Pre-configured user with newbie badge
  • discord.mention(body): Create Discord-style mention element
  • discord.chat(theme, layout, width, validate, auto-mention, ..messages): Discord-style interface

Utilities (oc.utils)

  • validate-theme(theme, reference, field-type): Validate theme dictionary fields
  • validate-layout(layout, reference): Validate layout dictionary fields
  • resolve-theme(themes, theme, default, validate): Resolve theme with inheritance support
  • resolve-layout(layout, default-layout, validate): Merge and validate layout settings
  • stretch-cover(item): Scale content to cover its container
  • auto-mention-rule(auto-mention, styler): Create show rule for automatic mention styling

Contributing

We welcome contributions! Please check our GitHub repository for:

  • Bug reports and feature requests
  • Code contributions and improvements
  • Documentation updates
  • New theme proposals and existing theme improvements

License

MIT License - see LICENSE file for details.

About

Forge wonderful chat messages in typst

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors