From 0640c5a70fbc5063a91e61ed9d646c7af316c66b Mon Sep 17 00:00:00 2001 From: MykolaGolubyev Date: Mon, 1 Jun 2026 20:31:08 -0400 Subject: [PATCH 1/3] presentation: fix blockquote and updated paragraph presentation --- znai-reactjs/src/App.css | 2 + .../src/doc-elements/paragraph/Paragraph.css | 12 ++++-- .../src/doc-elements/paragraph/Paragraph.tsx | 7 ++++ .../presentation/Presentation.css | 3 ++ .../doc-elements/presentation/SlidePanel.css | 2 + .../src/doc-elements/quote/BlockQuote.css | 27 +++++++------ .../src/doc-elements/quote/BlockQuote.jsx | 38 ++++++++++--------- .../quote/PresentationBlockQuote.demo.jsx | 35 ++++++++++------- .../src/theme/znai-dark/znai-dark.css | 2 + 9 files changed, 83 insertions(+), 45 deletions(-) diff --git a/znai-reactjs/src/App.css b/znai-reactjs/src/App.css index c75c3270c..572d06247 100644 --- a/znai-reactjs/src/App.css +++ b/znai-reactjs/src/App.css @@ -26,6 +26,8 @@ --znai-zoom-overlay-background-color: rgba(70, 70, 70, 0.9); --znai-zoom-container-border: 1px #000 solid; + --znai-presentation-paragraph-background: linear-gradient(135deg, #eef3fb 0%, #dfe8f6 100%); + /* single column render width to keep content centered it changes its value for mobile and when other content is nested diff --git a/znai-reactjs/src/doc-elements/paragraph/Paragraph.css b/znai-reactjs/src/doc-elements/paragraph/Paragraph.css index 77fe538a0..a37d9fb34 100644 --- a/znai-reactjs/src/doc-elements/paragraph/Paragraph.css +++ b/znai-reactjs/src/doc-elements/paragraph/Paragraph.css @@ -47,8 +47,14 @@ not belong to the same parent node so margins won't even each other out. justify-content: center; } +.presentation .znai-presentation-paragraph-wrapper > *:not(.znai-attention-block) { + max-width: var(--znai-presentation-text-max-width); + font-size: var(--znai-presentation-text-font-size); + overflow-wrap: break-word; +} + .znai-presentation-paragraph-default { - background-color: var(--znai-attention-note-background-color); - border-left: 3px solid var(--znai-attention-note-color); - padding: 16px; + background: var(--znai-presentation-paragraph-background); + padding: 2.5cqw 3cqw; + border-radius: 1.2cqw; } diff --git a/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx b/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx index 3def7cbd6..567a3150c 100644 --- a/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx +++ b/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx @@ -178,6 +178,13 @@ const presentationParagraph = { ? 1 : 0; }, + // plain/forced paragraphs are fixed-font text (not transform-scaled), so the font stays + // consistent and the text wraps into more lines. attention paragraphs (Question:/Note:/...) + // render as attention blocks and are auto-scaled like a standalone attention block, so + // their chrome (icon/label) and any inline code scale uniformly with the slide + slideInfoProvider: ({ content }: { content: DocElementContent }) => ({ + isSlideScaled: allSuffixes.some((suffix) => paragraphStartsWith(content, suffix)), + }), }; function isParagraphPresentationForced(content: DocElementContent) { diff --git a/znai-reactjs/src/doc-elements/presentation/Presentation.css b/znai-reactjs/src/doc-elements/presentation/Presentation.css index 69d3da5e3..e98d5b8ba 100644 --- a/znai-reactjs/src/doc-elements/presentation/Presentation.css +++ b/znai-reactjs/src/doc-elements/presentation/Presentation.css @@ -20,6 +20,9 @@ flex-direction: column; height: 100vh; width: 100vw; + + --znai-presentation-text-font-size: 4cqw; + --znai-presentation-text-max-width: 70cqw; } .presentation .header { diff --git a/znai-reactjs/src/doc-elements/presentation/SlidePanel.css b/znai-reactjs/src/doc-elements/presentation/SlidePanel.css index e096e4d54..8df52b5bb 100644 --- a/znai-reactjs/src/doc-elements/presentation/SlidePanel.css +++ b/znai-reactjs/src/doc-elements/presentation/SlidePanel.css @@ -17,4 +17,6 @@ .znai-presentation-slide-panel { height: 100%; overflow-y: hidden; + + container-type: inline-size; } diff --git a/znai-reactjs/src/doc-elements/quote/BlockQuote.css b/znai-reactjs/src/doc-elements/quote/BlockQuote.css index 63c0fd2eb..a39d1c497 100644 --- a/znai-reactjs/src/doc-elements/quote/BlockQuote.css +++ b/znai-reactjs/src/doc-elements/quote/BlockQuote.css @@ -27,32 +27,37 @@ blockquote { } .presentation blockquote { - max-width: 400px; margin: 0; - font-size: 20px; + max-width: var(--znai-presentation-text-max-width); + font-size: var(--znai-presentation-text-font-size); + padding-left: 4cqw; + overflow-wrap: break-word; +} + +.presentation blockquote .content-block { + max-width: none; } .presentation .znai-presentation-slide-container blockquote { - display: none; + visibility: hidden; } .presentation .znai-presentation-slide-appeared blockquote.no-animation { - display: block; + visibility: visible; } .presentation .znai-presentation-slide-appeared blockquote.animate { - display: block; - animation: blockquote-presentation-appear; - animation-fill-mode:forwards; - animation-duration: 1.5s; + visibility: visible; + animation: blockquote-presentation-appear 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; } @keyframes blockquote-presentation-appear { from { - padding: 10px 20px 10px 120px; - max-width: 500px; + opacity: 0; + transform: translateX(-12%) scale(0.94); } to { - padding: 10px 20px 10px 20px; + opacity: 1; + transform: translateX(0) scale(1); } } \ No newline at end of file diff --git a/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx b/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx index 93de32b78..e918ad5d4 100644 --- a/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx +++ b/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx @@ -15,28 +15,32 @@ * limitations under the License. */ -import React from 'react' +import React from "react"; -import './BlockQuote.css' +import "./BlockQuote.css"; const BlockQuote = (props) => ( -
- -
-) +
+ +
+); const PresentationBlockQuote = (props) => { - const className = props.isPresentationDisplayed ? "no-animation" : "animate"; - return ( -
- -
- ) -} + const className = props.isPresentationDisplayed ? "no-animation" : "animate"; + return ( +
+ +
+ ); +}; const presentationBlockQuoteHandler = { - component: PresentationBlockQuote, - numberOfSlides: () => 1 -} + component: PresentationBlockQuote, + numberOfSlides: () => 1, + // don't transform-scale the quote to fill the slide. instead it renders at a fixed, + // slide-relative size (font-size/max-width in cqw, see BlockQuote.css) so the font + // stays consistent and the text simply wraps into more lines when space is tight + slideInfoProvider: () => ({ isSlideScaled: false }), +}; -export {BlockQuote, presentationBlockQuoteHandler} +export { BlockQuote, presentationBlockQuoteHandler }; diff --git a/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx b/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx index 130823aac..e99b6d59a 100644 --- a/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx +++ b/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2026 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +15,30 @@ * limitations under the License. */ -import {createPresentationDemo} from '../demo-utils/PresentationDemo' +import { createPresentationDemo } from "../demo-utils/PresentationDemo"; export function blockQuotePresentationDemo(registry) { - registry - .add('block quote', createPresentationDemo([{ - type: 'BlockQuote', - content: paragraph() - }])) + registry.add( + "block quote", + createPresentationDemo([ + { + type: "BlockQuote", + content: paragraph(), + }, + ]) + ); } function paragraph() { - return [ + return [ + { + type: "Paragraph", + content: [ { - type: 'Paragraph', - content: [{ - type: 'SimpleText', - text: 'quote text quote text' - }] - } - ] + type: "SimpleText", + text: "quote text quote text. More long text more text for some extra lines and then some more ", + }, + ], + }, + ]; } diff --git a/znai-reactjs/src/theme/znai-dark/znai-dark.css b/znai-reactjs/src/theme/znai-dark/znai-dark.css index a93d6078d..705b1dae0 100644 --- a/znai-reactjs/src/theme/znai-dark/znai-dark.css +++ b/znai-reactjs/src/theme/znai-dark/znai-dark.css @@ -21,6 +21,8 @@ --znai-background-color: #1e2529; + --znai-presentation-paragraph-background: linear-gradient(135deg, #2c3744 0%, #1f272f 100%); + --znai-zoom-overlay-background-color: rgba(10, 10, 10, 0.9); --znai-zoom-container-border: 1px #333 solid; From e39d321f638aa5639fa719944880b6ea593e5a1c Mon Sep 17 00:00:00 2001 From: MykolaGolubyev Date: Mon, 1 Jun 2026 20:31:08 -0400 Subject: [PATCH 2/3] presentation: fix blockquote and updated paragraph presentation --- znai-reactjs/src/App.css | 2 + .../src/doc-elements/paragraph/Paragraph.css | 12 ++++-- .../src/doc-elements/paragraph/Paragraph.tsx | 7 ++++ .../presentation/Presentation.css | 3 ++ .../doc-elements/presentation/SlidePanel.css | 2 + .../src/doc-elements/quote/BlockQuote.css | 27 +++++++------ .../src/doc-elements/quote/BlockQuote.jsx | 38 ++++++++++--------- .../quote/PresentationBlockQuote.demo.jsx | 35 ++++++++++------- .../src/theme/znai-dark/znai-dark.css | 2 + 9 files changed, 83 insertions(+), 45 deletions(-) diff --git a/znai-reactjs/src/App.css b/znai-reactjs/src/App.css index c75c3270c..572d06247 100644 --- a/znai-reactjs/src/App.css +++ b/znai-reactjs/src/App.css @@ -26,6 +26,8 @@ --znai-zoom-overlay-background-color: rgba(70, 70, 70, 0.9); --znai-zoom-container-border: 1px #000 solid; + --znai-presentation-paragraph-background: linear-gradient(135deg, #eef3fb 0%, #dfe8f6 100%); + /* single column render width to keep content centered it changes its value for mobile and when other content is nested diff --git a/znai-reactjs/src/doc-elements/paragraph/Paragraph.css b/znai-reactjs/src/doc-elements/paragraph/Paragraph.css index 77fe538a0..a37d9fb34 100644 --- a/znai-reactjs/src/doc-elements/paragraph/Paragraph.css +++ b/znai-reactjs/src/doc-elements/paragraph/Paragraph.css @@ -47,8 +47,14 @@ not belong to the same parent node so margins won't even each other out. justify-content: center; } +.presentation .znai-presentation-paragraph-wrapper > *:not(.znai-attention-block) { + max-width: var(--znai-presentation-text-max-width); + font-size: var(--znai-presentation-text-font-size); + overflow-wrap: break-word; +} + .znai-presentation-paragraph-default { - background-color: var(--znai-attention-note-background-color); - border-left: 3px solid var(--znai-attention-note-color); - padding: 16px; + background: var(--znai-presentation-paragraph-background); + padding: 2.5cqw 3cqw; + border-radius: 1.2cqw; } diff --git a/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx b/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx index 3def7cbd6..567a3150c 100644 --- a/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx +++ b/znai-reactjs/src/doc-elements/paragraph/Paragraph.tsx @@ -178,6 +178,13 @@ const presentationParagraph = { ? 1 : 0; }, + // plain/forced paragraphs are fixed-font text (not transform-scaled), so the font stays + // consistent and the text wraps into more lines. attention paragraphs (Question:/Note:/...) + // render as attention blocks and are auto-scaled like a standalone attention block, so + // their chrome (icon/label) and any inline code scale uniformly with the slide + slideInfoProvider: ({ content }: { content: DocElementContent }) => ({ + isSlideScaled: allSuffixes.some((suffix) => paragraphStartsWith(content, suffix)), + }), }; function isParagraphPresentationForced(content: DocElementContent) { diff --git a/znai-reactjs/src/doc-elements/presentation/Presentation.css b/znai-reactjs/src/doc-elements/presentation/Presentation.css index 69d3da5e3..e98d5b8ba 100644 --- a/znai-reactjs/src/doc-elements/presentation/Presentation.css +++ b/znai-reactjs/src/doc-elements/presentation/Presentation.css @@ -20,6 +20,9 @@ flex-direction: column; height: 100vh; width: 100vw; + + --znai-presentation-text-font-size: 4cqw; + --znai-presentation-text-max-width: 70cqw; } .presentation .header { diff --git a/znai-reactjs/src/doc-elements/presentation/SlidePanel.css b/znai-reactjs/src/doc-elements/presentation/SlidePanel.css index e096e4d54..8df52b5bb 100644 --- a/znai-reactjs/src/doc-elements/presentation/SlidePanel.css +++ b/znai-reactjs/src/doc-elements/presentation/SlidePanel.css @@ -17,4 +17,6 @@ .znai-presentation-slide-panel { height: 100%; overflow-y: hidden; + + container-type: inline-size; } diff --git a/znai-reactjs/src/doc-elements/quote/BlockQuote.css b/znai-reactjs/src/doc-elements/quote/BlockQuote.css index 63c0fd2eb..a39d1c497 100644 --- a/znai-reactjs/src/doc-elements/quote/BlockQuote.css +++ b/znai-reactjs/src/doc-elements/quote/BlockQuote.css @@ -27,32 +27,37 @@ blockquote { } .presentation blockquote { - max-width: 400px; margin: 0; - font-size: 20px; + max-width: var(--znai-presentation-text-max-width); + font-size: var(--znai-presentation-text-font-size); + padding-left: 4cqw; + overflow-wrap: break-word; +} + +.presentation blockquote .content-block { + max-width: none; } .presentation .znai-presentation-slide-container blockquote { - display: none; + visibility: hidden; } .presentation .znai-presentation-slide-appeared blockquote.no-animation { - display: block; + visibility: visible; } .presentation .znai-presentation-slide-appeared blockquote.animate { - display: block; - animation: blockquote-presentation-appear; - animation-fill-mode:forwards; - animation-duration: 1.5s; + visibility: visible; + animation: blockquote-presentation-appear 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; } @keyframes blockquote-presentation-appear { from { - padding: 10px 20px 10px 120px; - max-width: 500px; + opacity: 0; + transform: translateX(-12%) scale(0.94); } to { - padding: 10px 20px 10px 20px; + opacity: 1; + transform: translateX(0) scale(1); } } \ No newline at end of file diff --git a/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx b/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx index 93de32b78..e918ad5d4 100644 --- a/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx +++ b/znai-reactjs/src/doc-elements/quote/BlockQuote.jsx @@ -15,28 +15,32 @@ * limitations under the License. */ -import React from 'react' +import React from "react"; -import './BlockQuote.css' +import "./BlockQuote.css"; const BlockQuote = (props) => ( -
- -
-) +
+ +
+); const PresentationBlockQuote = (props) => { - const className = props.isPresentationDisplayed ? "no-animation" : "animate"; - return ( -
- -
- ) -} + const className = props.isPresentationDisplayed ? "no-animation" : "animate"; + return ( +
+ +
+ ); +}; const presentationBlockQuoteHandler = { - component: PresentationBlockQuote, - numberOfSlides: () => 1 -} + component: PresentationBlockQuote, + numberOfSlides: () => 1, + // don't transform-scale the quote to fill the slide. instead it renders at a fixed, + // slide-relative size (font-size/max-width in cqw, see BlockQuote.css) so the font + // stays consistent and the text simply wraps into more lines when space is tight + slideInfoProvider: () => ({ isSlideScaled: false }), +}; -export {BlockQuote, presentationBlockQuoteHandler} +export { BlockQuote, presentationBlockQuoteHandler }; diff --git a/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx b/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx index 130823aac..e99b6d59a 100644 --- a/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx +++ b/znai-reactjs/src/doc-elements/quote/PresentationBlockQuote.demo.jsx @@ -1,4 +1,5 @@ /* + * Copyright 2026 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,24 +15,30 @@ * limitations under the License. */ -import {createPresentationDemo} from '../demo-utils/PresentationDemo' +import { createPresentationDemo } from "../demo-utils/PresentationDemo"; export function blockQuotePresentationDemo(registry) { - registry - .add('block quote', createPresentationDemo([{ - type: 'BlockQuote', - content: paragraph() - }])) + registry.add( + "block quote", + createPresentationDemo([ + { + type: "BlockQuote", + content: paragraph(), + }, + ]) + ); } function paragraph() { - return [ + return [ + { + type: "Paragraph", + content: [ { - type: 'Paragraph', - content: [{ - type: 'SimpleText', - text: 'quote text quote text' - }] - } - ] + type: "SimpleText", + text: "quote text quote text. More long text more text for some extra lines and then some more ", + }, + ], + }, + ]; } diff --git a/znai-reactjs/src/theme/znai-dark/znai-dark.css b/znai-reactjs/src/theme/znai-dark/znai-dark.css index a93d6078d..705b1dae0 100644 --- a/znai-reactjs/src/theme/znai-dark/znai-dark.css +++ b/znai-reactjs/src/theme/znai-dark/znai-dark.css @@ -21,6 +21,8 @@ --znai-background-color: #1e2529; + --znai-presentation-paragraph-background: linear-gradient(135deg, #2c3744 0%, #1f272f 100%); + --znai-zoom-overlay-background-color: rgba(10, 10, 10, 0.9); --znai-zoom-container-border: 1px #333 solid; From 2cca4aac608e3aabc1583c46c79c71b141c45056 Mon Sep 17 00:00:00 2001 From: MykolaGolubyev Date: Mon, 1 Jun 2026 20:34:44 -0400 Subject: [PATCH 3/3] release notes --- ...fix-2026-06-01-presentation-blockquote-paragraph-wrapping.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 znai-docs/znai/release-notes/1.91/fix-2026-06-01-presentation-blockquote-paragraph-wrapping.md diff --git a/znai-docs/znai/release-notes/1.91/fix-2026-06-01-presentation-blockquote-paragraph-wrapping.md b/znai-docs/znai/release-notes/1.91/fix-2026-06-01-presentation-blockquote-paragraph-wrapping.md new file mode 100644 index 000000000..8a4ebd730 --- /dev/null +++ b/znai-docs/znai/release-notes/1.91/fix-2026-06-01-presentation-blockquote-paragraph-wrapping.md @@ -0,0 +1,2 @@ +* Fix: [Presentation](flow/presentation) mode renders blockquotes correctly +* Add: [Presentation](flow/presentation) mode wraps long paragraphs better \ No newline at end of file