From a321fc9f6da57eaae487adefcc9b68487735af21 Mon Sep 17 00:00:00 2001 From: Marek Mihok Date: Thu, 16 Nov 2023 11:26:52 +0100 Subject: [PATCH] feat: Improve markdown typography #2179 (#2189) --- py/examples/markdown.py | 87 ++- py/h2o_lightwave/h2o_lightwave/types.py | 10 + py/h2o_lightwave/h2o_lightwave/ui.py | 3 + py/h2o_wave/h2o_wave/types.py | 10 + py/h2o_wave/h2o_wave/ui.py | 3 + r/R/ui.R | 4 + .../resources/templates/wave-components.xml | 3 +- .../vscode-extension/component-snippets.json | 2 +- ui/jest.config.js | 2 - ui/src/index.scss | 76 +- ui/src/markdown.css | 656 ++++++++++++++++++ ui/src/markdown.tsx | 60 +- ui/src/react-app-env.d.ts | 5 + ui/src/setupTests.ts | 2 + website/widgets/content/markdown.md | 30 + 15 files changed, 807 insertions(+), 146 deletions(-) create mode 100644 ui/src/markdown.css diff --git a/py/examples/markdown.py b/py/examples/markdown.py index c0e9e27db8..94d59cd73a 100644 --- a/py/examples/markdown.py +++ b/py/examples/markdown.py @@ -1,34 +1,53 @@ # Markdown # Use a markdown card to display formatted content using #markdown. # --- -from h2o_wave import site, ui +from h2o_wave import site, ui, app, main, Q -page = site['/demo'] -sample_markdown = '''= -The **quick** _brown_ fox jumped over the lazy dog. +sample_markdown=''' +# Heading level 1 +## Heading level 2 +### Heading level 3 +#### Heading level 4 +##### Heading level 5 +###### Heading level 6 +___ +The **quick** __brown__ *fox* **_jumped_ over** the ~~lazy~~ _dog_. + +This is superscript and this is subscript! Block quote: > The quick brown fox jumped over the lazy dog. +Ordered list: + +1. James Madison +1. James Monroe +1. John Quincy Adams + Unordered list: -- The quick brown fox jumped over the lazy dog. -- The quick brown fox jumped over the lazy dog. -- The quick brown fox jumped over the lazy dog. +- George Washington +* John Adams ++ Thomas Jefferson ++ John Doe -Ordered list: +Nested list: -1. The quick brown fox jumped over the lazy dog. -1. The quick brown fox jumped over the lazy dog. -1. The quick brown fox jumped over the lazy dog. +1. First list item + - First nested list item + - Second nested list item Image: ![Monty Python](https://upload.wikimedia.org/wikipedia/en/c/cb/Flyingcircus_2.jpg) -Table: +Image caption: + +
A single track trail outside of Albuquerque, New Mexico.
+ +Table: | Column 1 | Column 2 | Column 3 | | -------- | -------- | -------- | @@ -36,17 +55,12 @@ | Item 1 | Item 2 | Item 3 | | Item 1 | Item 2 | Item 3 | -''' +Inline code: + +Use `ui.markdown_card` to start creating your own markdown content! + +Code block: -page['example'] = ui.markdown_card( - box='1 1 3 10', - title='I was made using markdown!', - content=sample_markdown, -) -page['example1'] = ui.markdown_card( - box='4 1 3 10', - title='I was made using markdown!', - content=''' ```py from h2o_wave import main, app, Q, ui @@ -59,8 +73,29 @@ async def serve(q: Q): content='Hello, world!' ) - await q.page`.save() -''', -) + await q.page.save() +``` + + + +Ignore \*markdown\* formatting. -page.save() +Linking: + +This framework is made by [h2o.ai](https://h2o.ai) +''' + +@app('/demo') +async def serve(q: Q): + q.page['example'] = ui.markdown_card( + box='1 1 3 9', + title='Markdown - compact (default)', + content=sample_markdown, + ) + q.page['example1'] = ui.markdown_card( + box='4 1 3 9', + title='Markdown - regular', + content=sample_markdown, + compact=False + ) + await q.page.save() diff --git a/py/h2o_lightwave/h2o_lightwave/types.py b/py/h2o_lightwave/h2o_lightwave/types.py index 6cad85112c..c7dc22ce29 100644 --- a/py/h2o_lightwave/h2o_lightwave/types.py +++ b/py/h2o_lightwave/h2o_lightwave/types.py @@ -9608,11 +9608,13 @@ def __init__( title: str, content: str, data: Optional[PackedRecord] = None, + compact: Optional[bool] = None, commands: Optional[List[Command]] = None, ): _guard_scalar('MarkdownCard.box', box, (str,), False, False, False) _guard_scalar('MarkdownCard.title', title, (str,), False, False, False) _guard_scalar('MarkdownCard.content', content, (str,), False, False, False) + _guard_scalar('MarkdownCard.compact', compact, (bool,), False, True, False) _guard_vector('MarkdownCard.commands', commands, (Command,), False, True, False) self.box = box """A string indicating how to place this component on the page.""" @@ -9622,6 +9624,8 @@ def __init__( """The markdown content. Supports Github Flavored Markdown (GFM): https://guides.github.com/features/mastering-markdown/""" self.data = data """Additional data for the card.""" + self.compact = compact + """Make spacing tighter. Defaults to True.""" self.commands = commands """Contextual menu commands for this component.""" @@ -9630,6 +9634,7 @@ def dump(self) -> Dict: _guard_scalar('MarkdownCard.box', self.box, (str,), False, False, False) _guard_scalar('MarkdownCard.title', self.title, (str,), False, False, False) _guard_scalar('MarkdownCard.content', self.content, (str,), False, False, False) + _guard_scalar('MarkdownCard.compact', self.compact, (bool,), False, True, False) _guard_vector('MarkdownCard.commands', self.commands, (Command,), False, True, False) return _dump( view='markdown', @@ -9637,6 +9642,7 @@ def dump(self) -> Dict: title=self.title, content=self.content, data=self.data, + compact=self.compact, commands=None if self.commands is None else [__e.dump() for __e in self.commands], ) @@ -9650,18 +9656,22 @@ def load(__d: Dict) -> 'MarkdownCard': __d_content: Any = __d.get('content') _guard_scalar('MarkdownCard.content', __d_content, (str,), False, False, False) __d_data: Any = __d.get('data') + __d_compact: Any = __d.get('compact') + _guard_scalar('MarkdownCard.compact', __d_compact, (bool,), False, True, False) __d_commands: Any = __d.get('commands') _guard_vector('MarkdownCard.commands', __d_commands, (dict,), False, True, False) box: str = __d_box title: str = __d_title content: str = __d_content data: Optional[PackedRecord] = __d_data + compact: Optional[bool] = __d_compact commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands] return MarkdownCard( box, title, content, data, + compact, commands, ) diff --git a/py/h2o_lightwave/h2o_lightwave/ui.py b/py/h2o_lightwave/h2o_lightwave/ui.py index 122b580b32..89bafb8628 100644 --- a/py/h2o_lightwave/h2o_lightwave/ui.py +++ b/py/h2o_lightwave/h2o_lightwave/ui.py @@ -3388,6 +3388,7 @@ def markdown_card( title: str, content: str, data: Optional[PackedRecord] = None, + compact: Optional[bool] = None, commands: Optional[List[Command]] = None, ) -> MarkdownCard: """Create a card that renders Markdown content. @@ -3402,6 +3403,7 @@ def markdown_card( title: The title for this card. content: The markdown content. Supports Github Flavored Markdown (GFM): https://guides.github.com/features/mastering-markdown/ data: Additional data for the card. + compact: Make spacing tighter. Defaults to True. commands: Contextual menu commands for this component. Returns: A `h2o_wave.types.MarkdownCard` instance. @@ -3411,6 +3413,7 @@ def markdown_card( title, content, data, + compact, commands, ) diff --git a/py/h2o_wave/h2o_wave/types.py b/py/h2o_wave/h2o_wave/types.py index 6cad85112c..c7dc22ce29 100644 --- a/py/h2o_wave/h2o_wave/types.py +++ b/py/h2o_wave/h2o_wave/types.py @@ -9608,11 +9608,13 @@ def __init__( title: str, content: str, data: Optional[PackedRecord] = None, + compact: Optional[bool] = None, commands: Optional[List[Command]] = None, ): _guard_scalar('MarkdownCard.box', box, (str,), False, False, False) _guard_scalar('MarkdownCard.title', title, (str,), False, False, False) _guard_scalar('MarkdownCard.content', content, (str,), False, False, False) + _guard_scalar('MarkdownCard.compact', compact, (bool,), False, True, False) _guard_vector('MarkdownCard.commands', commands, (Command,), False, True, False) self.box = box """A string indicating how to place this component on the page.""" @@ -9622,6 +9624,8 @@ def __init__( """The markdown content. Supports Github Flavored Markdown (GFM): https://guides.github.com/features/mastering-markdown/""" self.data = data """Additional data for the card.""" + self.compact = compact + """Make spacing tighter. Defaults to True.""" self.commands = commands """Contextual menu commands for this component.""" @@ -9630,6 +9634,7 @@ def dump(self) -> Dict: _guard_scalar('MarkdownCard.box', self.box, (str,), False, False, False) _guard_scalar('MarkdownCard.title', self.title, (str,), False, False, False) _guard_scalar('MarkdownCard.content', self.content, (str,), False, False, False) + _guard_scalar('MarkdownCard.compact', self.compact, (bool,), False, True, False) _guard_vector('MarkdownCard.commands', self.commands, (Command,), False, True, False) return _dump( view='markdown', @@ -9637,6 +9642,7 @@ def dump(self) -> Dict: title=self.title, content=self.content, data=self.data, + compact=self.compact, commands=None if self.commands is None else [__e.dump() for __e in self.commands], ) @@ -9650,18 +9656,22 @@ def load(__d: Dict) -> 'MarkdownCard': __d_content: Any = __d.get('content') _guard_scalar('MarkdownCard.content', __d_content, (str,), False, False, False) __d_data: Any = __d.get('data') + __d_compact: Any = __d.get('compact') + _guard_scalar('MarkdownCard.compact', __d_compact, (bool,), False, True, False) __d_commands: Any = __d.get('commands') _guard_vector('MarkdownCard.commands', __d_commands, (dict,), False, True, False) box: str = __d_box title: str = __d_title content: str = __d_content data: Optional[PackedRecord] = __d_data + compact: Optional[bool] = __d_compact commands: Optional[List[Command]] = None if __d_commands is None else [Command.load(__e) for __e in __d_commands] return MarkdownCard( box, title, content, data, + compact, commands, ) diff --git a/py/h2o_wave/h2o_wave/ui.py b/py/h2o_wave/h2o_wave/ui.py index 122b580b32..89bafb8628 100644 --- a/py/h2o_wave/h2o_wave/ui.py +++ b/py/h2o_wave/h2o_wave/ui.py @@ -3388,6 +3388,7 @@ def markdown_card( title: str, content: str, data: Optional[PackedRecord] = None, + compact: Optional[bool] = None, commands: Optional[List[Command]] = None, ) -> MarkdownCard: """Create a card that renders Markdown content. @@ -3402,6 +3403,7 @@ def markdown_card( title: The title for this card. content: The markdown content. Supports Github Flavored Markdown (GFM): https://guides.github.com/features/mastering-markdown/ data: Additional data for the card. + compact: Make spacing tighter. Defaults to True. commands: Contextual menu commands for this component. Returns: A `h2o_wave.types.MarkdownCard` instance. @@ -3411,6 +3413,7 @@ def markdown_card( title, content, data, + compact, commands, ) diff --git a/r/R/ui.R b/r/R/ui.R index ac25e8c291..d3ae9aa868 100644 --- a/r/R/ui.R +++ b/r/R/ui.R @@ -3948,6 +3948,7 @@ ui_list_item1_card <- function( #' @param title The title for this card. #' @param content The markdown content. Supports Github Flavored Markdown (GFM): https://guides.github.com/features/mastering-markdown/ #' @param data Additional data for the card. +#' @param compact Make spacing tighter. Defaults to True. #' @param commands Contextual menu commands for this component. #' @return A MarkdownCard instance. #' @export @@ -3956,17 +3957,20 @@ ui_markdown_card <- function( title, content, data = NULL, + compact = NULL, commands = NULL) { .guard_scalar("box", "character", box) .guard_scalar("title", "character", title) .guard_scalar("content", "character", content) # TODO Validate data: Rec + .guard_scalar("compact", "logical", compact) .guard_vector("commands", "WaveCommand", commands) .o <- list( box=box, title=title, content=content, data=data, + compact=compact, commands=commands, view='markdown') class(.o) <- append(class(.o), c(.wave_obj, "WaveMarkdownCard")) diff --git a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml index b24c294fac..149e668f93 100644 --- a/tools/intellij-plugin/src/main/resources/templates/wave-components.xml +++ b/tools/intellij-plugin/src/main/resources/templates/wave-components.xml @@ -1667,11 +1667,12 @@