Skip to content

Commit

Permalink
Add ui.MarkdownStream (#1782)
Browse files Browse the repository at this point in the history
  • Loading branch information
cpsievert authored Feb 3, 2025
1 parent 184a9eb commit a781305
Show file tree
Hide file tree
Showing 30 changed files with 1,228 additions and 304 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### New features

* Added a new `ui.MarkdownStream()` component for performantly streaming in chunks of markdown/html strings into the UI. This component is primarily useful for text-based generative AI where responses are received incrementally. (#1782)

* Added a new `.add_sass_layer_file()` method to `ui.Theme` that supports reading a Sass file with layer boundary comments, e.g. `/*-- scss:defaults --*/`. This format [is supported by Quarto](https://quarto.org/docs/output-formats/html-themes-more.html#bootstrap-bootswatch-layering) and makes it easier to store Sass rules and declarations that need to be woven into Shiny's Sass Bootstrap files. (#1790)

* The `ui.Chat()` component's `.on_user_submit()` decorator method now passes the user input to the decorated function. This makes it a bit more obvious how to access the user input inside the decorated function. See the new templates (mentioned below) for examples. (#1801)
Expand Down
6 changes: 5 additions & 1 deletion docs/_quartodoc-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ quartodoc:
contents:
- ui.Chat
- ui.chat_ui
- title: Streaming markdown
desc: Stream markdown content into the UI
contents:
- ui.MarkdownStream
- ui.output_markdown_stream
- title: Custom UI
desc: Lower-level UI functions for creating custom HTML/CSS/JS
contents:
Expand Down Expand Up @@ -358,4 +363,3 @@ quartodoc:
contents:
- name: experimental.ui.card_image
dynamic: false

4 changes: 4 additions & 0 deletions docs/_quartodoc-express.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ quartodoc:
desc: Build a chatbot interface
contents:
- express.ui.Chat
- title: Streaming markdown
desc: Stream markdown content into the UI
contents:
- express.ui.MarkdownStream
- title: Reactive programming
desc: Create reactive functions and dependencies.
contents:
Expand Down
14 changes: 14 additions & 0 deletions js/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ const opts: Array<BuildOptions> = [
plugins: [sassPlugin({ type: "css", sourceMap: false })],
metafile: true,
},
{
entryPoints: {
"markdown-stream/markdown-stream": "markdown-stream/markdown-stream.ts",
},
minify: true,
sourcemap: true,
},
{
entryPoints: {
"markdown-stream/markdown-stream": "markdown-stream/markdown-stream.scss",
},
plugins: [sassPlugin({ type: "css", sourceMap: false })],
metafile: true,
},
{
entryPoints: {
"chat/chat": "chat/chat.ts",
Expand Down
10 changes: 0 additions & 10 deletions js/chat/_utils.ts

This file was deleted.

54 changes: 1 addition & 53 deletions js/chat/chat.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
@use "highlight_styles" as highlight_styles;

shiny-chat-container {
--shiny-chat-border: var(--bs-border-width, 1px) solid var(--bs-border-color, #e9ecef);
--shiny-chat-user-message-bg: RGBA(var(--bs-primary-rgb, 0, 123, 194), 0.06);
Expand Down Expand Up @@ -39,7 +37,7 @@ shiny-chat-message {
}
}
/* Vertically center the 2nd column (message content) */
.message-content {
shiny-markdown-stream {
align-self: center;
}
}
Expand Down Expand Up @@ -101,53 +99,3 @@ shiny-chat-input {
.shiny-busy:has(shiny-chat-input[disabled])::after {
display: none;
}

/* Code highlighting (for both light and dark mode) */
@include highlight_styles.atom_one_light;
[data-bs-theme="dark"] {
@include highlight_styles.atom_one_dark;
}

/*
Styling for the code-copy button (inspired by Quarto's code-copy feature)
*/
pre:has(.code-copy-button) {
position: relative;
}

.code-copy-button {
position: absolute;
top: 0;
right: 0;
border: 0;
margin-top: 5px;
margin-right: 5px;
background-color: transparent;

> .bi {
display: flex;
gap: 0.25em;

&::after {
content: "";
display: block;
height: 1rem;
width: 1rem;
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M4 1.5H3a2 2 0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1h1a1 1 0 0 1 1 1V14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3.5a1 1 0 0 1 1-1h1v-1z"/><path d="M9.5 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3zm-3-1A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5 0h-3z"/></svg>');
background-color: var(--bs-body-color, #222);
}
}
}

.code-copy-button-checked {
> .bi::before {
content: "Copied!";
font-size: 0.75em;
vertical-align: 0.25em;
}

> .bi::after {
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M13.854 3.646a.5.5 0 0 1 0 .708l-7 7a.5.5 0 0 1-.708 0l-3.5-3.5a.5.5 0 1 1 .708-.708L6.5 10.293l6.646-6.647a.5.5 0 0 1 .708 0z"/></svg>');
background-color: var(--bs-success, #198754);
}
}
Loading

0 comments on commit a781305

Please sign in to comment.