From 6de5fc7ab3685edb581281ff75e07adc127b6784 Mon Sep 17 00:00:00 2001 From: Carson Date: Thu, 27 Mar 2025 13:25:29 -0500 Subject: [PATCH 1/3] fix(MarkdownStream): width and height are now respected; set a maximum width of 680px with auto margins --- js/markdown-stream/markdown-stream.scss | 4 ++++ shiny/ui/_markdown_stream.py | 3 ++- shiny/www/py-shiny/markdown-stream/markdown-stream.css | 2 +- shiny/www/py-shiny/markdown-stream/markdown-stream.css.map | 4 ++-- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/js/markdown-stream/markdown-stream.scss b/js/markdown-stream/markdown-stream.scss index 687c58f7b..7d03469f6 100644 --- a/js/markdown-stream/markdown-stream.scss +++ b/js/markdown-stream/markdown-stream.scss @@ -6,6 +6,10 @@ @include highlight_styles.atom_one_dark; } +shiny-markdown-stream { + display: block; +} + /* Styling for the code-copy button (inspired by Quarto's code-copy feature) */ diff --git a/shiny/ui/_markdown_stream.py b/shiny/ui/_markdown_stream.py index d7d5d26ff..5b689509a 100644 --- a/shiny/ui/_markdown_stream.py +++ b/shiny/ui/_markdown_stream.py @@ -320,7 +320,7 @@ def output_markdown_stream( content: TagChild = "", content_type: StreamingContentType = "markdown", auto_scroll: bool = True, - width: CssUnit = "100%", + width: CssUnit = "min(680px, 100%)", height: CssUnit = "auto", ) -> Tag: """ @@ -369,6 +369,7 @@ def output_markdown_stream( "style": css( width=as_css_unit(width), height=as_css_unit(height), + margin="0 auto", ), "content-type": content_type, "auto-scroll": "" if auto_scroll else None, diff --git a/shiny/www/py-shiny/markdown-stream/markdown-stream.css b/shiny/www/py-shiny/markdown-stream/markdown-stream.css index 2baaa6a20..00155edb2 100644 --- a/shiny/www/py-shiny/markdown-stream/markdown-stream.css +++ b/shiny/www/py-shiny/markdown-stream/markdown-stream.css @@ -1,2 +1,2 @@ -pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}pre:has(> code.hljs){color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-formula{color:#a626a4}.hljs-section,.hljs-name,.hljs-selector-tag,.hljs-deletion,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-string,.hljs-regexp,.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string{color:#50a14f}.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-type,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-number{color:#986801}.hljs-symbol,.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-title.class_,.hljs-class .hljs-title{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}[data-bs-theme=dark] pre code.hljs{display:block;overflow-x:auto;padding:1em}[data-bs-theme=dark] code.hljs{padding:3px 5px}[data-bs-theme=dark] pre:has(> code.hljs){color:#abb2bf;background:#282c34}[data-bs-theme=dark] .hljs-comment,[data-bs-theme=dark] .hljs-quote{color:#5c6370;font-style:italic}[data-bs-theme=dark] .hljs-doctag,[data-bs-theme=dark] .hljs-keyword,[data-bs-theme=dark] .hljs-formula{color:#c678dd}[data-bs-theme=dark] .hljs-section,[data-bs-theme=dark] .hljs-name,[data-bs-theme=dark] .hljs-selector-tag,[data-bs-theme=dark] .hljs-deletion,[data-bs-theme=dark] .hljs-subst{color:#e06c75}[data-bs-theme=dark] .hljs-literal{color:#56b6c2}[data-bs-theme=dark] .hljs-string,[data-bs-theme=dark] .hljs-regexp,[data-bs-theme=dark] .hljs-addition,[data-bs-theme=dark] .hljs-attribute,[data-bs-theme=dark] .hljs-meta .hljs-string{color:#98c379}[data-bs-theme=dark] .hljs-attr,[data-bs-theme=dark] .hljs-variable,[data-bs-theme=dark] .hljs-template-variable,[data-bs-theme=dark] .hljs-type,[data-bs-theme=dark] .hljs-selector-class,[data-bs-theme=dark] .hljs-selector-attr,[data-bs-theme=dark] .hljs-selector-pseudo,[data-bs-theme=dark] .hljs-number{color:#d19a66}[data-bs-theme=dark] .hljs-symbol,[data-bs-theme=dark] .hljs-bullet,[data-bs-theme=dark] .hljs-link,[data-bs-theme=dark] .hljs-meta,[data-bs-theme=dark] .hljs-selector-id,[data-bs-theme=dark] .hljs-title{color:#61aeee}[data-bs-theme=dark] .hljs-built_in,[data-bs-theme=dark] .hljs-title.class_,[data-bs-theme=dark] .hljs-class .hljs-title{color:#e6c07b}[data-bs-theme=dark] .hljs-emphasis{font-style:italic}[data-bs-theme=dark] .hljs-strong{font-weight:700}[data-bs-theme=dark] .hljs-link{text-decoration:underline}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}.code-copy-button>.bi{display:flex;gap:.25em}.code-copy-button>.bi:after{content:"";display:block;height:1rem;width:1rem;mask-image:url('data:image/svg+xml,');background-color:var(--bs-body-color, #222)}.code-copy-button-checked>.bi:before{content:"Copied!";font-size:.75em;vertical-align:.25em}.code-copy-button-checked>.bi:after{mask-image:url('data:image/svg+xml,');background-color:var(--bs-success, #198754)}@keyframes markdown-stream-dot-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(.4);opacity:.4}to{transform:scale(1);opacity:1}}.markdown-stream-dot{animation:markdown-stream-dot-pulse 1.75s infinite cubic-bezier(.18,.89,.32,1.28);animation-delay:.25s;display:inline-block;transform-origin:center} +pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}pre:has(> code.hljs){color:#383a42;background:#fafafa}.hljs-comment,.hljs-quote{color:#a0a1a7;font-style:italic}.hljs-doctag,.hljs-keyword,.hljs-formula{color:#a626a4}.hljs-section,.hljs-name,.hljs-selector-tag,.hljs-deletion,.hljs-subst{color:#e45649}.hljs-literal{color:#0184bb}.hljs-string,.hljs-regexp,.hljs-addition,.hljs-attribute,.hljs-meta .hljs-string{color:#50a14f}.hljs-attr,.hljs-variable,.hljs-template-variable,.hljs-type,.hljs-selector-class,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-number{color:#986801}.hljs-symbol,.hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-title{color:#4078f2}.hljs-built_in,.hljs-title.class_,.hljs-class .hljs-title{color:#c18401}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.hljs-link{text-decoration:underline}[data-bs-theme=dark] pre code.hljs{display:block;overflow-x:auto;padding:1em}[data-bs-theme=dark] code.hljs{padding:3px 5px}[data-bs-theme=dark] pre:has(> code.hljs){color:#abb2bf;background:#282c34}[data-bs-theme=dark] .hljs-comment,[data-bs-theme=dark] .hljs-quote{color:#5c6370;font-style:italic}[data-bs-theme=dark] .hljs-doctag,[data-bs-theme=dark] .hljs-keyword,[data-bs-theme=dark] .hljs-formula{color:#c678dd}[data-bs-theme=dark] .hljs-section,[data-bs-theme=dark] .hljs-name,[data-bs-theme=dark] .hljs-selector-tag,[data-bs-theme=dark] .hljs-deletion,[data-bs-theme=dark] .hljs-subst{color:#e06c75}[data-bs-theme=dark] .hljs-literal{color:#56b6c2}[data-bs-theme=dark] .hljs-string,[data-bs-theme=dark] .hljs-regexp,[data-bs-theme=dark] .hljs-addition,[data-bs-theme=dark] .hljs-attribute,[data-bs-theme=dark] .hljs-meta .hljs-string{color:#98c379}[data-bs-theme=dark] .hljs-attr,[data-bs-theme=dark] .hljs-variable,[data-bs-theme=dark] .hljs-template-variable,[data-bs-theme=dark] .hljs-type,[data-bs-theme=dark] .hljs-selector-class,[data-bs-theme=dark] .hljs-selector-attr,[data-bs-theme=dark] .hljs-selector-pseudo,[data-bs-theme=dark] .hljs-number{color:#d19a66}[data-bs-theme=dark] .hljs-symbol,[data-bs-theme=dark] .hljs-bullet,[data-bs-theme=dark] .hljs-link,[data-bs-theme=dark] .hljs-meta,[data-bs-theme=dark] .hljs-selector-id,[data-bs-theme=dark] .hljs-title{color:#61aeee}[data-bs-theme=dark] .hljs-built_in,[data-bs-theme=dark] .hljs-title.class_,[data-bs-theme=dark] .hljs-class .hljs-title{color:#e6c07b}[data-bs-theme=dark] .hljs-emphasis{font-style:italic}[data-bs-theme=dark] .hljs-strong{font-weight:700}[data-bs-theme=dark] .hljs-link{text-decoration:underline}shiny-markdown-stream{display:block}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}.code-copy-button>.bi{display:flex;gap:.25em}.code-copy-button>.bi:after{content:"";display:block;height:1rem;width:1rem;mask-image:url('data:image/svg+xml,');background-color:var(--bs-body-color, #222)}.code-copy-button-checked>.bi:before{content:"Copied!";font-size:.75em;vertical-align:.25em}.code-copy-button-checked>.bi:after{mask-image:url('data:image/svg+xml,');background-color:var(--bs-success, #198754)}@keyframes markdown-stream-dot-pulse{0%{transform:scale(1);opacity:1}50%{transform:scale(.4);opacity:.4}to{transform:scale(1);opacity:1}}.markdown-stream-dot{animation:markdown-stream-dot-pulse 1.75s infinite cubic-bezier(.18,.89,.32,1.28);animation-delay:.25s;display:inline-block;transform-origin:center} /*# sourceMappingURL=markdown-stream.css.map */ diff --git a/shiny/www/py-shiny/markdown-stream/markdown-stream.css.map b/shiny/www/py-shiny/markdown-stream/markdown-stream.css.map index 6d037d635..c1365aca5 100644 --- a/shiny/www/py-shiny/markdown-stream/markdown-stream.css.map +++ b/shiny/www/py-shiny/markdown-stream/markdown-stream.css.map @@ -1,7 +1,7 @@ { "version": 3, "sources": ["../../../../js/markdown-stream/markdown-stream.scss"], - "sourcesContent": ["/************************************************************\n From ../node_modules/highlight.js/styles/atom-one-light.css\n with minor adjustments\n************************************************************/\n/************************************************************\n From ../node_modules/highlight.js/styles/atom-one-dark.css\n with minor adjustments\n************************************************************/\n/* Code highlighting (for both light and dark mode) */\npre code.hljs {\n display: block;\n overflow-x: auto;\n padding: 1em;\n}\n\ncode.hljs {\n padding: 3px 5px;\n}\n\n/*\n\nAtom One Light by Daniel Gamage\nOriginal One Light Syntax theme from https://github.com/atom/one-light-syntax\n\nbase: #fafafa\nmono-1: #383a42\nmono-2: #686b77\nmono-3: #a0a1a7\nhue-1: #0184bb\nhue-2: #4078f2\nhue-3: #a626a4\nhue-4: #50a14f\nhue-5: #e45649\nhue-5-2: #c91243\nhue-6: #986801\nhue-6-2: #c18401\n\n*/\npre:has(> code.hljs) {\n color: #383a42;\n background: #fafafa;\n}\n\n.hljs-comment,\n.hljs-quote {\n color: #a0a1a7;\n font-style: italic;\n}\n\n.hljs-doctag,\n.hljs-keyword,\n.hljs-formula {\n color: #a626a4;\n}\n\n.hljs-section,\n.hljs-name,\n.hljs-selector-tag,\n.hljs-deletion,\n.hljs-subst {\n color: #e45649;\n}\n\n.hljs-literal {\n color: #0184bb;\n}\n\n.hljs-string,\n.hljs-regexp,\n.hljs-addition,\n.hljs-attribute,\n.hljs-meta .hljs-string {\n color: #50a14f;\n}\n\n.hljs-attr,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-type,\n.hljs-selector-class,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-number {\n color: #986801;\n}\n\n.hljs-symbol,\n.hljs-bullet,\n.hljs-link,\n.hljs-meta,\n.hljs-selector-id,\n.hljs-title {\n color: #4078f2;\n}\n\n.hljs-built_in,\n.hljs-title.class_,\n.hljs-class .hljs-title {\n color: #c18401;\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n\n.hljs-link {\n text-decoration: underline;\n}\n\n[data-bs-theme=dark] {\n /*\n\n Atom One Dark by Daniel Gamage\n Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax\n\n base: #282c34\n mono-1: #abb2bf\n mono-2: #818896\n mono-3: #5c6370\n hue-1: #56b6c2\n hue-2: #61aeee\n hue-3: #c678dd\n hue-4: #98c379\n hue-5: #e06c75\n hue-5-2: #be5046\n hue-6: #d19a66\n hue-6-2: #e6c07b\n\n */\n}\n[data-bs-theme=dark] pre code.hljs {\n display: block;\n overflow-x: auto;\n padding: 1em;\n}\n[data-bs-theme=dark] code.hljs {\n padding: 3px 5px;\n}\n[data-bs-theme=dark] pre:has(> code.hljs) {\n color: #abb2bf;\n background: #282c34;\n}\n[data-bs-theme=dark] .hljs-comment,\n[data-bs-theme=dark] .hljs-quote {\n color: #5c6370;\n font-style: italic;\n}\n[data-bs-theme=dark] .hljs-doctag,\n[data-bs-theme=dark] .hljs-keyword,\n[data-bs-theme=dark] .hljs-formula {\n color: #c678dd;\n}\n[data-bs-theme=dark] .hljs-section,\n[data-bs-theme=dark] .hljs-name,\n[data-bs-theme=dark] .hljs-selector-tag,\n[data-bs-theme=dark] .hljs-deletion,\n[data-bs-theme=dark] .hljs-subst {\n color: #e06c75;\n}\n[data-bs-theme=dark] .hljs-literal {\n color: #56b6c2;\n}\n[data-bs-theme=dark] .hljs-string,\n[data-bs-theme=dark] .hljs-regexp,\n[data-bs-theme=dark] .hljs-addition,\n[data-bs-theme=dark] .hljs-attribute,\n[data-bs-theme=dark] .hljs-meta .hljs-string {\n color: #98c379;\n}\n[data-bs-theme=dark] .hljs-attr,\n[data-bs-theme=dark] .hljs-variable,\n[data-bs-theme=dark] .hljs-template-variable,\n[data-bs-theme=dark] .hljs-type,\n[data-bs-theme=dark] .hljs-selector-class,\n[data-bs-theme=dark] .hljs-selector-attr,\n[data-bs-theme=dark] .hljs-selector-pseudo,\n[data-bs-theme=dark] .hljs-number {\n color: #d19a66;\n}\n[data-bs-theme=dark] .hljs-symbol,\n[data-bs-theme=dark] .hljs-bullet,\n[data-bs-theme=dark] .hljs-link,\n[data-bs-theme=dark] .hljs-meta,\n[data-bs-theme=dark] .hljs-selector-id,\n[data-bs-theme=dark] .hljs-title {\n color: #61aeee;\n}\n[data-bs-theme=dark] .hljs-built_in,\n[data-bs-theme=dark] .hljs-title.class_,\n[data-bs-theme=dark] .hljs-class .hljs-title {\n color: #e6c07b;\n}\n[data-bs-theme=dark] .hljs-emphasis {\n font-style: italic;\n}\n[data-bs-theme=dark] .hljs-strong {\n font-weight: bold;\n}\n[data-bs-theme=dark] .hljs-link {\n text-decoration: underline;\n}\n\n/*\n Styling for the code-copy button (inspired by Quarto's code-copy feature)\n*/\npre:has(.code-copy-button) {\n position: relative;\n}\n\n.code-copy-button {\n position: absolute;\n top: 0;\n right: 0;\n border: 0;\n margin-top: 5px;\n margin-right: 5px;\n background-color: transparent;\n}\n.code-copy-button > .bi {\n display: flex;\n gap: 0.25em;\n}\n.code-copy-button > .bi::after {\n content: \"\";\n display: block;\n height: 1rem;\n width: 1rem;\n mask-image: url('data:image/svg+xml,');\n background-color: var(--bs-body-color, #222);\n}\n\n.code-copy-button-checked > .bi::before {\n content: \"Copied!\";\n font-size: 0.75em;\n vertical-align: 0.25em;\n}\n.code-copy-button-checked > .bi::after {\n mask-image: url('data:image/svg+xml,');\n background-color: var(--bs-success, #198754);\n}\n\n@keyframes markdown-stream-dot-pulse {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 50% {\n transform: scale(0.4);\n opacity: 0.4;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.markdown-stream-dot {\n animation: markdown-stream-dot-pulse 1.75s infinite cubic-bezier(0.18, 0.89, 0.32, 1.28);\n animation-delay: 250ms;\n display: inline-block;\n transform-origin: center;\n}"], - "mappings": "AASA,cACE,cACA,gBAXF,YAeA,UAfA,gBAsCA,qBACE,cACA,mBAGF,0BAEE,cACA,kBAGF,yCAGE,cAGF,uEAKE,cAGF,cACE,cAGF,iFAKE,cAGF,yIAQE,cAGF,8EAME,cAGF,0DAGE,cAGF,eACE,kBAGF,aACE,gBAGF,WACE,0BAwBF,mCACE,cACA,gBAxIF,YA2IA,+BA3IA,gBA8IA,0CACE,cACA,mBAEF,oEAEE,cACA,kBAEF,wGAGE,cAEF,gLAKE,cAEF,mCACE,cAEF,0LAKE,cAEF,iTAQE,cAEF,4MAME,cAEF,yHAGE,cAEF,oCACE,kBAEF,kCACE,gBAEF,gCACE,0BAMF,2BACE,kBAGF,kBACE,kBACA,MACA,QACA,SACA,eACA,iBACA,6BAEF,sBACE,aACA,UAEF,4BACE,WACA,cACA,YACA,WACA,ufACA,4CAGF,qCACE,kBACA,gBACA,qBAEF,oCACE,6RACA,4CAGF,wCAEI,mBACA,cAGA,oBACA,cAGA,mBACA,WAGJ,qBACE,kFACA,qBACA,qBACA", + "sourcesContent": ["/************************************************************\n From ../node_modules/highlight.js/styles/atom-one-light.css\n with minor adjustments\n************************************************************/\n/************************************************************\n From ../node_modules/highlight.js/styles/atom-one-dark.css\n with minor adjustments\n************************************************************/\n/* Code highlighting (for both light and dark mode) */\npre code.hljs {\n display: block;\n overflow-x: auto;\n padding: 1em;\n}\n\ncode.hljs {\n padding: 3px 5px;\n}\n\n/*\n\nAtom One Light by Daniel Gamage\nOriginal One Light Syntax theme from https://github.com/atom/one-light-syntax\n\nbase: #fafafa\nmono-1: #383a42\nmono-2: #686b77\nmono-3: #a0a1a7\nhue-1: #0184bb\nhue-2: #4078f2\nhue-3: #a626a4\nhue-4: #50a14f\nhue-5: #e45649\nhue-5-2: #c91243\nhue-6: #986801\nhue-6-2: #c18401\n\n*/\npre:has(> code.hljs) {\n color: #383a42;\n background: #fafafa;\n}\n\n.hljs-comment,\n.hljs-quote {\n color: #a0a1a7;\n font-style: italic;\n}\n\n.hljs-doctag,\n.hljs-keyword,\n.hljs-formula {\n color: #a626a4;\n}\n\n.hljs-section,\n.hljs-name,\n.hljs-selector-tag,\n.hljs-deletion,\n.hljs-subst {\n color: #e45649;\n}\n\n.hljs-literal {\n color: #0184bb;\n}\n\n.hljs-string,\n.hljs-regexp,\n.hljs-addition,\n.hljs-attribute,\n.hljs-meta .hljs-string {\n color: #50a14f;\n}\n\n.hljs-attr,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-type,\n.hljs-selector-class,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-number {\n color: #986801;\n}\n\n.hljs-symbol,\n.hljs-bullet,\n.hljs-link,\n.hljs-meta,\n.hljs-selector-id,\n.hljs-title {\n color: #4078f2;\n}\n\n.hljs-built_in,\n.hljs-title.class_,\n.hljs-class .hljs-title {\n color: #c18401;\n}\n\n.hljs-emphasis {\n font-style: italic;\n}\n\n.hljs-strong {\n font-weight: bold;\n}\n\n.hljs-link {\n text-decoration: underline;\n}\n\n[data-bs-theme=dark] {\n /*\n\n Atom One Dark by Daniel Gamage\n Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax\n\n base: #282c34\n mono-1: #abb2bf\n mono-2: #818896\n mono-3: #5c6370\n hue-1: #56b6c2\n hue-2: #61aeee\n hue-3: #c678dd\n hue-4: #98c379\n hue-5: #e06c75\n hue-5-2: #be5046\n hue-6: #d19a66\n hue-6-2: #e6c07b\n\n */\n}\n[data-bs-theme=dark] pre code.hljs {\n display: block;\n overflow-x: auto;\n padding: 1em;\n}\n[data-bs-theme=dark] code.hljs {\n padding: 3px 5px;\n}\n[data-bs-theme=dark] pre:has(> code.hljs) {\n color: #abb2bf;\n background: #282c34;\n}\n[data-bs-theme=dark] .hljs-comment,\n[data-bs-theme=dark] .hljs-quote {\n color: #5c6370;\n font-style: italic;\n}\n[data-bs-theme=dark] .hljs-doctag,\n[data-bs-theme=dark] .hljs-keyword,\n[data-bs-theme=dark] .hljs-formula {\n color: #c678dd;\n}\n[data-bs-theme=dark] .hljs-section,\n[data-bs-theme=dark] .hljs-name,\n[data-bs-theme=dark] .hljs-selector-tag,\n[data-bs-theme=dark] .hljs-deletion,\n[data-bs-theme=dark] .hljs-subst {\n color: #e06c75;\n}\n[data-bs-theme=dark] .hljs-literal {\n color: #56b6c2;\n}\n[data-bs-theme=dark] .hljs-string,\n[data-bs-theme=dark] .hljs-regexp,\n[data-bs-theme=dark] .hljs-addition,\n[data-bs-theme=dark] .hljs-attribute,\n[data-bs-theme=dark] .hljs-meta .hljs-string {\n color: #98c379;\n}\n[data-bs-theme=dark] .hljs-attr,\n[data-bs-theme=dark] .hljs-variable,\n[data-bs-theme=dark] .hljs-template-variable,\n[data-bs-theme=dark] .hljs-type,\n[data-bs-theme=dark] .hljs-selector-class,\n[data-bs-theme=dark] .hljs-selector-attr,\n[data-bs-theme=dark] .hljs-selector-pseudo,\n[data-bs-theme=dark] .hljs-number {\n color: #d19a66;\n}\n[data-bs-theme=dark] .hljs-symbol,\n[data-bs-theme=dark] .hljs-bullet,\n[data-bs-theme=dark] .hljs-link,\n[data-bs-theme=dark] .hljs-meta,\n[data-bs-theme=dark] .hljs-selector-id,\n[data-bs-theme=dark] .hljs-title {\n color: #61aeee;\n}\n[data-bs-theme=dark] .hljs-built_in,\n[data-bs-theme=dark] .hljs-title.class_,\n[data-bs-theme=dark] .hljs-class .hljs-title {\n color: #e6c07b;\n}\n[data-bs-theme=dark] .hljs-emphasis {\n font-style: italic;\n}\n[data-bs-theme=dark] .hljs-strong {\n font-weight: bold;\n}\n[data-bs-theme=dark] .hljs-link {\n text-decoration: underline;\n}\n\nshiny-markdown-stream {\n display: block;\n}\n\n/*\n Styling for the code-copy button (inspired by Quarto's code-copy feature)\n*/\npre:has(.code-copy-button) {\n position: relative;\n}\n\n.code-copy-button {\n position: absolute;\n top: 0;\n right: 0;\n border: 0;\n margin-top: 5px;\n margin-right: 5px;\n background-color: transparent;\n}\n.code-copy-button > .bi {\n display: flex;\n gap: 0.25em;\n}\n.code-copy-button > .bi::after {\n content: \"\";\n display: block;\n height: 1rem;\n width: 1rem;\n mask-image: url('data:image/svg+xml,');\n background-color: var(--bs-body-color, #222);\n}\n\n.code-copy-button-checked > .bi::before {\n content: \"Copied!\";\n font-size: 0.75em;\n vertical-align: 0.25em;\n}\n.code-copy-button-checked > .bi::after {\n mask-image: url('data:image/svg+xml,');\n background-color: var(--bs-success, #198754);\n}\n\n@keyframes markdown-stream-dot-pulse {\n 0% {\n transform: scale(1);\n opacity: 1;\n }\n 50% {\n transform: scale(0.4);\n opacity: 0.4;\n }\n 100% {\n transform: scale(1);\n opacity: 1;\n }\n}\n.markdown-stream-dot {\n animation: markdown-stream-dot-pulse 1.75s infinite cubic-bezier(0.18, 0.89, 0.32, 1.28);\n animation-delay: 250ms;\n display: inline-block;\n transform-origin: center;\n}"], + "mappings": "AASA,cACE,cACA,gBAXF,YAeA,UAfA,gBAsCA,qBACE,cACA,mBAGF,0BAEE,cACA,kBAGF,yCAGE,cAGF,uEAKE,cAGF,cACE,cAGF,iFAKE,cAGF,yIAQE,cAGF,8EAME,cAGF,0DAGE,cAGF,eACE,kBAGF,aACE,gBAGF,WACE,0BAwBF,mCACE,cACA,gBAxIF,YA2IA,+BA3IA,gBA8IA,0CACE,cACA,mBAEF,oEAEE,cACA,kBAEF,wGAGE,cAEF,gLAKE,cAEF,mCACE,cAEF,0LAKE,cAEF,iTAQE,cAEF,4MAME,cAEF,yHAGE,cAEF,oCACE,kBAEF,kCACE,gBAEF,gCACE,0BAGF,sBACE,cAMF,2BACE,kBAGF,kBACE,kBACA,MACA,QACA,SACA,eACA,iBACA,6BAEF,sBACE,aACA,UAEF,4BACE,WACA,cACA,YACA,WACA,ufACA,4CAGF,qCACE,kBACA,gBACA,qBAEF,oCACE,6RACA,4CAGF,wCAEI,mBACA,cAGA,oBACA,cAGA,mBACA,WAGJ,qBACE,kFACA,qBACA,qBACA", "names": [] } From c6a90117d601a723a6aa06672b507629099d0772 Mon Sep 17 00:00:00 2001 From: Carson Date: Thu, 27 Mar 2025 13:39:37 -0500 Subject: [PATCH 2/3] Missed a default --- shiny/ui/_markdown_stream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shiny/ui/_markdown_stream.py b/shiny/ui/_markdown_stream.py index 5b689509a..c9fa1864c 100644 --- a/shiny/ui/_markdown_stream.py +++ b/shiny/ui/_markdown_stream.py @@ -271,7 +271,7 @@ def ui( content: TagChild = "", content_type: StreamingContentType = "markdown", auto_scroll: bool = True, - width: CssUnit = "100%", + width: CssUnit = "min(680px, 100%)", height: CssUnit = "auto", ) -> Tag: """ From 41ef78f965f91408e38f04bfc60a23809e964d7b Mon Sep 17 00:00:00 2001 From: Carson Date: Thu, 27 Mar 2025 13:43:12 -0500 Subject: [PATCH 3/3] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 56774871f..9634d44ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * The `.get_latest_stream_result()` method on `ui.MarkdownStream()` was deprecated in favor of the new `.latest_stream` property. Call `.result()` on the property to get the latest result, `.status` to check the status, and `.cancel()` to cancel the stream. +* `MarkdownStream()` now has a default maximum width of `680px` for better readability. Also, similar to `Chat()`, it now also horizontally centers itself. (#1944) + * `ui.page_navbar()` and `ui.navset_bar()` now correctly apply `theme` and additional attributes from `navbar_options` created with `ui.navbar_options()`. (#1942) ### Bug fixes @@ -28,6 +30,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed an issue where the `.update_user_input()` method on `ui.Chat()` isn't working in shinylive. (#1891) +* Fixed an issue where `width` and `height` on `MarkdownStream()` were not working as intended. (#1944) + * Fixed an issue with the `.click()` method on InputActionButton controllers in `shiny.playwright.controllers` where the method would not work as expected. (#1886) ## [1.3.0] - 2025-03-03