From e437bf5bbe15d1e674568d07cc29bb3c091892a6 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Mon, 22 Jul 2024 00:38:41 +0200 Subject: [PATCH 01/80] Introduced MaskedInput widget --- CHANGELOG.md | 4 + docs/examples/widgets/masked_input.py | 32 + docs/widget_gallery.md | 10 + docs/widgets/masked_input.md | 84 +++ mkdocs-nav.yml | 1 + src/textual/widgets/__init__.py | 2 + src/textual/widgets/_masked_input.py | 576 ++++++++++++++++++ .../__snapshots__/test_snapshots.ambr | 160 +++++ .../snapshot_apps/masked_input.py | 13 + tests/snapshot_tests/test_snapshots.py | 9 + tests/test_masked_input.py | 218 +++++++ 11 files changed, 1109 insertions(+) create mode 100644 docs/examples/widgets/masked_input.py create mode 100644 docs/widgets/masked_input.md create mode 100644 src/textual/widgets/_masked_input.py create mode 100644 tests/snapshot_tests/snapshot_apps/masked_input.py create mode 100644 tests/test_masked_input.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ef7ca7302..094daa66cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +### Added + +- Added `MaskedInput` widget + ### Fixed - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 diff --git a/docs/examples/widgets/masked_input.py b/docs/examples/widgets/masked_input.py new file mode 100644 index 0000000000..dab3b442b4 --- /dev/null +++ b/docs/examples/widgets/masked_input.py @@ -0,0 +1,32 @@ +from textual.app import App, ComposeResult +from textual.widgets import Label, MaskedInput + + +class MaskedInputApp(App): + # (1)! + CSS = """ + MaskedInput.-valid { + border: tall $success 60%; + } + MaskedInput.-valid:focus { + border: tall $success; + } + MaskedInput { + margin: 1 1; + } + Label { + margin: 1 2; + } + """ + + def compose(self) -> ComposeResult: + yield Label("Enter a valid credit card number.") + yield MaskedInput( + template="9999-9999-9999-9999;0", # (2)! + ) + + +app = MaskedInputApp() + +if __name__ == "__main__": + app.run() diff --git a/docs/widget_gallery.md b/docs/widget_gallery.md index 1d5ef708cb..324cef5f4a 100644 --- a/docs/widget_gallery.md +++ b/docs/widget_gallery.md @@ -182,6 +182,16 @@ Display a markdown document. ```{.textual path="docs/examples/widgets/markdown.py"} ``` +## MaskedInput + +A control to enter input according to a template mask. + +[MaskedInput reference](./widgets/masked_input.md){ .md-button .md-button--primary } + + +```{.textual path="docs/examples/widgets/masked_input.py"} +``` + ## OptionList Display a vertical list of options (options may be Rich renderables). diff --git a/docs/widgets/masked_input.md b/docs/widgets/masked_input.md new file mode 100644 index 0000000000..0a8820d27c --- /dev/null +++ b/docs/widgets/masked_input.md @@ -0,0 +1,84 @@ +# MaskedInput + +!!! tip "Added in version 0.74.0" + +A masked input derived from `Input`, allowing to restrict user input and give visual aid via a simple template mask, which also acts as an implicit *[validator][textual.validation.Validator]*. + +- [x] Focusable +- [ ] Container + +## Example + +The example below shows a masked input to ease entering a credit card number. + +=== "Output" + + ```{.textual path="docs/examples/widgets/masked_input.py"} + ``` + +=== "checkbox.py" + + ```python + --8<-- "docs/examples/widgets/masked_input.py" + ``` + +## Reactive Attributes + +| Name | Type | Default | Description | +| ---------- | ----- | ------- | ------------------------- | +| `template` | `str` | `""` | The template mask string. | + +### The template string format + +A `MaskedInput` template length defines the maximum length of the input value. Each character of the mask defines a regular expression used to restrict what the user can insert in the corresponding position, and whether the presence of the character in the user input is required for the `MaskedInput` value to be considered valid, according to the following table: + +| Mask character | Regular expression | Required? | +| -------------- | ------------------ | --------- | +| `A` | `[A-Za-z]` | Yes | +| `a` | `[A-Za-z]` | No | +| `N` | `[A-Za-z0-9]` | Yes | +| `n` | `[A-Za-z0-9]` | No | +| `X` | `[^ ]` | Yes | +| `x` | `[^ ]` | No | +| `9` | `[0-9]` | Yes | +| `0` | `[0-9]` | No | +| `D` | `[1-9]` | Yes | +| `d` | `[1-9]` | No | +| `#` | `[0-9+\-]` | No | +| `H` | `[A-Fa-f0-9]` | Yes | +| `h` | `[A-Fa-f0-9]` | No | +| `B` | `[0-1]` | Yes | +| `b` | `[0-1]` | No | + +There are some special characters that can be used to control automatic case conversion during user input: `>` converts all subsequent user input to uppercase; `<` to lowercase; `!` disables automatic case conversion. Any other character that appears in the template mask is assumed to be a separator, which is a character that is automatically inserted when user reaches its position. All mask characters can be escaped by placing `\` in front of them, allowing any character to be used as separator. +The mask can be terminated by `;c`, where `c` is any character you want to be used as placeholder character. The `placeholder` parameter inherited by `Input` can be used to override this allowing finer grain tuning of the placeholder string. + +## Messages + +- [MaskedInput.Changed][textual.widgets.MaskedInput.Changed] +- [MaskedInput.Submitted][textual.widgets.MaskedInput.Submitted] + +## Bindings + +The masked input widget defines the following bindings: + +::: textual.widgets.MaskedInput.BINDINGS + options: + show_root_heading: false + show_root_toc_entry: false + +## Component Classes + +The masked input widget provides the following component classes: + +::: textual.widgets.MaskedInput.COMPONENT_CLASSES + options: + show_root_heading: false + show_root_toc_entry: false + +--- + + +::: textual.widgets.MaskedInput + options: + heading_level: 2 diff --git a/mkdocs-nav.yml b/mkdocs-nav.yml index f52cb4df78..af63dd6785 100644 --- a/mkdocs-nav.yml +++ b/mkdocs-nav.yml @@ -158,6 +158,7 @@ nav: - "widgets/log.md" - "widgets/markdown_viewer.md" - "widgets/markdown.md" + - "widgets/masked_input.md" - "widgets/option_list.md" - "widgets/placeholder.md" - "widgets/pretty.md" diff --git a/src/textual/widgets/__init__.py b/src/textual/widgets/__init__.py index a9505aa0dc..6014af279c 100644 --- a/src/textual/widgets/__init__.py +++ b/src/textual/widgets/__init__.py @@ -27,6 +27,7 @@ from ._loading_indicator import LoadingIndicator from ._log import Log from ._markdown import Markdown, MarkdownViewer + from ._masked_input import MaskedInput from ._option_list import OptionList from ._placeholder import Placeholder from ._pretty import Pretty @@ -66,6 +67,7 @@ "Log", "Markdown", "MarkdownViewer", + "MaskedInput", "OptionList", "Placeholder", "Pretty", diff --git a/src/textual/widgets/_masked_input.py b/src/textual/widgets/_masked_input.py new file mode 100644 index 0000000000..f10f6f6e79 --- /dev/null +++ b/src/textual/widgets/_masked_input.py @@ -0,0 +1,576 @@ +from __future__ import annotations + +import re +from dataclasses import dataclass +from enum import IntFlag +from typing import TYPE_CHECKING, Iterable, Pattern + +from rich.console import Console, ConsoleOptions, RenderableType +from rich.console import RenderResult as RichRenderResult +from rich.segment import Segment +from rich.text import Text +from typing_extensions import Literal + +from .. import events +from .._segment_tools import line_crop + +if TYPE_CHECKING: + from ..app import RenderResult + +from ..reactive import var +from ..validation import ValidationResult, Validator +from ._input import Input + +InputValidationOn = Literal["blur", "changed", "submitted"] +"""Possible messages that trigger input validation.""" + + +class _CharFlags(IntFlag): + """Misc flags for a single template character definition""" + + REQUIRED = 0x1 + """Is this character required for validation?""" + + SEPARATOR = 0x2 + """Is this character a separator?""" + + UPPERCASE = 0x4 + """Char is forced to be uppercase""" + + LOWERCASE = 0x8 + """Char is forced to be lowercase""" + + +_TEMPLATE_CHARACTERS = { + "A": (r"[A-Za-z]", _CharFlags.REQUIRED), + "a": (r"[A-Za-z]", None), + "N": (r"[A-Za-z0-9]", _CharFlags.REQUIRED), + "n": (r"[A-Za-z0-9]", None), + "X": (r"[^ ]", _CharFlags.REQUIRED), + "x": (r"[^ ]", None), + "9": (r"[0-9]", _CharFlags.REQUIRED), + "0": (r"[0-9]", None), + "D": (r"[1-9]", _CharFlags.REQUIRED), + "d": (r"[1-9]", None), + "#": (r"[0-9+\-]", None), + "H": (r"[A-Fa-f0-9]", _CharFlags.REQUIRED), + "h": (r"[A-Fa-f0-9]", None), + "B": (r"[0-1]", _CharFlags.REQUIRED), + "b": (r"[0-1]", None), +} + + +class _InputRenderable: + """Render the input content.""" + + def __init__(self, input: Input, cursor_visible: bool) -> None: + self.input = input + self.cursor_visible = cursor_visible + + def __rich_console__( + self, console: "Console", options: "ConsoleOptions" + ) -> RichRenderResult: + input = self.input + result = input._value + width = input.content_size.width + + # Add the completion with a faded style. + value = input.value + value_length = len(value) + template = input._template + style = input.get_component_rich_style("input--placeholder") + result += Text( + template.mask[value_length:], + style, + ) + for index, (c, char_def) in enumerate(zip(value, template.template)): + if c == " ": + result.stylize(style, index, index + 1) + + if self.cursor_visible and input.has_focus: + if input._cursor_at_end: + result.pad_right(1) + cursor_style = input.get_component_rich_style("input--cursor") + cursor = input.cursor_position + result.stylize(cursor_style, cursor, cursor + 1) + + segments = list(result.render(console)) + line_length = Segment.get_line_length(segments) + if line_length < width: + segments = Segment.adjust_line_length(segments, width) + line_length = width + + line = line_crop( + list(segments), + input.view_position, + input.view_position + width, + line_length, + ) + yield from line + + +class _Template(Validator): + """Template mask enforcer.""" + + @dataclass + class CharDef: + """Holds data for a single char of the template mask.""" + + pattern: Pattern[str] + """Compiled regular expression to check for matches.""" + + flags: _CharFlags = _CharFlags(0) + """Flags defining special behaviors""" + + char: str = "" + """Mask character (separator or blank or placeholder)""" + + def __init__(self, input: Input, template_str: str) -> None: + self.input = input + self.template: list[_Template.CharDef] = [] + self.blank: str = " " + escaped = False + flags = _CharFlags(0) + template_chars: list[str] = list(template_str) + + while template_chars: + c = template_chars.pop(0) + if escaped: + char = self.CharDef(re.compile(re.escape(c)), _CharFlags.SEPARATOR, c) + escaped = False + else: + if c == "\\": + escaped = True + continue + elif c == ";": + break + + new_flags = { + ">": _CharFlags.UPPERCASE, + "<": _CharFlags.LOWERCASE, + "!": 0, + }.get(c, None) + if new_flags is not None: + flags = new_flags + continue + + pattern, required_flag = _TEMPLATE_CHARACTERS.get(c, (None, None)) + if pattern: + char_flags = _CharFlags.REQUIRED if required_flag else _CharFlags(0) + char = self.CharDef(re.compile(pattern), char_flags) + else: + char = self.CharDef( + re.compile(re.escape(c)), _CharFlags.SEPARATOR, c + ) + + char.flags |= flags + self.template.append(char) + + if template_chars: + self.blank = template_chars[0] + + if all(char.flags & _CharFlags.SEPARATOR for char in self.template): + raise ValueError( + "Template must contain at least one non-separator character" + ) + + self.update_mask(input.placeholder) + + def validate(self, value: str) -> ValidationResult: + if self.check(value.ljust(len(self.template), chr(0)), False): + return self.success() + else: + return self.failure("Value does not match template!", value) + + def check(self, value: str, allow_space: bool) -> bool: + for c, char_def in zip(value, self.template): + if ( + (char_def.flags & _CharFlags.REQUIRED) + and (not char_def.pattern.match(c)) + and ((c != " ") or not allow_space) + ): + return False + return True + + def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int]: + while cursor_position < len(self.template) and ( + self.template[cursor_position].flags & _CharFlags.SEPARATOR + ): + value = ( + value[:cursor_position] + + self.template[cursor_position].char + + value[cursor_position + 1 :] + ) + cursor_position += 1 + return value, cursor_position + + def insert_text_at_cursor(self, text: str) -> str | None: + value = self.input.value + cursor_position = self.input.cursor_position + separators = set( + [ + char_def.char + for char_def in self.template + if char_def.flags & _CharFlags.SEPARATOR + ] + ) + for c in text: + if c in separators: + if c == self.next_separator(cursor_position): + prev_position = self.prev_separator_position(cursor_position) + if (cursor_position > 0) and (prev_position != cursor_position - 1): + next_position = self.next_separator_position(cursor_position) + while cursor_position < next_position + 1: + if ( + self.template[cursor_position].flags + & _CharFlags.SEPARATOR + ): + char = self.template[cursor_position].char + else: + char = " " + value = ( + value[:cursor_position] + + char + + value[cursor_position + 1 :] + ) + cursor_position += 1 + continue + if cursor_position >= len(self.template): + break + char_def = self.template[cursor_position] + assert (char_def.flags & _CharFlags.SEPARATOR) == 0 + if not char_def.pattern.match(c): + return None + if char_def.flags & _CharFlags.LOWERCASE: + c = c.lower() + elif char_def.flags & _CharFlags.UPPERCASE: + c = c.upper() + value = value[:cursor_position] + c + value[cursor_position + 1 :] + cursor_position += 1 + value, cursor_position = self.insert_separators(value, cursor_position) + return value, cursor_position + + def move_cursor(self, delta: int) -> None: + cursor_position = self.input.cursor_position + if delta < 0 and all( + [c.flags & _CharFlags.SEPARATOR for c in self.template[:cursor_position]] + ): + return + cursor_position += delta + while ( + (cursor_position >= 0) + and (cursor_position < len(self.template)) + and (self.template[cursor_position].flags & _CharFlags.SEPARATOR) + ): + cursor_position += delta + self.input.cursor_position = cursor_position + + def delete_at_position(self, position: int | None = None) -> None: + value = self.input.value + if position is None: + position = self.input.cursor_position + cursor_position = position + if cursor_position < len(self.template): + assert (self.template[cursor_position].flags & _CharFlags.SEPARATOR) == 0 + if cursor_position == len(value) - 1: + value = value[:cursor_position] + else: + value = value[:cursor_position] + " " + value[cursor_position + 1 :] + pos = len(value) + while pos > 0: + char_def = self.template[pos - 1] + if ((char_def.flags & _CharFlags.SEPARATOR) == 0) and ( + value[pos - 1] != " " + ): + break + pos -= 1 + value = value[:pos] + if cursor_position > len(value): + cursor_position = len(value) + value, cursor_position = self.insert_separators(value, cursor_position) + self.input.cursor_position = cursor_position + self.input.value = value + + def at_separator(self, position: int | None = None) -> bool: + if position is None: + position = self.input.cursor_position + if (position >= 0) and (position < len(self.template)): + return bool(self.template[position].flags & _CharFlags.SEPARATOR) + else: + return False + + def prev_separator_position(self, position: int | None = None) -> int | None: + if position is None: + position = self.input.cursor_position + for index in range(position - 1, 0, -1): + if self.template[index].flags & _CharFlags.SEPARATOR: + return index + else: + return None + + def next_separator_position(self, position: int | None = None) -> int | None: + if position is None: + position = self.input.cursor_position + for index in range(position + 1, len(self.template)): + if self.template[index].flags & _CharFlags.SEPARATOR: + return index + else: + return None + + def next_separator(self, position: int | None = None) -> str | None: + position = self.next_separator_position(position) + if position is None: + return None + else: + return self.template[position].char + + def display(self, value: str) -> str: + result = [] + for c, char_def in zip(value, self.template): + if c == " ": + c = char_def.char + result.append(c) + return "".join(result) + + def update_mask(self, placeholder: str) -> None: + for index, char_def in enumerate(self.template): + if (char_def.flags & _CharFlags.SEPARATOR) == 0: + if index < len(placeholder): + char_def.char = placeholder[index] + else: + char_def.char = self.blank + + @property + def mask(self) -> str: + return "".join([c.char for c in self.template]) + + @property + def empty_mask(self) -> str: + return "".join( + [ + " " if (c.flags & _CharFlags.SEPARATOR) == 0 else c.char + for c in self.template + ] + ) + + +class MaskedInput(Input, can_focus=True): + """A masked text input widget.""" + + template = var("") + """Input template mask currently in use.""" + + def __init__( + self, + template: str, + value: str | None = None, + placeholder: str = "", + *, + validators: Validator | Iterable[Validator] | None = None, + validate_on: Iterable[InputValidationOn] | None = None, + valid_empty: bool = False, + name: str | None = None, + id: str | None = None, + classes: str | None = None, + disabled: bool = False, + tooltip: RenderableType | None = None, + ) -> None: + """Initialise the `Input` widget. + + Args: + template: Template string. + value: An optional default value for the input. + placeholder: Optional placeholder text for the input. + validators: An iterable of validators that the MaskedInput value will be checked against. + validate_on: Zero or more of the values "blur", "changed", and "submitted", + which determine when to do input validation. The default is to do + validation for all messages. + valid_empty: Empty values are valid. + name: Optional name for the masked input widget. + id: Optional ID for the widget. + classes: Optional initial classes for the widget. + disabled: Whether the input is disabled or not. + tooltip: Optional tooltip. + """ + self._template: _Template = None + super().__init__( + placeholder=placeholder, + validators=validators, + validate_on=validate_on, + valid_empty=valid_empty, + name=name, + id=id, + classes=classes, + disabled=disabled, + ) + + self._template = _Template(self, template) + self.template = template + + value, _ = self._template.insert_separators(value or "", 0) + self.value = value + if tooltip is not None: + self.tooltip = tooltip + + def validate_value(self, value: str) -> str: + if self._template is None: + return value + if not self._template.check(value, True): + raise ValueError("Value does not match template!") + return value[: len(self._template.mask)] + + def _watch_template(self, template: str) -> None: + """Revalidate when template changes.""" + self._template = _Template(self, template) if template else None + if self.is_mounted: + self._watch_value(self.value) + + def _watch_placeholder(self, placeholder: str) -> None: + """Update template display mask when placeholder changes.""" + if self._template is not None: + self._template.update_mask(placeholder) + self.refresh() + + def validate(self, value: str) -> ValidationResult | None: + """Run all the validators associated with this MaskedInput on the supplied value. + + Same as `Input.validate()` but also validates against template which acts as an + additional implicit validator. + + Returns: + A ValidationResult indicating whether *all* validators succeeded or not. + That is, if *any* validator fails, the result will be an unsuccessful + validation. + """ + + def set_classes() -> None: + """Set classes for valid flag.""" + valid = self._valid + self.set_class(not valid, "-invalid") + self.set_class(valid, "-valid") + + result = super().validate(value) + validation_results: list[ValidationResult] = [self._template.validate(value)] + if result is not None: + validation_results.append(result) + combined_result = ValidationResult.merge(validation_results) + self._valid = combined_result.is_valid + set_classes() + + return combined_result + + def render(self) -> RenderResult: + return _InputRenderable(self, self._cursor_visible) + + @property + def _value(self) -> Text: + """Value rendered as text.""" + value = self._template.display(self.value) + return Text(value, no_wrap=True, overflow="ignore") + + async def _on_click(self, event: events.Click) -> None: + await super()._on_click(event) + if self._template.at_separator(): + self._template.move_cursor(1) + + def insert_text_at_cursor(self, text: str) -> None: + """Insert new text at the cursor, move the cursor to the end of the new text. + + Args: + text: New text to insert. + """ + + new_value = self._template.insert_text_at_cursor(text) + if new_value is not None: + self.value, self.cursor_position = new_value + else: + self.restricted() + + def clear(self) -> None: + """Clear the masked input.""" + self.value, self.cursor_position = self._template.insert_separators("", 0) + + def action_cursor_left(self) -> None: + """Move the cursor one position to the left.""" + self._template.move_cursor(-1) + + def action_cursor_right(self) -> None: + """Accept an auto-completion or move the cursor one position to the right.""" + self._template.move_cursor(1) + + def action_home(self) -> None: + """Move the cursor to the start of the input.""" + self._template.move_cursor(-len(self.template)) + + def action_cursor_left_word(self) -> None: + """Move the cursor left to the start of a word.""" + if self._template.at_separator(self.cursor_position - 1): + position = self._template.prev_separator_position(self.cursor_position - 1) + else: + position = self._template.prev_separator_position() + if position: + position += 1 + self.cursor_position = position or 0 + + def action_cursor_right_word(self) -> None: + """Move the cursor right to the start of a word.""" + position = self._template.next_separator_position() + if position is None: + self.cursor_position = len(self._template.mask) + else: + self.cursor_position = position + 1 + + def action_delete_right(self) -> None: + """Delete one character at the current cursor position.""" + self._template.delete_at_position() + + def action_delete_right_word(self) -> None: + """Delete the current character and all rightward to the start of the next word.""" + position = self._template.next_separator_position() + if position is not None: + position += 1 + else: + position = len(self.value) + for index in range(self.cursor_position, position): + self.cursor_position = index + if not self._template.at_separator(): + self._template.delete_at_position() + + def action_delete_left(self) -> None: + """Delete one character to the left of the current cursor position.""" + if self.cursor_position <= 0: + # Cursor at the start, so nothing to delete + return + self._template.move_cursor(-1) + self._template.delete_at_position() + + def action_delete_left_word(self) -> None: + """Delete leftward of the cursor position to the start of a word.""" + if self.cursor_position <= 0: + return + if self._template.at_separator(self.cursor_position - 1): + position = self._template.prev_separator_position(self.cursor_position - 1) + else: + position = self._template.prev_separator_position() + if position: + position += 1 + else: + position = 0 + for index in range(position, self.cursor_position): + self.cursor_position = index + if not self._template.at_separator(): + self._template.delete_at_position() + self.cursor_position = position + + def action_delete_left_all(self) -> None: + """Delete all characters to the left of the cursor position.""" + if self.cursor_position > 0: + cursor_position = self.cursor_position + if cursor_position >= len(self.value): + self.value = "" + else: + self.value = ( + self._template.empty_mask[:cursor_position] + + self.value[cursor_position:] + ) + self.cursor_position = 0 diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index ff24988bb4..b0a9d01353 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -28169,6 +28169,166 @@ ''' # --- +# name: test_masked_input + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TemplateApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ABC01-DE___-_____-_____ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + YYYY-MM-DD + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- # name: test_max_height_100 ''' diff --git a/tests/snapshot_tests/snapshot_apps/masked_input.py b/tests/snapshot_tests/snapshot_apps/masked_input.py new file mode 100644 index 0000000000..d5ff2e401e --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/masked_input.py @@ -0,0 +1,13 @@ +from textual.app import App, ComposeResult +from textual.widgets import MaskedInput + + +class TemplateApp(App[None]): + def compose(self) -> ComposeResult: + yield MaskedInput(">NNNNN-NNNNN-NNNNN-NNNNN;_") + yield MaskedInput("9999-99-99", placeholder="YYYY-MM-DD") + + +if __name__ == "__main__": + app = TemplateApp() + app.run() \ No newline at end of file diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index a942aa0268..fd33c3ccc2 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -111,6 +111,15 @@ async def run_before(pilot): ) +def test_masked_input(snap_compare): + async def run_before(pilot): + pilot.app.query(Input).first().cursor_blink = False + + assert snap_compare( + SNAPSHOT_APPS_DIR / "masked_input.py", press=["A","B","C","0","1","-","D","E"], run_before=run_before + ) + + def test_buttons_render(snap_compare): # Testing button rendering. We press tab to focus the first button too. assert snap_compare(WIDGET_EXAMPLES_DIR / "button.py", press=["tab"]) diff --git a/tests/test_masked_input.py b/tests/test_masked_input.py new file mode 100644 index 0000000000..6a980f0dad --- /dev/null +++ b/tests/test_masked_input.py @@ -0,0 +1,218 @@ +from typing import Union + +import pytest + +from textual import on +from textual.app import App, ComposeResult +from textual.validation import Failure, ValidationResult +from textual.widgets import MaskedInput + +InputEvent = Union[MaskedInput.Changed, MaskedInput.Submitted] + + +class InputApp(App[None]): + def __init__(self, template: str, placeholder: str = ""): + super().__init__() + self.messages: list[InputEvent] = [] + self.template = template + self.placeholder = placeholder + + def compose(self) -> ComposeResult: + yield MaskedInput(template=self.template, placeholder=self.placeholder) + + @on(MaskedInput.Changed) + @on(MaskedInput.Submitted) + def on_changed_or_submitted(self, event: InputEvent) -> None: + self.messages.append(event) + + +async def test_missing_required(): + app = InputApp(">9999-99-99") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + input.value = "2024-12" + assert not input.is_valid + await pilot.pause() + assert len(app.messages) == 1 + assert app.messages[0].validation_result == ValidationResult.failure( + failures=[ + Failure( + value="2024-12", + validator=input._template, + description="Value does not match template!", + ) + ], + ) + + +async def test_valid_required(): + app = InputApp(">9999-99-99") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + input.value = "2024-12-31" + assert input.is_valid + await pilot.pause() + assert len(app.messages) == 1 + assert app.messages[0].validation_result == ValidationResult.success() + + +async def test_missing_optional(): + app = InputApp(">9999-99-00") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + input.value = "2024-12" + assert input.is_valid + await pilot.pause() + assert len(app.messages) == 1 + assert app.messages[0].validation_result == ValidationResult.success() + + +async def test_editing(): + serial = "ABCDE-FGHIJ-KLMNO-PQRST" + app = InputApp(">NNNNN-NNNNN-NNNNN-NNNNN;_") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + await pilot.press("A", "B", "C", "D") + assert input.cursor_position == 4 + assert input.value == "ABCD" + await pilot.press("E") + assert input.cursor_position == 6 + assert input.value == "ABCDE-" + await pilot.press("backspace") + assert input.cursor_position == 4 + assert input.value == "ABCD" + input.value = serial + assert input.is_valid + app.set_focus(None) + input.focus() + await pilot.pause() + assert input.cursor_position == len(serial) + await pilot.press("U") + assert input.cursor_position == len(serial) + + +async def test_key_movement_actions(): + serial = "ABCDE-FGHIJ-KLMNO-PQRST" + app = InputApp(">NNNNN-NNNNN-NNNNN-NNNNN;_") + async with app.run_test(): + input = app.query_one(MaskedInput) + input.value = serial + assert input.is_valid + input.action_cursor_right_word() + assert input.cursor_position == 6 + input.action_cursor_right() + input.action_cursor_right_word() + assert input.cursor_position == 12 + input.action_cursor_left() + input.action_cursor_left() + assert input.cursor_position == 9 + input.action_cursor_left_word() + assert input.cursor_position == 6 + + +async def test_key_modification_actions(): + serial = "ABCDE-FGHIJ-KLMNO-PQRST" + app = InputApp(">NNNNN-NNNNN-NNNNN-NNNNN;_") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + input.value = serial + assert input.is_valid + input.action_delete_right() + assert input.value == " BCDE-FGHIJ-KLMNO-PQRST" + input.cursor_position = 3 + input.action_delete_left() + assert input.value == " B DE-FGHIJ-KLMNO-PQRST" + input.cursor_position = 6 + input.action_delete_left() + assert input.value == " B D -FGHIJ-KLMNO-PQRST" + input.cursor_position = 9 + input.action_delete_left_word() + assert input.value == " B D - IJ-KLMNO-PQRST" + input.action_delete_left_word() + assert input.value == " - IJ-KLMNO-PQRST" + input.cursor_position = 15 + input.action_delete_right_word() + assert input.value == " - IJ-KLM -PQRST" + input.action_delete_right_word() + assert input.value == " - IJ-KLM" + input.cursor_position = 10 + input.action_delete_right_all() + assert input.value == " - I" + await pilot.press("J") + assert input.value == " - IJ-" + input.action_cursor_left() + input.action_delete_left_all() + assert input.value == " - J-" + input.clear() + assert input.value == "" + + +async def test_cursor_word_right_after_last_separator(): + app = InputApp(">NNN-NNN-NNN-NNNNN;_") + async with app.run_test(): + input = app.query_one(MaskedInput) + input.value = "123-456-789-012" + input.cursor_position = 13 + input.action_cursor_right_word() + assert input.cursor_position == 15 + + +async def test_case_conversion_meta_characters(): + app = InputApp("NN<-N!N>N") + async with app.run_test() as pilot: + input = app.query_one(MaskedInput) + await pilot.press("a", "B", "C", "D", "e") + assert input.value == "aB-cDE" + assert input.is_valid + + +async def test_case_conversion_override(): + app = InputApp(">- Date: Fri, 2 Aug 2024 00:42:15 +0200 Subject: [PATCH 02/80] Addressed review issues --- src/textual/widgets/_masked_input.py | 286 ++++++++++++++++++++------- 1 file changed, 214 insertions(+), 72 deletions(-) diff --git a/src/textual/widgets/_masked_input.py b/src/textual/widgets/_masked_input.py index f10f6f6e79..6e8e17c994 100644 --- a/src/textual/widgets/_masked_input.py +++ b/src/textual/widgets/_masked_input.py @@ -2,7 +2,7 @@ import re from dataclasses import dataclass -from enum import IntFlag +from enum import Flag, auto from typing import TYPE_CHECKING, Iterable, Pattern from rich.console import Console, ConsoleOptions, RenderableType @@ -25,19 +25,22 @@ """Possible messages that trigger input validation.""" -class _CharFlags(IntFlag): +class _CharFlags(Flag): """Misc flags for a single template character definition""" - REQUIRED = 0x1 + NONE = 0 + """Empty flags value""" + + REQUIRED = auto() """Is this character required for validation?""" - SEPARATOR = 0x2 + SEPARATOR = auto() """Is this character a separator?""" - UPPERCASE = 0x4 + UPPERCASE = auto() """Char is forced to be uppercase""" - LOWERCASE = 0x8 + LOWERCASE = auto() """Char is forced to be lowercase""" @@ -83,8 +86,8 @@ def __rich_console__( template.mask[value_length:], style, ) - for index, (c, char_def) in enumerate(zip(value, template.template)): - if c == " ": + for index, (char, char_definition) in enumerate(zip(value, template.template)): + if char == " ": result.stylize(style, index, index + 1) if self.cursor_visible and input.has_focus: @@ -113,63 +116,78 @@ class _Template(Validator): """Template mask enforcer.""" @dataclass - class CharDef: + class CharDefinition: """Holds data for a single char of the template mask.""" pattern: Pattern[str] """Compiled regular expression to check for matches.""" - flags: _CharFlags = _CharFlags(0) + flags: _CharFlags = _CharFlags.NONE """Flags defining special behaviors""" char: str = "" """Mask character (separator or blank or placeholder)""" def __init__(self, input: Input, template_str: str) -> None: + """Initialise the mask enforcer, which is also a subclass of `Validator`. + + Args: + input: The `MaskedInput` that owns this object. + template_str: Template string controlling masked input behavior. + """ self.input = input - self.template: list[_Template.CharDef] = [] + self.template: list[_Template.CharDefinition] = [] self.blank: str = " " escaped = False - flags = _CharFlags(0) + flags = _CharFlags.NONE template_chars: list[str] = list(template_str) while template_chars: - c = template_chars.pop(0) + char = template_chars.pop(0) if escaped: - char = self.CharDef(re.compile(re.escape(c)), _CharFlags.SEPARATOR, c) + char_definition = self.CharDefinition( + re.compile(re.escape(char)), _CharFlags.SEPARATOR, char + ) escaped = False else: - if c == "\\": + if char == "\\": escaped = True continue - elif c == ";": + elif char == ";": break new_flags = { ">": _CharFlags.UPPERCASE, "<": _CharFlags.LOWERCASE, - "!": 0, - }.get(c, None) + "!": _CharFlags.NONE, + }.get(char, None) if new_flags is not None: flags = new_flags continue - pattern, required_flag = _TEMPLATE_CHARACTERS.get(c, (None, None)) + pattern, required_flag = _TEMPLATE_CHARACTERS.get(char, (None, None)) if pattern: - char_flags = _CharFlags.REQUIRED if required_flag else _CharFlags(0) - char = self.CharDef(re.compile(pattern), char_flags) + char_flags = ( + _CharFlags.REQUIRED if required_flag else _CharFlags.NONE + ) + char_definition = self.CharDefinition( + re.compile(pattern), char_flags + ) else: - char = self.CharDef( - re.compile(re.escape(c)), _CharFlags.SEPARATOR, c + char_definition = self.CharDefinition( + re.compile(re.escape(char)), _CharFlags.SEPARATOR, char ) - char.flags |= flags - self.template.append(char) + char_definition.flags |= flags + self.template.append(char_definition) if template_chars: self.blank = template_chars[0] - if all(char.flags & _CharFlags.SEPARATOR for char in self.template): + if all( + (_CharFlags.SEPARATOR in char_definition.flags) + for char_definition in self.template + ): raise ValueError( "Template must contain at least one non-separator character" ) @@ -177,24 +195,52 @@ def __init__(self, input: Input, template_str: str) -> None: self.update_mask(input.placeholder) def validate(self, value: str) -> ValidationResult: + """Checks if `value` matches this template, always returning a ValidationResult. + + Args: + value: The string value to be validated. + + Returns: + A ValidationResult with the validation outcome. + + """ if self.check(value.ljust(len(self.template), chr(0)), False): return self.success() else: return self.failure("Value does not match template!", value) def check(self, value: str, allow_space: bool) -> bool: - for c, char_def in zip(value, self.template): + """Checks if `value matches this template, but returns result as a bool. + + Args: + value: The string value to be validated. + allow_space: Consider space character in `value` as valid. + + Returns: + True if `value` is valid for this template, False otherwise. + """ + for char, char_definition in zip(value, self.template): if ( - (char_def.flags & _CharFlags.REQUIRED) - and (not char_def.pattern.match(c)) - and ((c != " ") or not allow_space) + (_CharFlags.REQUIRED in char_definition.flags) + and (not char_definition.pattern.match(char)) + and ((char != " ") or not allow_space) ): return False return True def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int]: + """Automatically inserts separators in `value` at `cursor_position` if expected, eventually advancing + the current cursor position. + + Args: + value: Current control value entered by user. + cursor_position: Where to start inserting separators (if any). + + Returns: + A tuple in the form `(value, cursor_position)` with new value and possibly advanced cursor position. + """ while cursor_position < len(self.template) and ( - self.template[cursor_position].flags & _CharFlags.SEPARATOR + _CharFlags.SEPARATOR in self.template[cursor_position].flags ): value = ( value[:cursor_position] @@ -205,25 +251,35 @@ def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int] return value, cursor_position def insert_text_at_cursor(self, text: str) -> str | None: + """Inserts `text` at current cursor position. If not present in `text`, any expected separator is automatically + inserted at the correct position. + + Args: + text: The text to be inserted. + + Returns: + A tuple in the form `(value, cursor_position)` with the new control value and current cursor position if + `text` matches the template, None otherwise. + """ value = self.input.value cursor_position = self.input.cursor_position separators = set( [ - char_def.char - for char_def in self.template - if char_def.flags & _CharFlags.SEPARATOR + char_definition.char + for char_definition in self.template + if _CharFlags.SEPARATOR in char_definition.flags ] ) - for c in text: - if c in separators: - if c == self.next_separator(cursor_position): + for char in text: + if char in separators: + if char == self.next_separator(cursor_position): prev_position = self.prev_separator_position(cursor_position) if (cursor_position > 0) and (prev_position != cursor_position - 1): next_position = self.next_separator_position(cursor_position) while cursor_position < next_position + 1: if ( - self.template[cursor_position].flags - & _CharFlags.SEPARATOR + _CharFlags.SEPARATOR + in self.template[cursor_position].flags ): char = self.template[cursor_position].char else: @@ -237,49 +293,65 @@ def insert_text_at_cursor(self, text: str) -> str | None: continue if cursor_position >= len(self.template): break - char_def = self.template[cursor_position] - assert (char_def.flags & _CharFlags.SEPARATOR) == 0 - if not char_def.pattern.match(c): + char_definition = self.template[cursor_position] + assert _CharFlags.SEPARATOR not in char_definition.flags + if not char_definition.pattern.match(char): return None - if char_def.flags & _CharFlags.LOWERCASE: - c = c.lower() - elif char_def.flags & _CharFlags.UPPERCASE: - c = c.upper() - value = value[:cursor_position] + c + value[cursor_position + 1 :] + if _CharFlags.LOWERCASE in char_definition.flags: + char = char.lower() + elif _CharFlags.UPPERCASE in char_definition.flags: + char = char.upper() + value = value[:cursor_position] + char + value[cursor_position + 1 :] cursor_position += 1 value, cursor_position = self.insert_separators(value, cursor_position) return value, cursor_position def move_cursor(self, delta: int) -> None: + """Moves the cursor position by `delta` characters, skipping separators if + running over them. + + Args: + delta: The number of characters to move; positive moves right, negative + moves left. + """ cursor_position = self.input.cursor_position if delta < 0 and all( - [c.flags & _CharFlags.SEPARATOR for c in self.template[:cursor_position]] + [ + (_CharFlags.SEPARATOR in char_definition.flags) + for char_definition in self.template[:cursor_position] + ] ): return cursor_position += delta while ( (cursor_position >= 0) and (cursor_position < len(self.template)) - and (self.template[cursor_position].flags & _CharFlags.SEPARATOR) + and (_CharFlags.SEPARATOR in self.template[cursor_position].flags) ): cursor_position += delta self.input.cursor_position = cursor_position def delete_at_position(self, position: int | None = None) -> None: + """Deletes character at `position`. + + Args: + position: Position within the control value where to delete a character; + if None the current cursor position is used. + """ value = self.input.value if position is None: position = self.input.cursor_position cursor_position = position if cursor_position < len(self.template): - assert (self.template[cursor_position].flags & _CharFlags.SEPARATOR) == 0 + assert _CharFlags.SEPARATOR not in self.template[cursor_position].flags if cursor_position == len(value) - 1: value = value[:cursor_position] else: value = value[:cursor_position] + " " + value[cursor_position + 1 :] pos = len(value) while pos > 0: - char_def = self.template[pos - 1] - if ((char_def.flags & _CharFlags.SEPARATOR) == 0) and ( + char_definition = self.template[pos - 1] + if (_CharFlags.SEPARATOR not in char_definition.flags) and ( value[pos - 1] != " " ): break @@ -292,32 +364,74 @@ def delete_at_position(self, position: int | None = None) -> None: self.input.value = value def at_separator(self, position: int | None = None) -> bool: + """Checks if character at `position` is a separator. + + Args: + position: Position within the control value where to check; + if None the current cursor position is used. + + Returns: + True if character is a separator, False otherwise. + """ if position is None: position = self.input.cursor_position if (position >= 0) and (position < len(self.template)): - return bool(self.template[position].flags & _CharFlags.SEPARATOR) + return _CharFlags.SEPARATOR in self.template[position].flags else: return False def prev_separator_position(self, position: int | None = None) -> int | None: + """Obtains the position of the previous separator character starting from + `position` within the template string. + + Args: + position: Starting position from which to search previous separator. + If None, current cursor position is used. + + Returns: + The position of the previous separator, or None if no previous + separator is found. + """ if position is None: position = self.input.cursor_position for index in range(position - 1, 0, -1): - if self.template[index].flags & _CharFlags.SEPARATOR: + if _CharFlags.SEPARATOR in self.template[index].flags: return index else: return None def next_separator_position(self, position: int | None = None) -> int | None: + """Obtains the position of the next separator character starting from + `position` within the template string. + + Args: + position: Starting position from which to search next separator. + If None, current cursor position is used. + + Returns: + The position of the next separator, or None if no next + separator is found. + """ if position is None: position = self.input.cursor_position for index in range(position + 1, len(self.template)): - if self.template[index].flags & _CharFlags.SEPARATOR: + if _CharFlags.SEPARATOR in self.template[index].flags: return index else: return None def next_separator(self, position: int | None = None) -> str | None: + """Obtains the next separator character starting from `position` + within the template string. + + Args: + position: Starting position from which to search next separator. + If None, current cursor position is used. + + Returns: + The next separator character, or None if no next + separator is found. + """ position = self.next_separator_position(position) if position is None: return None @@ -325,31 +439,53 @@ def next_separator(self, position: int | None = None) -> str | None: return self.template[position].char def display(self, value: str) -> str: + """Returns `value` ready for display, with spaces replaced by + placeholder characters. + + Args: + value: String value to display. + + Returns: + New string value with spaces replaced by placeholders. + """ result = [] - for c, char_def in zip(value, self.template): - if c == " ": - c = char_def.char - result.append(c) + for char, char_definition in zip(value, self.template): + if char == " ": + char = char_definition.char + result.append(char) return "".join(result) def update_mask(self, placeholder: str) -> None: - for index, char_def in enumerate(self.template): - if (char_def.flags & _CharFlags.SEPARATOR) == 0: + """Updates template placeholder characters from `placeholder`. If + given string is smaller than template string, template blank character + is used to fill remaining template placeholder characters. + + Args: + placeholder: New placeholder string. + """ + for index, char_definition in enumerate(self.template): + if _CharFlags.SEPARATOR not in char_definition.flags: if index < len(placeholder): - char_def.char = placeholder[index] + char_definition.char = placeholder[index] else: - char_def.char = self.blank + char_definition.char = self.blank @property def mask(self) -> str: - return "".join([c.char for c in self.template]) + """Property returning the template placeholder mask.""" + return "".join([char_definition.char for char_definition in self.template]) @property def empty_mask(self) -> str: + """Property returning the template placeholder mask with all non-separators replaced by space.""" return "".join( [ - " " if (c.flags & _CharFlags.SEPARATOR) == 0 else c.char - for c in self.template + ( + " " + if (_CharFlags.SEPARATOR not in char_definition.flags) + else char_definition.char + ) + for char_definition in self.template ] ) @@ -413,6 +549,7 @@ def __init__( self.tooltip = tooltip def validate_value(self, value: str) -> str: + """Validates value against template.""" if self._template is None: return value if not self._template.check(value, True): @@ -469,6 +606,7 @@ def _value(self) -> Text: return Text(value, no_wrap=True, overflow="ignore") async def _on_click(self, event: events.Click) -> None: + """Ensure clicking on value does not leave cursor on a separator.""" await super()._on_click(event) if self._template.at_separator(): self._template.move_cursor(1) @@ -491,11 +629,11 @@ def clear(self) -> None: self.value, self.cursor_position = self._template.insert_separators("", 0) def action_cursor_left(self) -> None: - """Move the cursor one position to the left.""" + """Move the cursor one position to the left; separators are skipped.""" self._template.move_cursor(-1) def action_cursor_right(self) -> None: - """Accept an auto-completion or move the cursor one position to the right.""" + """Move the cursor one position to the right; separators are skipped.""" self._template.move_cursor(1) def action_home(self) -> None: @@ -503,7 +641,8 @@ def action_home(self) -> None: self._template.move_cursor(-len(self.template)) def action_cursor_left_word(self) -> None: - """Move the cursor left to the start of a word.""" + """Move the cursor left next to the previous separator. If no previous + separator is found, moves the cursor to the start of the input.""" if self._template.at_separator(self.cursor_position - 1): position = self._template.prev_separator_position(self.cursor_position - 1) else: @@ -513,7 +652,8 @@ def action_cursor_left_word(self) -> None: self.cursor_position = position or 0 def action_cursor_right_word(self) -> None: - """Move the cursor right to the start of a word.""" + """Move the cursor right next to the next separator. If no next + separator is found, moves the cursor to the end of the input.""" position = self._template.next_separator_position() if position is None: self.cursor_position = len(self._template.mask) @@ -525,7 +665,8 @@ def action_delete_right(self) -> None: self._template.delete_at_position() def action_delete_right_word(self) -> None: - """Delete the current character and all rightward to the start of the next word.""" + """Delete the current character and all rightward to next separator or + the end of the input.""" position = self._template.next_separator_position() if position is not None: position += 1 @@ -545,7 +686,8 @@ def action_delete_left(self) -> None: self._template.delete_at_position() def action_delete_left_word(self) -> None: - """Delete leftward of the cursor position to the start of a word.""" + """Delete leftward of the cursor position to the previous separator or + the start of the input.""" if self.cursor_position <= 0: return if self._template.at_separator(self.cursor_position - 1): From d67431c045c41675318619bf677274c12c35cd96 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Sun, 21 Jul 2024 20:47:46 +0100 Subject: [PATCH 03/80] typing --- src/textual/renderables/styled.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/textual/renderables/styled.py b/src/textual/renderables/styled.py index 71caff4183..40ae6af372 100644 --- a/src/textual/renderables/styled.py +++ b/src/textual/renderables/styled.py @@ -4,13 +4,8 @@ from rich.segment import Segment if TYPE_CHECKING: - from rich.console import ( - Console, - ConsoleOptions, - RenderableType, - RenderResult, - StyleType, - ) + from rich.console import Console, ConsoleOptions, RenderableType, RenderResult + from rich.style import StyleType class Styled: From a26851d0784020f4ab8170d8c6bccdfad0c7ff67 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 11:43:05 +0100 Subject: [PATCH 04/80] fix select --- src/textual/widgets/_select.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/textual/widgets/_select.py b/src/textual/widgets/_select.py index 6049dd3227..ef5be915c5 100644 --- a/src/textual/widgets/_select.py +++ b/src/textual/widgets/_select.py @@ -493,7 +493,10 @@ def _on_mount(self, _event: events.Mount) -> None: def _watch_expanded(self, expanded: bool) -> None: """Display or hide overlay.""" - overlay = self.query_one(SelectOverlay) + try: + overlay = self.query_one(SelectOverlay) + except NoMatches: + return self.set_class(expanded, "-expanded") if expanded: overlay.focus() From 5ffc452e46242a43538ab972fbee218acb03c265 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 11:45:37 +0100 Subject: [PATCH 05/80] changelog --- CHANGELOG.md | 1 + tests/select/test_remove.py | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/select/test_remove.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 094daa66cb..fce8b7c21e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 +- Fixed exception when removing Selects ## [0.73.0] - 2024-07-18 diff --git a/tests/select/test_remove.py b/tests/select/test_remove.py new file mode 100644 index 0000000000..989884a8c9 --- /dev/null +++ b/tests/select/test_remove.py @@ -0,0 +1,25 @@ +from textual.app import App, ComposeResult +from textual.widgets import Header, Select + +LINES = """I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me.""".splitlines() + + +async def test_select_remove(): + # Regression test for https://github.com/Textualize/textual/issues/4782 + class SelectApp(App): + def compose(self) -> ComposeResult: + self.select = Select((line, line) for line in LINES) + self.select.watch_value = self.on_select + yield Header() + yield self.select + + def on_select(self): + self.select.remove() + + app = SelectApp() + async with app.run_test() as pilot: + await pilot.press("enter", "down", "down", "enter") From 7936693716e723ede09267d97bd07b377e28faf1 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 11:47:14 +0100 Subject: [PATCH 06/80] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fce8b7c21e..7912084a08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 -- Fixed exception when removing Selects +- Fixed exception when removing Selects https://github.com/Textualize/textual/pull/4786 ## [0.73.0] - 2024-07-18 From fa3b6749e6ae65ff5ec7a43c5e6915d395b19547 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 12:19:01 +0100 Subject: [PATCH 07/80] comment --- src/textual/widgets/_select.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textual/widgets/_select.py b/src/textual/widgets/_select.py index ef5be915c5..12c6f05537 100644 --- a/src/textual/widgets/_select.py +++ b/src/textual/widgets/_select.py @@ -496,6 +496,7 @@ def _watch_expanded(self, expanded: bool) -> None: try: overlay = self.query_one(SelectOverlay) except NoMatches: + # The widget has likely been removed return self.set_class(expanded, "-expanded") if expanded: From 7c817dc201f5646b0f75334ba395c6b43de371a3 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 15:54:03 +0100 Subject: [PATCH 08/80] refactor of screen dismiss --- src/textual/_dispatch_key.py | 64 ++++++++++++++++++++++++++++++++++++ src/textual/app.py | 3 +- src/textual/message_pump.py | 61 ---------------------------------- src/textual/screen.py | 8 +++-- src/textual/widget.py | 3 +- 5 files changed, 73 insertions(+), 66 deletions(-) create mode 100644 src/textual/_dispatch_key.py diff --git a/src/textual/_dispatch_key.py b/src/textual/_dispatch_key.py new file mode 100644 index 0000000000..e4b0a5e8a9 --- /dev/null +++ b/src/textual/_dispatch_key.py @@ -0,0 +1,64 @@ +from typing import Callable + +from . import events +from ._callback import invoke +from .dom import DOMNode +from .errors import DuplicateKeyHandlers +from .message_pump import MessagePump + + +async def dispatch_key(node: DOMNode, event: events.Key) -> bool: + """Dispatch a key event to method. + + This method will call the method named 'key_' if it exists. + Some keys have aliases. The first alias found will be invoked if it exists. + If multiple handlers exist that match the key, an exception is raised. + + Args: + event: A key event. + + Returns: + True if key was handled, otherwise False. + + Raises: + DuplicateKeyHandlers: When there's more than 1 handler that could handle this key. + """ + + def get_key_handler(pump: MessagePump, key: str) -> Callable | None: + """Look for the public and private handler methods by name on self.""" + return getattr(pump, f"key_{key}", None) or getattr(pump, f"_key_{key}", None) + + handled = False + invoked_method = None + key_name = event.name + if not key_name: + return False + + def _raise_duplicate_key_handlers_error( + key_name: str, first_handler: str, second_handler: str + ) -> None: + """Raise exception for case where user presses a key and there are multiple candidate key handler methods for it.""" + raise DuplicateKeyHandlers( + f"Multiple handlers for key press {key_name!r}.\n" + f"We found both {first_handler!r} and {second_handler!r}, " + f"and didn't know which to call.\n" + f"Consider combining them into a single handler.", + ) + + screen = node.screen + for key_method_name in event.name_aliases: + key_method = get_key_handler(node, key_method_name) + if key_method is not None: + if invoked_method: + _raise_duplicate_key_handlers_error( + key_name, invoked_method.__name__, key_method.__name__ + ) + # If key handlers return False, then they are not considered handled + # This allows key handlers to do some conditional logic + + if not screen.is_active: + break + handled = (await invoke(key_method, event)) is not False + invoked_method = key_method + + return handled diff --git a/src/textual/app.py b/src/textual/app.py index 9f38dcb3af..5e23f429c1 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -72,6 +72,7 @@ from ._compositor import CompositorUpdate from ._context import active_app, active_message_pump from ._context import message_hook as message_hook_context_var +from ._dispatch_key import dispatch_key from ._event_broker import NoHandler, extract_handler_actions from ._path import CSSPathType, _css_path_type_as_list, _make_path_object_relative from ._types import AnimationLevel @@ -3282,7 +3283,7 @@ async def _on_layout(self, message: messages.Layout) -> None: async def _on_key(self, event: events.Key) -> None: if not (await self._check_bindings(event.key)): - await self.dispatch_key(event) + await dispatch_key(self, event) async def _on_resize(self, event: events.Resize) -> None: event.stop() diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 108c51b4cf..9b7a597f9a 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -36,7 +36,6 @@ from ._on import OnNoWidget from ._time import time from .css.match import match -from .errors import DuplicateKeyHandlers from .events import Event from .message import Message from .reactive import Reactive, TooManyComputesError @@ -802,54 +801,6 @@ async def on_callback(self, event: events.Callback) -> None: return await invoke(event.callback) - # TODO: Does dispatch_key belong on message pump? - async def dispatch_key(self, event: events.Key) -> bool: - """Dispatch a key event to method. - - This method will call the method named 'key_' if it exists. - Some keys have aliases. The first alias found will be invoked if it exists. - If multiple handlers exist that match the key, an exception is raised. - - Args: - event: A key event. - - Returns: - True if key was handled, otherwise False. - - Raises: - DuplicateKeyHandlers: When there's more than 1 handler that could handle this key. - """ - - def get_key_handler(pump: MessagePump, key: str) -> Callable | None: - """Look for the public and private handler methods by name on self.""" - public_handler_name = f"key_{key}" - public_handler = getattr(pump, public_handler_name, None) - - private_handler_name = f"_key_{key}" - private_handler = getattr(pump, private_handler_name, None) - - return public_handler or private_handler - - handled = False - invoked_method = None - key_name = event.name - if not key_name: - return False - - for key_method_name in event.name_aliases: - key_method = get_key_handler(self, key_method_name) - if key_method is not None: - if invoked_method: - _raise_duplicate_key_handlers_error( - key_name, invoked_method.__name__, key_method.__name__ - ) - # If key handlers return False, then they are not considered handled - # This allows key handlers to do some conditional logic - handled = (await invoke(key_method, event)) is not False - invoked_method = key_method - - return handled - async def on_timer(self, event: events.Timer) -> None: if not self.app._running: return @@ -862,15 +813,3 @@ async def on_timer(self, event: events.Timer) -> None: raise CallbackError( f"unable to run callback {event.callback!r}; {error}" ) - - -def _raise_duplicate_key_handlers_error( - key_name: str, first_handler: str, second_handler: str -) -> None: - """Raise exception for case where user presses a key and there are multiple candidate key handler methods for it.""" - raise DuplicateKeyHandlers( - f"Multiple handlers for key press {key_name!r}.\n" - f"We found both {first_handler!r} and {second_handler!r}, " - f"and didn't know which to call.\n" - f"Consider combining them into a single handler.", - ) diff --git a/src/textual/screen.py b/src/textual/screen.py index 43750d5417..d51831da3c 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1253,12 +1253,14 @@ def dismiss( """ if not self.is_active: - from .app import ScreenError - - raise ScreenError("Screen is not active") + self.log.warning("Can't dismiss inactive screen") + return AwaitComplete() if result is not self._NoResult and self._result_callbacks: self._result_callbacks[-1](cast(ScreenResultType, result)) await_pop = self.app.pop_screen() + if asyncio.current_task() is self._task: + self.log.warning("Can't await dismiss from a screen's own message handler") + return AwaitComplete() return await_pop async def action_dismiss( diff --git a/src/textual/widget.py b/src/textual/widget.py index 8c4f1598d5..f4b0463e7d 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -50,6 +50,7 @@ from ._arrange import DockArrangeResult, arrange from ._compose import compose from ._context import NoActiveAppError, active_app +from ._dispatch_key import dispatch_key from ._easing import DEFAULT_SCROLL_EASING from ._layout import Layout from ._segment_tools import align_lines @@ -3775,7 +3776,7 @@ async def _on_key(self, event: events.Key) -> None: await self.handle_key(event) async def handle_key(self, event: events.Key) -> bool: - return await self.dispatch_key(event) + return await dispatch_key(self, event) async def _on_compose(self, event: events.Compose) -> None: _rich_traceback_omit = True From f328c35aece91e660f1ac5427d85461eb73850ca Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 22 Jul 2024 16:47:12 +0100 Subject: [PATCH 09/80] refactor --- src/textual/_dispatch_key.py | 10 ++++++---- src/textual/app.py | 2 +- src/textual/screen.py | 9 ++------- tests/test_message_pump.py | 7 ++++--- tests/test_screens.py | 8 +++++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/textual/_dispatch_key.py b/src/textual/_dispatch_key.py index e4b0a5e8a9..92bf7312c8 100644 --- a/src/textual/_dispatch_key.py +++ b/src/textual/_dispatch_key.py @@ -45,10 +45,12 @@ def _raise_duplicate_key_handlers_error( f"Consider combining them into a single handler.", ) - screen = node.screen + try: + screen = node.screen + except Exception: + screen = None for key_method_name in event.name_aliases: - key_method = get_key_handler(node, key_method_name) - if key_method is not None: + if (key_method := get_key_handler(node, key_method_name)) is not None: if invoked_method: _raise_duplicate_key_handlers_error( key_name, invoked_method.__name__, key_method.__name__ @@ -56,7 +58,7 @@ def _raise_duplicate_key_handlers_error( # If key handlers return False, then they are not considered handled # This allows key handlers to do some conditional logic - if not screen.is_active: + if screen is not None and not screen.is_active: break handled = (await invoke(key_method, event)) is not False invoked_method = key_method diff --git a/src/textual/app.py b/src/textual/app.py index 5e23f429c1..7aab856659 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -801,7 +801,7 @@ def is_inline(self) -> bool: return False if self._driver is None else self._driver.is_inline @property - def screen_stack(self) -> Sequence[Screen[Any]]: + def screen_stack(self) -> list[Screen[Any]]: """A snapshot of the current screen stack. Returns: diff --git a/src/textual/screen.py b/src/textual/screen.py index d51831da3c..b7e8c5998b 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1237,8 +1237,8 @@ def dismiss( !!! note - Only the active screen may be dismissed. If you try to dismiss a screen that isn't active, - this method will raise a `ScreenError`. + Only the active screen may be dismissed. This method will produce a warning in the logs if + called on an inactive screen (but otherwise have no effect). If `result` is provided and a callback was set when the screen was [pushed][textual.app.App.push_screen], then the callback will be invoked with `result`. @@ -1246,11 +1246,6 @@ def dismiss( Args: result: The optional result to be passed to the result callback. - Raises: - ScreenError: If the screen being dismissed is not active. - ScreenStackError: If trying to dismiss a screen that is not at the top of - the stack. - """ if not self.is_active: self.log.warning("Can't dismiss inactive screen") diff --git a/tests/test_message_pump.py b/tests/test_message_pump.py index 90b840bf85..58fb5d325a 100644 --- a/tests/test_message_pump.py +++ b/tests/test_message_pump.py @@ -1,5 +1,6 @@ import pytest +from textual._dispatch_key import dispatch_key from textual.app import App, ComposeResult from textual.errors import DuplicateKeyHandlers from textual.events import Key @@ -20,7 +21,7 @@ def key_ctrl_i(self): async def test_dispatch_key_valid_key(): widget = ValidWidget() - result = await widget.dispatch_key(Key(key="x", character="x")) + result = await dispatch_key(widget, Key(key="x", character="x")) assert result is True assert widget.called_by == widget.key_x @@ -29,7 +30,7 @@ async def test_dispatch_key_valid_key_alias(): """When you press tab or ctrl+i, it comes through as a tab key event, but handlers for tab and ctrl+i are both considered valid.""" widget = ValidWidget() - result = await widget.dispatch_key(Key(key="tab", character="\t")) + result = await dispatch_key(widget, Key(key="tab", character="\t")) assert result is True assert widget.called_by == widget.key_ctrl_i @@ -55,7 +56,7 @@ async def test_dispatch_key_raises_when_conflicting_handler_aliases(): In the terminal, they're the same thing, so we fail fast via exception here.""" widget = DuplicateHandlersWidget() with pytest.raises(DuplicateKeyHandlers): - await widget.dispatch_key(Key(key="tab", character="\t")) + await dispatch_key(widget, Key(key="tab", character="\t")) assert widget.called_by == widget.key_tab diff --git a/tests/test_screens.py b/tests/test_screens.py index aef83dfdb4..adb8afecd6 100644 --- a/tests/test_screens.py +++ b/tests/test_screens.py @@ -5,7 +5,7 @@ import pytest from textual import work -from textual.app import App, ComposeResult, ScreenError, ScreenStackError +from textual.app import App, ComposeResult, ScreenStackError from textual.events import MouseMove from textual.geometry import Offset from textual.screen import Screen @@ -301,8 +301,10 @@ async def key_p(self) -> None: app = MyApp() async with app.run_test() as pilot: await pilot.press("p") - with pytest.raises(ScreenError): - await app.bottom.dismiss() + # A noop if not the top + stack = list(app.screen_stack) + await app.bottom.dismiss() + assert app.screen_stack == stack async def test_dismiss_action(): From 75c6ca3168d592f2a953c087b6189b6bce1a55e3 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 23 Jul 2024 10:59:05 +0100 Subject: [PATCH 10/80] annotations fix --- src/textual/_dispatch_key.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/textual/_dispatch_key.py b/src/textual/_dispatch_key.py index 92bf7312c8..f4ba908da7 100644 --- a/src/textual/_dispatch_key.py +++ b/src/textual/_dispatch_key.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from typing import Callable from . import events @@ -10,7 +12,7 @@ async def dispatch_key(node: DOMNode, event: events.Key) -> bool: """Dispatch a key event to method. - This method will call the method named 'key_' if it exists. + This function will call the method named 'key_' on a node if it exists. Some keys have aliases. The first alias found will be invoked if it exists. If multiple handlers exist that match the key, an exception is raised. From 66ff918498bcc079bbf8bafd33a2b5fcdfbf79ee Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 23 Jul 2024 12:06:06 +0100 Subject: [PATCH 11/80] pre await callback --- src/textual/await_complete.py | 26 ++++++++++++++++++++++++-- src/textual/screen.py | 25 +++++++++++++++++++------ 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/textual/await_complete.py b/src/textual/await_complete.py index ebc3c84ea5..c6a72d27de 100644 --- a/src/textual/await_complete.py +++ b/src/textual/await_complete.py @@ -1,25 +1,44 @@ from __future__ import annotations from asyncio import Future, gather -from typing import Any, Awaitable, Generator +from typing import TYPE_CHECKING, Any, Awaitable, Generator import rich.repr from typing_extensions import Self from .message_pump import MessagePump +if TYPE_CHECKING: + from .types import CallbackType + @rich.repr.auto(angular=True) class AwaitComplete: """An 'optionally-awaitable' object which runs one or more coroutines (or other awaitables) concurrently.""" - def __init__(self, *awaitables: Awaitable) -> None: + def __init__( + self, *awaitables: Awaitable, pre_await: CallbackType | None = None + ) -> None: """Create an AwaitComplete. Args: awaitables: One or more awaitables to run concurrently. """ + self._awaitables = awaitables self._future: Future[Any] = gather(*awaitables) + self._pre_await: CallbackType | None = pre_await + + def __rich_repr__(self) -> rich.repr.Result: + yield self._awaitables + yield "pre_await", self._pre_await, None + + def set_pre_await_callback(self, pre_await: CallbackType | None) -> None: + """Set a callback to run prior to awaiting. + + Args: + pre_await: A callback. + """ + self._pre_await = pre_await def call_next(self, node: MessagePump) -> Self: """Await after the next message. @@ -34,6 +53,9 @@ async def __call__(self) -> Any: return await self def __await__(self) -> Generator[Any, None, Any]: + _rich_traceback_omit = True + if self._pre_await is not None: + self._pre_await() return self._future.__await__() @property diff --git a/src/textual/screen.py b/src/textual/screen.py index b7e8c5998b..aa813e3844 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1235,10 +1235,12 @@ def dismiss( ) -> AwaitComplete: """Dismiss the screen, optionally with a result. - !!! note + Only the active screen may be dismissed. This method will produce a warning in the logs if + called on an inactive screen (but otherwise have no effect). - Only the active screen may be dismissed. This method will produce a warning in the logs if - called on an inactive screen (but otherwise have no effect). + !!! warning + + You should avoid awaiting the return value from the Screen's message handler, or a widget in the screen being dismissed. If `result` is provided and a callback was set when the screen was [pushed][textual.app.App.push_screen], then the callback will be invoked with `result`. @@ -1247,15 +1249,26 @@ def dismiss( result: The optional result to be passed to the result callback. """ + _rich_traceback_omit = True if not self.is_active: self.log.warning("Can't dismiss inactive screen") return AwaitComplete() if result is not self._NoResult and self._result_callbacks: self._result_callbacks[-1](cast(ScreenResultType, result)) await_pop = self.app.pop_screen() - if asyncio.current_task() is self._task: - self.log.warning("Can't await dismiss from a screen's own message handler") - return AwaitComplete() + + def pre_await() -> None: + """Called by the AwaitComplete object.""" + _rich_traceback_omit = True + if active_message_pump.get() is self: + from textual.app import ScreenError + + raise ScreenError( + "Can't await screen.dismiss() from the screen's message handler; try removing the await keyword." + ) + + await_pop.set_pre_await_callback(pre_await) + return await_pop async def action_dismiss( From 48e058b2676bd82529bb7ca107020a6fd1297756 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 23 Jul 2024 13:43:24 +0100 Subject: [PATCH 12/80] docs --- src/textual/await_complete.py | 3 +++ src/textual/screen.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/textual/await_complete.py b/src/textual/await_complete.py index c6a72d27de..0780f7caaf 100644 --- a/src/textual/await_complete.py +++ b/src/textual/await_complete.py @@ -35,6 +35,9 @@ def __rich_repr__(self) -> rich.repr.Result: def set_pre_await_callback(self, pre_await: CallbackType | None) -> None: """Set a callback to run prior to awaiting. + This is used by Textual, mainly to check for possible deadlocks. + You are unlikely to need to call this method in an app. + Args: pre_await: A callback. """ diff --git a/src/textual/screen.py b/src/textual/screen.py index aa813e3844..d978bba440 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1240,7 +1240,9 @@ def dismiss( !!! warning - You should avoid awaiting the return value from the Screen's message handler, or a widget in the screen being dismissed. + Textual will raise a [`ScreenError`][textual.app.ScreenError] if you await the return value from a + message handler on the Screen being dismissed. If you want to dismiss the current screen, you can + call `self.dimiss()` _without_ awaiting. If `result` is provided and a callback was set when the screen was [pushed][textual.app.App.push_screen], then the callback will be invoked with `result`. From 41a2cf345d9332cf7516af96cf0ebec07801cc15 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 23 Jul 2024 13:45:19 +0100 Subject: [PATCH 13/80] typo --- src/textual/screen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index d978bba440..f1d308111d 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1242,7 +1242,7 @@ def dismiss( Textual will raise a [`ScreenError`][textual.app.ScreenError] if you await the return value from a message handler on the Screen being dismissed. If you want to dismiss the current screen, you can - call `self.dimiss()` _without_ awaiting. + call `self.dismiss()` _without_ awaiting. If `result` is provided and a callback was set when the screen was [pushed][textual.app.App.push_screen], then the callback will be invoked with `result`. From 8580c0b67fd1d91d67be241fcf28a47ffd6cdf3d Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 16:05:00 +0100 Subject: [PATCH 14/80] improve simulate key --- src/textual/app.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/textual/app.py b/src/textual/app.py index 7aab856659..4952cc91f9 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -3029,7 +3029,14 @@ def simulate_key(self, key: str) -> None: Args: key: Key to simulate. May also be the name of a key, e.g. "space". """ - self.call_later(self._check_bindings, key) + event = events.Key(key, None) + self.post_message(event) + + # async def dispatch_simulated_key() -> None: + # if not (await self._check_bindings(event.key, priority=True)): + # await dispatch_key(self, event) + + # self.call_later(dispatch_simulated_key) async def _check_bindings(self, key: str, priority: bool = False) -> bool: """Handle a key press. From 86d29406634d5d1123c0170a73e1bf2e70809476 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 16:45:13 +0100 Subject: [PATCH 15/80] add test --- src/textual/app.py | 9 +----- src/textual/pilot.py | 1 + tests/footer/test_footer.py | 58 +++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 tests/footer/test_footer.py diff --git a/src/textual/app.py b/src/textual/app.py index 4952cc91f9..1fa10ef0ce 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -3029,14 +3029,7 @@ def simulate_key(self, key: str) -> None: Args: key: Key to simulate. May also be the name of a key, e.g. "space". """ - event = events.Key(key, None) - self.post_message(event) - - # async def dispatch_simulated_key() -> None: - # if not (await self._check_bindings(event.key, priority=True)): - # await dispatch_key(self, event) - - # self.call_later(dispatch_simulated_key) + self.post_message(events.Key(key, None)) async def _check_bindings(self, key: str, priority: bool = False) -> bool: """Handle a key press. diff --git a/src/textual/pilot.py b/src/textual/pilot.py index 036b18a6b3..90c4baf0d2 100644 --- a/src/textual/pilot.py +++ b/src/textual/pilot.py @@ -342,6 +342,7 @@ async def _post_mouse_events( # E.g., the click event is preceded by MouseDown/MouseUp to emulate how # the driver works and emits a click event. widget_at, _ = app.get_widget_at(*offset) + print(widget_at) event = mouse_event_cls(**message_arguments) # Bypass event processing in App.on_event. Because App.on_event # is responsible for updating App.mouse_position, and because diff --git a/tests/footer/test_footer.py b/tests/footer/test_footer.py new file mode 100644 index 0000000000..d4ed2d59f8 --- /dev/null +++ b/tests/footer/test_footer.py @@ -0,0 +1,58 @@ +from textual.app import App, ComposeResult +from textual.binding import Binding +from textual.widget import Widget +from textual.widgets import Button, Footer + + +async def test_footer_bindings() -> None: + app_binding_count = 0 + + class TestWidget(Widget, can_focus=True): + BINDINGS = [ + Binding("b", "widget_binding", "Overridden Binding"), + ] + + DEFAULT_CSS = """ + TestWidget { + border: tall $background; + width: 50%; + height: 50%; + content-align: center middle; + + &:focus { + border: tall $accent; + } + } + """ + + def action_widget_binding(self) -> None: + assert False, "should never be called since there is a priority binding" + + class PriorityBindingApp(App): + BINDINGS = [ + Binding("b", "app_binding", "Priority Binding", priority=True), + ] + + CSS = """ + Screen { + align: center middle; + } + """ + + def compose(self) -> ComposeResult: + yield TestWidget() + yield Button("Move Focus") + yield Footer() + + def action_app_binding(self) -> None: + nonlocal app_binding_count + app_binding_count += 1 + + app = PriorityBindingApp() + async with app.run_test() as pilot: + await pilot.pause() + assert app_binding_count == 0 + await pilot.click("Footer", offset=(1, 0)) + assert app_binding_count == 1 + await pilot.click("Footer") + assert app_binding_count == 2 From 70f3ea92f59443a074baf40e04c7aaa83eeb9a26 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 16:45:56 +0100 Subject: [PATCH 16/80] remove debug --- src/textual/pilot.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/textual/pilot.py b/src/textual/pilot.py index 90c4baf0d2..036b18a6b3 100644 --- a/src/textual/pilot.py +++ b/src/textual/pilot.py @@ -342,7 +342,6 @@ async def _post_mouse_events( # E.g., the click event is preceded by MouseDown/MouseUp to emulate how # the driver works and emits a click event. widget_at, _ = app.get_widget_at(*offset) - print(widget_at) event = mouse_event_cls(**message_arguments) # Bypass event processing in App.on_event. Because App.on_event # is responsible for updating App.mouse_position, and because From a6c15d71cb1f7370026abc72252dd1fe520b1c1a Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 16:46:51 +0100 Subject: [PATCH 17/80] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7912084a08..e4629f1a74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 - Fixed exception when removing Selects https://github.com/Textualize/textual/pull/4786 +- Fixed issue with non-clickable Footer keys https://github.com/Textualize/textual/pull/4798 ## [0.73.0] - 2024-07-18 From ba8ba51eb8dfdc31c35c51e744661754dc5fc6a1 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 10:12:22 +0100 Subject: [PATCH 18/80] allow None in callback --- src/textual/screen.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index f1d308111d..8ef0134f82 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -68,7 +68,8 @@ """The result type of a screen.""" ScreenResultCallbackType = Union[ - Callable[[ScreenResultType], None], Callable[[ScreenResultType], Awaitable[None]] + Callable[[ScreenResultType | None], None], + Callable[[ScreenResultType | None], Awaitable[None]], ] """Type of a screen result callback function.""" @@ -1244,8 +1245,7 @@ def dismiss( message handler on the Screen being dismissed. If you want to dismiss the current screen, you can call `self.dismiss()` _without_ awaiting. - If `result` is provided and a callback was set when the screen was [pushed][textual.app.App.push_screen], then - the callback will be invoked with `result`. + If `result` is not supplied, then the callback will be invoked with `None`. Args: result: The optional result to be passed to the result callback. @@ -1255,8 +1255,10 @@ def dismiss( if not self.is_active: self.log.warning("Can't dismiss inactive screen") return AwaitComplete() - if result is not self._NoResult and self._result_callbacks: - self._result_callbacks[-1](cast(ScreenResultType, result)) + if self._result_callbacks: + self._result_callbacks[-1]( + cast(ScreenResultType, None if result is self._NoResult else result) + ) await_pop = self.app.pop_screen() def pre_await() -> None: From b28a98748454900162db8a4a0a30bcaa1a73391d Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:30:10 +0100 Subject: [PATCH 19/80] fix command palette --- docs/examples/guide/screens/modal03.py | 2 +- src/textual/_debug.py | 23 ++++++++++++++++++ src/textual/app.py | 2 +- src/textual/await_complete.py | 4 ++++ src/textual/await_remove.py | 10 ++++++++ src/textual/command.py | 7 +++--- src/textual/message_pump.py | 5 ++++ src/textual/screen.py | 33 +++++++++++--------------- src/textual/widget.py | 8 +++++++ tests/test_modal.py | 2 +- 10 files changed, 71 insertions(+), 25 deletions(-) create mode 100644 src/textual/_debug.py diff --git a/docs/examples/guide/screens/modal03.py b/docs/examples/guide/screens/modal03.py index 410722255c..6f796234fe 100644 --- a/docs/examples/guide/screens/modal03.py +++ b/docs/examples/guide/screens/modal03.py @@ -44,7 +44,7 @@ def compose(self) -> ComposeResult: def action_request_quit(self) -> None: """Action to display the quit dialog.""" - def check_quit(quit: bool) -> None: + def check_quit(quit: bool | None) -> None: """Called when QuitScreen is dismissed.""" if quit: self.exit() diff --git a/src/textual/_debug.py b/src/textual/_debug.py new file mode 100644 index 0000000000..7e02f918e7 --- /dev/null +++ b/src/textual/_debug.py @@ -0,0 +1,23 @@ +""" +Function related to debugging. +""" + +from . import constants + + +def get_caller_file_and_line() -> str | None: + """Get the caller filename and line, if in debug mode, otherwise return `None`: + + Returns: + Path and file if `constants.DEBUG==True` + """ + import inspect + + if not constants.DEBUG: + return None + try: + current_frame = inspect.currentframe() + caller_frame = inspect.getframeinfo(current_frame.f_back.f_back) + return f"{caller_frame.filename}:{caller_frame.lineno}" + except Exception: + return None diff --git a/src/textual/app.py b/src/textual/app.py index 1fa10ef0ce..13859bf2a5 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -3599,7 +3599,7 @@ def clear_notifications(self) -> None: def action_command_palette(self) -> None: """Show the Textual command palette.""" if self.use_command_palette and not CommandPalette.is_open(self): - self.push_screen(CommandPalette(), callback=self.call_next) + self.push_screen(CommandPalette()) def _suspend_signal(self) -> None: """Signal that the application is being suspended.""" diff --git a/src/textual/await_complete.py b/src/textual/await_complete.py index 0780f7caaf..715c4ab00b 100644 --- a/src/textual/await_complete.py +++ b/src/textual/await_complete.py @@ -6,6 +6,8 @@ import rich.repr from typing_extensions import Self +from textual._inspection import get_caller_file_and_line + from .message_pump import MessagePump if TYPE_CHECKING: @@ -27,10 +29,12 @@ def __init__( self._awaitables = awaitables self._future: Future[Any] = gather(*awaitables) self._pre_await: CallbackType | None = pre_await + self._caller = get_caller_file_and_line() def __rich_repr__(self) -> rich.repr.Result: yield self._awaitables yield "pre_await", self._pre_await, None + yield "caller", self._caller, None def set_pre_await_callback(self, pre_await: CallbackType | None) -> None: """Set a callback to run prior to awaiting. diff --git a/src/textual/await_remove.py b/src/textual/await_remove.py index 28698c1c94..c15da97001 100644 --- a/src/textual/await_remove.py +++ b/src/textual/await_remove.py @@ -8,10 +8,14 @@ from asyncio import Task, gather from typing import Generator +import rich.repr + from ._callback import invoke +from ._debug import get_caller_file_and_line from ._types import CallbackType +@rich.repr.auto class AwaitRemove: """An awaitable that waits for nodes to be removed.""" @@ -20,6 +24,12 @@ def __init__( ) -> None: self._tasks = tasks self._post_remove = post_remove + self._caller = get_caller_file_and_line() + + def __rich_repr__(self) -> rich.repr.Result: + yield "tasks", self._tasks + yield "post_remove", self._post_remove + yield "caller", self._caller, None async def __call__(self) -> None: await self diff --git a/src/textual/command.py b/src/textual/command.py index 63a88c9b4c..e44075c991 100644 --- a/src/textual/command.py +++ b/src/textual/command.py @@ -39,7 +39,7 @@ from .reactive import var from .screen import Screen, SystemModalScreen from .timer import Timer -from .types import CallbackType, IgnoreReturnCallbackType +from .types import IgnoreReturnCallbackType from .widget import Widget from .widgets import Button, Input, LoadingIndicator, OptionList, Static from .widgets.option_list import Option @@ -419,7 +419,7 @@ class CommandInput(Input): """ -class CommandPalette(SystemModalScreen[CallbackType]): +class CommandPalette(SystemModalScreen): """The Textual command palette.""" AUTO_FOCUS = "CommandInput" @@ -1079,7 +1079,8 @@ def _select_or_command( # decide what to do with it (hopefully it'll run it). self._cancel_gather_commands() self.app.post_message(CommandPalette.Closed(option_selected=True)) - self.dismiss(self._selected_command.command) + self.dismiss() + self.app.call_later(self._selected_command.command) @on(OptionList.OptionHighlighted) def _stop_event_leak(self, event: OptionList.OptionHighlighted) -> None: diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 9b7a597f9a..52ab087669 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -446,6 +446,7 @@ def call_next(self, callback: Callback, *args: Any, **kwargs: Any) -> None: *args: Positional arguments to pass to the callable. **kwargs: Keyword arguments to pass to the callable. """ + assert callback is not None, "Callback must not be None" callback_message = events.Callback(callback=partial(callback, *args, **kwargs)) callback_message._prevent.update(self._get_prevented_messages()) self._next_callbacks.append(callback_message) @@ -617,7 +618,11 @@ async def _flush_next_callbacks(self) -> None: """Invoke pending callbacks in next callbacks queue.""" callbacks = self._next_callbacks.copy() self._next_callbacks.clear() + from rich import print + + print(callbacks) for callback in callbacks: + print(callback.callback) try: with self.prevent(*callback._prevent): await invoke(callback.callback) diff --git a/src/textual/screen.py b/src/textual/screen.py index 8ef0134f82..117ed106be 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -20,10 +20,9 @@ Generic, Iterable, Iterator, - Type, + Optional, TypeVar, Union, - cast, ) import rich.repr @@ -68,8 +67,8 @@ """The result type of a screen.""" ScreenResultCallbackType = Union[ - Callable[[ScreenResultType | None], None], - Callable[[ScreenResultType | None], Awaitable[None]], + Callable[[Optional[ScreenResultType]], None], + Callable[[Optional[ScreenResultType]], Awaitable[None]], ] """Type of a screen result callback function.""" @@ -107,10 +106,12 @@ def __call__(self, result: ScreenResultType) -> None: Note: If the requested or the callback are `None` this will be a no-op. """ + print("callback", self.callback) if self.future is not None: self.future.set_result(result) if self.requester is not None and self.callback is not None: self.requester.call_next(self.callback, result) + self.callback = None @rich.repr.auto @@ -210,7 +211,7 @@ def __init__( self._dirty_widgets: set[Widget] = set() self.__update_timer: Timer | None = None self._callbacks: list[tuple[CallbackType, MessagePump]] = [] - self._result_callbacks: list[ResultCallback[ScreenResultType]] = [] + self._result_callbacks: list[ResultCallback[ScreenResultType | None]] = [] self._tooltip_widget: Widget | None = None self._tooltip_timer: Timer | None = None @@ -885,7 +886,7 @@ def _push_result_callback( self, requester: MessagePump, callback: ScreenResultCallbackType[ScreenResultType] | None, - future: asyncio.Future[ScreenResultType] | None = None, + future: asyncio.Future[ScreenResultType | None] | None = None, ) -> None: """Add a result callback to the screen. @@ -895,7 +896,7 @@ def _push_result_callback( future: A Future to hold the result. """ self._result_callbacks.append( - ResultCallback[ScreenResultType](requester, callback, future) + ResultCallback[ScreenResultType | None](requester, callback, future) ) def _pop_result_callback(self) -> None: @@ -1228,14 +1229,11 @@ def _forward_event(self, event: events.Event) -> None: else: self.post_message(event) - class _NoResult: - """Class used to mark that there is no result.""" - - def dismiss( - self, result: ScreenResultType | Type[_NoResult] = _NoResult - ) -> AwaitComplete: + def dismiss(self, result: ScreenResultType | None = None) -> AwaitComplete: """Dismiss the screen, optionally with a result. + Additionally, any callback provided in [push_screen][textual.app.push_screen] will be invoked. + Only the active screen may be dismissed. This method will produce a warning in the logs if called on an inactive screen (but otherwise have no effect). @@ -1256,9 +1254,8 @@ def dismiss( self.log.warning("Can't dismiss inactive screen") return AwaitComplete() if self._result_callbacks: - self._result_callbacks[-1]( - cast(ScreenResultType, None if result is self._NoResult else result) - ) + callback = self._result_callbacks[-1] + callback(result) await_pop = self.app.pop_screen() def pre_await() -> None: @@ -1275,9 +1272,7 @@ def pre_await() -> None: return await_pop - async def action_dismiss( - self, result: ScreenResultType | Type[_NoResult] = _NoResult - ) -> None: + async def action_dismiss(self, result: ScreenResultType | None = None) -> None: """A wrapper around [`dismiss`][textual.screen.Screen.dismiss] that can be called as an action. Args: diff --git a/src/textual/widget.py b/src/textual/widget.py index f4b0463e7d..bad0c79603 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -52,6 +52,7 @@ from ._context import NoActiveAppError, active_app from ._dispatch_key import dispatch_key from ._easing import DEFAULT_SCROLL_EASING +from ._inspection import get_caller_file_and_line from ._layout import Layout from ._segment_tools import align_lines from ._styles_cache import StylesCache @@ -114,6 +115,7 @@ _MOUSE_EVENTS_ALLOW_IF_DISABLED = (events.MouseScrollDown, events.MouseScrollUp) +@rich.repr.auto class AwaitMount: """An *optional* awaitable returned by [mount][textual.widget.Widget.mount] and [mount_all][textual.widget.Widget.mount_all]. @@ -126,6 +128,12 @@ class AwaitMount: def __init__(self, parent: Widget, widgets: Sequence[Widget]) -> None: self._parent = parent self._widgets = widgets + self._caller = get_caller_file_and_line() + + def __rich_repr__(self) -> rich.repr.Result: + yield "parent", self._parent + yield "widgets", self._widgets + yield "caller", self._caller, None async def __call__(self) -> None: """Allows awaiting via a call operation.""" diff --git a/tests/test_modal.py b/tests/test_modal.py index d0af4d6770..f7372863e1 100644 --- a/tests/test_modal.py +++ b/tests/test_modal.py @@ -72,7 +72,7 @@ def compose(self) -> ComposeResult: def action_request_quit(self) -> None: """Action to display the quit dialog.""" - def check_quit(quit: bool) -> None: + def check_quit(quit: bool | None) -> None: """Called when QuitScreen is dismissed.""" if quit: From 6d8f594f8b3cfb47a1273261264f8fe11936c6db Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:31:48 +0100 Subject: [PATCH 20/80] typo --- src/textual/_debug.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/_debug.py b/src/textual/_debug.py index 7e02f918e7..bd8f56165f 100644 --- a/src/textual/_debug.py +++ b/src/textual/_debug.py @@ -1,5 +1,5 @@ """ -Function related to debugging. +Functions related to debugging. """ from . import constants From 1393a08eecf97f9d097ee7883395240547310c04 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:34:56 +0100 Subject: [PATCH 21/80] rename _inspection to debug --- CHANGELOG.md | 4 ++++ src/textual/await_complete.py | 3 +-- src/textual/widget.py | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4629f1a74..d2e9cf29b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed exception when removing Selects https://github.com/Textualize/textual/pull/4786 - Fixed issue with non-clickable Footer keys https://github.com/Textualize/textual/pull/4798 +### Changed + +- Calling `Screen.dismiss` with no arguments, will invoke the screen callback with `None` (previously the callback wasn't invoke at all). https://github.com/Textualize/textual/pull/4795 + ## [0.73.0] - 2024-07-18 ### Added diff --git a/src/textual/await_complete.py b/src/textual/await_complete.py index 715c4ab00b..027befffb7 100644 --- a/src/textual/await_complete.py +++ b/src/textual/await_complete.py @@ -6,8 +6,7 @@ import rich.repr from typing_extensions import Self -from textual._inspection import get_caller_file_and_line - +from ._debug import get_caller_file_and_line from .message_pump import MessagePump if TYPE_CHECKING: diff --git a/src/textual/widget.py b/src/textual/widget.py index bad0c79603..9a28da4e75 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -50,9 +50,9 @@ from ._arrange import DockArrangeResult, arrange from ._compose import compose from ._context import NoActiveAppError, active_app +from ._debug import get_caller_file_and_line from ._dispatch_key import dispatch_key from ._easing import DEFAULT_SCROLL_EASING -from ._inspection import get_caller_file_and_line from ._layout import Layout from ._segment_tools import align_lines from ._styles_cache import StylesCache From 247219e49d23821e0a77cc3a62852d6a0090c20c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:37:12 +0100 Subject: [PATCH 22/80] annotations --- src/textual/_debug.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/textual/_debug.py b/src/textual/_debug.py index bd8f56165f..2d953ef65a 100644 --- a/src/textual/_debug.py +++ b/src/textual/_debug.py @@ -2,6 +2,8 @@ Functions related to debugging. """ +from __future__ import annotations + from . import constants @@ -11,10 +13,11 @@ def get_caller_file_and_line() -> str | None: Returns: Path and file if `constants.DEBUG==True` """ - import inspect if not constants.DEBUG: return None + import inspect + try: current_frame = inspect.currentframe() caller_frame = inspect.getframeinfo(current_frame.f_back.f_back) From 76d82151912f8a360648c6df302e3173d83c3e67 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:39:57 +0100 Subject: [PATCH 23/80] remove debug --- src/textual/message_pump.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 52ab087669..13a99f6923 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -618,11 +618,8 @@ async def _flush_next_callbacks(self) -> None: """Invoke pending callbacks in next callbacks queue.""" callbacks = self._next_callbacks.copy() self._next_callbacks.clear() - from rich import print - print(callbacks) for callback in callbacks: - print(callback.callback) try: with self.prevent(*callback._prevent): await invoke(callback.callback) From 3538cc57aba4d4367a4ca25bd2876638386233eb Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 13:49:14 +0100 Subject: [PATCH 24/80] test --- CHANGELOG.md | 2 +- src/textual/message_pump.py | 1 - src/textual/screen.py | 5 +---- tests/test_screens.py | 19 +++++++++++++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2e9cf29b5..2730c23e07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed -- Calling `Screen.dismiss` with no arguments, will invoke the screen callback with `None` (previously the callback wasn't invoke at all). https://github.com/Textualize/textual/pull/4795 +- Calling `Screen.dismiss` with no arguments will invoke the screen callback with `None` (previously the callback wasn't invoke at all). https://github.com/Textualize/textual/pull/4795 ## [0.73.0] - 2024-07-18 diff --git a/src/textual/message_pump.py b/src/textual/message_pump.py index 13a99f6923..2c32c31b77 100644 --- a/src/textual/message_pump.py +++ b/src/textual/message_pump.py @@ -618,7 +618,6 @@ async def _flush_next_callbacks(self) -> None: """Invoke pending callbacks in next callbacks queue.""" callbacks = self._next_callbacks.copy() self._next_callbacks.clear() - for callback in callbacks: try: with self.prevent(*callback._prevent): diff --git a/src/textual/screen.py b/src/textual/screen.py index 117ed106be..968bbccb64 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -106,7 +106,6 @@ def __call__(self, result: ScreenResultType) -> None: Note: If the requested or the callback are `None` this will be a no-op. """ - print("callback", self.callback) if self.future is not None: self.future.set_result(result) if self.requester is not None and self.callback is not None: @@ -1232,7 +1231,7 @@ def _forward_event(self, event: events.Event) -> None: def dismiss(self, result: ScreenResultType | None = None) -> AwaitComplete: """Dismiss the screen, optionally with a result. - Additionally, any callback provided in [push_screen][textual.app.push_screen] will be invoked. + Any callback provided in [push_screen][textual.app.push_screen] will be invoked with the supplied result. Only the active screen may be dismissed. This method will produce a warning in the logs if called on an inactive screen (but otherwise have no effect). @@ -1243,8 +1242,6 @@ def dismiss(self, result: ScreenResultType | None = None) -> AwaitComplete: message handler on the Screen being dismissed. If you want to dismiss the current screen, you can call `self.dismiss()` _without_ awaiting. - If `result` is not supplied, then the callback will be invoked with `None`. - Args: result: The optional result to be passed to the result callback. diff --git a/tests/test_screens.py b/tests/test_screens.py index adb8afecd6..553daba26f 100644 --- a/tests/test_screens.py +++ b/tests/test_screens.py @@ -326,6 +326,25 @@ def callback(self, result: bool) -> None: assert app.bingo +async def test_dismiss_action_no_argument(): + class ConfirmScreen(Screen[bool]): + BINDINGS = [("y", "dismiss", "Dismiss")] + + class MyApp(App[None]): + bingo = False + + def on_mount(self) -> None: + self.push_screen(ConfirmScreen(), callback=self.callback) + + def callback(self, result: bool | None) -> None: + self.bingo = result + + app = MyApp() + async with app.run_test() as pilot: + await pilot.press("y") + assert app.bingo is None + + async def test_switch_screen_no_op(): """Regression test for https://github.com/Textualize/textual/issues/2650""" From 8b2616e259fd4985ca03876311b96da3784ff7a8 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 15:13:50 +0100 Subject: [PATCH 25/80] call next --- src/textual/command.py | 2 +- tests/test_unmount.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/textual/command.py b/src/textual/command.py index e44075c991..b6df359d02 100644 --- a/src/textual/command.py +++ b/src/textual/command.py @@ -1080,7 +1080,7 @@ def _select_or_command( self._cancel_gather_commands() self.app.post_message(CommandPalette.Closed(option_selected=True)) self.dismiss() - self.app.call_later(self._selected_command.command) + self.app.call_next(self._selected_command.command) @on(OptionList.OptionHighlighted) def _stop_event_leak(self, event: OptionList.OptionHighlighted) -> None: diff --git a/tests/test_unmount.py b/tests/test_unmount.py index 2301e4010a..324a3812a3 100644 --- a/tests/test_unmount.py +++ b/tests/test_unmount.py @@ -6,7 +6,7 @@ from textual.screen import Screen -async def test_unmount(): +async def test_unmount() -> None: """Test unmount events are received in reverse DOM order.""" unmount_ids: list[str] = [] From 6c425a23113470a93b6dcf31fadc6b3f56714ff5 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 15:14:27 +0100 Subject: [PATCH 26/80] Call on screen --- src/textual/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/command.py b/src/textual/command.py index b6df359d02..5a8d55de75 100644 --- a/src/textual/command.py +++ b/src/textual/command.py @@ -1080,7 +1080,7 @@ def _select_or_command( self._cancel_gather_commands() self.app.post_message(CommandPalette.Closed(option_selected=True)) self.dismiss() - self.app.call_next(self._selected_command.command) + self.call_next(self._selected_command.command) @on(OptionList.OptionHighlighted) def _stop_event_leak(self, event: OptionList.OptionHighlighted) -> None: From 6ebac18f10c488e40dec7db27e32b89df366a4ec Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 15:22:43 +0100 Subject: [PATCH 27/80] fix typing issue --- src/textual/screen.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index 968bbccb64..0b308d5817 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -895,7 +895,7 @@ def _push_result_callback( future: A Future to hold the result. """ self._result_callbacks.append( - ResultCallback[ScreenResultType | None](requester, callback, future) + ResultCallback[Optional[ScreenResultType]](requester, callback, future) ) def _pop_result_callback(self) -> None: From b5252e6d774478b5487c36b5aefcff17b38058f1 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 15:23:06 +0100 Subject: [PATCH 28/80] revert call later --- src/textual/command.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/command.py b/src/textual/command.py index 5a8d55de75..ad519deeb8 100644 --- a/src/textual/command.py +++ b/src/textual/command.py @@ -1080,7 +1080,7 @@ def _select_or_command( self._cancel_gather_commands() self.app.post_message(CommandPalette.Closed(option_selected=True)) self.dismiss() - self.call_next(self._selected_command.command) + self.call_later(self._selected_command.command) @on(OptionList.OptionHighlighted) def _stop_event_leak(self, event: OptionList.OptionHighlighted) -> None: From 10d93a0e672d89cb00a4a0448c449162da5d1fc7 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 15:29:46 +0100 Subject: [PATCH 29/80] annotations --- tests/test_modal.py | 2 ++ tests/test_screens.py | 2 ++ 2 files changed, 4 insertions(+) diff --git a/tests/test_modal.py b/tests/test_modal.py index f7372863e1..6a394e2bab 100644 --- a/tests/test_modal.py +++ b/tests/test_modal.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from textual.app import App, ComposeResult from textual.containers import Grid from textual.screen import ModalScreen diff --git a/tests/test_screens.py b/tests/test_screens.py index 553daba26f..6eb83a114e 100644 --- a/tests/test_screens.py +++ b/tests/test_screens.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import asyncio import sys import threading From 6ab59d493a279303a857a8fac1f870f858e21286 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Wed, 24 Jul 2024 19:44:47 +0100 Subject: [PATCH 30/80] doc --- src/textual/widgets/_digits.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/textual/widgets/_digits.py b/src/textual/widgets/_digits.py index 3bd04fcc25..7c21d471ed 100644 --- a/src/textual/widgets/_digits.py +++ b/src/textual/widgets/_digits.py @@ -33,7 +33,8 @@ def __init__( classes: str | None = None, disabled: bool = False, ) -> None: - """ + """Initialize a Digits widget. + Args: value: Value to display in widget. name: The name of the widget. From 4c3825e356b3f722c80c0fde3bdbe3e946df778c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 10:41:58 +0100 Subject: [PATCH 31/80] allow recompose before mount --- src/textual/reactive.py | 17 ++++++++++------- src/textual/widget.py | 12 ++++++------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index bb87ca9f0f..df4af2e805 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -132,15 +132,18 @@ def __init__( self._recompose = recompose self._bindings = bindings self._owner: Type[MessageTarget] | None = None + self.name: str | None = None def __rich_repr__(self) -> rich.repr.Result: - yield self._default - yield "layout", self._layout - yield "repaint", self._repaint - yield "init", self._init - yield "always_update", self._always_update - yield "compute", self._run_compute - yield "recompose", self._recompose + yield None, self._default + yield "layout", self._layout, False + yield "repaint", self._repaint, True + yield "init", self._init, False + yield "always_update", self._always_update, False + yield "compute", self._run_compute, True + yield "recompose", self._recompose, False + yield "bindings", self._bindings, False + yield "name", self.name, None @property def owner(self) -> Type[MessageTarget]: diff --git a/src/textual/widget.py b/src/textual/widget.py index 9a28da4e75..687a97e7ef 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -3473,17 +3473,17 @@ def refresh( break ancestor._clear_arrangement_cache() - if not self._is_mounted: - self._repaint_required = True - self.check_idle() - return self - if recompose: self._recompose_required = True self.call_next(self._check_recompose) return self - elif repaint: + if not self._is_mounted: + self._repaint_required = True + self.check_idle() + return self + + if repaint: self._set_dirty(*regions) self.clear_cached_dimensions() self._rich_style_cache.clear() From bcedc9b0e8cbe880a1da2bbf91a3acfcfd4bd349 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 10:48:14 +0100 Subject: [PATCH 32/80] add test --- src/textual/reactive.py | 4 ++-- tests/snapshot_tests/test_snapshots.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/textual/reactive.py b/src/textual/reactive.py index df4af2e805..17b109d77e 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -132,7 +132,7 @@ def __init__( self._recompose = recompose self._bindings = bindings self._owner: Type[MessageTarget] | None = None - self.name: str | None = None + self.name: str def __rich_repr__(self) -> rich.repr.Result: yield None, self._default @@ -143,7 +143,7 @@ def __rich_repr__(self) -> rich.repr.Result: yield "compute", self._run_compute, True yield "recompose", self._recompose, False yield "bindings", self._bindings, False - yield "name", self.name, None + yield "name", getattr(self, "name", None), None @property def owner(self) -> Type[MessageTarget]: diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index fd33c3ccc2..2e7d987c53 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -1392,3 +1392,8 @@ def test_component_text_opacity(snap_compare): def test_progress_gradient(snap_compare): """Test gradient parameter on ProgressBar""" assert snap_compare(SNAPSHOT_APPS_DIR / "progress_gradient.py") + + +def test_recompose_in_mount(snap_compare): + """Regression test for https://github.com/Textualize/textual/issues/4799""" + assert snap_compare(SNAPSHOT_APPS_DIR / "recompose_on_mount.py") From c662d57341ee2491f4002c5e18780fb33e813f08 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 10:48:21 +0100 Subject: [PATCH 33/80] snapshot --- .../snapshot_apps/recompose_on_mount.py | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/snapshot_tests/snapshot_apps/recompose_on_mount.py diff --git a/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py b/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py new file mode 100644 index 0000000000..23d8af8b16 --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py @@ -0,0 +1,43 @@ +from textual.app import App, ComposeResult +from textual.screen import Screen +from textual.widgets import Header, Footer, Static, RadioSet +from textual.reactive import reactive + + +class Profile(Static): + choices: reactive[list[str]] = reactive(list, recompose=True) + + def compose(self) -> ComposeResult: + yield RadioSet(*self.choices) + + async def on_mount(self) -> None: + self.choices.append("Foo") + self.choices.append("Bar") + self.mutate_reactive(Profile.choices) + + +class Landing(Screen): + def compose(self) -> ComposeResult: + """Create child widgets for the app.""" + yield Header() + yield Static(" Profile ", id="title") + yield Profile() + yield Footer() + + +class ForecastApp(App): + """A Textual app to forecast Financials.""" + + def compose(self) -> ComposeResult: + """Create child widgets for the app.""" + yield Header() + yield Footer() + + def on_mount(self) -> None: + self.install_screen(Landing(), name="landing") + self.push_screen("landing") + + +if __name__ == "__main__": + app = ForecastApp() + app.run() From dd7aada832135250ee041025adb075db57a62b7e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 10:57:56 +0100 Subject: [PATCH 34/80] snapshot --- CHANGELOG.md | 1 + .../__snapshots__/test_snapshots.ambr | 164 ++++++++++++++++++ 2 files changed, 165 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2730c23e07..78c90e93e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 - Fixed exception when removing Selects https://github.com/Textualize/textual/pull/4786 - Fixed issue with non-clickable Footer keys https://github.com/Textualize/textual/pull/4798 +- Fixed issue with recompose not working from Mount handler https://github.com/Textualize/textual/pull/4802 ### Changed diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index b0a9d01353..ca5d517574 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -35556,6 +35556,170 @@ ''' # --- +# name: test_recompose_in_mount + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ForecastApp + + + + + + + + + + ForecastApp +  Profile  + ▔▔▔▔▔▔▔▔▔▔ + Foo +  Bar + ▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- # name: test_remove_with_auto_height ''' From 1f9140ea52c5cf5791dc107fe6e78a9f4d3ecdb5 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 11:06:10 +0100 Subject: [PATCH 35/80] typing for snapshot --- tests/snapshot_tests/snapshot_apps/recompose_on_mount.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py b/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py index 23d8af8b16..f3ec5133fa 100644 --- a/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py +++ b/tests/snapshot_tests/snapshot_apps/recompose_on_mount.py @@ -1,3 +1,5 @@ +from __future__ import annotations + from textual.app import App, ComposeResult from textual.screen import Screen from textual.widgets import Header, Footer, Static, RadioSet From dc1c734c7fd90b386eee98b8916579ec9cf7f751 Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Thu, 25 Jul 2024 11:50:54 +0100 Subject: [PATCH 36/80] Update snapshots (#4788) * Update snapshots * Update to use textual-snapshot v1.0.0 * Dont use xdist on CI * Update pytest-cov to fix warnings * Remove xdist thing from pythonpackage.yml GitHub workflow --- Makefile | 6 +- poetry.lock | 124 +- pyproject.toml | 9 +- .../__snapshots__/test_snapshots.ambr | 51393 ---------------- .../test_alignment_containers.svg | 158 + .../test_ansi_color_mapping[False].svg | 166 + .../test_ansi_color_mapping[True].svg | 164 + .../test_snapshots/test_app_blur.svg | 153 + .../test_snapshots/test_auto_fr.svg | 159 + .../test_snapshots/test_auto_grid.svg | 154 + .../test_auto_grid_default_height.svg | 155 + .../test_snapshots/test_auto_tab_active.svg | 161 + .../test_snapshots/test_auto_table.svg | 220 + .../test_snapshots/test_auto_width_input.svg | 155 + .../test_snapshots/test_big_buttons.svg | 154 + .../test_bindings_screen_overrides_show.svg | 153 + .../test_snapshots/test_blur_on_disabled.svg | 153 + .../test_snapshots/test_border_alpha.svg | 156 + .../test_snapshots/test_button_outline.svg | 152 + .../test_snapshots/test_button_widths.svg | 155 + .../test_button_with_console_markup.svg | 160 + .../test_button_with_multiline_label.svg | 153 + .../test_snapshots/test_buttons_render.svg | 181 + .../test_snapshots/test_checkbox_example.svg | 162 + .../test_collapsible_collapsed.svg | 156 + .../test_collapsible_custom_symbol.svg | 153 + .../test_collapsible_expanded.svg | 158 + .../test_collapsible_nested.svg | 154 + .../test_collapsible_render.svg | 157 + .../test_snapshots/test_columns_height.svg | 152 + .../test_snapshots/test_command_palette.svg | 157 + .../test_command_palette_discovery.svg | 157 + .../test_component_text_opacity.svg | 150 + .../test_content_switcher_example_initial.svg | 159 + .../test_content_switcher_example_switch.svg | 262 + .../test_snapshots/test_css_hot_reloading.svg | 150 + .../test_css_hot_reloading_on_screen.svg | 150 + .../test_css_property[align.py].svg | 153 + .../test_css_property[align_all.py].svg | 153 + .../test_css_property[background.py].svg | 150 + ...s_property[background_transparency.py].svg | 159 + .../test_css_property[border.py].svg | 153 + .../test_css_property[border_all.py].svg | 152 + ...roperty[border_sub_title_align_all.py].svg | 160 + ...css_property[border_subtitle_align.py].svg | 153 + ...st_css_property[border_title_align.py].svg | 153 + ...t_css_property[border_title_colors.py].svg | 153 + .../test_css_property[box_sizing.py].svg | 151 + .../test_css_property[color.py].svg | 152 + .../test_css_property[color_auto.py].svg | 154 + .../test_css_property[column_span.py].svg | 157 + .../test_css_property[content_align.py].svg | 152 + ...est_css_property[content_align_all.py].svg | 151 + .../test_css_property[display.py].svg | 151 + .../test_css_property[dock_all.py].svg | 151 + .../test_css_property[grid.py].svg | 152 + .../test_css_property[grid_columns.py].svg | 151 + .../test_css_property[grid_gutter.py].svg | 151 + .../test_css_property[grid_rows.py].svg | 151 + .../test_css_property[grid_size_both.py].svg | 151 + ...est_css_property[grid_size_columns.py].svg | 151 + .../test_css_property[hatch.py].svg | 156 + .../test_css_property[height.py].svg | 151 + ...est_css_property[height_comparison.py].svg | 159 + .../test_css_property[keyline.py].svg | 155 + ...st_css_property[keyline_horizontal.py].svg | 153 + .../test_css_property[layout.py].svg | 153 + .../test_css_property[link_background.py].svg | 153 + ...css_property[link_background_hover.py].svg | 151 + .../test_css_property[link_color.py].svg | 153 + ...test_css_property[link_color_hover.py].svg | 151 + .../test_css_property[link_style.py].svg | 153 + ...test_css_property[link_style_hover.py].svg | 151 + .../test_css_property[links.py].svg | 152 + .../test_css_property[margin.py].svg | 152 + .../test_css_property[margin_all.py].svg | 159 + .../test_css_property[max_height.py].svg | 154 + .../test_css_property[max_width.py].svg | 154 + .../test_css_property[min_height.py].svg | 155 + .../test_css_property[min_width.py].svg | 154 + .../test_css_property[offset.py].svg | 153 + .../test_css_property[opacity.py].svg | 159 + .../test_css_property[outline.py].svg | 152 + .../test_css_property[outline_all.py].svg | 152 + ...est_css_property[outline_vs_border.py].svg | 152 + .../test_css_property[overflow.py].svg | 154 + .../test_css_property[padding.py].svg | 150 + .../test_css_property[padding_all.py].svg | 158 + .../test_css_property[row_span.py].svg | 157 + ...ss_property[scrollbar_corner_color.py].svg | 151 + ...test_css_property[scrollbar_gutter.py].svg | 151 + .../test_css_property[scrollbar_size.py].svg | 151 + .../test_css_property[scrollbar_size2.py].svg | 154 + .../test_css_property[scrollbars.py].svg | 154 + .../test_css_property[scrollbars2.py].svg | 151 + .../test_css_property[text_align.py].svg | 157 + .../test_css_property[text_opacity.py].svg | 153 + .../test_css_property[text_style.py].svg | 153 + .../test_css_property[text_style_all.py].svg | 157 + .../test_css_property[tint.py].svg | 159 + .../test_css_property[visibility.py].svg | 151 + ...css_property[visibility_containers.py].svg | 156 + .../test_css_property[width.py].svg | 151 + ...test_css_property[width_comparison.py].svg | 159 + .../test_data_table_in_tabs.svg | 156 + .../test_datatable_add_column.svg | 153 + .../test_datatable_add_row_auto_height.svg | 153 + ...t_datatable_add_row_auto_height_sorted.svg | 153 + .../test_datatable_cell_padding.svg | 153 + .../test_datatable_change_cell_padding.svg | 153 + .../test_datatable_column_cursor_render.svg | 156 + .../test_datatable_hot_reloading.svg | 156 + .../test_datatable_labels_and_fixed_data.svg | 154 + .../test_datatable_remove_row.svg | 153 + .../test_snapshots/test_datatable_render.svg | 153 + .../test_datatable_row_cursor_render.svg | 155 + .../test_datatable_sort_multikey.svg | 153 + .../test_datatable_style_ordering.svg | 156 + .../test_snapshots/test_demo.svg | 187 + .../test_snapshots/test_digits.svg | 151 + .../test_directory_tree_reloading.svg | 155 + .../test_snapshots/test_disabled_widgets.svg | 180 + .../test_dock_layout_sidebar.svg | 152 + .../test_snapshots/test_dock_scroll.svg | 160 + .../test_snapshots/test_dock_scroll2.svg | 160 + .../test_dock_scroll_off_by_one.svg | 160 + .../test_snapshots/test_dynamic_bindings.svg | 155 + .../test_example_calculator.svg | 162 + .../test_example_color_command.svg | 152 + .../test_example_dictionary.svg | 157 + .../test_example_five_by_five.svg | 157 + .../test_snapshots/test_example_json_tree.svg | 160 + .../test_snapshots/test_example_markdown.svg | 162 + .../test_snapshots/test_example_merlin.svg | 158 + .../test_snapshots/test_example_pride.svg | 155 + .../test_focus_component_class.svg | 154 + .../test_footer_classic_styling.svg | 152 + .../test_snapshots/test_footer_compact.svg | 153 + .../test_footer_compact_with_hover.svg | 154 + .../test_snapshots/test_footer_render.svg | 153 + ..._footer_standard_after_reactive_change.svg | 153 + .../test_footer_standard_with_hover.svg | 154 + .../test_snapshots/test_fr_margins.svg | 156 + .../test_snapshots/test_fr_unit_with_min.svg | 154 + .../test_snapshots/test_fr_units.svg | 151 + .../test_snapshots/test_grid_auto.svg | 160 + .../test_snapshots/test_grid_gutter.svg | 156 + .../test_snapshots/test_grid_layout_basic.svg | 151 + .../test_grid_layout_basic_overflow.svg | 151 + .../test_grid_layout_gutter.svg | 151 + .../test_snapshots/test_hatch.svg | 157 + .../test_snapshots/test_header_render.svg | 151 + .../test_snapshots/test_horizontal_layout.svg | 151 + ...test_horizontal_layout_width_auto_dock.svg | 154 + .../test_snapshots/test_input_and_focus.svg | 154 + .../test_input_percentage_width.svg | 154 + .../test_snapshots/test_input_suggestions.svg | 156 + .../test_snapshots/test_input_validation.svg | 157 + .../test_snapshots/test_key_display.svg | 153 + .../test_snapshots/test_keyline.svg | 154 + .../test_snapshots/test_label_widths.svg | 153 + .../test_snapshots/test_layer_fix.svg | 155 + .../test_snapshots/test_layers.svg | 152 + .../test_snapshots/test_layout_containers.svg | 162 + .../test_line_api_scrollbars.svg | 151 + .../test_snapshots/test_list_view.svg | 153 + .../test_snapshots/test_listview_index.svg | 153 + .../test_snapshots/test_loading_indicator.svg | 154 + ...test_loading_indicator_disables_widget.svg | 155 + .../test_snapshots/test_log_write.svg | 150 + .../test_snapshots/test_log_write_lines.svg | 152 + .../test_snapshots/test_margin_multiple.svg | 153 + ...t_markdown_component_classes_reloading.svg | 161 + .../test_markdown_dark_theme_override.svg | 157 + .../test_snapshots/test_markdown_example.svg | 155 + .../test_markdown_light_theme_override.svg | 157 + .../test_markdown_space_squashing.svg | 163 + .../test_markdown_theme_switching.svg | 158 + .../test_markdown_viewer_example.svg | 160 + .../test_snapshots/test_max_height_100.svg | 153 + .../test_missing_vertical_scroll.svg | 155 + .../test_modal_dialog_bindings.svg | 154 + .../test_modal_dialog_bindings_input.svg | 159 + .../test_snapshots/test_mount_style_fix.svg | 152 + .../test_snapshots/test_multi_keys.svg | 153 + .../test_snapshots/test_multiple_css.svg | 152 + .../test_nested_auto_heights.svg | 155 + .../test_snapshots/test_nested_fr.svg | 152 + .../test_nested_specificity.svg | 153 + .../test_notification_with_inline_link.svg | 154 + ...st_notification_with_inline_link_hover.svg | 154 + .../test_notifications_example.svg | 158 + ...st_notifications_loading_overlap_order.svg | 136 + .../test_notifications_through_modes.svg | 153 + .../test_notifications_through_screens.svg | 153 + .../test_snapshots/test_offsets.svg | 152 + .../test_snapshots/test_option_list_build.svg | 157 + .../test_option_list_options.svg | 159 + ...prompt_from_single_line_to_single_line.svg | 156 + ...e_prompt_from_single_line_to_two_lines.svg | 156 + ...e_prompt_from_two_lines_to_three_lines.svg | 156 + ...est_option_list_scrolling_in_long_list.svg | 154 + ..._list_scrolling_with_multiline_options.svg | 160 + .../test_option_list_strings.svg | 156 + .../test_option_list_tables.svg | 160 + .../test_order_independence.svg | 155 + .../test_order_independence_toggle.svg | 155 + .../test_pilot_resize_terminal.svg | 94 + .../test_placeholder_disabled.svg | 151 + .../test_placeholder_render.svg | 161 + .../test_pretty_grid_gutter_interaction.svg | 86 + .../test_snapshots/test_print_capture.svg | 150 + .../test_programmatic_disable_button.svg | 156 + ...t_programmatic_scrollbar_gutter_change.svg | 151 + .../test_progress_bar_completed.svg | 154 + .../test_progress_bar_completed_styled.svg | 156 + .../test_progress_bar_halfway.svg | 155 + .../test_progress_bar_halfway_styled.svg | 157 + .../test_progress_bar_indeterminate.svg | 155 + ...test_progress_bar_indeterminate_styled.svg | 157 + .../test_snapshots/test_progress_gradient.svg | 167 + .../test_quickly_change_tabs.svg | 154 + .../test_radio_button_example.svg | 158 + .../test_snapshots/test_radio_set_example.svg | 159 + .../test_snapshots/test_recompose.svg | 154 + .../test_recompose_in_mount.svg | 159 + .../test_remove_with_auto_height.svg | 156 + .../test_snapshots/test_richlog_max_lines.svg | 150 + .../test_snapshots/test_richlog_scroll.svg | 150 + .../test_snapshots/test_richlog_width.svg | 150 + .../test_rule_horizontal_rules.svg | 151 + .../test_rule_vertical_rules.svg | 151 + .../test_snapshots/test_rules.svg | 151 + .../test_snapshots/test_scoped_css.svg | 152 + .../test_snapshots/test_screen_switch.svg | 154 + .../test_snapshots/test_scroll_to.svg | 161 + .../test_snapshots/test_scroll_to_center.svg | 155 + .../test_snapshots/test_scroll_visible.svg | 151 + .../test_scroll_visible_with_margin.svg | 155 + .../test_scrollbar_thumb_height.svg | 153 + .../test_snapshots/test_select.svg | 155 + .../test_snapshots/test_select_expanded.svg | 159 + .../test_select_expanded_changed.svg | 155 + .../test_select_from_values_expanded.svg | 159 + ...test_select_no_blank_has_default_value.svg | 155 + .../test_snapshots/test_select_rebuild.svg | 158 + .../test_select_set_options.svg | 155 + .../test_selection_list_selected.svg | 160 + .../test_selection_list_selections.svg | 158 + .../test_selection_list_tuples.svg | 158 + .../test_snapshots/test_sort_children.svg | 155 + ...est_sparkline_component_classes_colors.svg | 701 + .../test_snapshots/test_sparkline_render.svg | 236 + .../test_snapshots/test_switches.svg | 155 + .../test_snapshots/test_tab_rename.svg | 154 + .../test_snapshots/test_tabbed_content.svg | 159 + ...est_tabbed_content_styling_not_leaking.svg | 158 + ...test_tabbed_content_with_modified_tabs.svg | 159 + .../test_snapshots/test_table_markup.svg | 155 + .../test_snapshots/test_tabs_invalidate.svg | 155 + .../test_text_area_alternate_screen.svg | 98 + ...est_text_area_language_rendering[bash].svg | 475 + ...test_text_area_language_rendering[css].svg | 348 + .../test_text_area_language_rendering[go].svg | 352 + ...est_text_area_language_rendering[html].svg | 303 + ...est_text_area_language_rendering[java].svg | 493 + ...xt_area_language_rendering[javascript].svg | 389 + ...est_text_area_language_rendering[json].svg | 200 + ...t_text_area_language_rendering[kotlin].svg | 461 + ...text_area_language_rendering[markdown].svg | 350 + ...t_text_area_language_rendering[python].svg | 393 + ...st_text_area_language_rendering[regex].svg | 175 + ...est_text_area_language_rendering[rust].svg | 497 + ...test_text_area_language_rendering[sql].svg | 253 + ...est_text_area_language_rendering[toml].svg | 180 + ...est_text_area_language_rendering[yaml].svg | 228 + .../test_text_area_line_number_start.svg | 92 + ...t_text_area_read_only_cursor_rendering.svg | 78 + ...t_area_selection_rendering[selection0].svg | 90 + ...t_area_selection_rendering[selection1].svg | 90 + ...t_area_selection_rendering[selection2].svg | 90 + ...t_area_selection_rendering[selection3].svg | 90 + ...t_area_selection_rendering[selection4].svg | 89 + ...t_area_selection_rendering[selection5].svg | 89 + .../test_text_area_themes[css].svg | 100 + .../test_text_area_themes[dracula].svg | 99 + .../test_text_area_themes[github_light].svg | 102 + .../test_text_area_themes[monokai].svg | 100 + .../test_text_area_themes[vscode_dark].svg | 98 + .../test_text_area_wrapping_and_folding.svg | 166 + .../test_text_log_blank_write.svg | 150 + .../test_textual_dev_border_preview.svg | 157 + .../test_textual_dev_colors_preview.svg | 171 + .../test_textual_dev_easing_preview.svg | 167 + .../test_textual_dev_keys_preview.svg | 164 + .../test_toggle_style_order.svg | 159 + .../test_tooltips_in_compound_widgets.svg | 153 + .../test_tree_clearing_and_expansion.svg | 152 + .../test_snapshots/test_tree_example.svg | 152 + .../test_snapshots/test_unscoped_css.svg | 152 + .../test_snapshots/test_vertical_layout.svg | 151 + .../test_vertical_max_height.svg | 152 + .../test_vertical_min_height.svg | 152 + ...t_viewport_height_and_width_properties.svg | 151 + .../test_snapshots/test_visibility.svg | 152 + .../test_snapshots/test_welcome.svg | 157 + .../test_snapshots/test_width_100.svg | 152 + .../test_zero_scrollbar_size.svg | 150 + tests/test_slug.py | 2 + 309 files changed, 49787 insertions(+), 51460 deletions(-) delete mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots.ambr create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_alignment_containers.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[False].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[True].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_app_blur.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_fr.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid_default_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_tab_active.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_table.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_width_input.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_big_buttons.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_bindings_screen_overrides_show.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_blur_on_disabled.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_border_alpha.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_button_outline.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_button_widths.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_console_markup.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_multiline_label.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_buttons_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_checkbox_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_collapsed.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_custom_symbol.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_expanded.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_nested.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_columns_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette_discovery.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_component_text_opacity.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_initial.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_switch.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading_on_screen.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background_transparency.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_sub_title_align_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_subtitle_align.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_align.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_colors.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[box_sizing.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color_auto.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[column_span.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[display.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[dock_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_columns.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_gutter.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_rows.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_both.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_columns.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[hatch.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height_comparison.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline_horizontal.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[layout.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background_hover.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color_hover.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style_hover.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[links.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_height.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_width.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_height.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_width.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[offset.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[opacity.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_vs_border.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[overflow.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[row_span.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_corner_color.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_gutter.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size2.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars2.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_align.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_opacity.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style_all.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[tint.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility_containers.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width_comparison.py].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_data_table_in_tabs.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_column.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height_sorted.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_cell_padding.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_change_cell_padding.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_column_cursor_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_hot_reloading.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_labels_and_fixed_data.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_remove_row.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_row_cursor_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_sort_multikey.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_style_ordering.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_demo.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_digits.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_directory_tree_reloading.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_disabled_widgets.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_layout_sidebar.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll2.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll_off_by_one.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_dynamic_bindings.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_calculator.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_color_command.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_dictionary.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_five_by_five.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_json_tree.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_markdown.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_merlin.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_example_pride.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_focus_component_class.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_classic_styling.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact_with_hover.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_after_reactive_change.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_with_hover.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_margins.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_unit_with_min.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_units.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_auto.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_gutter.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic_overflow.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_gutter.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_hatch.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_header_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout_width_auto_dock.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_input_and_focus.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_input_suggestions.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_input_validation.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_key_display.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_keyline.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_label_widths.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_layer_fix.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_layers.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_layout_containers.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_line_api_scrollbars.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_list_view.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_listview_index.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator_disables_widget.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write_lines.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_margin_multiple.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_component_classes_reloading.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_dark_theme_override.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_light_theme_override.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_space_squashing.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_theme_switching.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_viewer_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_max_height_100.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_missing_vertical_scroll.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings_input.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_mount_style_fix.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_multi_keys.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_multiple_css.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_auto_heights.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_fr.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_specificity.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link_hover.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_loading_overlap_order.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_modes.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_screens.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_offsets.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_options.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_single_line.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_two_lines.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_two_lines_to_three_lines.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_in_long_list.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_with_multiline_options.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_strings.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_tables.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence_toggle.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_pilot_resize_terminal.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_disabled.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_pretty_grid_gutter_interaction.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_print_capture.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_disable_button.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_scrollbar_gutter_change.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed_styled.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway_styled.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate_styled.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_gradient.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_quickly_change_tabs.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_button_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_set_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose_in_mount.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_with_auto_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_max_lines.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_scroll.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_width.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_horizontal_rules.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_vertical_rules.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_rules.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scoped_css.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_screen_switch.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to_center.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible_with_margin.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_scrollbar_thumb_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded_changed.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_from_values_expanded.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_no_blank_has_default_value.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_rebuild.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_select_set_options.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selected.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selections.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_tuples.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_sort_children.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_component_classes_colors.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_render.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_switches.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tab_rename.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_styling_not_leaking.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_with_modified_tabs.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_table_markup.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tabs_invalidate.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[bash].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[css].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[go].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[html].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[java].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[javascript].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[json].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[kotlin].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[markdown].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[python].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[regex].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[rust].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[sql].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[toml].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[yaml].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_line_number_start.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_read_only_cursor_rendering.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[css].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[dracula].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[github_light].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[monokai].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[vscode_dark].svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_wrapping_and_folding.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_text_log_blank_write.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_border_preview.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_colors_preview.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_easing_preview.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_keys_preview.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_toggle_style_order.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tooltips_in_compound_widgets.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_clearing_and_expansion.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_example.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_unscoped_css.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_layout.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_max_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_min_height.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_viewport_height_and_width_properties.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_visibility.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_welcome.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_width_100.svg create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_zero_scrollbar_size.svg diff --git a/Makefile b/Makefile index 8b5f8d2191..e4e7bdaf39 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,15 @@ run := poetry run .PHONY: test test: - $(run) pytest --cov-report term-missing --cov=textual tests/ -vv + $(run) pytest --cov-report term-missing --cov=textual tests/ -n 16 --dist=loadgroup $(ARGS) .PHONY: unit-test unit-test: - $(run) pytest --cov-report term-missing --cov=textual tests/ -vv -m "not integration_test" + $(run) pytest --cov-report term-missing --cov=textual tests/ -m "not integration_test" -n 16 --dist=loadgroup $(ARGS) .PHONY: test-snapshot-update test-snapshot-update: - $(run) pytest --cov-report term-missing --cov=textual tests/ -vv --snapshot-update + $(run) pytest --cov-report term-missing --cov=textual tests/ --snapshot-update -n 16 --dist=loadgroup $(ARGS) .PHONY: coverage coverage: diff --git a/poetry.lock b/poetry.lock index 639c7a1f37..fa62ea1f85 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "aiohttp" @@ -371,16 +371,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "colored" -version = "1.4.4" -description = "Simple library for color and formatting to terminal" -optional = false -python-versions = "*" -files = [ - {file = "colored-1.4.4.tar.gz", hash = "sha256:04ff4d4dd514274fe3b99a21bb52fb96f2688c01e93fba7bef37221e7cb56ce0"}, -] - [[package]] name = "coverage" version = "7.5.1" @@ -442,6 +432,9 @@ files = [ {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, ] +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + [package.extras] toml = ["tomli"] @@ -470,6 +463,20 @@ files = [ [package.extras] test = ["pytest (>=6)"] +[[package]] +name = "execnet" +version = "2.1.1" +description = "execnet: rapid multi-Python deployment" +optional = false +python-versions = ">=3.8" +files = [ + {file = "execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc"}, + {file = "execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3"}, +] + +[package.extras] +testing = ["hatch", "pre-commit", "pytest", "tox"] + [[package]] name = "filelock" version = "3.14.0" @@ -1497,13 +1504,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "7.4.4" +version = "8.3.1" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, + {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, ] [package.dependencies] @@ -1511,11 +1518,11 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" @@ -1537,41 +1544,60 @@ testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-cov" -version = "2.12.1" +version = "5.0.0" description = "Pytest plugin for measuring coverage." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.8" files = [ - {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, - {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, + {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, + {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, ] [package.dependencies] -coverage = ">=5.2.1" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" -toml = "*" [package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "pytest-textual-snapshot" -version = "0.4.0" +version = "1.0.0" description = "Snapshot testing for Textual apps" optional = false -python-versions = ">=3.6,<4.0" +python-versions = "<4.0.0,>=3.8.1" files = [ - {file = "pytest_textual_snapshot-0.4.0-py3-none-any.whl", hash = "sha256:879cc5de29cdd31cfe1b6daeb1dc5e42682abebcf4f88e7e3375bd5200683fc0"}, - {file = "pytest_textual_snapshot-0.4.0.tar.gz", hash = "sha256:63782e053928a925d88ff7359dd640f2900e23bc708b3007f8b388e65f2527cb"}, + {file = "pytest_textual_snapshot-1.0.0-py3-none-any.whl", hash = "sha256:dd3a421491a6b1987ee7b4336d7f65299524924d2b0a297e69733b73b01570e1"}, + {file = "pytest_textual_snapshot-1.0.0.tar.gz", hash = "sha256:065217055ed833b8a16f2320a0613f39a0154e8d9fee63535f29f32c6414b9d7"}, ] [package.dependencies] jinja2 = ">=3.0.0" -pytest = ">=7.0.0" +pytest = ">=8.0.0" rich = ">=12.0.0" -syrupy = ">=3.0.0" +syrupy = ">=4.0.0" textual = ">=0.28.0" +[[package]] +name = "pytest-xdist" +version = "3.6.1" +description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest_xdist-3.6.1-py3-none-any.whl", hash = "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7"}, + {file = "pytest_xdist-3.6.1.tar.gz", hash = "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d"}, +] + +[package.dependencies] +execnet = ">=2.1" +pytest = ">=7.0.0" + +[package.extras] +psutil = ["psutil (>=3.0)"] +setproctitle = ["setproctitle"] +testing = ["filelock"] + [[package]] name = "python-dateutil" version = "2.9.0.post0" @@ -1609,7 +1635,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -1617,15 +1642,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -1642,7 +1660,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -1650,7 +1667,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -1866,18 +1882,17 @@ files = [ [[package]] name = "syrupy" -version = "3.0.6" +version = "4.6.1" description = "Pytest Snapshot Test Utility" optional = false -python-versions = ">=3.7,<4" +python-versions = ">=3.8.1,<4" files = [ - {file = "syrupy-3.0.6-py3-none-any.whl", hash = "sha256:9c18e22264026b34239bcc87ab7cc8d893eb17236ea7dae634217ea4f22a848d"}, - {file = "syrupy-3.0.6.tar.gz", hash = "sha256:583aa5ca691305c27902c3e29a1ce9da50ff9ab5f184c54b1dc124a16e4a6cf4"}, + {file = "syrupy-4.6.1-py3-none-any.whl", hash = "sha256:203e52f9cb9fa749cf683f29bd68f02c16c3bc7e7e5fe8f2fc59bdfe488ce133"}, + {file = "syrupy-4.6.1.tar.gz", hash = "sha256:37a835c9ce7857eeef86d62145885e10b3cb9615bc6abeb4ce404b3f18e1bb36"}, ] [package.dependencies] -colored = ">=1.3.92,<2.0.0" -pytest = ">=5.1.0,<8.0.0" +pytest = ">=7.0.0,<9.0.0" [[package]] name = "textual-dev" @@ -1897,17 +1912,6 @@ msgpack = ">=1.0.3" textual = ">=0.36.0" typing-extensions = ">=4.4.0,<5.0.0" -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - [[package]] name = "tomli" version = "2.0.1" @@ -2351,5 +2355,5 @@ syntax = ["tree-sitter", "tree-sitter-languages"] [metadata] lock-version = "2.0" -python-versions = "^3.8" -content-hash = "7cf7f99ade9d00e6b4b190af1563eaeccb55e4e8e424f67ace7da2e3e9c62308" +python-versions = "^3.8.1" +content-hash = "a632a2480a0262dcdbf49a456c2528dd6193a14cd00f203887dabab10c55c450" diff --git a/pyproject.toml b/pyproject.toml index 21faa4d742..609033f695 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,7 +40,7 @@ include = [ "Bug Tracker" = "https://github.com/Textualize/textual/issues" [tool.poetry.dependencies] -python = "^3.8" +python = "^3.8.1" markdown-it-py = { extras = ["plugins", "linkify"], version = ">=2.1.0" } rich = ">=13.3.3" #rich = {path="../rich", develop=true} @@ -64,15 +64,16 @@ mkdocstrings = { extras = ["python"], version = "^0.20.0" } mkdocstrings-python = "0.10.1" mypy = "^1.0.0" pre-commit = "^2.13.0" -pytest = "^7.1.3" +pytest = "^8.3.1" +pytest-xdist = "^3.6.1" pytest-asyncio = "*" -pytest-cov = "^2.12.1" -pytest-textual-snapshot = ">=0.4.0" +pytest-cov = "^5.0.0" textual-dev = "^1.2.0" types-setuptools = "^67.2.0.1" types-tree-sitter = "^0.20.1.4" types-tree-sitter-languages = "^1.7.0.1" isort = "^5.13.2" +pytest-textual-snapshot = "^1.0.0" [tool.pytest.ini_options] asyncio_mode = "auto" diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr deleted file mode 100644 index ca5d517574..0000000000 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ /dev/null @@ -1,51393 +0,0 @@ -# name: test_alignment_containers - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AlignContainersApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  center  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  middle  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - ''' -# --- -# name: test_ansi_color_mapping[False] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AnsiMappingApp - - - - - - - - - - Foreground & background                                                          - red - dim red - green - dim green - yellow - dim yellow - blue - dim blue - magenta - dim magenta - cyan - dim cyan - white - dim white - black - dim black - - - - - - - - - - - - ''' -# --- -# name: test_ansi_color_mapping[True] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AnsiMappingApp - - - - - - - - - - Foreground & background                                                          - red - dim red - green - dim green - yellow - dim yellow - blue - dim blue - magenta - dim magenta - cyan - dim cyan - white - dim white - black - dim black - - - - - - - - - - - - ''' -# --- -# name: test_app_blur - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AppBlurApp - - - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This should be the blur style      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This should also be the blur style - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - ''' -# --- -# name: test_auto_fr - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FRApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌────────────────────────────┐ - Hello one line               - ┌──────────────────────────┐ - Widget#child - - - - - - - - - - - - - - └──────────────────────────┘ - - Two - Lines with 1x2 margin - - └────────────────────────────┘ - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_auto_grid - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - foo         ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - foo▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - foo bar foo bar foo bar foo ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - bar foo bar foo bar foo bar  - foo bar foo bar foo bar ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - Longer label                  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_auto_grid_default_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridHeightAuto - - - - - - - - - - GridHeightAuto - Here is some text before the grid                                                - ┌──────────────────────────────────────────────────────────────────────────────┐ - Cell #0                   Cell #1                   Cell #2                    - Cell #3                   Cell #4                   Cell #5                    - Cell #6                   Cell #7                   Cell #8                    - └──────────────────────────────────────────────────────────────────────────────┘ - Here is some text after the grid                                                 - - - - - - - - - - - - - - - -  g Grid  v Vertical  h Horizontal  c Container  - - - - - ''' -# --- -# name: test_auto_tab_active - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ExampleApp - - - - - - - - - - - Parent 1Parent 2 - ━━━━━━━━━━━━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - - Child 2.1Child 2.2 - ━━━━━━━━━━━━━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button 2.2  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - -  SPACE Focus button 2.2  - - - - - ''' -# --- -# name: test_auto_table - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - MyApp - ╭──────────────────╮╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ - ok                ││test                                                                                               - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍││╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - ││╭─ 0 ──────────────────────────────────────╮╭─ 1 ──────────────────────────────────────╮╭─ 2 ─────│ - │││││││ - │││ Foo       Bar         Baz              ││ Foo       Bar         Baz              ││ Foo      - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH - ││╰──────────────────────────────────────────╯╰──────────────────────────────────────────╯╰─────────│ - ││ - ╰──────────────────╯╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_auto_width_input - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputWidthAutoApp - - - - - - - - - - InputWidthAutoApp - ▔▔▔▔▔▔▔▔▔▔ - Hello - ▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_big_buttons - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ButtonApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - -  Hello  - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - -  Hello  -  World !!  - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - ''' -# --- -# name: test_bindings_screen_overrides_show - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HideBindingApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  p Binding shown  - - - - - ''' -# --- -# name: test_blur_on_disabled - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BlurApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - foo                                                                        - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_border_alpha - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderAlphaApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - - - - - ''' -# --- -# name: test_button_outline - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ButtonIssue - - - - - - - - - - ┌──────────────┐ -  Test  - └──────────────┘ - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_button_widths - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HorizontalWidthAutoApp - - - - - - - - - - ┌────────────────────────────┐ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  This is a very wide button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - └────────────────────────────┘ - ┌────────────────────────────────────────────────────────┐ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  This is a very wide button  This is a very wide button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - └────────────────────────────────────────────────────────┘ - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_button_with_console_markup - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ButtonsWithMarkupApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Focused Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Blurred Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Disabled Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_button_with_multiline_label - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ButtonWithMultilineLabelApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  -  with  -  multi-line  -  label  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_buttons_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ButtonsApp - - - - - - - - - - - Standard ButtonsDisabled Buttons - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Default  Default  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Primary!  Primary!  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Success!  Success!  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Warning!  Warning!  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Error!  Error!  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - ''' -# --- -# name: test_checkbox_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CheckboxApp - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - X Arrakis 😓 - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔ - X Caladan - ▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔ - X Chusuk - ▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - XGiedi Prime - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔ - XGinaz - ▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔ - X Grumman - ▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▃▃ - XKaitain - ▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - ''' -# --- -# name: test_collapsible_collapsed - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CollapsibleApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▶ Leto - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▶ Jessica - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▶ Paul - - - - - - - - - - - - - - - -  c Collapse All  e Expand All  - - - - - ''' -# --- -# name: test_collapsible_custom_symbol - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CollapsibleApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - >>> Togglev Toggle - - Hello, world.                        - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_collapsible_expanded - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CollapsibleApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Leto - - # Duke Leto I Atreides - - Head of House Atreides.                                                    - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Jessica - - - - Lady Jessica - -   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Paul▆▆ - - - -  c Collapse All  e Expand All  - - - - - ''' -# --- -# name: test_collapsible_nested - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CollapsibleApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Toggle - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▶ Toggle - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_collapsible_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CollapsibleApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Leto - - # Duke Leto I Atreides - - Head of House Atreides.                                                      - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▼ Jessica - - - - Lady Jessica - -   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▶ Paul - - - -  c Collapse All  e Expand All  - - - - - ''' -# --- -# name: test_columns_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HeightApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌────────────────────┐┌────────────────┐┌──────────────────────┐ - As tall as container││This has default││I have a static height - ││height││ - ││but a││ - ││few lines││ - │└────────────────┘│ - - - - - - - - - - └────────────────────┘└──────────────────────┘ - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - - - - - - - ''' -# --- -# name: test_command_palette - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CommandPaletteApp - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - 🔎A - - -   This is a test of this code 0                                                  -   This is a test of this code 1                                                  -   This is a test of this code 2                                                  -   This is a test of this code 3                                                  -   This is a test of this code 4                                                  -   This is a test of this code 5                                                  -   This is a test of this code 6                                                  -   This is a test of this code 7                                                  -   This is a test of this code 8                                                  -   This is a test of this code 9                                                  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ''' -# --- -# name: test_command_palette_discovery - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CommandPaletteApp - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - 🔎Search for commands… - - -   This is a test of this code 0                                                  -   This is a test of this code 1                                                  -   This is a test of this code 2                                                  -   This is a test of this code 3                                                  -   This is a test of this code 4                                                  -   This is a test of this code 5                                                  -   This is a test of this code 6                                                  -   This is a test of this code 7                                                  -   This is a test of this code 8                                                  -   This is a test of this code 9                                                  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ''' -# --- -# name: test_component_text_opacity - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TestApp - - - - - - - - - - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW - - - - - ''' -# --- -# name: test_content_switcher_example_initial - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ContentSwitcherApp - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  DataTable  Markdown  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ╭────────────────────────────────────────────────────────────────────╮ -  Book                                 Year  -  Dune                                 1965  -  Dune Messiah                         1969  -  Children of Dune                     1976  -  God Emperor of Dune                  1981  -  Heretics of Dune                     1984  -  Chapterhouse: Dune                   1985  - - - - - - - - - - - ╰────────────────────────────────────────────────────────────────────╯ - - - - - - ''' -# --- -# name: test_content_switcher_example_switch - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ContentSwitcherApp - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  DataTable  Markdown  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ╭─────────────────────────────────────────╮ - - - Three Flavours Cornetto - -   The Three Flavours Cornetto trilogy  -   is an anthology series of British  -   comedic genre films directed by Edgar   -   Wright. - - - Shaun of the Dead - - - UK Release   - Flavour   Date        Director    -    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    -    Strawberry 2004-04-09   Edgar          -                            Wright         - - - - Hot Fuzz - - - UK Release    - Flavour Date         Director     -    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    -    Classico 2007-02-17    Edgar Wright    - - - - The World's End - - - UK Release     - FlavourDate          Director     -    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    -    Mint    2013-07-19     Edgar Wright    - - - - - - ╰─────────────────────────────────────────╯ - - - - - - ''' -# --- -# name: test_css_hot_reloading - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HotReloadingApp - - - - - - - - - - Hello, world!                                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_hot_reloading_on_screen - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HotReloadingApp - - - - - - - - - - Hello, world!                                                                    - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[align.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AlignApp - - - - - - - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - Vertical alignment with Textual - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - Take note, browsers. - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - - - - - - ''' -# --- -# name: test_css_property[align_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AlignAllApp - - - - - - - - - - ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ - left topcenter topright top - - - - - └────────────────────────┘└────────────────────────┘└────────────────────────┘ - - ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ - - - left middlecenter middleright middle - - - └────────────────────────┘└────────────────────────┘└────────────────────────┘ - - ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ - - - - - - left bottomcenter bottomright bottom - └────────────────────────┘└────────────────────────┘└────────────────────────┘ - - - - - ''' -# --- -# name: test_css_property[background.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BackgroundApp - - - - - - - - - - - - - Widget 1 - - - - - - - - Widget 2 - - - - - - - - Widget 3 - - - - - - - - - ''' -# --- -# name: test_css_property[background_transparency.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BackgroundTransparencyApp - - - - - - - - - - - - - - - - - - - - - 10%20%30%40%50%60%70%80%90%100% - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[border.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderApp - - - - - - - - - - - ┌────────────────────────────────────────────────────────────────────────────┐ - - My border is solid red - - └────────────────────────────────────────────────────────────────────────────┘ - - ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ - - My border is dashed green - - ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - My border is tall blue - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - ''' -# --- -# name: test_css_property[border_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AllBordersApp - - - - - - - - - - - +----------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓╔═════════════════╗ - |ascii|blankdasheddouble - +----------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛╚═════════════════╝ - - - - ┏━━━━━━━━━━━━━━━━┓▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ - heavyhidden/nonehkeyinner - ┗━━━━━━━━━━━━━━━━┛▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ - - - - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜█████████████████▎╭────────────────╮┌─────────────────┐ - outerpanelroundsolid - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎╰────────────────╯└─────────────────┘ - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█▏                ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - tallthickvkeywide - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▏                ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - ''' -# --- -# name: test_css_property[border_sub_title_align_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderSubTitleAlignAll - - - - - - - - - - - - ▏  Border title      ▕╭─ Lef… ─╮▁▁▁▁▁ Left ▁▁▁▁▁ - This is the story ofa Pythondeveloper that - ▏   Border subtitle  ▕╰─ Cen… ─╯▔▔▔▔▔ @@@ ▔▔▔▔▔▔ - - - - - - +--------------+─Title───────────────── - |had to fill up|             nine labels          and ended up redoing it   - +- Left -------+──────────────Subtitle─ - - - - - ─Title, but really looo…─ - ─Title, but r…──Title, but reall…─ - because the first try       had some labels          that were too long.     - ─Subtitle, bu…──Subtitle, but re…─ - ─Subtitle, but really l…─ - - - - - - - ''' -# --- -# name: test_css_property[border_subtitle_align.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderSubtitleAlignApp - - - - - - - - - - - ┌────────────────────────────────────────────────────────────────────────────┐ - - My subtitle is on the left. - - └─ < Left ───────────────────────────────────────────────────────────────────┘ - - ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ - - My subtitle is centered - - ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ - - My subtitle is on the right - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Right > ▁▎ - - - - - - - - - - - ''' -# --- -# name: test_css_property[border_title_align.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderTitleAlignApp - - - - - - - - - - - ┌─ < Left ───────────────────────────────────────────────────────────────────┐ - - My title is on the left. - - └────────────────────────────────────────────────────────────────────────────┘ - - ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ - - My title is centered - - ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Right > ▔▎ - - My title is on the right - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ - - - - - - - - - - - ''' -# --- -# name: test_css_property[border_title_colors.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderTitleApp - - - - - - - - - - - - - - - - ┏━ Textual Rocks ━━━━━━━━━━━━━┓ - - - - - Hello, World! - - - - - ┗━━━━━━━━━━━━━ Textual Rocks ━┛ - - - - - - - - - - - - ''' -# --- -# name: test_css_property[box_sizing.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BoxSizingApp - - - - - - - - - - - -   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   - - I'm using border-box! - -   ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   - - -   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   - - I'm using content-box! - - - - - -   ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   - - - - - - - - - - - ''' -# --- -# name: test_css_property[color.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ColorApp - - - - - - - - - - - - - I'm red! - - - - - - - - I'm rgb(0, 255, 0)! - - - - - - - - I'm hsl(240, 100%, 50%)! - - - - - - - - - ''' -# --- -# name: test_css_property[color_auto.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ColorApp - - - - - - - - - - - The quick brown fox jumps over the lazy dog! - - - - - The quick brown fox jumps over the lazy dog! - - - - - The quick brown fox jumps over the lazy dog! - - - - - The quick brown fox jumps over the lazy dog! - - - - - The quick brown fox jumps over the lazy dog! - - - - - - - ''' -# --- -# name: test_css_property[column_span.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - - - #p1 - - - - - - #p2#p3 - - - - - - #p4#p5 - - - - - - #p6#p7 - - - - - - - - ''' -# --- -# name: test_css_property[content_align.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ContentAlignApp - - - - - - - - - - - With content-align you can... - - - - - - - - - - ...Easily align content... - - - - - - - - - - - ...Horizontally and vertically! - - - - - - ''' -# --- -# name: test_css_property[content_align_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AllContentAlignApp - - - - - - - - - - left topcenter topright top - - - - - - - - - - - left middlecenter middleright middle - - - - - - - - - - - - left bottomcenter bottomright bottom - - - - - ''' -# --- -# name: test_css_property[display.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DisplayApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┃Widget 1 - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┃Widget 3 - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[dock_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DockAllApp - - - - - - - - - - - - - ╭──────────────────────────────────────────────────────────╮ -                            top                             - - - - - - - left                                                 right - - - - - - - -                           bottom                           - ╰──────────────────────────────────────────────────────────╯ - - - - - - - - ''' -# --- -# name: test_css_property[grid.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridApp - - - - - - - - - - - Grid cell 1Grid cell 2 - - row-span: 3; - column-span: 2; - - - Grid cell 3 - - - - - - Grid cell 4 - - - - - - Grid cell 5Grid cell 6Grid cell 7 - - - - - - - - - ''' -# --- -# name: test_css_property[grid_columns.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ - 1fr││width = 16││2fr││1fr││width = 16 - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ - ╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ - 1fr││width = 16││2fr││1fr││width = 16 - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ││││││││ - ╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ - - - - - ''' -# --- -# name: test_css_property[grid_gutter.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ - - 12 - - ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ - - ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ - - 34 - - ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ - - ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ - - 56 - - ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ - - ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ - - 78 - - - ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_css_property[grid_rows.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - 1fr││1fr - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - height = 6││height = 6 - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - 25%││25% - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - 1fr││1fr - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - height = 6││height = 6 - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_css_property[grid_size_both.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - 1││2 - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - 3││4 - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮ - - 5 - - - ╰──────────────────────────────────────╯ - - - - - - - - - - - ''' -# --- -# name: test_css_property[grid_size_columns.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - ││ - 1││2 - ││ - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ - ││ - ││ - 3││4 - ││ - ││ - ││ - ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ - ╭──────────────────────────────────────╮ - - - 5 - - - - ╰──────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_css_property[hatch.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HatchApp - - - - - - - - - - ┌─ cross ──────┐┌─ horizontal ─┐┌─ custom ─────┐┌─ left ───────┐┌─ right ──────┐ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - └──────────────┘└──────────────┘└──────────────┘└──────────────┘└──────────────┘ - - - - - ''' -# --- -# name: test_css_property[height.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HeightApp - - - - - - - - - - Widget - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[height_comparison.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HeightComparisonApp - - - - - - - - - - #cells· - · - · - #percent· - - · - #w· - · - · - - #h· - · - · - · - #vw - · - · - · - #vh· - - #auto· - #fr1· - #fr2· - · - - - - - ''' -# --- -# name: test_css_property[keyline.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KeylineApp - - - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ - - - #foo - - - ┣━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┫#bar - - - Placeholder - - - ┣━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━┫ - - - #baz - - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - ''' -# --- -# name: test_css_property[keyline_horizontal.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KeylineApp - - - - - - - - - - ┌─────────────────────────┬─────────────────────────┬──────────────────────────┐ - - - - - - - - - - - PlaceholderPlaceholderPlaceholder - - - - - - - - - - - - └─────────────────────────┴─────────────────────────┴──────────────────────────┘ - - - - - ''' -# --- -# name: test_css_property[layout.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LayoutApp - - - - - - - - - - - Layout - - Is - - Vertical - - - LayoutIsHorizontal - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_background.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkBackgroundApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_background_hover.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkHoverBackgroundApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_color.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkColorApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_color_hover.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkHoverColorApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_style.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkStyleApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[link_style_hover.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinkHoverStyleApp - - - - - - - - - - Visit the Textualize website.                                                    - Click here for the bell sound.                                                   - You can also click here for the bell sound.                                      - Exit this application. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[links.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LinksApp - - - - - - - - - - Here is a link which you can click! - - Here is a link which you can click! - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[margin.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarginApp - - - - - - - - - - - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see  - its path. - Where the fear has gone there will be nothing. Only I will  - remain. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[margin_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarginAllApp - - - - - - - - - - ╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ - - - - marginmargin: 1  - no marginmargin: 1: 1 51 2 6 - - - - - ╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ - - ╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ - - - margin-bottom: 4 - - margin-right: margin-left: 3 - 3 - margin-top: 4 - - - - ╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ - - - - - ''' -# --- -# name: test_css_property[max_height.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxHeightApp - - - - - - - - - - - - - max-height: 10w - max-height: 10 - max-height: 50% - - - - - - max-height: 999 - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[max_width.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MaxWidthApp - - - - - - - - - - - - max-width:  - 50h - - - - - max-width: 999 - - - - - - max-width: 50% - - - - - - max-width: 30 - - - - - - - - ''' -# --- -# name: test_css_property[min_height.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MinHeightApp - - - - - - - - - - - - - - - min-height: 25% - - - min-height: 75% - - - - - - min-height: 30 - min-height: 40w - - - ▃▃ - - - - - - - - - - ''' -# --- -# name: test_css_property[min_width.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MinWidthApp - - - - - - - - - - - - min-width: 25% - - - - - min-width: 75% - - - - - - min-width: 100 - - - - - - min-width: 400h - - - - - - - - - ''' -# --- -# name: test_css_property[offset.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OffsetApp - - - - - - - - - - - Chani (offset 0  - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜-3) - - - - ▌Paul (offset 8 2)▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - - - - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ - - - ▌Duncan (offset 4  - ▌10) - - - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - - - - - - - - - ''' -# --- -# name: test_css_property[opacity.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OpacityApp - - - - - - - - - - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - opacity: 0% - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - - opacity: 25% - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - - opacity: 50% - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - - opacity: 75% - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ - - opacity: 100% - - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ - - - - - ''' -# --- -# name: test_css_property[outline.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OutlineApp - - - - - - - - - - - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ear is the mind-killer. - ear is the little-death that brings total obliteration. -  will face my fear. -  will permit it to pass over me and through me. - nd when it has gone past, I will turn the inner eye to see its - ath. - here the fear has gone there will be nothing. Only I will  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[outline_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AllOutlinesApp - - - - - - - - - - +------------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ - |ascii|blankdashed - +------------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ - - - ╔══════════════════╗┏━━━━━━━━━━━━━━━━━━┓ - doubleheavyhidden/none - ╚══════════════════╝┗━━━━━━━━━━━━━━━━━━┛ - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ - hkeyinnernone - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ - - - ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜╭──────────────────╮┌──────────────────┐ - outerroundsolid - ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟╰──────────────────╯└──────────────────┘ - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▏                  ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - tallvkeywide - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▏                  ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - ''' -# --- -# name: test_css_property[outline_vs_border.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OutlineBorderApp - - - - - - - - - - ╭───────────────────────────────────────────────────────────────────╮ - ear is the mind-killer. - ear is the little-death that brings total obliteration. -  will face my fear. -  will permit it to pass over me and through me. - nd when it has gone past, I will turn the inner eye to see its path - here the fear has gone there will be nothing. Only I will remain. - ╰───────────────────────────────────────────────────────────────────╯ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ╭─────────────────────────────────────────────────────────────────────╮ - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - ╰─────────────────────────────────────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_css_property[overflow.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OverflowApp - - - - - - - - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that Fear is the little-death that  - brings total obliteration.brings total obliteration. - I will face my fear.I will face my fear. - I will permit it to pass over meI will permit it to pass over me  - and through me.and through me. - And when it has gone past, I And when it has gone past, I will  - will turn the inner eye to see turn the inner eye to see its  - its path.▁▁path. - Where the fear has gone there Where the fear has gone there will - will be nothing. Only I will be nothing. Only I will remain. - remain.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I must not fear. - I must not fear.Fear is the mind-killer. - Fear is the mind-killer.Fear is the little-death that  - Fear is the little-death that brings total obliteration. - brings total obliteration.I will face my fear. - I will face my fear.I will permit it to pass over me  - I will permit it to pass over meand through me. - - - - - ''' -# --- -# name: test_css_property[padding.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PaddingApp - - - - - - - - - - - - - - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its  - path. - Where the fear has gone there will be nothing. Only I will  - remain. - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[padding_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PaddingAllApp - - - - - - - - - - no padding - padding: 1padding:padding: 1 1 - 1 52 6 - - - - - - - - - - padding-right: 3padding-bottom: 4padding-left: 3 - - - - padding-top: 4 - - - - - - - - - - - - ''' -# --- -# name: test_css_property[row_span.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - - - #p4 - - - #p3 - - - #p2 - - - #p1 - - - #p5 - - - #p6 - - - #p7 - - - - - - - - ''' -# --- -# name: test_css_property[scrollbar_corner_color.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollbarCornerColorApp - - - - - - - - - - I must not fear. Fear is the mind-killer. Fear is the little-death that brings - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - Where the fear has gone there will be nothing. Only I will remain.▅▅ - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - - - - - - ''' -# --- -# name: test_css_property[scrollbar_gutter.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollbarGutterApp - - - - - - - - - - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - Where the fear has gone there will be nothing. Only I will remain. - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[scrollbar_size.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollbarApp - - - - - - - - - - - - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration.▁▁▁▁ - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path. - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[scrollbar_size2.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollbarApp - - - - - - - - - - I must not fear.I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death Fear is the little-death tFear is the little-death  - I will face my fear.I will face my fear.I will face my fear. - I will permit it to pass I will permit it to pass oI will permit it to pass  - And when it has gone pastAnd when it has gone past,And when it has gone past - Where the fear has gone tWhere the fear has gone thWhere the fear has gone t - I must not fear.I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death Fear is the little-death tFear is the little-death  - I will face my fear.I will face my fear.I will face my fear.▇▇ - I will permit it to pass I will permit it to pass oI will permit it to pass  - And when it has gone pastAnd when it has gone past,And when it has gone past - Where the fear has gone tWhere the fear has gone thWhere the fear has gone t - I must not fear.I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death Fear is the little-death tFear is the little-death  - I will face my fear.I will face my fear.I will face my fear. - I will permit it to pass I will permit it to pass oI will permit it to pass  - And when it has gone past, - Where the fear has gone th - I must not fear. - Fear is the mind-killer. - - - - - - ''' -# --- -# name: test_css_property[scrollbars.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollbarApp - - - - - - - - - - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that brings tFear is the little-death that brings t - I will face my fear.I will face my fear. - I will permit it to pass over me and tI will permit it to pass over me and t - And when it has gone past, I will turnAnd when it has gone past, I will turn - see its path.see its path. - Where the fear has gone there will be Where the fear has gone there will be  - will remain.will remain. - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that brings tFear is the little-death that brings t - I will face my fear.I will face my fear. - I will permit it to pass over me and tI will permit it to pass over me and t - And when it has gone past, I will turnAnd when it has gone past, I will turn - see its path.▃▃see its path.▃▃ - Where the fear has gone there will be Where the fear has gone there will be  - will remain.will remain. - I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death that brings tFear is the little-death that brings t - I will face my fear.I will face my fear. - I will permit it to pass over me and tI will permit it to pass over me and t - - - - - - ''' -# --- -# name: test_css_property[scrollbars2.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Scrollbar2App - - - - - - - - - - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path.          - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - Fear is the mind-killer.▇▇ - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path.          - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - I will face my fear. - I will permit it to pass over me and through me. - And when it has gone past, I will turn the inner eye to see its path.          - Where the fear has gone there will be nothing. Only I will remain. - I must not fear. - Fear is the mind-killer. - Fear is the little-death that brings total obliteration. - - - - - ''' -# --- -# name: test_css_property[text_align.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAlign - - - - - - - - - - - Left alignedCenter aligned - I must not fear. Fear is the            I must not fear. Fear is the     - mind-killer. Fear is the                  mind-killer. Fear is the       - little-death that brings total         little-death that brings total    - obliteration. I will face my fear. Iobliteration. I will face my fear. I - will permit it to pass over me and   will permit it to pass over me and  - through me.                                     through me.              - - - - - - Right alignedJustified -         I must not fear. Fear is theI  must  not  fear.  Fear   is   the -             mind-killer. Fear is themind-killer.     Fear     is     the -       little-death that brings totallittle-death   that   brings   total - obliteration. I will face my fear. Iobliteration. I will face my fear. I -   will permit it to pass over me andwill permit it to pass over  me  and -                          through me.through me. - - - - - - - - - ''' -# --- -# name: test_css_property[text_opacity.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextOpacityApp - - - - - - - - - - - - - -                                text-opacity: 25%                                 - - - - -                                text-opacity: 50%                                 - - - - -                                text-opacity: 75%                                 - - - - -                                text-opacity: 100%                                - - - - - - - - - ''' -# --- -# name: test_css_property[text_style.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextStyleApp - - - - - - - - - - I must not fear.I must not fear.I must not fear. - Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. - Fear is the little-death Fear is the little-death Fear is the little-death  - that brings total that brings total that brings total  - obliteration.obliteration.obliteration. - I will face my fear.I will face my fear.I will face my fear. - I will permit it to pass I will permit it to pass I will permit it to pass  - over me and through me.over me and through me.over me and through me. - And when it has gone past,And when it has gone past, And when it has gone past,  - I will turn the inner eye I will turn the inner eye I will turn the inner eye  - to see its path.to see its path.to see its path. - Where the fear has gone Where the fear has gone Where the fear has gone  - there will be nothing. there will be nothing. Onlythere will be nothing. Only - Only I will remain.I will remain.I will remain. - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[text_style_all.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AllTextStyleApp - - - - - - - - - - -   nonebolditalicreverse -   I must not fear.I must not fear.I must not fear.I must not fear. -   Fear is the Fear is the Fear is the Fear is the  -   mind-killer.mind-killer.mind-killer.mind-killer. -   Fear is the Fear is the Fear is the Fear is the  -   little-death that  little-death that little-death thatlittle-death that  -   brings total brings total brings total brings total  -   obliteration.obliteration.obliteration.obliteration. -   I will face my I will face my I will face my I will face my  -   fear.fear.fear.fear. - - strikeunderlinebold italicreverse strike - I must not fear.I must not fear.I must not fear.I must not fear. - Fear is the Fear is the Fear is the Fear is the  - mind-killer.mind-killer.mind-killer.mind-killer. - Fear is the Fear is the Fear is the Fear is the  - little-death thatlittle-death that little-death thatlittle-death that  - brings total brings total brings total brings total  - obliteration.obliteration.obliteration.obliteration. - I will face my I will face my I will face my I will face my  - fear.fear.fear.fear. - I will permit it I will permit it I will permit it I will permit it  - - - - - - ''' -# --- -# name: test_css_property[tint.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TintApp - - - - - - - - - - - tint: green 0%; - - - tint: green 10%; - - - tint: green 20%; - - - tint: green 30%; - - - tint: green 40%; - - - tint: green 50%; - ▄▄ - - tint: green 60%; - - - tint: green 70%; - - - - - - ''' -# --- -# name: test_css_property[visibility.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VisibilityApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┃Widget 1 - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┃Widget 3 - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[visibility_containers.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VisibilityContainersApp - - - - - - - - - - - - - PlaceholderPlaceholderPlaceholder - - - - - - - - - - - - - - - - PlaceholderPlaceholderPlaceholder - - - - - - - - - ''' -# --- -# name: test_css_property[width.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WidthApp - - - - - - - - - - Widget - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_css_property[width_comparison.py] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WidthComparisonApp - - - - - - - - - - - - - - - - - - - - - #cells#percent#w#h#vw#vh#auto#fr1#fr3 - - - - - - - - - - - - ····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• - - - - - ''' -# --- -# name: test_data_table_in_tabs - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dashboard - - - - - - - - - - - Workflows - ━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -  Id   Description  Status  Result Id  -  1    2            3       4          -  a    b            c       d          -  fee  fy           fo      fum        - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_add_column - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AddColumn - - - - - - - - - -  Movies          No Default  With Default  Long Default          -  Severance       ABC           01234567890123456789  -  Foundation      ABC           01234567890123456789  -  Dark            Hello!      ABC           01234567890123456789  -  The Boys        ABC           01234567890123456789  -  The Last of Us  ABC           01234567890123456789  -  Lost in Space   ABC           01234567890123456789  -  Altered Carbon  ABC           01234567890123456789  - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_add_row_auto_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AutoHeightRowsApp - - - - - - - - - -  N  Column      -  3  hey there   -  1  hey there   -  5  long        -  string      -  2  ╭───────╮   -  │ Hello │   -  │ world │   -  ╰───────╯   -  4  1           -  2           -  3           -  4           -  5           -  6           -  7           - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_add_row_auto_height_sorted - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AutoHeightRowsApp - - - - - - - - - -  N  Column      -  1  hey there   -  2  ╭───────╮   -  │ Hello │   -  │ world │   -  ╰───────╯   -  3  hey there   -  4  1           -  2           -  3           -  4           -  5           -  6           -  7           -  5  long        -  string      - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_cell_padding - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - - - one  two  three - valuevalueval   - -  one    two    three  -  value  value  val    - -   one      two      three   -   value    value    val     - -    one        two        three    -    value      value      val      - -     one          two          three     -     value        value        val       - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_change_cell_padding - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - - - one  two  three - valuevalueval   - -  one    two    three  -  value  value  val    - -   one      two      three   -   value    value    val     - -    one        two        three    -    value      value      val      - -           one                      two                      three           -           value                    value                    val             - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_column_cursor_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  4     Joseph Schooling      Singapore      50.39  -  2     Michael Phelps        United States  51.14  -  5     Chad le Clos          South Africa   51.14  -  6     László Cseh           Hungary        51.14  -  3     Li Zhuhao             China          51.26  -  8     Mehdy Metella         France         51.58  -  7     Tom Shields           United States  51.73  -  1     Aleksandr Sadovnikov  Russia         51.84  - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_hot_reloading - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DataTableHotReloadingApp - - - - - - - - - -  A           B     -  one         two   -  three       four  -  five        six   - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_labels_and_fixed_data - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  0  5     Chad le Clos          South Africa   51.14  -  1  4     Joseph Schooling      Singapore      50.39  -  2  2     Michael Phelps        United States  51.14  -  3  6     László Cseh           Hungary        51.14  -  4  3     Li Zhuhao             China          51.26  -  5  8     Mehdy Metella         France         51.58  -  6  7     Tom Shields           United States  51.73  -  7  10    Darren Burns          Scotland       51.84  -  8  1     Aleksandr Sadovnikov  Russia         51.84  - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_remove_row - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  5     Chad le Clos          South Africa   51.14  -  4     Joseph Schooling      Singapore      50.39  -  6     László Cseh           Hungary        51.14  -  3     Li Zhuhao             China          51.26  -  7     Tom Shields           United States  51.73  -  10    Darren Burns          Scotland       51.84  - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  4     Joseph Schooling      Singapore      50.39  -  2     Michael Phelps        United States  51.14  -  5     Chad le Clos          South Africa   51.14  -  6     László Cseh           Hungary        51.14  -  3     Li Zhuhao             China          51.26  -  8     Mehdy Metella         France         51.58  -  7     Tom Shields           United States  51.73  -  1     Aleksandr Sadovnikov  Russia         51.84  -  10    Darren Burns          Scotland       51.84  - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_row_cursor_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  4     Joseph Schooling      Singapore      50.39  -  2     Michael Phelps        United States  51.14  -  5     Chad le Clos          South Africa   51.14  -  6     László Cseh           Hungary        51.14  -  3     Li Zhuhao             China          51.26  -  8     Mehdy Metella         France         51.58  -  7     Tom Shields           United States  51.73  -  1     Aleksandr Sadovnikov  Russia         51.84  - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_sort_multikey - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableApp - - - - - - - - - -  lane  swimmer               country        time   -  4     Joseph Schooling      Singapore      50.39  -  2     Michael Phelps        United States  51.14  -  5     Chad le Clos          South Africa   51.14  -  6     László Cseh           Hungary        51.14  -  3     Li Zhuhao             China          51.26  -  8     Mehdy Metella         France         51.58  -  7     Tom Shields           United States  51.73  -  1     Aleksandr Sadovnikov  Russia         51.84  -  10    Darren Burns          Scotland       51.84  - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_datatable_style_ordering - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DataTableCursorStyles - - - - - - - - - - Foreground is 'css', background is 'css':                                        -  Movies      -  Severance   - Foundation - Dark - - Foreground is 'css', background is 'renderable':                                 -  Movies      - Severance - Foundation - Dark - - Foreground is 'renderable', background is 'renderable':                          -  Movies      - Severance - Foundation - Dark - - Foreground is 'renderable', background is 'css':                                 -  Movies      - Severance - Foundation - Dark - - - - - - ''' -# --- -# name: test_demo - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Textual Demo - - - - - - - - - - Textual Demo - - - TOP - - ▆▆ - - Widgets - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - Rich contentTextual Demo - - Welcome! Textual is a framework for creating sophisticated - applications with the terminal.                            - CSS - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Start  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - -  ^b Sidebar  ^t Toggle Dark mode  ^s Screenshot  f1 Notes  ^q Quit  - - - - - ''' -# --- -# name: test_digits - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DigitApp - - - - - - - - - - ╺━┓  ┓ ╻ ╻╺━┓╺━┓                                                                 -  ━┫  ┃ ┗━┫┏━┛  ┃                                                                 - ╺━┛.╺┻╸  ╹┗━╸  ╹                                                                 -                       ┏━┓ ┓ ╺━┓╺━┓╻ ╻┏━╸┏━╸╺━┓┏━┓┏━┓                             -                       ┃ ┃ ┃ ┏━┛ ━┫┗━┫┗━┓┣━┓  ┃┣━┫┗━┫╺╋╸╺━╸                       -                       ┗━┛╺┻╸┗━╸╺━┛  ╹╺━┛┗━┛  ╹┗━┛╺━┛      .,                     -                                                               ╺━┓    ┓ ┏━┓ ^ ╻ ╻ -                                                                ━┫ ×  ┃ ┃ ┃   ┗━┫ -                                                               ╺━┛   ╺┻╸┗━┛     ╹ - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_directory_tree_reloading - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DirectoryTreeReloadApp - - - - - - - - - - 📂 test_directory_tree_reloading0 - ├── 📂 b1 - │   ├── 📂 c1 - │   │   ┣━━ 📂 d1 - │   │   ┃   ┣━━ 📄 f1.txt - │   │   ┃   ┗━━ 📄 f2.txt - │   │   ┣━━ 📄 f1.txt - │   │   ┗━━ 📄 f2.txt - │   ├── 📄 f1.txt - │   └── 📄 f2.txt - ├── 📄 f1.txt - └── 📄 f2.txt - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_disabled_widgets - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WidgetDisableTestApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  Button  Button  Button  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_dock_layout_sidebar - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DockLayoutExample - - - - - - - - - - Sidebar1Docking a widget removes it from the layout and  - fixes its position, aligned to either the top,  - right, bottom, or left edges of a container. - - Docked widgets will not scroll out of view,  - making them ideal for sticky headers, footers,  - and sidebars. - ▇▇ - Docking a widget removes it from the layout and  - fixes its position, aligned to either the top,  - right, bottom, or left edges of a container. - - Docked widgets will not scroll out of view,  - making them ideal for sticky headers, footers,  - and sidebars. - - Docking a widget removes it from the layout and  - fixes its position, aligned to either the top,  - right, bottom, or left edges of a container. - - Docked widgets will not scroll out of view,  - making them ideal for sticky headers, footers,  - and sidebars. - - - - - - ''' -# --- -# name: test_dock_scroll - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TestApp - - - - - - - - - - TestApp - ┌─────────┐ - this - is - a - sample - sentence - and - here - are - some - wordsthis - is - a - sample - sentence - and - here - are - some - words -  ^q Quit  - - - ▇▇ - - - - - ''' -# --- -# name: test_dock_scroll2 - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TestApp - - - - - - - - - - TestApp - ┌─────────┐ - this - is - a - sample - sentence - and - here - are - some - wordsthis - is - a▅▅ - sample - sentence - and - here - are - some - words -  ^q Quit  - - - - - - - - ''' -# --- -# name: test_dock_scroll_off_by_one - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollOffByOne - - - - - - - - - - ▔▔▔▔▔▔▔▔ - X 92 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 93 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 94 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 95 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 96 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 97 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 98 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 99▁▁ - ▁▁▁▁▁▁▁▁ - - - - - - ''' -# --- -# name: test_dynamic_bindings - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BindingsApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  a  c  - - - - - ''' -# --- -# name: test_example_calculator - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CalculatorApp - - - - - - - - - - - -                                                                      ┏━┓ -                                                                      ┃ ┃ -                                                                      ┗━┛ - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  AC  +/-  %  ÷  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  7  8  9  ×  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  4  5  6  -  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  2  3  +  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - ''' -# --- -# name: test_example_color_command - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press ctrl + \ and type a color - - - - - - - - - - Press ctrl + \ and type a color - - - - - ansi_red - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_example_dictionary - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DictionaryApp - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Search for a word - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - - - - - - - - - - - - - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - ''' -# --- -# name: test_example_five_by_five - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 5x5 -- A little annoying puzzle - - - - - - - - - - 5x5 -- A little annoying puzzleMoves: 0Filled: 5 - ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ - ││││││││ - ││││││││ - ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ - ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ - ││││ - ││││ - ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ - ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ - ││││ - ││││ - ││││ - ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ - ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ - ││││ - ││││ - ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ - ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ - ││││││││ - ││││││││ - ││││││││ - ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ -  n New Game  ? Help  q Quit  ^d Toggle Dark Mode  - - - - - ''' -# --- -# name: test_example_json_tree - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TreeApp - - - - - - - - - - TreeApp - ▼ Root - └── ▼ {} JSON▁▁ -     ├── code='5060292302201' -     ├── ▼ {} product -     │   ┣━━ _id='5060292302201' -     │   ┣━━ ▶ [] _keywords -     │   ┣━━ ▶ [] added_countries_tags -     │   ┣━━ ▶ [] additives_debug_tags -     │   ┣━━ additives_n=2 -     │   ┣━━ additives_old_n=2 -     │   ┣━━ ▶ [] additives_old_tags -     │   ┣━━ ▶ [] additives_original_tags -     │   ┣━━ ▶ [] additives_prev_original_tags -     │   ┣━━ ▶ [] additives_tags -     │   ┣━━ additives_tags_n=None -     │   ┣━━ allergens='en:milk' -     │   ┣━━ ▶ [] allergens_debug_tags -     │   ┣━━ allergens_from_ingredients='en:milk, milk' -     │   ┣━━ allergens_from_user='(en) en:milk' -     │   ┣━━ ▶ [] allergens_hierarchy -     │   ┣━━ ▶ [] allergens_tags - -  a Add node  c Clear  t Toggle root  - - - - - ''' -# --- -# name: test_example_markdown - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownApp - - - - - - - - - - - ▼ Ⅰ Textual Markdown Browser - └── Ⅱ Do You Want to Know More?Textual Markdown Browser - -   Welcome fellow adventurer! If you ran  - markdown.py from the terminal you are  -   viewing demo.md with Textual's built in      -   Markdown widget. - -   The widget supports much of the Markdown     -   spec. There is also an optional Table of     -   Contents sidebar which you will see to  -   your left. - - - Do You Want to Know More? - -   See example.md for more examples of what     -   this can do. - - - - -  t TOC  b Back  f Forward  - - - - - ''' -# --- -# name: test_example_merlin - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MerlinApp - - - - - - - - - - - - ┏━┓   ┏━┓┏━┓   ┏━┓┏━┓ - ┃ ┃ : ┃ ┃┃ ┃ : ┃ ┃┃ ┃ - ┗━┛   ┗━┛┗━┛   ┗━┛┗━┛ - - - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - -     7         8         9      - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -     4         5         6      - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -     1         2         3      - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▇▇ - - - - - ''' -# --- -# name: test_example_pride - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PrideApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_focus_component_class - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StyleBugApp - - - - - - - - - - StyleBugApp - test widget 0 - test widget 1 - test widget 2 - test widget 3 - test widget 4 - test widget 5 - test widget 6 - test widget 7 - test widget 8 - test widget 9 - test widget 10 - test widget 11 - test widget 12▇▇ - test widget 13 - test widget 14 - test widget 15 - test widget 16 - test widget 17 - test widget 18 - test widget 19 - test widget 20 - test widget 21 - - - - - - ''' -# --- -# name: test_footer_classic_styling - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ClassicFooterStylingApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  CTRL+T  Toggle Dark mode  CTRL+Q  Quit                                          - - - - - ''' -# --- -# name: test_footer_compact - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleCompactFooterApp - - - - - - - - - - - - - - - - - - - - -                                  Compact Footer                                  - - - - - - - - - - - - ^t Toggle Compact Footer^q Quit - - - - - ''' -# --- -# name: test_footer_compact_with_hover - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleCompactFooterApp - - - - - - - - - - - - - - - - - - - - -                                  Compact Footer                                  - - - - - - - - - - - - ^t Toggle Compact Footer^q Quit - - - - - ''' -# --- -# name: test_footer_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FooterApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  q Quit the app  ? Show help screen  delete Delete the thing  - - - - - ''' -# --- -# name: test_footer_standard_after_reactive_change - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleCompactFooterApp - - - - - - - - - - - - - - - - - - - - -                                 Standard Footer                                  - - - - - - - - - - - -  ^t Toggle Compact Footer  ^q Quit  - - - - - ''' -# --- -# name: test_footer_standard_with_hover - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToggleCompactFooterApp - - - - - - - - - - - - - - - - - - - - -                                 Standard Footer                                  - - - - - - - - - - - -  ^t Toggle Compact Footer  ^q Quit  - - - - - ''' -# --- -# name: test_fr_margins - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TestApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - - - Hello - - - - - - - World - - - - - - - !! - - - - - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - ''' -# --- -# name: test_fr_unit_with_min - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScreenSplitApp - - - - - - - - - - ScreenSplitApp - This is content This is content number 0 - number 0This is content number 1 - This is content ▄▄This is content number 2 - number 1This is content number 3 - This is content This is content number 4▁▁ - number 2This is content number 5 - This is content This is content number 6 - number 3This is content number 7 - This is content This is content number 8 - number 4This is content number 9 - This is content This is content number 10 - number 5This is content number 11 - This is content This is content number 12 - number 6This is content number 13 - This is content This is content number 14 - number 7This is content number 15 - This is content This is content number 16 - number 8This is content number 17 - This is content This is content number 18 - number 9This is content number 19 - This is content This is content number 20 - number 10This is content number 21 - - - - - - ''' -# --- -# name: test_fr_units - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FRApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - HEADER - - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ┏━━━━━━━━┓┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━┓ - foo┃┃bar┃┃baz - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┃┃┃┃ - ┗━━━━━━━━┛┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━┛ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - FOOTER - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - ''' -# --- -# name: test_grid_auto - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KeylineApp - - - - - - - - - - ┌──┬──┬──┐ - abc - ├──┼──┼──┤ - def - ├──┼──┼──┤ - ghi - └──┴──┴──┘ - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_grid_gutter - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Demonstrator - - - - - - - - - - - - ┌──────────────────────────────────────────────────────────┐ - - Information - ━╸━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ - aaa naa aaaaa aaa aaaan, aaa aaa, aaaa?", aa aaa - aaaaanaaa anaaaaaaana aaaaaaaa aaaaaana aaa      - aaaaa aa aaa, aa aaaaaaaaa aaa aaaa, "aaaa, an   - aaaa aaa aaaa, a aa". "aaaa, naa aaaaaaaaaaa,    - aaa a aaaa aaaaaanaa aaaa aa a aaa!", aaa        - anaaaa, aaaaa aaaaaaaa aanaaaaa. "Na! aaa naa.   - aaaaa. aa aaaaa naa. aaaaa aa na aaa.", aaa      - aaaaaaaa aaaanaaaaa DONE.                        - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ - - - - - └──────────────────────────────────────────────────────────┘ - - - - - - - ''' -# --- -# name: test_grid_layout_basic - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridLayoutExample - - - - - - - - - - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - One││Two││Three - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - Four││Five││Six - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - - - - - ''' -# --- -# name: test_grid_layout_basic_overflow - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridLayoutExample - - - - - - - - - - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - One││Two││Three - ││││ - ││││ - ││││ - ││││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - Four││Five││Six - ││││ - ││││ - ││││ - ││││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - ┌────────────────────────┐ - Seven - - - - - - └────────────────────────┘ - - - - - ''' -# --- -# name: test_grid_layout_gutter - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - GridLayoutExample - - - - - - - - - - OneTwoThree - - - - - - - - - - - - FourFiveSix - - - - - - - - - - - - - - - - ''' -# --- -# name: test_hatch - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HatchApp - - - - - - - - - - ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──┌─ Hello World ────────────────────────────────────┐──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼Hatched┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳──└──────────────────────────────────────────────────┘──╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ - ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ - ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ - - - - - ''' -# --- -# name: test_header_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HeaderApp - - - - - - - - - - HeaderApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_horizontal_layout - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HorizontalLayoutExample - - - - - - - - - - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - One││Two││Three - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - - - - - ''' -# --- -# name: test_horizontal_layout_width_auto_dock - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HorizontalAutoWidth - - - - - - - - - - Docke - Widget 1Widget 2 - left  - 1Docked left 2 - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_input_and_focus - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Darren                                                                     - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Burns - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_input_percentage_width - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputVsTextArea - - - - - - - - - - 01234567890123456789012345678901234567890123456789012345678901234567890123456789 - ┌──────────────────────────────────────┐ - - - - └──────────────────────────────────────┘ - ┌──────────────────────────────────────┐ - - - - - └──────────────────────────────────────┘ - ┌──────────────────────────────────────┐ - - - - - └──────────────────────────────────────┘ - ┌──────────────────────────────────────┐ - -  Button  - - - └──────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_input_suggestions - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FruitsApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - strawberry - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - straw                                                                      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - p                                                                          - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - b                                                                          - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - a                                                                          - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - ''' -# --- -# name: test_input_validation - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputApp - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - -2                                                                     - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 3                                                                      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - -2 - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Enter a number between 1 and 5 - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - ''' -# --- -# name: test_key_display - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KeyDisplayApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  ? Question  ^q Quit app  Escape! Escape  a Letter A  - - - - - ''' -# --- -# name: test_keyline - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - KeylineApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - 1 - ├──────────────────────────────────────────────────────────────────────────────┤ - 2 - ├──────────────────────────────────────────────────────────────────────────────┤ - 3 - - └──────────────────────────────────────────────────────────────────────────────┘ - ┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - 456 - - - - - - ┗━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - ╔══════════════════════════════════════╦═══════════════════════════════════════╗ - 78 - - ╠══════════════════════════════════════╬═══════════════════════════════════════╝ - 9 - - - ╚══════════════════════════════════════╝ - - - - - ''' -# --- -# name: test_label_widths - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LabelWrap - - - - - - - - - - - - - - - - Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix Ch - - - Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix  - Chimera Castle - - - ╭────────────────────────────────────────────────────────────────────────────╮ - │ Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur       │ - │ Phoenix Chimera Castle                                                     │ - ╰────────────────────────────────────────────────────────────────────────────╯ - - - - - - - - - - - - ''' -# --- -# name: test_layer_fix - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DialogIssueApp - - - - - - - - - - DialogIssueApp - - - - - - ╭──────────────────────────────────────╮ - - - - - This should not cause a scrollbar to a - - - - - - ╰──────────────────────────────────────╯ - - - - - -  d Toggle the dialog  - - - - - ''' -# --- -# name: test_layers - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LayersExample - - - - - - - - - - - - - - - - - - - - - box1 (layer = above) - - - - - - box2 (layer = below) - - - - - - - - - - - ''' -# --- -# name: test_layout_containers - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Accept  Decline  Accept  Decline  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Accept  Accept  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Decline  Decline  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▆ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - 0                                 0 - - 1000000                                 1000000                                - - - - - ''' -# --- -# name: test_line_api_scrollbars - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollViewApp - - - - - - - - - - - -                                  11 01234567 -                                  12 01234567 -                                  13 01234567 -                                  14 01234567 -                                  15 01234567▁▁ -                                  16 01234567 -                                  17 01234567 -                                  18 01234567 -                                  19 01234567 - -                                  11 01234567 -                                  12 01234567 -                                  13 01234567 -                                  14 01234567 -                                  15 01234567▁▁ -                                  16 01234567 -                                  17 01234567 -                                  18 01234567 -                                  19 01234567 - - - - - - - - ''' -# --- -# name: test_list_view - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ListViewExample - - - - - - - - - - - - - - - - - - One - - - Two - - - Three - - - - - - - - - - - - - - ''' -# --- -# name: test_listview_index - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ListViewIndexApp - - - - - - - - - - 10                                                                             - 12                                                                             - 14                                                                             - 16                                                                            ▆▆ - 18                                                                             - 20                                                                             - 22                                                                             - 24                                                                             - 26                                                                             - 28                                                                             - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_loading_indicator - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LoadingOverlayRedux - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo   ▄▄ - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - Loading!foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - foo barfoo barfoo barfoo barfoo    - bar                                - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_loading_indicator_disables_widget - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LoadingOverlayRedux - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     ▄▄foo barfoo barfoo barfoo barfoo   ▄▄ - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - hello world hello world hello     foo barfoo barfoo barfoo barfoo    - world hello world hello world     bar                                - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_log_write - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LogApp - - - - - - - - - - Hello, World!                                                                  - What's up?                                                                     - FOO                                                                            - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_log_write_lines - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LogApp - - - - - - - - - - I must not fear.  And when it has goHello, World      Fear is the mind-k - Fear is the mind-kWhere the fear hasFear is the little - Fear is the littleI must not fear.  I will face my fea - I will face my fea▁▁Fear is the mind-kI will permit it t - I will permit it tFear is the littleAnd when it has go - And when it has goI will face my feaWhere the fear has - Where the fear hasI will permit it t - I must not fear.  And when it has go - Fear is the mind-kWhere the fear has - Fear is the littleI must not fear.   - I will face my feaFear is the mind-k - I will permit it tFear is the little - And when it has goI will face my fea - Where the fear hasI will permit it t - I must not fear.  And when it has go - Fear is the mind-kWhere the fear has - Fear is the littleI must not fear.   - I will face my feaFear is the mind-k - I will permit it tFear is the little - And when it has goI will face my fea▇▇ - Where the fear hasI will permit it t - I must not fear.  And when it has go - Fear is the mind-kWhere the fear has - - - - - - ''' -# --- -# name: test_margin_multiple - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ╔═══╗ - foo - ╚═══╝ - - - ┌────────────────────────────┐ - - - ┌────────────────────────────┐ - - ╔═══╗ - bar - ╔═══╗╚═══╝ - bar - ╚═══╝ - - - - └────────────────────────────┘└────────────────────────────┘ - - - - - - - - - - ''' -# --- -# name: test_markdown_component_classes_reloading - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - - - This is a header - - - col1                                 col2                                 -  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  -  value 1                               value 2                               - -   Here's some code: from itertools import productBold textEmphasized text - strikethrough - - - print("Hello, world!") - - - That was some code. - - - - - - - - - - - - ''' -# --- -# name: test_markdown_dark_theme_override - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownThemeSwitchertApp - - - - - - - - - - - - This is a H1 - - - defmain(): - │   print("Hello world!") - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_markdown_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownExampleApp - - - - - - - - - - - - Markdown Document - -   This is an example of Textual's Markdown widget. - - - Features - -   Markdown syntax and extensions are supported. - - ● Typography emphasisstronginline code etc. - ● Headers - ● Lists (bullet and ordered) - ● Syntax highlighted code blocks - ● Tables! - - - - - - - - - - - - - ''' -# --- -# name: test_markdown_light_theme_override - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownThemeSwitchertApp - - - - - - - - - - - - This is a H1 - - - defmain(): - │   print("Hello world!") - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_markdown_space_squashing - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownSpaceApp - - - - - - - - - - X XX XX X X X X X - - X XX XX X X X X X - - X XX X X X X X - - X XX X X X X X - - ┌─────────────────────────────────────────────────────────────────────────────── - - - # Two spaces:  see? - classFoo: - │   '''This is    a doc    string.''' - │   some_code(1,2,3,4) - - - - - - - - - - - - - - ''' -# --- -# name: test_markdown_theme_switching - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownThemeSwitchertApp - - - - - - - - - - - - This is a H1 - - - defmain(): - │   print("Hello world!") - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_markdown_viewer_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MarkdownExampleApp - - - - - - - - - - - ▼ Ⅰ Markdown Viewer - ├── Ⅱ FeaturesMarkdown Viewer - ├── Ⅱ Tables - └── Ⅱ Code Blocks  This is an example of Textual's MarkdownViewer -   widget. - - - Features - -   Markdown syntax and extensions are supported. - ▇▇ - ● Typography emphasisstronginline code etc. - ● Headers - ● Lists (bullet and ordered) - ● Syntax highlighted code blocks - ● Tables! - - - Tables - -   Tables are displayed in a DataTable widget. - - - - - - - ''' -# --- -# name: test_masked_input - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TemplateApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ABC01-DE___-_____-_____ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - YYYY-MM-DD - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_max_height_100 - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HappyDataTableFunApp - - - - - - - - - -  Column 0  Column 1  Column 2  Column 3  Column 4  Column 5  Column 6  Column  -  0         0         0         0         0         0         0         0       -  0         1         2         3         4         5         6         7       -  0         2         4         6         8         10        12        14      -  0         3         6         9         12        15        18        21      -  0         4         8         12        16        20        24        28     ▆▆ -  0         5         10        15        20        25        30        35      -  0         6         12        18        24        30        36        42      -  0         7         14        21        28        35        42        49      -  0         8         16        24        32        40        48        56      -  0         9         18        27        36        45        54        63      -  0         10        20        30        40        50        60        70      -  0         11        22        33        44        55        66        77      -  0         12        24        36        48        60        72        84      -  0         13        26        39        52        65        78        91      -  0         14        28        42        56        70        84        98      -  0         15        30        45        60        75        90        105     -  0         16        32        48        64        80        96        112     -  0         17        34        51        68        85        102       119     -  0         18        36        54        72        90        108       126     -  0         19        38        57        76        95        114       133     -  0         20        40        60        80        100       120       140     -  0         21        42        63        84        105       126       147     - - - - - - ''' -# --- -# name: test_missing_vertical_scroll - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MissingScrollbarApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 0                  0                  ▎▊0                        - 1                  1                  ▎▊1                        - 2                  ▄▄2                  ▄▄▎▊2                       ▄▄ - 3                  3                  ▎▊3                        - 4                  4                  ▎▊4                        - 5                  5                  ▎▊5                        - 6                  6                  ▎▊6                        - 7                  7                  ▎▊7                        - 8                  8                  ▎▊8                        - 9                  9                  ▎▊9                        - 10                 10                 ▎▊10                       - 11                 11                 ▎▊11                       - 12                 12                 ▎▊12                       - 13                 13                 ▎▊13                       - 14                 14                 ▎▊14                       - 15                 15                 ▎▊15                       - 16                 16                 ▎▊16                       - 17                 17                 ▎▊17                       - 18                 18                 ▎▊18                       - 19                 19                 ▎▊19                       - 20                 20                 ▎▊20                       - 21                 21                 ▎▊21                       - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_modal_dialog_bindings - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ModalApp - - - - - - - - - - ModalApp - Hello                                                                            - - - - - - - - - - - - - - - - - - - - - -  ⏎ Open Dialog  - - - - - ''' -# --- -# name: test_modal_dialog_bindings_input - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ModalApp - - - - - - - - - - DialogModalApp - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - hi!                                                                        - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  OK  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - -  ⏎ Open Dialog  - - - - - ''' -# --- -# name: test_mount_style_fix - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BrokenClassesApp - - - - - - - - - - - - - - - - ┌──────────────────────────────────────┐ - This should have a red background - - - - - - - - - - └──────────────────────────────────────┘ - - - - - - - - - - - ''' -# --- -# name: test_multi_keys - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  o Options  - - - - - ''' -# --- -# name: test_multiple_css - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MultipleCSSApp - - - - - - - - - - #one - #two - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_nested_auto_heights - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NestedAutoApp - - - - - - - - - - ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ - ┏━━━━━━━━━━━━━━━┓ - ┏━━━━━━━━━━━━━┓ - JUST ONE LINE - ┗━━━━━━━━━━━━━┛ - ┗━━━━━━━━━━━━━━━┛ - ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_nested_fr - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - AutoApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌────────────────────────────────────────────────────────────────────────────┐ - Hello - World! - foo - - - - - - - - - - - - - - - - - - └────────────────────────────────────────────────────────────────────────────┘ - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_nested_specificity - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NestedPseudoClassesApp - - - - - - - - - - ╭──────────────────────────────────────╮ - This isn't using nested CSSThis is using nested CSS - - - - - - - - - - - - - - - - - - - - - - ╰──────────────────────────────────────╯ - - - - - ''' -# --- -# name: test_notification_with_inline_link - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotifyWithInlineLinkApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Click here for the bell sound. - - - - - - - ''' -# --- -# name: test_notification_with_inline_link_hover - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotifyWithInlineLinkApp - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Click here for the bell sound. - - - - - - - ''' -# --- -# name: test_notifications_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ToastApp - - - - - - - - - - - - - - It's an older code, sir, but it  - checks out. - - - - Possible trap detected - Now witness the firepower of this  - fully ARMED and OPERATIONAL battle  - station! - - - - It's a trap! - - - - It's against my programming to  - impersonate a deity. - - - - - - - ''' -# --- -# name: test_notifications_loading_overlap_order - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LoadingOverlayApp - - - - - - - - - - - - - - - - - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - This is a big notification. - - - - - - - - ''' -# --- -# name: test_notifications_through_modes - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotifyThroughModesApp - - - - - - - - - - This is a mode screen                   - 4 - - - - 5 - - - - 6 - - - - 7 - - - - 8 - - - - 9 - - - - - - - ''' -# --- -# name: test_notifications_through_screens - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NotifyDownScreensApp - - - - - - - - - - Screen 10                               - 4 - - - - 5 - - - - 6 - - - - 7 - - - - 8 - - - - 9 - - - - - - - ''' -# --- -# name: test_offsets - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OffsetsApp - - - - - - - - - - - - - - - ┌──────────────┐ - FOO - BAR - BAZ - └──────────────┘ - - - - - - ┌──────────────┐ - FOO - BAR - BAZ - └──────────────┘ - - - - - - - - - ''' -# --- -# name: test_option_list_build - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - One                   One                    ▎▊One                     - Two                   Two                    ▎▊Two                     - ─────────────────────────────────────────────▎▊─────────────────────── - ThreeThree▎▊Three - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_option_list_options - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Aerilon                                            - Aquaria                                            - ────────────────────────────────────────────────── - Canceron                                           - Caprica                                            - ────────────────────────────────────────────────── - Gemenon                                            - ────────────────────────────────────────────────── - Leonis                                             - Libran                                             - ────────────────────────────────────────────────── - Picon                                             ▁▁ - ────────────────────────────────────────────────── - Sagittaron                                         - Scorpia                                            - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - ''' -# --- -# name: test_option_list_replace_prompt_from_single_line_to_single_line - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1. Another single line                                                       - 2. Two                                                                       - lines                                                                        - 3. Three                                                                     - lines                                                                        - of text                                                                      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_option_list_replace_prompt_from_single_line_to_two_lines - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1. Two                                                                       - lines                                                                        - 2. Two                                                                       - lines                                                                        - 3. Three                                                                     - lines                                                                        - of text                                                                      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_option_list_replace_prompt_from_two_lines_to_three_lines - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1. Single line                                                               - 1. Three                                                                     - lines                                                                        - of text                                                                      - 3. Three                                                                     - lines                                                                        - of text                                                                      - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_option_list_scrolling_in_long_list - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LongOptionListApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - This is option #78                                                         - This is option #79                                                         - This is option #80                                                         - This is option #81                                                         - This is option #82                                                         - This is option #83                                                         - This is option #84                                                         - This is option #85                                                         - This is option #86                                                         - This is option #87                                                         - This is option #88                                                         - This is option #89                                                         - This is option #90                                                         - This is option #91                                                         - This is option #92                                                         - This is option #93                                                         - This is option #94                                                         - This is option #95                                                        ▇▇ - This is option #96                                                         - This is option #97                                                         - This is option #98                                                         - This is option #99                                                         - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_option_list_scrolling_with_multiline_options - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ - │ Dionysus      │ 450 Million   │ Celeste        │ - └───────────────┴───────────────┴────────────────┘ -                  Data for Tauron                   - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ -  Patron God     Population     Capital City    - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ - │ Ares          │ 2.5 Billion   │ Hypatia        │ - └───────────────┴───────────────┴────────────────┘ -                  Data for Virgon                   - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ - ┃ Patron God    ┃ Population    ┃ Capital City   ┃▁▁ - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ - │ Hestia        │ 4.3 Billion   │ Boskirk        │ - └───────────────┴───────────────┴────────────────┘ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - ''' -# --- -# name: test_option_list_strings - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Aerilon                                              - Aquaria                                              - Canceron                                             - Caprica                                              - Gemenon                                              - Leonis                                               - Libran                                               - Picon                                                - Sagittaron                                           - Scorpia                                              - Tauron                                               - Virgon                                               - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - ''' -# --- -# name: test_option_list_tables - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - OptionListApp - - - - - - - - - - OptionListApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -                  Data for Aerilon                  - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ - ┃ Patron God    ┃ Population    ┃ Capital City   ┃ - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩▇▇ - │ Demeter       │ 1.2 Billion   │ Gaoth          │ - └───────────────┴───────────────┴────────────────┘ -                  Data for Aquaria                  - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ -  Patron God     Population     Capital City    - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ - │ Hermes        │ 75,000        │ None           │ - └───────────────┴───────────────┴────────────────┘ -                 Data for Canceron                  - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ -  Patron God     Population     Capital City    - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - ''' -# --- -# name: test_order_independence - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Layers - - - - - - - - - - ┌──────────────────────────────────┐Layers - It's full of stars! My God! It's full of sta - - This should float over the top - - - └──────────────────────────────────┘ - - - - - - - - - - - - - - - - -  t Toggle Screen  - - - - - ''' -# --- -# name: test_order_independence_toggle - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Layers - - - - - - - - - - ┌──────────────────────────────────┐Layers - It's full of stars! My God! It's full of sta - - This should float over the top - - - └──────────────────────────────────┘ - - - - - - - - - - - - - - - - -  t Toggle Screen  - - - - - ''' -# --- -# name: test_pilot_resize_terminal - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SingleLabelApp - - - - - - - - - - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - 12345678901234567890 - - - - - ''' -# --- -# name: test_placeholder_disabled - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - DisabledPlaceholderApp - - - - - - - - - - - - - - - Placeholder - - - - - - - - - - - - Placeholder - - - - - - - - - - - ''' -# --- -# name: test_placeholder_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PlaceholderApp - - - - - - - - - - - Placeholder p2 here! - This is a custom label for p1. - #p4 - #p3#p5Placeholde - r - - Lorem ipsum dolor sit  - 26 x 6amet, consectetur 27 x 6 - adipiscing elit. Etiam  - feugiat ac elit sit amet  - - - Lorem ipsum dolor sit amet,  - consectetur adipiscing elit. Etiam 40 x 6 - feugiat ac elit sit amet accumsan.  - Suspendisse bibendum nec libero quis  - gravida. Phasellus id eleifend ligula. - Nullam imperdiet sem tellus, sed  - vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  - Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  - lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  - sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  - - - - - - ''' -# --- -# name: test_pretty_grid_gutter_interaction - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ['This is a string that has some chars'] - - This should be 1 cell away from ^ - - - - - - - - - ''' -# --- -# name: test_print_capture - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CaptureApp - - - - - - - - - - RichLog                                                                        - This will be captured!                                                         - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_programmatic_disable_button - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ExampleApp - - - - - - - - - - - - - - - - - - -                         Hover the button then hit space                          - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Disabled  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - -  SPACE Toggle Button  - - - - - ''' -# --- -# name: test_programmatic_scrollbar_gutter_change - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProgrammaticScrollbarGutterChange - - - - - - - - - - onetwo - - - - - - - - - - - - threefour - - - - - - - - - - - - - - - - ''' -# --- -# name: test_progress_bar_completed - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IndeterminateProgressBar - - - - - - - - - - - - - - - - - - - - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:--                  - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_bar_completed_styled - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StyledProgressBar - - - - - - - - - - - - - - - - - - - - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:-- - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_bar_halfway - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IndeterminateProgressBar - - - - - - - - - - - - - - - - - - - - - ━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07                  - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_bar_halfway_styled - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StyledProgressBar - - - - - - - - - - - - - - - - - - - - - ━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07 - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_bar_indeterminate - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IndeterminateProgressBar - - - - - - - - - - - - - - - - - - - - - ━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:--                  - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_bar_indeterminate_styled - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StyledProgressBar - - - - - - - - - - - - - - - - - - - - - ━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:-- - - - - - - - - - - - -  s Start  - - - - - ''' -# --- -# name: test_progress_gradient - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ProgressApp - - - - - - - - - - ╺━━━━━━━━━━━━━━━50%--:--:--                                   - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_quickly_change_tabs - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - QuicklyChangeTabsApp - - - - - - - - - - - onetwothree - ━━━━━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - three                                                                        - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_radio_button_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RadioChoicesApp - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Battlestar Galactica -  Dune 1984 -  Dune 2021 -  Serenity -  Star Trek: The Motion Picture -  Star Wars: A New Hope -  The Last Starfighter -  Total Recall 👉 🔴 -  Wing Commander - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - ''' -# --- -# name: test_radio_set_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RadioChoicesApp - - - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Battlestar Galactica Amanda -  Dune 1984 Connor MacLeod -  Dune 2021 Duncan MacLeod -  Serenity Heather MacLeod -  Star Trek: The Motion Pictur Joe Dawson -  Star Wars: A New Hope Kurgan, The -  The Last Starfighter Methos -  Total Recall 👉 🔴 Rachel Ellenstein -  Wing Commander Ramírez - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - ''' -# --- -# name: test_recompose - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RecomposeApp - - - - - - - - - - ┌─────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐ -  ┓ ┏━┓   ││ ┓  ┓    ││ ┓ ╺━┓    ││ ┓ ╺━┓   ││ ┓ ╻ ╻    ││ ┓ ┏━╸   ││ ┓ ┏━╸     -  ┃ ┃ ┃   ││ ┃  ┃    ││ ┃ ┏━┛    ││ ┃  ━┫   ││ ┃ ┗━┫    ││ ┃ ┗━┓   ││ ┃ ┣━┓     - ╺┻╸┗━┛   ││╺┻╸╺┻╸   ││╺┻╸┗━╸    ││╺┻╸╺━┛   ││╺┻╸  ╹    ││╺┻╸╺━┛   ││╺┻╸┗━┛     - └─────────┘└─────────┘└──────────┘└─────────┘└──────────┘└─────────┘└──────────┘ - - - - - - - - ━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━50%                                            - - - - - - - - - - - - - - - - ''' -# --- -# name: test_recompose_in_mount - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ForecastApp - - - - - - - - - - ForecastApp -  Profile  - ▔▔▔▔▔▔▔▔▔▔ - Foo -  Bar - ▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_remove_with_auto_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerticalRemoveApp - - - - - - - - - - VerticalRemoveApp - ╭──────────────────────────────────────────────────────────────────────────────╮ - ╭────────────────────╮ - │This is a test label│ - ╰────────────────────╯ - ╰──────────────────────────────────────────────────────────────────────────────╯ - - - - - - - - - - - - - - - - - -  a Add  d Delete  - - - - - ''' -# --- -# name: test_richlog_max_lines - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RichLogLines - - - - - - - - - - Key press #3                                                                   - Key press #4                                                                   - Key press #5                                                                   - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_richlog_scroll - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RichLogScrollApp - - - - - - - - - - Line 0                  Line 10                  Line 0                    - Line 1                  Line 11                  Line 1                    - Line 2                  Line 12                  Line 2                    - Line 3                  Line 13                  Line 3                    - Line 4                  Line 14                  Line 4                    - Line 5                  Line 15                  Line 5                    - Line 6                  Line 16                  Line 6                    - Line 7                  Line 17                  Line 7                    - Line 8                  Line 18                  Line 8                    - Line 9                  Line 19                  Line 9                    - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_richlog_width - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RichLogWidth - - - - - - - - - -               hello1 -               world2 -               hello3 -               world4 - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_rule_horizontal_rules - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - HorizontalRulesApp - - - - - - - - - -                                 solid (default)                                  - - ──────────────────────────────────────────────────────────────── - -                                      heavy                                       - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - -                                      thick                                       - - ████████████████████████████████████████████████████████████████ - -                                      dashed                                      - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - -                                      double                                      - - ════════════════════════════════════════════════════════════════ - -                                      ascii                                       - - ---------------------------------------------------------------- - - - - - - ''' -# --- -# name: test_rule_vertical_rules - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerticalRulesApp - - - - - - - - - - - -        solid     heavy     thick     dashed    double    ascii   | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - - - - - - - - ''' -# --- -# name: test_rules - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RuleApp - - - - - - - - - - - -------------------------------------------------------------------------------- - - - - ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ - - ════════════════════════════════════════════════════════════════════════════════ - - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - - | - | - | - | - | - | - | - | - | - | - | - | - - - - - ''' -# --- -# name: test_scoped_css - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌───┐ - foo - └───┘ - ┌───┐ - bar - └───┘ - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌───┐ - foo - └───┘ - ┌───┐ - bar - └───┘ - └──────────────────────────────────────────────────────────────────────────────┘ - I should not be styled                                                           - - - - - - - - - - - - ''' -# --- -# name: test_screen_switch - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ModalApp - - - - - - - - - - ModalApp - B - - - - - - - - - - - - - - - - - - - - - -  a Push screen A  - - - - - ''' -# --- -# name: test_scroll_to - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollOffByOne - - - - - - - - - - ▔▔▔▔▔▔▔▔ - X 43 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 44 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 45 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 46▄▄ - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▃▃ - X 47 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 48 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 49 - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ - X 50 - ▁▁▁▁▁▁▁▁ - - - - - - ''' -# --- -# name: test_scroll_to_center - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - SPAM                                                                           - ╭────────────────────────────────────────────────────────────────────────────╮ - SPAM                                                                       - SPAM                                                                       - SPAM                                                                       - SPAM                                                                       - SPAM                                                                       - SPAM                                                                       - SPAM                                                                       - SPAM                                                                      ▁▁ - ╭────────────────────────────────────────────────────────────────────────╮ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>>bullseye<<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - - ▄▄ - ▄▄ - - - - - - - ╰────────────────────────────────────────────────────────────────────────────╯ - SPAM                                                                           - SPAM                                                                           - - - - - ''' -# --- -# name: test_scroll_visible - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - | - |▆▆ - | - | - | - | - SHOULD BE VISIBLE - - - - - ''' -# --- -# name: test_scroll_visible_with_margin - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollVisibleMargin - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (19)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (20)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (21)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▅▅ -  Hello, world! (22)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (23)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (24)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (25)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Hello, world! (26)  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_scrollbar_thumb_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ScrollViewTester - - - - - - - - - - ScrollViewTester - ╭─ 1 ──────────────────────────────────────────────────────────────────────────╮ - Welcome to line 980                                                          - Welcome to line 981                                                          - Welcome to line 982                                                          - Welcome to line 983                                                          - Welcome to line 984                                                          - Welcome to line 985                                                          - Welcome to line 986                                                          - Welcome to line 987                                                          - Welcome to line 988                                                          - Welcome to line 989                                                          - Welcome to line 990                                                          - Welcome to line 991                                                          - Welcome to line 992                                                          - Welcome to line 993                                                          - Welcome to line 994                                                          - Welcome to line 995                                                          - Welcome to line 996                                                          - Welcome to line 997                                                          - Welcome to line 998                                                          - Welcome to line 999                                                          - ╰──────────────────────────────────────────────────────────────────────────────╯ - - - - - - ''' -# --- -# name: test_select - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - SelectApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_select_expanded - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - SelectApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select -  I must not fear.                                        -  Fear is the mind-killer.                                -  Fear is the little-death that brings total              -  obliteration.                                           -  I will face my fear.                                    -  I will permit it to pass over me and through me.        - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - ''' -# --- -# name: test_select_expanded_changed - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - I must not fear. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I must not fear. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_select_from_values_expanded - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - SelectApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select -  I must not fear.                                        -  Fear is the mind-killer.                                -  Fear is the little-death that brings total              -  obliteration.                                           -  I will face my fear.                                    -  I will permit it to pass over me and through me.        - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - ''' -# --- -# name: test_select_no_blank_has_default_value - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - I must not fear. - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I must not fear. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_select_rebuild - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectRebuildApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select -  This                                                                        -  Should                                                                      -  Be                                                                          -  What                                                                        -  Goes                                                                        -  Into                                                                        -  The                                                                         -  Snapshit                                                                    - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - ''' -# --- -# name: test_select_set_options - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectApp - - - - - - - - - - Twinkle, twinkle, little star, - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Twinkle, twinkle, little star, - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_selection_list_selected - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectionListApp - - - - - - - - - - SelectionListApp - - - ┌─ Shall we play some games? ──┐┌─ Selected games ─────────────┐ - [ - X Falken's Maze           'secret_back_door', - X Black Jack              'a_nice_game_of_chess', - X Gin Rummy               'fighter_combat' - X Hearts                  ] - X Bridge                  └──────────────────────────────┘ - X Checkers                 - X Chess                    - X Poker                    - X Fighter Combat           - - └──────────────────────────────┘ - - - - - - - - - - - - - ''' -# --- -# name: test_selection_list_selections - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectionListApp - - - - - - - - - - SelectionListApp - - - ┌─ Shall we play some games? ──────────────────────────────────┐ - - X Falken's Maze                                            - X Black Jack                                               - X Gin Rummy                                                - X Hearts                                                   - X Bridge                                                   - X Checkers                                                 - X Chess                                                    - X Poker                                                    - X Fighter Combat                                           - - - - - - └──────────────────────────────────────────────────────────────┘ - - - - - - - - - ''' -# --- -# name: test_selection_list_tuples - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SelectionListApp - - - - - - - - - - SelectionListApp - - - ┌─ Shall we play some games? ──────────────────────────────────┐ - - X Falken's Maze                                            - X Black Jack                                               - X Gin Rummy                                                - X Hearts                                                   - X Bridge                                                   - X Checkers                                                 - X Chess                                                    - X Poker                                                    - X Fighter Combat                                           - - - - - - └──────────────────────────────────────────────────────────────┘ - - - - - - - - - ''' -# --- -# name: test_sort_children - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SortApp - - - - - - - - - - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - 5││1││5 - │└─────────────────────────┘│ - │┌─────────────────────────┐│ - ││2││ - ││││ - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ - 1││3││4 - └────────────────────────┘│││ - ┌────────────────────────┐│││ - 3│└─────────────────────────┘│ - │┌─────────────────────────┐└─────────────────────────┘ - ││4│┌─────────────────────────┐ - └────────────────────────┘│││3 - ┌────────────────────────┐│││ - 2││││ - │└─────────────────────────┘└─────────────────────────┘ - └────────────────────────┘┌─────────────────────────┐┌─────────────────────────┐ - ┌────────────────────────┐│5││2 - 4││││ - │││└─────────────────────────┘ - │││┌─────────────────────────┐ - ││││1 - └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ - - - - - ''' -# --- -# name: test_sparkline_component_classes_colors - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SparklineColorsApp - - - - - - - - - - - ▇▇▇▇▇ - - ▇▇▇▇▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇▇█▇ - - ▇▇▇▇▇▇ - - ▇▇▇▇▇▇▇█▇ - - - - - - - - - ''' -# --- -# name: test_sparkline_render - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SparklineSummaryFunctionApp - - - - - - - - - - - - - - - ▂▂▁▁ - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_switches - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - SwitchApp - - - - - - - - - - - - - - Example switches - - - ▔▔▔▔▔▔▔▔ -                               off:      - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ -                               on:       - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ -                               focused:  - ▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔ -                               custom:   - ▁▁▁▁▁▁▁▁ - - - - - - - - - - ''' -# --- -# name: test_tab_rename - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TabRenameApp - - - - - - - - - - - This is a much longer label for the tab011222333344444 - ━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - TabPane#test - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tabbed_content - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TabbedApp - - - - - - - - - - - LetoJessicaPaul - ━━━━━━━━╸━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - - - Lady Jessica - -   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. - - - - PaulAlia - ━╸━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - First child                                                              - - - - - - - -  l Leto  j Jessica  p Paul  - - - - - ''' -# --- -# name: test_tabbed_content_styling_not_leaking - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TabbedContentStyleLeakTestApp - - - - - - - - - - - Leak Test - ━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - This label should come first                                                 - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  This button should come second  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - TheseTabsShouldComeLast - ━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tabbed_content_with_modified_tabs - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - FiddleWithTabsApp - - - - - - - - - - - Tab 1Tab 2Tab 4Tab 5 - ━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Button  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_table_markup - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TableStaticApp - - - - - - - - - - ┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┓ - Foo Bar     baz        - ┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━┩ - │ Hello World! │ Italic │ Underline │ - └──────────────┴────────┴───────────┘ - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tabs_invalidate - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TabApp - - - - - - - - - - - Tab 1Tab 2 - ━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ┌──────────────────────────────────────────────────────────────────────────────┐ - - world                                                                      - - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_text_area_alternate_screen - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TABug - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ - foo                                          - bar                                          - baz                                          - - - - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ - - - - - ''' -# --- -# name: test_text_area_language_rendering[bash] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -   1  #!/bin/bash -   2   -   3  # Variables -   4  name="John" -   5  age=30                                                                  -   6  is_student=true                                                         -   7   -   8  # Printing variables -   9  echo"Hello, $name! You are $age years old." -  10   -  11  # Conditional statements -  12  if [[ $age -ge 18 &&$is_student == true ]]; then -  13  echo"You are an adult student." -  14  elif [[ $age -ge 18 ]]; then -  15  echo"You are an adult." -  16  else -  17  echo"You are a minor." -  18  fi -  19   -  20  # Arrays -  21  numbers=(1 2 3 4 5)                                                     -  22  echo"Numbers: ${numbers[@]}" -  23   -  24  # Loops -  25  for num in"${numbers[@]}"do -  26  echo"Number: $num" -  27  done -  28   -  29  # Functions -  30  greet() {                                                               -  31    local name=$1                                                         -  32  echo"Hello, $name!" -  33  }                                                                       -  34  greet"Alice" -  35   -  36  # Command substitution -  37  current_date=$(date +%Y-%m-%d)                                          -  38  echo"Current date: $current_date" -  39   -  40  # File operations -  41  touch file.txt                                                          -  42  echo"Some content"> file.txt                                          -  43  cat file.txt                                                            -  44   -  45  # Conditionals with file checks -  46  if [[ -f file.txt ]]; then -  47  echo"file.txt exists." -  48  else -  49  echo"file.txt does not exist." -  50  fi -  51   -  52  # Case statement -  53  case$age in -  54    18)                                                                   -  55  echo"You are 18 years old." -  56      ;;                                                                  -  57    30)                                                                   -  58  echo"You are 30 years old." -  59      ;;                                                                  -  60    *)                                                                    -  61  echo"You are neither 18 nor 30 years old." -  62      ;;                                                                  -  63  esac -  64   -  65  # While loop -  66  counter=0                                                               -  67  while [[ $counter -lt 5 ]]; do -  68  echo"Counter: $counter" -  69    ((counter++))                                                         -  70  done -  71   -  72  # Until loop -  73  until [[ $counter -eq 0 ]]; do -  74  echo"Counter: $counter" -  75    ((counter--))                                                         -  76  done -  77   -  78  # Heredoc -  79  cat << EOF -  80  This is a heredoc.  -  81  It allows you to write multiple lines of text.  -  82  EOF  -  83   -  84  # Redirection -  85  ls> file_list.txt                                                      -  86  grep"file" file_list.txt > filtered_list.txt                           -  87   -  88  # Pipes -  89  cat file_list.txt |wc -l                                               -  90   -  91  # Arithmetic operations -  92  result=$((10 + 5))                                                      -  93  echo"Result: $result" -  94   -  95  # Exporting variables -  96  export DB_PASSWORD="secret" -  97   -  98  # Sourcing external files -  99  source config.sh                                                        - 100   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[css] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  /* This is a comment in CSS */ -  2   -  3  /* Basic selectors and properties */ -  4  body {                                                                   -  5      font-family: Arial, sans-serif;                                      -  6      background-color: #f4f4f4;                                           -  7      margin: 0;                                                           -  8      padding: 0;                                                          -  9  }                                                                        - 10   - 11  /* Class and ID selectors */ - 12  .header {                                                                - 13      background-color: #333;                                              - 14      color: #fff;                                                         - 15      padding: 10px0;                                                     - 16      text-align: center;                                                  - 17  }                                                                        - 18   - 19  #logo {                                                                  - 20      font-size: 24px;                                                     - 21      font-weight: bold;                                                   - 22  }                                                                        - 23   - 24  /* Descendant and child selectors */ - 25  .nav ul {                                                                - 26      list-style-type: none;                                               - 27      padding: 0;                                                          - 28  }                                                                        - 29   - 30  .nav > li {                                                              - 31      display: inline-block;                                               - 32      margin-right: 10px;                                                  - 33  }                                                                        - 34   - 35  /* Pseudo-classes */ - 36  a:hover {                                                                - 37      text-decoration: underline;                                          - 38  }                                                                        - 39   - 40  input:focus {                                                            - 41      border-color: #007BFF;                                               - 42  }                                                                        - 43   - 44  /* Media query */ - 45  @media (max-width: 768px) {                                              - 46      body {                                                               - 47          font-size: 16px;                                                 - 48      }                                                                    - 49   - 50      .header {                                                            - 51          padding: 5px0;                                                  - 52      }                                                                    - 53  }                                                                        - 54   - 55  /* Keyframes animation */ - 56  @keyframes slideIn {                                                     - 57  from {                                                               - 58          transform: translateX(-100%);                                    - 59      }                                                                    - 60  to {                                                                 - 61          transform: translateX(0);                                        - 62      }                                                                    - 63  }                                                                        - 64   - 65  .slide-in-element {                                                      - 66      animation: slideIn 0.5s forwards;                                    - 67  }                                                                        - 68   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[go] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  package main                                                             -  2   -  3  import (                                                                 -  4  "fmt" -  5  "math" -  6  "strings" -  7  )                                                                        -  8   -  9  const PI =3.14159 - 10   - 11  type Shape interface {                                                   - 12      Area() float64                                                       - 13  }                                                                        - 14   - 15  type Circle struct {                                                     - 16      Radius float64                                                       - 17  }                                                                        - 18   - 19  func (c Circle) Area() float64 {                                         - 20  return PI * c.Radius * c.Radius                                      - 21  }                                                                        - 22   - 23  funcmain() {                                                            - 24  var name string ="John" - 25      age :=30 - 26      isStudent :=true - 27   - 28      fmt.Printf("Hello, %s! You are %d years old.", name, age)            - 29   - 30  if age >=18&& isStudent {                                          - 31          fmt.Println("You are an adult student.")                         - 32      } elseif age >=18 {                                                - 33          fmt.Println("You are an adult.")                                 - 34      } else {                                                             - 35          fmt.Println("You are a minor.")                                  - 36      }                                                                    - 37   - 38      numbers := []int{12345}                                      - 39      sum :=0 - 40  for _, num :=range numbers {                                        - 41          sum += num                                                       - 42      }                                                                    - 43      fmt.Printf("The sum is: %d", sum)                                    - 44   - 45      message :="Hello, World!" - 46      uppercaseMessage := strings.ToUpper(message)                         - 47      fmt.Println(uppercaseMessage)                                        - 48   - 49      circle := Circle{Radius: 5}                                          - 50      fmt.Printf("Circle area: %.2f", circle.Area())                       - 51   - 52      result :=factorial(5)                                               - 53      fmt.Printf("Factorial of 5: %d", result)                             - 54   - 55  defer fmt.Println("Program finished.")                               - 56   - 57      sqrt :=func(x float64) float64 {                                    - 58  return math.Sqrt(x)                                              - 59      }                                                                    - 60      fmt.Printf("Square root of 16: %.2f"sqrt(16))                      - 61  }                                                                        - 62   - 63  funcfactorial(n int) int {                                              - 64  if n ==0 {                                                          - 65  return1 - 66      }                                                                    - 67  return n *factorial(n-1)                                            - 68  }                                                                        - 69   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[html] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  <!DOCTYPE html>                                                          -  2  <html lang="en">                                                         -  3   -  4  <head>                                                                   -  5  <!-- Meta tags --> -  6      <meta charset="UTF-8">                                               -  7      <meta name="viewport" content="width=device-width, initial-scale=1.0 -  8  <!-- Title --> -  9      <title>HTML Test Page</title>                                        - 10  <!-- Link to CSS --> - 11      <link rel="stylesheet" href="styles.css">                            - 12  </head>                                                                  - 13   - 14  <body>                                                                   - 15  <!-- Header section --> - 16      <header class="header">                                              - 17          <h1 id="logo">HTML Test Page</h1>                                - 18      </header>                                                            - 19   - 20  <!-- Navigation --> - 21      <nav class="nav">                                                    - 22          <ul>                                                             - 23              <li><a href="#">Home</a></li>                                - 24              <li><a href="#">About</a></li>                               - 25              <li><a href="#">Contact</a></li>                             - 26          </ul>                                                            - 27      </nav>                                                               - 28   - 29  <!-- Main content area --> - 30      <main>                                                               - 31          <article>                                                        - 32              <h2>Welcome to the Test Page</h2>                            - 33              <p>This is a paragraph to test the HTML structure.</p>       - 34              <img src="test-image.jpg" alt="Test Image" width="300">      - 35          </article>                                                       - 36      </main>                                                              - 37   - 38  <!-- Form --> - 39      <section>                                                            - 40          <form action="/submit" method="post">                            - 41              <label for="name">Name:</label>                              - 42              <input type="text" id="name" name="name">                    - 43              <input type="submit" value="Submit">                         - 44          </form>                                                          - 45      </section>                                                           - 46   - 47  <!-- Footer --> - 48      <footer>                                                             - 49          <p>&copy; 2023 HTML Test Page</p>                                - 50      </footer>                                                            - 51   - 52  <!-- Script tag --> - 53      <script src="scripts.js"></script>                                   - 54  </body>                                                                  - 55   - 56  </html>                                                                  - 57   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[java] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -   1  import java.util.ArrayList;                                             -   2  import java.util.HashMap;                                               -   3  import java.util.List;                                                  -   4  import java.util.Map;                                                   -   5   -   6  // Classes and interfaces -   7  interface Shape {                                                       -   8      double getArea();                                                   -   9  }                                                                       -  10   -  11  class Rectangle implements Shape {                                      -  12  private double width;                                               -  13  private double height;                                              -  14   -  15  public Rectangle(double width, double height) {                     -  16          this.width = width;                                             -  17          this.height = height;                                           -  18      }                                                                   -  19   -  20  @Override                                                           -  21  public double getArea() {                                           -  22  return width * height;                                          -  23      }                                                                   -  24  }                                                                       -  25   -  26  // Enums -  27  enum DaysOfWeek {                                                       -  28      MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY      -  29  }                                                                       -  30   -  31  publicclass Main {                                                     -  32  // Constants -  33  privatestaticfinal double PI = 3.14159;                           -  34   -  35  // Methods -  36  publicstatic int sum(int a, int b) {                               -  37  return a + b;                                                   -  38      }                                                                   -  39   -  40  publicstatic void main(String[] args) {                            -  41  // Variables -  42          String name = "John";                                           -  43          int age = 30;                                                   -  44          boolean isStudent = true;                                       -  45   -  46  // Printing variables -  47          System.out.println("Hello, " + name + "! You are " + age + " ye -  48   -  49  // Conditional statements -  50  if (age >= 18 && isStudent) {                                   -  51              System.out.println("You are an adult student.");            -  52          } elseif (age >= 18) {                                         -  53              System.out.println("You are an adult.");                    -  54          } else {                                                        -  55              System.out.println("You are a minor.");                     -  56          }                                                               -  57   -  58  // Arrays -  59          int[] numbers = {12345};                                -  60          System.out.println("Numbers: " + Arrays.toString(numbers));     -  61   -  62  // Lists -  63          List<String> fruits = new ArrayList<>();                        -  64          fruits.add("apple");                                            -  65          fruits.add("banana");                                           -  66          fruits.add("orange");                                           -  67          System.out.println("Fruits: " + fruits);                        -  68   -  69  // Loops -  70  for (int num : numbers) {                                       -  71              System.out.println("Number: " + num);                       -  72          }                                                               -  73   -  74  // Hash maps -  75          Map<String, Integer> scores = new HashMap<>();                  -  76          scores.put("Alice"100);                                       -  77          scores.put("Bob"80);                                          -  78          System.out.println("Alice's score: " + scores.get("Alice"));    -  79   -  80  // Exception handling -  81  try {                                                           -  82              int result = 10 / 0;                                        -  83          } catch (ArithmeticException e) {                               -  84              System.out.println("Error: " + e.getMessage());             -  85          }                                                               -  86   -  87  // Instantiating objects -  88          Rectangle rect = new Rectangle(1020);                         -  89          System.out.println("Rectangle area: " + rect.getArea());        -  90   -  91  // Enums -  92          DaysOfWeek today = DaysOfWeek.MONDAY;                           -  93          System.out.println("Today is " + today);                        -  94   -  95  // Calling methods -  96          int sum = sum(510);                                           -  97          System.out.println("Sum: " + sum);                              -  98   -  99  // Ternary operator - 100          String message = age >= 18 ? "You are an adult." : "You are a m - 101          System.out.println(message);                                    - 102      }                                                                   - 103  }                                                                       - 104   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[javascript] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  // Variable declarations -  2  const name ="John";                                                     -  3  let age =30;                                                            -  4  var isStudent =true;                                                    -  5   -  6  // Template literals -  7  console.log(`Hello, ${name}! You are ${age} years old.`);                -  8   -  9  // Conditional statements - 10  if (age >=18&& isStudent) {                                            - 11    console.log("You are an adult student.");                              - 12  elseif (age >=18) {                                                  - 13    console.log("You are an adult.");                                      - 14  else {                                                                 - 15    console.log("You are a minor.");                                       - 16  }                                                                        - 17   - 18  // Arrays and array methods - 19  const numbers = [12345];                                         - 20  const doubledNumbers = numbers.map((num) => num *2);                    - 21  console.log("Doubled numbers:", doubledNumbers);                         - 22   - 23  // Objects - 24  const person = {                                                         - 25    firstName: "John",                                                     - 26    lastName: "Doe",                                                       - 27    getFullName() {                                                        - 28  return`${this.firstName} ${this.lastName}`;                         - 29    },                                                                     - 30  };                                                                       - 31  console.log("Full name:", person.getFullName());                         - 32   - 33  // Classes - 34  class Rectangle {                                                        - 35    constructor(width, height) {                                           - 36      this.width = width;                                                  - 37      this.height = height;                                                - 38    }                                                                      - 39   - 40    getArea() {                                                            - 41  return this.width * this.height;                                     - 42    }                                                                      - 43  }                                                                        - 44  const rectangle =new Rectangle(53);                                   - 45  console.log("Rectangle area:", rectangle.getArea());                     - 46   - 47  // Async/Await and Promises - 48  asyncfunctionfetchData() {                                             - 49  try {                                                                  - 50  const response =awaitfetch("https://api.example.com/data");        - 51  const data =await response.json();                                  - 52      console.log("Fetched data:", data);                                  - 53    } catch (error) {                                                      - 54      console.error("Error:", error);                                      - 55    }                                                                      - 56  }                                                                        - 57  fetchData();                                                             - 58   - 59  // Arrow functions - 60  constgreet= (name) => {                                                - 61    console.log(`Hello, ${name}!`);                                        - 62  };                                                                       - 63  greet("Alice");                                                          - 64   - 65  // Destructuring assignment - 66  const [a, b, ...rest] = [12345];                                 - 67  console.log(a, b, rest);                                                 - 68   - 69  // Spread operator - 70  const arr1 = [123];                                                  - 71  const arr2 = [456];                                                  - 72  const combinedArr = [...arr1, ...arr2];                                  - 73  console.log("Combined array:", combinedArr);                             - 74   - 75  // Ternary operator - 76  const message = age >=18 ? "You are an adult." : "You are a minor.";    - 77  console.log(message);                                                    - 78   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[json] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  { -  2  "name""John Doe",                                                  -  3  "age"30,                                                           -  4  "isStudent"false,                                                  -  5  "address": {                                                         -  6  "street""123 Main St",                                         -  7  "city""Anytown",                                               -  8  "state""CA",                                                   -  9  "zip""12345" - 10      },                                                                   - 11  "phoneNumbers": [                                                    - 12          {                                                                - 13  "type""home",                                              - 14  "number""555-555-1234" - 15          },                                                               - 16          {                                                                - 17  "type""work",                                              - 18  "number""555-555-5678" - 19          }                                                                - 20      ],                                                                   - 21  "hobbies": ["reading""hiking""swimming"],                        - 22  "pets": [                                                            - 23          {                                                                - 24  "type""dog",                                               - 25  "name""Fido" - 26          },                                                               - 27      ],                                                                   - 28  "graduationYear"null - 29  } - 30   - 31   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[kotlin] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  // Variables -  2  val name ="John" -  3  var age =30 -  4  var isStudent =true -  5   -  6  // Printing variables -  7  println("Hello, $name! You are $age years old.")                         -  8   -  9  // Conditional statements - 10  when {                                                                   - 11      age >=18&& isStudent ->println("You are an adult student.")       - 12      age >=18->println("You are an adult.")                            - 13  else->println("You are a minor.")                                  - 14  }                                                                        - 15   - 16  // Arrays - 17  val numbers =arrayOf(12345)                                     - 18  println("Numbers: ${numbers.contentToString()}")                         - 19   - 20  // Lists - 21  val fruits =listOf("apple""banana""orange")                         - 22  println("Fruits: $fruits")                                               - 23   - 24  // Loops - 25  for (num in numbers) {                                                   - 26  println("Number: $num")                                              - 27  }                                                                        - 28   - 29  // Functions - 30  fungreet(name: String) {                                                - 31  println("Hello, $name!")                                             - 32  }                                                                        - 33  greet("Alice")                                                           - 34   - 35  // Lambda functions - 36  val square = { num: Int -> num * num }                                   - 37  println("Square of 5: ${square(5)}")                                     - 38   - 39  // Extension functions - 40  fun String.reverse(): String {                                           - 41  return this.reversed() - 42  }                                                                        - 43  val reversed ="Hello".reverse()                                         - 44  println("Reversed: $reversed")                                           - 45   - 46  // Data classes - 47  dataclass Person(val name: String, val age: Int)                        - 48  val person =Person("John"30)                                          - 49  println("Person: $person")                                               - 50   - 51  // Null safety - 52  var nullable: String? =null - 53  println("Length: ${nullable?.length}")                                   - 54   - 55  // Elvis operator - 56  val length = nullable?.length ?:0 - 57  println("Length (Elvis): $length")                                       - 58   - 59  // Smart casts - 60  funprintLength(obj: Any) {                                              - 61  if (obj is String) {                                                 - 62  println("Length: ${obj.length}")                                 - 63      }                                                                    - 64  }                                                                        - 65  printLength("Hello")                                                     - 66   - 67  // Object expressions - 68  val comparator =object : Comparator<Int> {                              - 69  overridefun compare(a: Int, b: Int): Int {                          - 70  return a - b - 71      }                                                                    - 72  }                                                                        - 73  val sortedNumbers = numbers.sortedWith(comparator)                       - 74  println("Sorted numbers: ${sortedNumbers.contentToString()}")            - 75   - 76  // Companion objects - 77  class MyClass {                                                          - 78      companion object {                                                   - 79  funcreate(): MyClass {                                          - 80  return MyClass() - 81          }                                                                - 82      }                                                                    - 83  }                                                                        - 84  val obj = MyClass.create()                                               - 85   - 86  // Sealed classes - 87  sealedclass Result {                                                    - 88  dataclass Success(val data: String) : Result()                      - 89  dataclass Error(val message: String) : Result()                     - 90  }                                                                        - 91  val result: Result = Result.Success("Data")                              - 92  when (result) {                                                          - 93  is Result.Success ->println("Success: ${result.data}")              - 94  is Result.Error ->println("Error: ${result.message}")               - 95  }                                                                        - 96   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[markdown] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  Heading -  2  =======                                                                  -  3   -  4  Sub-heading -  5  -----------                                                              -  6   -  7  ### Heading -  8   -  9  #### H4 Heading - 10   - 11  ##### H5 Heading - 12   - 13  ###### H6 Heading - 14   - 15   - 16  Paragraphs are separated                                                 - 17  by a blank line.                                                         - 18   - 19  Two spaces at the end of a line                                          - 20  produces a line break.                                                   - 21   - 22  Text attributes _italic_,                                                - 23  **bold**`monospace`.                                                   - 24   - 25  Horizontal rule:                                                         - 26   - 27  ---                                                                      - 28   - 29  Bullet list:                                                             - 30   - 31  * apples                                                               - 32  * oranges                                                              - 33  * pears                                                                - 34   - 35  Numbered list:                                                           - 36   - 37  1. lather                                                              - 38  2. rinse                                                               - 39  3. repeat                                                              - 40   - 41  An [example](http://example.com).                                        - 42   - 43  > Markdown uses email-style > characters for blockquoting.               - 44  >                                                                        - 45  > Lorem ipsum                                                            - 46   - 47  ![progress](https://github.com/textualize/rich/raw/master/imgs/progress. - 48   - 49   - 50  ```                                                                      - 51  a=1                                                                      - 52  ```                                                                      - 53   - 54  ```python                                                                - 55  import this                                                              - 56  ```                                                                      - 57   - 58  ```somelang                                                              - 59  foobar                                                                   - 60  ```                                                                      - 61   - 62      import this                                                          - 63   - 64   - 65  1. List item                                                             - 66   - 67         Code block                                                        - 68   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[python] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  import math                                                              -  2  from os import path                                                      -  3   -  4  # I'm a comment :) -  5   -  6  string_var ="Hello, world!" -  7  int_var =42 -  8  float_var =3.14 -  9  complex_var =1+2j - 10   - 11  list_var = [12345]                                               - 12  tuple_var = (12345)                                              - 13  set_var = {12345}                                                - 14  dict_var = {"a"1"b"2"c"3}                                      - 15   - 16  deffunction_no_args():                                                  - 17  return"No arguments" - 18   - 19  deffunction_with_args(a, b):                                            - 20  return a + b                                                         - 21   - 22  deffunction_with_default_args(a=0, b=0):                                - 23  return a * b                                                         - 24   - 25  lambda_func =lambda x: x**2 - 26   - 27  if int_var ==42:                                                        - 28  print("It's the answer!")                                            - 29  elif int_var <42:                                                       - 30  print("Less than the answer.")                                       - 31  else:                                                                    - 32  print("Greater than the answer.")                                    - 33   - 34  for index, value inenumerate(list_var):                                 - 35  print(f"Index: {index}, Value: {value}")                             - 36   - 37  counter =0 - 38  while counter <5:                                                       - 39  print(f"Counter value: {counter}")                                   - 40      counter +=1 - 41   - 42  squared_numbers = [x**2for x inrange(10if x %2==0]                - 43   - 44  try:                                                                     - 45      result =10/0 - 46  except ZeroDivisionError:                                                - 47  print("Cannot divide by zero!")                                      - 48  finally:                                                                 - 49  print("End of try-except block.")                                    - 50   - 51  classAnimal:                                                            - 52  def__init__(self, name):                                            - 53          self.name = name                                                 - 54   - 55  defspeak(self):                                                     - 56  raiseNotImplementedError("Subclasses must implement this method - 57   - 58  classDog(Animal):                                                       - 59  defspeak(self):                                                     - 60  returnf"{self.name} says Woof!" - 61   - 62  deffibonacci(n):                                                        - 63      a, b =01 - 64  for _ inrange(n):                                                   - 65  yield a                                                          - 66          a, b = b, a + b                                                  - 67   - 68  for num infibonacci(5):                                                 - 69  print(num)                                                           - 70   - 71  withopen('test.txt''w'as f:                                         - 72      f.write("Testing with statement.")                                   - 73   - 74  @my_decorator                                                            - 75  defsay_hello():                                                         - 76  print("Hello!")                                                      - 77   - 78  say_hello()                                                              - 79   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[regex] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  ^abc            # Matches any string that starts with "abc" -  2  abc$            # Matches any string that ends with "abc" -  3  ^abc$           # Matches the string "abc" and nothing else -  4  a.b             # Matches any string containing "a", any character, then -  5  a[.]b           # Matches the string "a.b" -  6  a|b             # Matches either "a" or "b" -  7  a{2}            # Matches "aa" -  8  a{2,}           # Matches two or more consecutive "a" characters -  9  a{2,5}          # Matches between 2 and 5 consecutive "a" characters - 10  a?              # Matches "a" or nothing (0 or 1 occurrence of "a")      - 11  a*              # Matches zero or more consecutive "a" characters - 12  a+              # Matches one or more consecutive "a" characters - 13  \d              # Matches any digit (equivalent to [0-9])                - 14  \D              # Matches any non-digit - 15  \w              # Matches any word character (equivalent to [a-zA-Z0-9_] - 16  \W              # Matches any non-word character - 17  \s              # Matches any whitespace character (spaces, tabs, line b - 18  \S              # Matches any non-whitespace character - 19  (?i)abc         # Case-insensitive match for "abc" - 20  (?:a|b)         # Non-capturing group for either "a" or "b" - 21  (?<=a)b         # Positive lookbehind: matches "b" that is preceded by " - 22  (?<!a)b         # Negative lookbehind: matches "b" that is not preceded  - 23  a(?=b)          # Positive lookahead: matches "a" that is followed by "b - 24  a(?!b)          # Negative lookahead: matches "a" that is not followed b - 25   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[rust] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -   1  use std::collections::HashMap;                                          -   2   -   3  // Constants -   4  const PI: f64 = 3.14159;                                                -   5   -   6  // Structs -   7  struct Rectangle {                                                      -   8      width: u32,                                                         -   9      height: u32,                                                        -  10  }                                                                       -  11   -  12  impl Rectangle {                                                        -  13  fnarea(&self) -> u32 {                                             -  14          self.width * self.height                                        -  15      }                                                                   -  16  }                                                                       -  17   -  18  // Enums -  19  enum Result<T, E> {                                                     -  20      Ok(T),                                                              -  21      Err(E),                                                             -  22  }                                                                       -  23   -  24  // Functions -  25  fngreet(name: &str) {                                                  -  26      println!("Hello, {}!", name);                                       -  27  }                                                                       -  28   -  29  fnmain() {                                                             -  30  // Variables -  31  let name = "John";                                                  -  32  letmut age = 30;                                                   -  33  let is_student = true;                                              -  34   -  35  // Printing variables -  36      println!("Hello, {}! You are {} years old.", name, age);            -  37   -  38  // Conditional statements -  39  if age >= 18 && is_student {                                        -  40          println!("You are an adult student.");                          -  41      } elseif age >= 18 {                                               -  42          println!("You are an adult.");                                  -  43      } else {                                                            -  44          println!("You are a minor.");                                   -  45      }                                                                   -  46   -  47  // Arrays -  48  let numbers = [12345];                                      -  49      println!("Numbers: {:?}", numbers);                                 -  50   -  51  // Vectors -  52  letmut fruits = vec!["apple""banana""orange"];                 -  53      fruits.push("grape");                                               -  54      println!("Fruits: {:?}", fruits);                                   -  55   -  56  // Loops -  57  for num in&numbers {                                               -  58          println!("Number: {}", num);                                    -  59      }                                                                   -  60   -  61  // Pattern matching -  62  let result = Result::Ok(42);                                        -  63  match result {                                                      -  64          Result::Ok(value) => println!("Value: {}", value),              -  65          Result::Err(error) => println!("Error: {:?}", error),           -  66      }                                                                   -  67   -  68  // Ownership and borrowing -  69  let s1 = String::from("hello");                                     -  70  let s2 = s1.clone();                                                -  71      println!("s1: {}, s2: {}", s1, s2);                                 -  72   -  73  // References -  74  let rect = Rectangle {                                              -  75          width: 10,                                                      -  76          height: 20,                                                     -  77      };                                                                  -  78      println!("Rectangle area: {}", rect.area());                        -  79   -  80  // Hash maps -  81  letmut scores = HashMap::new();                                    -  82      scores.insert("Alice"100);                                        -  83      scores.insert("Bob"80);                                           -  84      println!("Alice's score: {}", scores["Alice"]);                     -  85   -  86  // Closures -  87  let square = |num: i32| num * num;                                  -  88      println!("Square of 5: {}", square(5));                             -  89   -  90  // Traits -  91  trait Printable {                                                   -  92  fnprint(&self);                                                -  93      }                                                                   -  94   -  95  impl Printable for Rectangle {                                      -  96  fnprint(&self) {                                               -  97              println!("Rectangle: width={}, height={}", self.width, self -  98          }                                                               -  99      }                                                                   - 100      rect.print();                                                       - 101   - 102  // Modules - 103  greet("Alice");                                                     - 104  }                                                                       - 105   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[sql] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  -- This is a comment in SQL -  2   -  3  -- Create tables -  4  CREATETABLE Authors (                                                   -  5      AuthorID INT PRIMARY KEY,                                            -  6      Name VARCHAR(255NOT NULL,                                          -  7      Country VARCHAR(50)                                                  -  8  );                                                                       -  9   - 10  CREATETABLE Books (                                                     - 11      BookID INT PRIMARY KEY,                                              - 12      Title VARCHAR(255NOT NULL,                                         - 13      AuthorID INT,                                                        - 14      PublishedDate DATE,                                                  - 15      FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)                  - 16  );                                                                       - 17   - 18  -- Insert data - 19  INSERTINTO Authors (AuthorID, Name, Country) VALUES (1'George Orwell' - 20   - 21  INSERTINTO Books (BookID, Title, AuthorID, PublishedDate) VALUES (1'1 - 22   - 23  -- Update data - 24  UPDATE Authors SET Country ='United Kingdom'WHERE Country ='UK';      - 25   - 26  -- Select data with JOIN - 27  SELECT Books.Title, Authors.Name                                         - 28  FROM Books                                                               - 29  JOIN Authors ON Books.AuthorID = Authors.AuthorID;                       - 30   - 31  -- Delete data (commented to preserve data for other examples) - 32  -- DELETE FROM Books WHERE BookID = 1; - 33   - 34  -- Alter table structure - 35  ALTER TABLE Authors ADD COLUMN BirthDate DATE;                           - 36   - 37  -- Create index - 38  CREATEINDEX idx_author_name ON Authors(Name);                           - 39   - 40  -- Drop index (commented to avoid actually dropping it) - 41  -- DROP INDEX idx_author_name ON Authors; - 42   - 43  -- End of script - 44   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[toml] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  # This is a comment in TOML -  2   -  3  string = "Hello, world!" -  4  integer = 42 -  5  float = 3.14 -  6  boolean = true -  7  datetime = 1979-05-27T07:32:00Z -  8   -  9  fruits = ["apple""banana""cherry"]                                   - 10   - 11  [address]                                                                - 12  street = "123 Main St" - 13  city = "Anytown" - 14  state = "CA" - 15  zip = "12345" - 16   - 17  [person.john]                                                            - 18  name = "John Doe" - 19  age = 28 - 20  is_student = false - 21   - 22   - 23  [[animals]]                                                              - 24  name = "Fido" - 25  type = "dog" - 26   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_language_rendering[yaml] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  # This is a comment in YAML -  2   -  3  # Scalars -  4  string"Hello, world!" -  5  integer42 -  6  float3.14 -  7  booleantrue -  8   -  9  # Sequences (Arrays) - 10  fruits:                                                                  - 11    - Apple - 12    - Banana - 13    - Cherry - 14   - 15  # Nested sequences - 16  persons:                                                                 - 17    - nameJohn - 18  age28 - 19  is_studentfalse - 20    - nameJane - 21  age22 - 22  is_studenttrue - 23   - 24  # Mappings (Dictionaries) - 25  address:                                                                 - 26  street123 Main St - 27  cityAnytown - 28  stateCA - 29  zip'12345' - 30   - 31  # Multiline string - 32  description - 33    This is a multiline  - 34    string in YAML. - 35   - 36  # Inline and nested collections - 37  colors: { redFF0000green00FF00blue0000FF }                     - 38   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_line_number_start - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - LineNumbersReactive - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ -  9999  Foo                   - 10000  Bar                   - 10001  Baz                   - 10002   - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ - - - - - ''' -# --- -# name: test_text_area_read_only_cursor_rendering - ''' - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  Hello, world!           - - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection0] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line. - - I am another line.         - - I am the final line.       - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection1] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line. - - I am another line.         - - I am the final line.       - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection2] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line. - - I am another line. - - I am the final line.       - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection3] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line. - - I am another line. - - I am the final line. - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection4] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line.               - - I am another line.         - - I am the final line.       - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_selection_rendering[selection5] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - I am a line.               - - I am another line.         - - I am the final line.       - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_themes[css] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  defhello(name): - 2      x =123 - 3  whilenotFalse:                      - 4  print("hello "+ name)            - 5  continue - 6   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_themes[dracula] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  defhello(name): - 2      x =123 - 3  whilenotFalse:                      - 4  print("hello "+ name)            - 5  continue - 6   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_themes[github_light] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  defhello(name): - 2  x=123 - 3  whilenotFalse:                      - 4  print("hello "+name)            - 5  continue - 6   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_themes[monokai] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  defhello(name): - 2      x =123 - 3  whilenotFalse:                      - 4  print("hello "+ name)            - 5  continue - 6   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_themes[vscode_dark] - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaSnapshot - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - 1  defhello(name): - 2      x =123 - 3  whilenotFalse:                      - 4  print("hello "+ name)            - 5  continue - 6   - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_area_wrapping_and_folding - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TextAreaWrapping - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  1  # The  - Wonders  - of Space  - Explorati - on -  2   -  3  Space      - explorati  - on has     - *always* - captured   - the        - human      - imaginati  - on.        -  4  ▃▃ -  5  ダレンバ   - ーンズ     -  6   -  7   - Thisissom  - elongtext  - thatshoul  - dfoldcorr  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_text_log_blank_write - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - RichLogApp - - - - - - - - - - Hello                                                                          - - World                                                                          - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_textual_dev_border_preview - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - BorderApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  ascii  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔+------------------- ascii --------------------+ -  blank || - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|I must not fear.| -  dashed |Fear is the mind-killer.| - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|Fear is the little-death that brings | - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|total obliteration.| -  double |I will face my fear.| - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅|I will permit it to pass over me and | - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|through me.| -  heavy |And when it has gone past, I will turn| - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|the inner eye to see its path.| - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|Where the fear has gone there will be | -  hidden |nothing. Only I will remain.| - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|| -  hkey +----------------------------------------------+ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  inner  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_textual_dev_colors_preview - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ColorsApp - - - - - - - - - - - Theme ColorsNamed Colors - ━╸━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  primary  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  secondary "primary" - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  background $primary-darken-3$t - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  primary-background $primary-darken-2$t - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  secondary-background $primary-darken-1$t - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  surface $primary$t - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - -  d Toggle dark mode  - - - - - ''' -# --- -# name: test_textual_dev_easing_preview - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - EasingApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  round ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Animation Duration:1.0                        - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -  out_sine  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ -  out_quint  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Welcome to Textual! - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  out_quart I must not fear. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Fear is the  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mind-killer. -  out_quad Fear is the  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁little-death that  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔brings total  -  out_expo obliteration. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I will face my fear. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will permit it to  -  out_elastic pass over me and  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁through me. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔And when it has gone  -  out_cubic  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ^p Focus: Duration Input  ^b Toggle Dark  - - - - - ''' -# --- -# name: test_textual_dev_keys_preview - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Textual Keys - - - - - - - - - - Textual Keys - ╭────────────────────────────────────────────────────────────────────────────╮ - │ Press some keys!                                                           │ - │                                                                            │ - │ To quit the app press ctrl+ctwice or press the Quit button below.         │ - ╰────────────────────────────────────────────────────────────────────────────╯ - Key(key='a'character='a'name='a'is_printable=True) - Key(key='b'character='b'name='b'is_printable=True) - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  Clear  Quit  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_toggle_style_order - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - CheckboxApp - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - XThis is just some text. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - This is just some text. - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tooltips_in_compound_widgets - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TooltipApp - - - - - - - - - - ━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━10%                                            - - Hello, Tooltip! - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tree_clearing_and_expansion - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TreeClearingSnapshotApp - - - - - - - - - - ▼ Left▶ Right - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_tree_example - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TreeApp - - - - - - - - - - ▼ Dune - ┗━━ ▼ Characters -     ┣━━ Paul -     ┣━━ Jessica -     ┗━━ Chani - - - - - - - - - - - - - - - - - - - - - - - - ''' -# --- -# name: test_unscoped_css - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MyApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌───┐ - foo - └───┘ - ┌───┐ - bar - └───┘ - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - ┌───┐ - foo - └───┘ - ┌───┐ - bar - └───┘ - └──────────────────────────────────────────────────────────────────────────────┘ - ┌───────────────────┐ - This will be styled - └───────────────────┘ - - - - - - - - - - ''' -# --- -# name: test_vertical_layout - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerticalLayoutExample - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - One - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - Two - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - Three - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_vertical_max_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerticalApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - - - - - - #top - - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - - - - #bottom - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_vertical_min_height - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VerticalApp - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - - - - #top - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - ┌──────────────────────────────────────────────────────────────────────────────┐ - - - - - - #bottom - - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_viewport_height_and_width_properties - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ViewportUnits - - - - - - - - - - ┌──────────────────────────────────────────────────────────────────────────────┐ - Hello, world! - - - - - - - - - - - - - - - - - - - - - - └──────────────────────────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_visibility - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Visibility - - - - - - - - - - ┌──────────────────────────────────────┐ - bar - ┌────────────────────────────────────┐┌────────────────────────────────────┐ - floatfloat - └────────────────────────────────────┘└────────────────────────────────────┘ - - - - - - - - - - - - - - - - - - - └──────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_welcome - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - WelcomeApp - - - - - - - - - - -  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  -  ┃                                 Welcome!                                 ┃  -  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛  - -  Textual is a TUI, or Text User Interface, framework for Python inspired by    -  modern web development. We hope you enjoy using Textual! - - - Dune quote - - ▌ "I must not fear. Fear is the mind-killer. Fear is the little-death that - ▌ brings total obliteration. I will face my fear. I will permit it to pass - ▌ over me and through me. And when it has gone past, I will turn the inner - ▌ eye to see its path. Where the fear has gone there will be nothing. Only - ▌ I will remain."                                                          - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ -  OK  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - ''' -# --- -# name: test_width_100 - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Width100PCentApp - - - - - - - - - - ┌───────────────────────────────────────────────────────────┐ - ┌─────────────────────────────────────────────────────────┐ - I want to be 100% of my parent - └─────────────────────────────────────────────────────────┘ - ┌─────────────────────────────────────────────────────────┐ - I want my parent to be wide enough to wrap me and no more - └─────────────────────────────────────────────────────────┘ - - - - - - - - - - - - - - - - - └───────────────────────────────────────────────────────────┘ - - - - - ''' -# --- -# name: test_zero_scrollbar_size - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - TestApp - - - - - - - - - - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - Hello, world! - - - - - ''' -# --- diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_alignment_containers.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_alignment_containers.svg new file mode 100644 index 0000000000..d4d1abf605 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_alignment_containers.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignContainersApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + center  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + middle  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[False].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[False].svg new file mode 100644 index 0000000000..cee95d69f7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[False].svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AnsiMappingApp + + + + + + + + + + Foreground & background                                                          +red +dim red +green +dim green +yellow +dim yellow +blue +dim blue +magenta +dim magenta +cyan +dim cyan +white +dim white +black +dim black + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[True].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[True].svg new file mode 100644 index 0000000000..884440ba70 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_ansi_color_mapping[True].svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AnsiMappingApp + + + + + + + + + + Foreground & background                                                          +red +dim red +green +dim green +yellow +dim yellow +blue +dim blue +magenta +dim magenta +cyan +dim cyan +white +dim white +black +dim black + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_app_blur.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_app_blur.svg new file mode 100644 index 0000000000..8c917b4f37 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_app_blur.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AppBlurApp + + + + + + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +This should be the blur style      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +This should also be the blur style +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_fr.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_fr.svg new file mode 100644 index 0000000000..caa65f18f4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_fr.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FRApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +┌────────────────────────────┐ +Hello one line               +┌──────────────────────────┐ +Widget#child + + + + + + + + + + + + + +└──────────────────────────┘ + +Two +Lines with 1x2 margin + +└────────────────────────────┘ +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid.svg new file mode 100644 index 0000000000..79be6b73f6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +foo         ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +foo▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +foo bar foo bar foo bar foo ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +bar foo bar foo bar foo bar  +foo bar foo bar foo bar ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +Longer label                  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid_default_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid_default_height.svg new file mode 100644 index 0000000000..2812eab76a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_grid_default_height.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridHeightAuto + + + + + + + + + + GridHeightAuto +Here is some text before the grid                                                +┌──────────────────────────────────────────────────────────────────────────────┐ +Cell #0                   Cell #1                   Cell #2                    +Cell #3                   Cell #4                   Cell #5                    +Cell #6                   Cell #7                   Cell #8                    +└──────────────────────────────────────────────────────────────────────────────┘ +Here is some text after the grid                                                 + + + + + + + + + + + + + + + + g Grid  v Vertical  h Horizontal  c Container  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_tab_active.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_tab_active.svg new file mode 100644 index 0000000000..777e57bfe6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_tab_active.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ExampleApp + + + + + + + + + + +Parent 1Parent 2 +━━━━━━━━━━━━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + +Child 2.1Child 2.2 +━━━━━━━━━━━━━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button 2.2  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + SPACE Focus button 2.2  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_table.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_table.svg new file mode 100644 index 0000000000..ccfb82f1cb --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_table.svg @@ -0,0 +1,220 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + MyApp +╭──────────────────╮╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ +ok                ││test                                                                                               +╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍││╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ +││╭─ 0 ──────────────────────────────────────╮╭─ 1 ──────────────────────────────────────╮╭─ 2 ─────│ +│││││││ +│││ Foo       Bar         Baz              ││ Foo       Bar         Baz              ││ Foo      +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +│││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH +││╰──────────────────────────────────────────╯╰──────────────────────────────────────────╯╰─────────│ +││ +╰──────────────────╯╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_width_input.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_width_input.svg new file mode 100644 index 0000000000..bff7bce97d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_auto_width_input.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputWidthAutoApp + + + + + + + + + + InputWidthAutoApp +▔▔▔▔▔▔▔▔▔▔ +Hello +▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_big_buttons.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_big_buttons.svg new file mode 100644 index 0000000000..5a76dffcd2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_big_buttons.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + Hello  + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + Hello  + World !!  + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_bindings_screen_overrides_show.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_bindings_screen_overrides_show.svg new file mode 100644 index 0000000000..81474728c7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_bindings_screen_overrides_show.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HideBindingApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + p Binding shown  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_blur_on_disabled.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_blur_on_disabled.svg new file mode 100644 index 0000000000..71ab54c3c2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_blur_on_disabled.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BlurApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +foo                                                                        +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_border_alpha.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_border_alpha.svg new file mode 100644 index 0000000000..1843e17b1e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_border_alpha.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderAlphaApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_outline.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_outline.svg new file mode 100644 index 0000000000..5c810d08e7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_outline.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonIssue + + + + + + + + + + ┌──────────────┐ + Test  +└──────────────┘ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_widths.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_widths.svg new file mode 100644 index 0000000000..eabd05e04a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_widths.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalWidthAutoApp + + + + + + + + + + ┌────────────────────────────┐ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This is a very wide button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└────────────────────────────┘ +┌────────────────────────────────────────────────────────┐ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This is a very wide button  This is a very wide button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +└────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_console_markup.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_console_markup.svg new file mode 100644 index 0000000000..c508a18efd --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_console_markup.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonsWithMarkupApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Focused Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Blurred Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Disabled Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_multiline_label.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_multiline_label.svg new file mode 100644 index 0000000000..cc5bf41bb9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_button_with_multiline_label.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonWithMultilineLabelApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  + with  + multi-line  + label  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_buttons_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_buttons_render.svg new file mode 100644 index 0000000000..4e3191c0bd --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_buttons_render.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonsApp + + + + + + + + + + +Standard ButtonsDisabled Buttons + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Default  Default  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Primary!  Primary!  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Success!  Success!  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Warning!  Warning!  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Error!  Error!  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_checkbox_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_checkbox_example.svg new file mode 100644 index 0000000000..9954dd99a0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_checkbox_example.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CheckboxApp + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +X Arrakis 😓 +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔ +X Caladan +▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔ +X Chusuk +▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +XGiedi Prime +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔ +XGinaz +▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔ +X Grumman +▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▃▃ +XKaitain +▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_collapsed.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_collapsed.svg new file mode 100644 index 0000000000..37b5e7883a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_collapsed.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ Leto + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ Jessica + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ Paul + + + + + + + + + + + + + + + + c Collapse All  e Expand All  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_custom_symbol.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_custom_symbol.svg new file mode 100644 index 0000000000..12ecbf8a5f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_custom_symbol.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +>>> Togglev Toggle + +Hello, world.                        + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_expanded.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_expanded.svg new file mode 100644 index 0000000000..902b008e19 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_expanded.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Leto + +# Duke Leto I Atreides + +Head of House Atreides.                                                    + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Jessica + + + +Lady Jessica + +  Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Paul▆▆ + + + + c Collapse All  e Expand All  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_nested.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_nested.svg new file mode 100644 index 0000000000..2a4926be45 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_nested.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Toggle + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ Toggle + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_render.svg new file mode 100644 index 0000000000..ef0e616b9a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_collapsible_render.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Leto + +# Duke Leto I Atreides + +Head of House Atreides.                                                      + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▼ Jessica + + + +Lady Jessica + +  Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▶ Paul + + + + c Collapse All  e Expand All  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_columns_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_columns_height.svg new file mode 100644 index 0000000000..c165ee6fe4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_columns_height.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +┌────────────────────┐┌────────────────┐┌──────────────────────┐ +As tall as container││This has default││I have a static height +││height││ +││but a││ +││few lines││ +│└────────────────┘│ + + + + + + + + + +└────────────────────┘└──────────────────────┘ +└──────────────────────────────────────────────────────────────────────────────┘ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette.svg new file mode 100644 index 0000000000..5241118c28 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CommandPaletteApp + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +🔎A + + +  This is a test of this code 0                                                  +  This is a test of this code 1                                                  +  This is a test of this code 2                                                  +  This is a test of this code 3                                                  +  This is a test of this code 4                                                  +  This is a test of this code 5                                                  +  This is a test of this code 6                                                  +  This is a test of this code 7                                                  +  This is a test of this code 8                                                  +  This is a test of this code 9                                                  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette_discovery.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette_discovery.svg new file mode 100644 index 0000000000..7202c8e17d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_command_palette_discovery.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CommandPaletteApp + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +🔎Search for commands… + + +  This is a test of this code 0                                                  +  This is a test of this code 1                                                  +  This is a test of this code 2                                                  +  This is a test of this code 3                                                  +  This is a test of this code 4                                                  +  This is a test of this code 5                                                  +  This is a test of this code 6                                                  +  This is a test of this code 7                                                  +  This is a test of this code 8                                                  +  This is a test of this code 9                                                  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_component_text_opacity.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_component_text_opacity.svg new file mode 100644 index 0000000000..1749e8bd22 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_component_text_opacity.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW +WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_initial.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_initial.svg new file mode 100644 index 0000000000..4d9cce465e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_initial.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentSwitcherApp + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + DataTable  Markdown  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +╭────────────────────────────────────────────────────────────────────╮ + Book                                 Year  + Dune                                 1965  + Dune Messiah                         1969  + Children of Dune                     1976  + God Emperor of Dune                  1981  + Heretics of Dune                     1984  + Chapterhouse: Dune                   1985  + + + + + + + + + + +╰────────────────────────────────────────────────────────────────────╯ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_switch.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_switch.svg new file mode 100644 index 0000000000..72d171cfca --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_content_switcher_example_switch.svg @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentSwitcherApp + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + DataTable  Markdown  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +╭─────────────────────────────────────────╮ + + +Three Flavours Cornetto + +  The Three Flavours Cornetto trilogy  +  is an anthology series of British  +  comedic genre films directed by Edgar   +  Wright. + + +Shaun of the Dead + + +UK Release   +Flavour   Date        Director    +   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +   Strawberry 2004-04-09   Edgar          +                           Wright         + + + +Hot Fuzz + + +UK Release    +Flavour Date         Director     +   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +   Classico 2007-02-17    Edgar Wright    + + + +The World's End + + +UK Release     +FlavourDate          Director     +   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +   Mint    2013-07-19     Edgar Wright    + + + + + +╰─────────────────────────────────────────╯ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading.svg new file mode 100644 index 0000000000..f5d367467f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HotReloadingApp + + + + + + + + + + Hello, world!                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading_on_screen.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading_on_screen.svg new file mode 100644 index 0000000000..f5d367467f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_hot_reloading_on_screen.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HotReloadingApp + + + + + + + + + + Hello, world!                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align.py].svg new file mode 100644 index 0000000000..1d9dbc5109 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignApp + + + + + + + + + + + + + + + +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +Vertical alignment with Textual + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + +Take note, browsers. + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align_all.py].svg new file mode 100644 index 0000000000..42dcd43a0f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[align_all.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignAllApp + + + + + + + + + + ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ +left topcenter topright top + + + + +└────────────────────────┘└────────────────────────┘└────────────────────────┘ + +┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ + + +left middlecenter middleright middle + + +└────────────────────────┘└────────────────────────┘└────────────────────────┘ + +┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ + + + + + +left bottomcenter bottomright bottom +└────────────────────────┘└────────────────────────┘└────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background.py].svg new file mode 100644 index 0000000000..aa95c6937c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background.py].svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BackgroundApp + + + + + + + + + + + + +Widget 1 + + + + + + + +Widget 2 + + + + + + + +Widget 3 + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background_transparency.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background_transparency.py].svg new file mode 100644 index 0000000000..0777d5b497 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[background_transparency.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BackgroundTransparencyApp + + + + + + + + + + + + + + + + + + + + +10%20%30%40%50%60%70%80%90%100% + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border.py].svg new file mode 100644 index 0000000000..17df5734de --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderApp + + + + + + + + + + +┌────────────────────────────────────────────────────────────────────────────┐ + +My border is solid red + +└────────────────────────────────────────────────────────────────────────────┘ + +┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + +My border is dashed green + +┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +My border is tall blue + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_all.py].svg new file mode 100644 index 0000000000..961d729b4b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_all.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllBordersApp + + + + + + + + + + ++----------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓╔═════════════════╗ +|ascii|blankdasheddouble ++----------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛╚═════════════════╝ + + + +┏━━━━━━━━━━━━━━━━┓▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ +heavyhidden/nonehkeyinner +┗━━━━━━━━━━━━━━━━┛▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ + + + +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜█████████████████▎╭────────────────╮┌─────────────────┐ +outerpanelroundsolid +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎╰────────────────╯└─────────────────┘ + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█▏                ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +tallthickvkeywide +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▏                ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_sub_title_align_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_sub_title_align_all.py].svg new file mode 100644 index 0000000000..c83db769bd --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_sub_title_align_all.py].svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderSubTitleAlignAll + + + + + + + + + + + +▏  Border title      ▕╭─ Lef… ─╮▁▁▁▁▁ Left ▁▁▁▁▁ +This is the story ofa Pythondeveloper that +▏   Border subtitle  ▕╰─ Cen… ─╯▔▔▔▔▔ @@@ ▔▔▔▔▔▔ + + + + + ++--------------+─Title───────────────── +|had to fill up|             nine labels          and ended up redoing it   ++- Left -------+──────────────Subtitle─ + + + + +─Title, but really looo…─ +─Title, but r…──Title, but reall…─ +because the first try       had some labels          that were too long.     +─Subtitle, bu…──Subtitle, but re…─ +─Subtitle, but really l…─ + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_subtitle_align.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_subtitle_align.py].svg new file mode 100644 index 0000000000..b789c41f67 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_subtitle_align.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderSubtitleAlignApp + + + + + + + + + + +┌────────────────────────────────────────────────────────────────────────────┐ + +My subtitle is on the left. + +└─ < Left ───────────────────────────────────────────────────────────────────┘ + +┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + +My subtitle is centered + +┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ + +My subtitle is on the right + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Right > ▁▎ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_align.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_align.py].svg new file mode 100644 index 0000000000..a97c7e8a6b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_align.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderTitleAlignApp + + + + + + + + + + +┌─ < Left ───────────────────────────────────────────────────────────────────┐ + +My title is on the left. + +└────────────────────────────────────────────────────────────────────────────┘ + +┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + +My title is centered + +┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Right > ▔▎ + +My title is on the right + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_colors.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_colors.py].svg new file mode 100644 index 0000000000..20c7686f17 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[border_title_colors.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderTitleApp + + + + + + + + + + + + + + + +┏━ Textual Rocks ━━━━━━━━━━━━━┓ + + + + +Hello, World! + + + + +┗━━━━━━━━━━━━━ Textual Rocks ━┛ + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[box_sizing.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[box_sizing.py].svg new file mode 100644 index 0000000000..0403d2613e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[box_sizing.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BoxSizingApp + + + + + + + + + + + +  ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   + +I'm using border-box! + +  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   + + +  ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   + +I'm using content-box! + + + + + +  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color.py].svg new file mode 100644 index 0000000000..f37b048512 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorApp + + + + + + + + + + + + +I'm red! + + + + + + + +I'm rgb(0, 255, 0)! + + + + + + + +I'm hsl(240, 100%, 50%)! + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color_auto.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color_auto.py].svg new file mode 100644 index 0000000000..ef077a4a8f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[color_auto.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorApp + + + + + + + + + + +The quick brown fox jumps over the lazy dog! + + + + +The quick brown fox jumps over the lazy dog! + + + + +The quick brown fox jumps over the lazy dog! + + + + +The quick brown fox jumps over the lazy dog! + + + + +The quick brown fox jumps over the lazy dog! + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[column_span.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[column_span.py].svg new file mode 100644 index 0000000000..90583fdc50 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[column_span.py].svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + +#p1 + + + + + +#p2#p3 + + + + + +#p4#p5 + + + + + +#p6#p7 + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align.py].svg new file mode 100644 index 0000000000..f9bb91a2fd --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentAlignApp + + + + + + + + + + +With content-align you can... + + + + + + + + + +...Easily align content... + + + + + + + + + + +...Horizontally and vertically! + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align_all.py].svg new file mode 100644 index 0000000000..9f6f0e1061 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[content_align_all.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllContentAlignApp + + + + + + + + + + left topcenter topright top + + + + + + + + + + +left middlecenter middleright middle + + + + + + + + + + + +left bottomcenter bottomright bottom + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[display.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[display.py].svg new file mode 100644 index 0000000000..5f5d0ed5d8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[display.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DisplayApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃Widget 1 + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃Widget 3 + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[dock_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[dock_all.py].svg new file mode 100644 index 0000000000..8ecd031cb8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[dock_all.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DockAllApp + + + + + + + + + + + + +╭──────────────────────────────────────────────────────────╮ +                           top                             + + + + + + +left                                                 right + + + + + + + +                          bottom                           +╰──────────────────────────────────────────────────────────╯ + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid.py].svg new file mode 100644 index 0000000000..4791efebd1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridApp + + + + + + + + + + +Grid cell 1Grid cell 2 + +row-span: 3; +column-span: 2; + + +Grid cell 3 + + + + + +Grid cell 4 + + + + + +Grid cell 5Grid cell 6Grid cell 7 + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_columns.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_columns.py].svg new file mode 100644 index 0000000000..c8f40e989a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_columns.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ +1fr││width = 16││2fr││1fr││width = 16 +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ +╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ +1fr││width = 16││2fr││1fr││width = 16 +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +││││││││ +╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_gutter.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_gutter.py].svg new file mode 100644 index 0000000000..46a3f0fa38 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_gutter.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + +12 + +╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + +╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + +34 + +╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + +╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + +56 + +╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + +╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + +78 + + +╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_rows.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_rows.py].svg new file mode 100644 index 0000000000..6d523cf260 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_rows.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +1fr││1fr +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +height = 6││height = 6 +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +25%││25% +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +1fr││1fr +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +height = 6││height = 6 +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_both.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_both.py].svg new file mode 100644 index 0000000000..449f34e217 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_both.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +1││2 +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +3││4 +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮ + +5 + + +╰──────────────────────────────────────╯ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_columns.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_columns.py].svg new file mode 100644 index 0000000000..4c1ba0406c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[grid_size_columns.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +││ +1││2 +││ +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮╭──────────────────────────────────────╮ +││ +││ +3││4 +││ +││ +││ +╰──────────────────────────────────────╯╰──────────────────────────────────────╯ +╭──────────────────────────────────────╮ + + +5 + + + +╰──────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[hatch.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[hatch.py].svg new file mode 100644 index 0000000000..743bbc4346 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[hatch.py].svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HatchApp + + + + + + + + + + ┌─ cross ──────┐┌─ horizontal ─┐┌─ custom ─────┐┌─ left ───────┐┌─ right ──────┐ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +└──────────────┘└──────────────┘└──────────────┘└──────────────┘└──────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height.py].svg new file mode 100644 index 0000000000..81991b5099 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightApp + + + + + + + + + + Widget + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height_comparison.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height_comparison.py].svg new file mode 100644 index 0000000000..2249581009 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[height_comparison.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightComparisonApp + + + + + + + + + + #cells· +· +· +#percent· + +· +#w· +· +· + +#h· +· +· +· +#vw +· +· +· +#vh· + +#auto· +#fr1· +#fr2· +· + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline.py].svg new file mode 100644 index 0000000000..984905f97c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline.py].svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + + +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ + + +#foo + + +┣━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┫#bar + + +Placeholder + + +┣━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━┫ + + +#baz + + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline_horizontal.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline_horizontal.py].svg new file mode 100644 index 0000000000..9be8fec043 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[keyline_horizontal.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌─────────────────────────┬─────────────────────────┬──────────────────────────┐ + + + + + + + + + + +PlaceholderPlaceholderPlaceholder + + + + + + + + + + + +└─────────────────────────┴─────────────────────────┴──────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[layout.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[layout.py].svg new file mode 100644 index 0000000000..c994a65259 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[layout.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LayoutApp + + + + + + + + + + +Layout + +Is + +Vertical + + +LayoutIsHorizontal + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background.py].svg new file mode 100644 index 0000000000..63a0871d73 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkBackgroundApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background_hover.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background_hover.py].svg new file mode 100644 index 0000000000..42d1c19bfc --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_background_hover.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverBackgroundApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color.py].svg new file mode 100644 index 0000000000..edf6054984 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkColorApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color_hover.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color_hover.py].svg new file mode 100644 index 0000000000..a76245768b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_color_hover.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverColorApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style.py].svg new file mode 100644 index 0000000000..15100fb267 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkStyleApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style_hover.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style_hover.py].svg new file mode 100644 index 0000000000..5ab9dc8e50 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[link_style_hover.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverStyleApp + + + + + + + + + + Visit the Textualize website.                                                    +Click here for the bell sound.                                                   +You can also click here for the bell sound.                                      +Exit this application. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[links.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[links.py].svg new file mode 100644 index 0000000000..6036dd28ca --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[links.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinksApp + + + + + + + + + + Here is a link which you can click! + +Here is a link which you can click! + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin.py].svg new file mode 100644 index 0000000000..9a242373b8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarginApp + + + + + + + + + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see  +its path. +Where the fear has gone there will be nothing. Only I will  +remain. +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin_all.py].svg new file mode 100644 index 0000000000..43ea4a2e93 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[margin_all.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarginAllApp + + + + + + + + + + ╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ + + + +marginmargin: 1  +no marginmargin: 1: 1 51 2 6 + + + + +╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ + +╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ + + +margin-bottom: 4 + +margin-right: margin-left: 3 +3 +margin-top: 4 + + + +╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_height.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_height.py].svg new file mode 100644 index 0000000000..137f4d0809 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_height.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxHeightApp + + + + + + + + + + + + +max-height: 10w +max-height: 10 +max-height: 50% + + + + + +max-height: 999 + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_width.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_width.py].svg new file mode 100644 index 0000000000..7b14e2ee82 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[max_width.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxWidthApp + + + + + + + + + + + +max-width:  +50h + + + + +max-width: 999 + + + + + +max-width: 50% + + + + + +max-width: 30 + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_height.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_height.py].svg new file mode 100644 index 0000000000..5cfcc54e8b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_height.py].svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinHeightApp + + + + + + + + + + + + + + +min-height: 25% + + +min-height: 75% + + + + + +min-height: 30 +min-height: 40w + + +▃▃ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_width.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_width.py].svg new file mode 100644 index 0000000000..146d99d734 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[min_width.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinWidthApp + + + + + + + + + + + +min-width: 25% + + + + +min-width: 75% + + + + + +min-width: 100 + + + + + +min-width: 400h + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[offset.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[offset.py].svg new file mode 100644 index 0000000000..d41067c4fc --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[offset.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffsetApp + + + + + + + + + + +Chani (offset 0  +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜-3) + + + +▌Paul (offset 8 2)▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + +▌Duncan (offset 4  +▌10) + + + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[opacity.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[opacity.py].svg new file mode 100644 index 0000000000..dabedbfa8b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[opacity.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OpacityApp + + + + + + + + + + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ +opacity: 0% + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + +opacity: 25% + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + +opacity: 50% + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + +opacity: 75% + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + +opacity: 100% + +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline.py].svg new file mode 100644 index 0000000000..1436be3e7d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OutlineApp + + + + + + + + + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +ear is the mind-killer. +ear is the little-death that brings total obliteration. + will face my fear. + will permit it to pass over me and through me. +nd when it has gone past, I will turn the inner eye to see its +ath. +here the fear has gone there will be nothing. Only I will  +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_all.py].svg new file mode 100644 index 0000000000..4aa74924c1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_all.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllOutlinesApp + + + + + + + + + + +------------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ +|ascii|blankdashed ++------------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + + +╔══════════════════╗┏━━━━━━━━━━━━━━━━━━┓ +doubleheavyhidden/none +╚══════════════════╝┗━━━━━━━━━━━━━━━━━━┛ + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ +hkeyinnernone +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ + + +▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜╭──────────────────╮┌──────────────────┐ +outerroundsolid +▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟╰──────────────────╯└──────────────────┘ + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▏                  ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +tallvkeywide +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▏                  ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_vs_border.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_vs_border.py].svg new file mode 100644 index 0000000000..ed503e7926 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[outline_vs_border.py].svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OutlineBorderApp + + + + + + + + + + ╭───────────────────────────────────────────────────────────────────╮ +ear is the mind-killer. +ear is the little-death that brings total obliteration. + will face my fear. + will permit it to pass over me and through me. +nd when it has gone past, I will turn the inner eye to see its path +here the fear has gone there will be nothing. Only I will remain. +╰───────────────────────────────────────────────────────────────────╯ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +╭─────────────────────────────────────────────────────────────────────╮ +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +╰─────────────────────────────────────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[overflow.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[overflow.py].svg new file mode 100644 index 0000000000..718af322c6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[overflow.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OverflowApp + + + + + + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death that Fear is the little-death that  +brings total obliteration.brings total obliteration. +I will face my fear.I will face my fear. +I will permit it to pass over meI will permit it to pass over me  +and through me.and through me. +And when it has gone past, I And when it has gone past, I will  +will turn the inner eye to see turn the inner eye to see its  +its path.▁▁path. +Where the fear has gone there Where the fear has gone there will +will be nothing. Only I will be nothing. Only I will remain. +remain.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I must not fear. +I must not fear.Fear is the mind-killer. +Fear is the mind-killer.Fear is the little-death that  +Fear is the little-death that brings total obliteration. +brings total obliteration.I will face my fear. +I will face my fear.I will permit it to pass over me  +I will permit it to pass over meand through me. + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding.py].svg new file mode 100644 index 0000000000..1a84cd793c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding.py].svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PaddingApp + + + + + + + + + + + + + +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its  +path. +Where the fear has gone there will be nothing. Only I will  +remain. + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding_all.py].svg new file mode 100644 index 0000000000..243d985e05 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[padding_all.py].svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PaddingAllApp + + + + + + + + + + no padding +padding: 1padding:padding: 1 1 +1 52 6 + + + + + + + + + +padding-right: 3padding-bottom: 4padding-left: 3 + + + +padding-top: 4 + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[row_span.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[row_span.py].svg new file mode 100644 index 0000000000..56ad130772 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[row_span.py].svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + +#p4 + + +#p3 + + +#p2 + + +#p1 + + +#p5 + + +#p6 + + +#p7 + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_corner_color.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_corner_color.py].svg new file mode 100644 index 0000000000..db9630ec9a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_corner_color.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarCornerColorApp + + + + + + + + + + I must not fear. Fear is the mind-killer. Fear is the little-death that brings +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain.▅▅ +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_gutter.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_gutter.py].svg new file mode 100644 index 0000000000..287c9aa165 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_gutter.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarGutterApp + + + + + + + + + + I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size.py].svg new file mode 100644 index 0000000000..3a056626c6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + + +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration.▁▁▁▁ +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path. +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size2.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size2.py].svg new file mode 100644 index 0000000000..d8ef0eaf94 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbar_size2.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + I must not fear.I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death Fear is the little-death tFear is the little-death  +I will face my fear.I will face my fear.I will face my fear. +I will permit it to pass I will permit it to pass oI will permit it to pass  +And when it has gone pastAnd when it has gone past,And when it has gone past +Where the fear has gone tWhere the fear has gone thWhere the fear has gone t +I must not fear.I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death Fear is the little-death tFear is the little-death  +I will face my fear.I will face my fear.I will face my fear.▇▇ +I will permit it to pass I will permit it to pass oI will permit it to pass  +And when it has gone pastAnd when it has gone past,And when it has gone past +Where the fear has gone tWhere the fear has gone thWhere the fear has gone t +I must not fear.I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death Fear is the little-death tFear is the little-death  +I will face my fear.I will face my fear.I will face my fear. +I will permit it to pass I will permit it to pass oI will permit it to pass  +And when it has gone past, +Where the fear has gone th +I must not fear. +Fear is the mind-killer. + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars.py].svg new file mode 100644 index 0000000000..ae33356a87 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars.py].svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death that brings tFear is the little-death that brings t +I will face my fear.I will face my fear. +I will permit it to pass over me and tI will permit it to pass over me and t +And when it has gone past, I will turnAnd when it has gone past, I will turn +see its path.see its path. +Where the fear has gone there will be Where the fear has gone there will be  +will remain.will remain. +I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death that brings tFear is the little-death that brings t +I will face my fear.I will face my fear. +I will permit it to pass over me and tI will permit it to pass over me and t +And when it has gone past, I will turnAnd when it has gone past, I will turn +see its path.▃▃see its path.▃▃ +Where the fear has gone there will be Where the fear has gone there will be  +will remain.will remain. +I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death that brings tFear is the little-death that brings t +I will face my fear.I will face my fear. +I will permit it to pass over me and tI will permit it to pass over me and t + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars2.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars2.py].svg new file mode 100644 index 0000000000..033989a904 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[scrollbars2.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Scrollbar2App + + + + + + + + + + I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path.          +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. +Fear is the mind-killer.▇▇ +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path.          +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. +I will face my fear. +I will permit it to pass over me and through me. +And when it has gone past, I will turn the inner eye to see its path.          +Where the fear has gone there will be nothing. Only I will remain. +I must not fear. +Fear is the mind-killer. +Fear is the little-death that brings total obliteration. + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_align.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_align.py].svg new file mode 100644 index 0000000000..1418702b56 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_align.py].svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAlign + + + + + + + + + + +Left alignedCenter aligned +I must not fear. Fear is the            I must not fear. Fear is the     +mind-killer. Fear is the                  mind-killer. Fear is the       +little-death that brings total         little-death that brings total    +obliteration. I will face my fear. Iobliteration. I will face my fear. I +will permit it to pass over me and   will permit it to pass over me and  +through me.                                     through me.              + + + + + +Right alignedJustified +        I must not fear. Fear is theI  must  not  fear.  Fear   is   the +            mind-killer. Fear is themind-killer.     Fear     is     the +      little-death that brings totallittle-death   that   brings   total +obliteration. I will face my fear. Iobliteration. I will face my fear. I +  will permit it to pass over me andwill permit it to pass over  me  and +                         through me.through me. + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_opacity.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_opacity.py].svg new file mode 100644 index 0000000000..9afc44eeec --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_opacity.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextOpacityApp + + + + + + + + + + + + + +                               text-opacity: 25%                                 + + + + +                               text-opacity: 50%                                 + + + + +                               text-opacity: 75%                                 + + + + +                               text-opacity: 100%                                + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style.py].svg new file mode 100644 index 0000000000..73c57898ed --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style.py].svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextStyleApp + + + + + + + + + + I must not fear.I must not fear.I must not fear. +Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. +Fear is the little-death Fear is the little-death Fear is the little-death  +that brings total that brings total that brings total  +obliteration.obliteration.obliteration. +I will face my fear.I will face my fear.I will face my fear. +I will permit it to pass I will permit it to pass I will permit it to pass  +over me and through me.over me and through me.over me and through me. +And when it has gone past,And when it has gone past, And when it has gone past,  +I will turn the inner eye I will turn the inner eye I will turn the inner eye  +to see its path.to see its path.to see its path. +Where the fear has gone Where the fear has gone Where the fear has gone  +there will be nothing. there will be nothing. Onlythere will be nothing. Only +Only I will remain.I will remain.I will remain. + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style_all.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style_all.py].svg new file mode 100644 index 0000000000..91ffb0bf99 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[text_style_all.py].svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllTextStyleApp + + + + + + + + + + +  nonebolditalicreverse +  I must not fear.I must not fear.I must not fear.I must not fear. +  Fear is the Fear is the Fear is the Fear is the  +  mind-killer.mind-killer.mind-killer.mind-killer. +  Fear is the Fear is the Fear is the Fear is the  +  little-death that  little-death that little-death thatlittle-death that  +  brings total brings total brings total brings total  +  obliteration.obliteration.obliteration.obliteration. +  I will face my I will face my I will face my I will face my  +  fear.fear.fear.fear. + +strikeunderlinebold italicreverse strike +I must not fear.I must not fear.I must not fear.I must not fear. +Fear is the Fear is the Fear is the Fear is the  +mind-killer.mind-killer.mind-killer.mind-killer. +Fear is the Fear is the Fear is the Fear is the  +little-death thatlittle-death that little-death thatlittle-death that  +brings total brings total brings total brings total  +obliteration.obliteration.obliteration.obliteration. +I will face my I will face my I will face my I will face my  +fear.fear.fear.fear. +I will permit it I will permit it I will permit it I will permit it  + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[tint.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[tint.py].svg new file mode 100644 index 0000000000..80ae144f69 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[tint.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TintApp + + + + + + + + + + +tint: green 0%; + + +tint: green 10%; + + +tint: green 20%; + + +tint: green 30%; + + +tint: green 40%; + + +tint: green 50%; +▄▄ + +tint: green 60%; + + +tint: green 70%; + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility.py].svg new file mode 100644 index 0000000000..c95545f629 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VisibilityApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃Widget 1 + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┃Widget 3 + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility_containers.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility_containers.py].svg new file mode 100644 index 0000000000..099e47db0c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[visibility_containers.py].svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VisibilityContainersApp + + + + + + + + + + + + +PlaceholderPlaceholderPlaceholder + + + + + + + + + + + + + + + +PlaceholderPlaceholderPlaceholder + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width.py].svg new file mode 100644 index 0000000000..74e4369b97 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width.py].svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidthApp + + + + + + + + + + Widget + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width_comparison.py].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width_comparison.py].svg new file mode 100644 index 0000000000..3e5645ea23 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_css_property[width_comparison.py].svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidthComparisonApp + + + + + + + + + + + + + + + + + + + + +#cells#percent#w#h#vw#vh#auto#fr1#fr3 + + + + + + + + + + + +····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_data_table_in_tabs.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_data_table_in_tabs.svg new file mode 100644 index 0000000000..4564153f55 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_data_table_in_tabs.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dashboard + + + + + + + + + + +Workflows +━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + Id   Description  Status  Result Id  + 1    2            3       4          + a    b            c       d          + fee  fy           fo      fum        + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_column.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_column.svg new file mode 100644 index 0000000000..b2a677069f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_column.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AddColumn + + + + + + + + + +  Movies          No Default  With Default  Long Default          + Severance       ABC           01234567890123456789  + Foundation      ABC           01234567890123456789  + Dark            Hello!      ABC           01234567890123456789  + The Boys        ABC           01234567890123456789  + The Last of Us  ABC           01234567890123456789  + Lost in Space   ABC           01234567890123456789  + Altered Carbon  ABC           01234567890123456789  + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height.svg new file mode 100644 index 0000000000..5f362bb6f1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoHeightRowsApp + + + + + + + + + +  N  Column      + 3  hey there   + 1  hey there   + 5  long        + string      + 2  ╭───────╮   + │ Hello │   + │ world │   + ╰───────╯   + 4  1           + 2           + 3           + 4           + 5           + 6           + 7           + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height_sorted.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height_sorted.svg new file mode 100644 index 0000000000..39b1d07c79 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_add_row_auto_height_sorted.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoHeightRowsApp + + + + + + + + + +  N  Column      + 1  hey there   + 2  ╭───────╮   + │ Hello │   + │ world │   + ╰───────╯   + 3  hey there   + 4  1           + 2           + 3           + 4           + 5           + 6           + 7           + 5  long        + string      + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_cell_padding.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_cell_padding.svg new file mode 100644 index 0000000000..162d68b81c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_cell_padding.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + + +one  two  three +valuevalueval   + + one    two    three  + value  value  val    + +  one      two      three   +  value    value    val     + +   one        two        three    +   value      value      val      + +    one          two          three     +    value        value        val       + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_change_cell_padding.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_change_cell_padding.svg new file mode 100644 index 0000000000..3937953149 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_change_cell_padding.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + + +one  two  three +valuevalueval   + + one    two    three  + value  value  val    + +  one      two      three   +  value    value    val     + +   one        two        three    +   value      value      val      + +          one                      two                      three           +          value                    value                    val             + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_column_cursor_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_column_cursor_render.svg new file mode 100644 index 0000000000..d302d7051a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_column_cursor_render.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 4     Joseph Schooling      Singapore      50.39  + 2     Michael Phelps        United States  51.14  + 5     Chad le Clos          South Africa   51.14  + 6     László Cseh           Hungary        51.14  + 3     Li Zhuhao             China          51.26  + 8     Mehdy Metella         France         51.58  + 7     Tom Shields           United States  51.73  + 1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_hot_reloading.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_hot_reloading.svg new file mode 100644 index 0000000000..71f4ec796d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_hot_reloading.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DataTableHotReloadingApp + + + + + + + + + +  A           B     + one         two   + three       four  + five        six   + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_labels_and_fixed_data.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_labels_and_fixed_data.svg new file mode 100644 index 0000000000..24bc0957a7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_labels_and_fixed_data.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 0  5     Chad le Clos          South Africa   51.14  + 1  4     Joseph Schooling      Singapore      50.39  + 2  2     Michael Phelps        United States  51.14  + 3  6     László Cseh           Hungary        51.14  + 4  3     Li Zhuhao             China          51.26  + 5  8     Mehdy Metella         France         51.58  + 6  7     Tom Shields           United States  51.73  + 7  10    Darren Burns          Scotland       51.84  + 8  1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_remove_row.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_remove_row.svg new file mode 100644 index 0000000000..66b2a25fda --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_remove_row.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 5     Chad le Clos          South Africa   51.14  + 4     Joseph Schooling      Singapore      50.39  + 6     László Cseh           Hungary        51.14  + 3     Li Zhuhao             China          51.26  + 7     Tom Shields           United States  51.73  + 10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_render.svg new file mode 100644 index 0000000000..9b91b0d930 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_render.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 4     Joseph Schooling      Singapore      50.39  + 2     Michael Phelps        United States  51.14  + 5     Chad le Clos          South Africa   51.14  + 6     László Cseh           Hungary        51.14  + 3     Li Zhuhao             China          51.26  + 8     Mehdy Metella         France         51.58  + 7     Tom Shields           United States  51.73  + 1     Aleksandr Sadovnikov  Russia         51.84  + 10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_row_cursor_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_row_cursor_render.svg new file mode 100644 index 0000000000..57ccf7bbf0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_row_cursor_render.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 4     Joseph Schooling      Singapore      50.39  + 2     Michael Phelps        United States  51.14  + 5     Chad le Clos          South Africa   51.14  + 6     László Cseh           Hungary        51.14  + 3     Li Zhuhao             China          51.26  + 8     Mehdy Metella         France         51.58  + 7     Tom Shields           United States  51.73  + 1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_sort_multikey.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_sort_multikey.svg new file mode 100644 index 0000000000..4231a82a62 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_sort_multikey.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   + 4     Joseph Schooling      Singapore      50.39  + 2     Michael Phelps        United States  51.14  + 5     Chad le Clos          South Africa   51.14  + 6     László Cseh           Hungary        51.14  + 3     Li Zhuhao             China          51.26  + 8     Mehdy Metella         France         51.58  + 7     Tom Shields           United States  51.73  + 1     Aleksandr Sadovnikov  Russia         51.84  + 10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_style_ordering.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_style_ordering.svg new file mode 100644 index 0000000000..e46b21e4c9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_datatable_style_ordering.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DataTableCursorStyles + + + + + + + + + + Foreground is 'css', background is 'css':                                        + Movies      + Severance   +Foundation +Dark + +Foreground is 'css', background is 'renderable':                                 + Movies      +Severance +Foundation +Dark + +Foreground is 'renderable', background is 'renderable':                          + Movies      +Severance +Foundation +Dark + +Foreground is 'renderable', background is 'css':                                 + Movies      +Severance +Foundation +Dark + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_demo.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_demo.svg new file mode 100644 index 0000000000..7f7a1c4577 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_demo.svg @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Textual Demo + + + + + + + + + + Textual Demo + + +TOP + +▆▆ + +Widgets +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + +Rich contentTextual Demo + +Welcome! Textual is a framework for creating sophisticated +applications with the terminal.                            +CSS +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Start  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + ^b Sidebar  ^t Toggle Dark mode  ^s Screenshot  f1 Notes  ^q Quit  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_digits.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_digits.svg new file mode 100644 index 0000000000..91fd49898b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_digits.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DigitApp + + + + + + + + + + ╺━┓  ┓ ╻ ╻╺━┓╺━┓                                                                 + ━┫  ┃ ┗━┫┏━┛  ┃                                                                 +╺━┛.╺┻╸  ╹┗━╸  ╹                                                                 +                      ┏━┓ ┓ ╺━┓╺━┓╻ ╻┏━╸┏━╸╺━┓┏━┓┏━┓                             +                      ┃ ┃ ┃ ┏━┛ ━┫┗━┫┗━┓┣━┓  ┃┣━┫┗━┫╺╋╸╺━╸                       +                      ┗━┛╺┻╸┗━╸╺━┛  ╹╺━┛┗━┛  ╹┗━┛╺━┛      .,                     +                                                              ╺━┓    ┓ ┏━┓ ^ ╻ ╻ +                                                               ━┫ ×  ┃ ┃ ┃   ┗━┫ +                                                              ╺━┛   ╺┻╸┗━┛     ╹ + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_directory_tree_reloading.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_directory_tree_reloading.svg new file mode 100644 index 0000000000..d2002a41a3 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_directory_tree_reloading.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DirectoryTreeReloadApp + + + + + + + + + + 📂 test_directory_tree_reloading0 +├── 📂 b1 +│   ├── 📂 c1 +│   │   ┣━━ 📂 d1 +│   │   ┃   ┣━━ 📄 f1.txt +│   │   ┃   ┗━━ 📄 f2.txt +│   │   ┣━━ 📄 f1.txt +│   │   ┗━━ 📄 f2.txt +│   ├── 📄 f1.txt +│   └── 📄 f2.txt +├── 📄 f1.txt +└── 📄 f2.txt + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_disabled_widgets.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_disabled_widgets.svg new file mode 100644 index 0000000000..2b0142c8c3 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_disabled_widgets.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidgetDisableTestApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  Button  Button  Button  Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_layout_sidebar.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_layout_sidebar.svg new file mode 100644 index 0000000000..18f0f51040 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_layout_sidebar.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DockLayoutExample + + + + + + + + + + Sidebar1Docking a widget removes it from the layout and  +fixes its position, aligned to either the top,  +right, bottom, or left edges of a container. + +Docked widgets will not scroll out of view,  +making them ideal for sticky headers, footers,  +and sidebars. +▇▇ +Docking a widget removes it from the layout and  +fixes its position, aligned to either the top,  +right, bottom, or left edges of a container. + +Docked widgets will not scroll out of view,  +making them ideal for sticky headers, footers,  +and sidebars. + +Docking a widget removes it from the layout and  +fixes its position, aligned to either the top,  +right, bottom, or left edges of a container. + +Docked widgets will not scroll out of view,  +making them ideal for sticky headers, footers,  +and sidebars. + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll.svg new file mode 100644 index 0000000000..a9e2b55665 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + TestApp +┌─────────┐ +this +is +a +sample +sentence +and +here +are +some +wordsthis +is +a +sample +sentence +and +here +are +some +words + ^q Quit  + + +▇▇ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll2.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll2.svg new file mode 100644 index 0000000000..f1da318f0e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll2.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + TestApp +┌─────────┐ +this +is +a +sample +sentence +and +here +are +some +wordsthis +is +a▅▅ +sample +sentence +and +here +are +some +words + ^q Quit  + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll_off_by_one.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll_off_by_one.svg new file mode 100644 index 0000000000..29851bc756 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dock_scroll_off_by_one.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollOffByOne + + + + + + + + + + ▔▔▔▔▔▔▔▔ +X 92 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 93 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 94 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 95 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 96 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 97 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 98 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 99▁▁ +▁▁▁▁▁▁▁▁ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_dynamic_bindings.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dynamic_bindings.svg new file mode 100644 index 0000000000..f758a9ddb4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_dynamic_bindings.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BindingsApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a  c  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_calculator.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_calculator.svg new file mode 100644 index 0000000000..a747b1a4fb --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_calculator.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CalculatorApp + + + + + + + + + + + +                                                                     ┏━┓ +                                                                     ┃ ┃ +                                                                     ┗━┛ + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + AC  +/-  %  ÷  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 7  8  9  ×  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 4  5  6  -  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  2  3  +  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_color_command.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_color_command.svg new file mode 100644 index 0000000000..46cf12347f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_color_command.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Press ctrl + \ and type a color + + + + + + + + + + Press ctrl + \ and type a color + + + + +ansi_red + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_dictionary.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_dictionary.svg new file mode 100644 index 0000000000..51abc39b86 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_dictionary.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DictionaryApp + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Search for a word +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_five_by_five.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_five_by_five.svg new file mode 100644 index 0000000000..dc94b9a913 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_five_by_five.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5x5 -- A little annoying puzzle + + + + + + + + + + 5x5 -- A little annoying puzzleMoves: 0Filled: 5 +╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ +││││││││ +││││││││ +╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ +╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ +││││ +││││ +╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ +╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ +││││ +││││ +││││ +╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ +╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ +││││ +││││ +╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ +╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ +││││││││ +││││││││ +││││││││ +╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ + n New Game  ? Help  q Quit  ^d Toggle Dark Mode  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_json_tree.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_json_tree.svg new file mode 100644 index 0000000000..3e998a5599 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_json_tree.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeApp + + + + + + + + + + TreeApp +▼ Root +└── ▼ {} JSON▁▁ +    ├── code='5060292302201' +    ├── ▼ {} product +    │   ┣━━ _id='5060292302201' +    │   ┣━━ ▶ [] _keywords +    │   ┣━━ ▶ [] added_countries_tags +    │   ┣━━ ▶ [] additives_debug_tags +    │   ┣━━ additives_n=2 +    │   ┣━━ additives_old_n=2 +    │   ┣━━ ▶ [] additives_old_tags +    │   ┣━━ ▶ [] additives_original_tags +    │   ┣━━ ▶ [] additives_prev_original_tags +    │   ┣━━ ▶ [] additives_tags +    │   ┣━━ additives_tags_n=None +    │   ┣━━ allergens='en:milk' +    │   ┣━━ ▶ [] allergens_debug_tags +    │   ┣━━ allergens_from_ingredients='en:milk, milk' +    │   ┣━━ allergens_from_user='(en) en:milk' +    │   ┣━━ ▶ [] allergens_hierarchy +    │   ┣━━ ▶ [] allergens_tags + + a Add node  c Clear  t Toggle root  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_markdown.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_markdown.svg new file mode 100644 index 0000000000..71590458dc --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_markdown.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownApp + + + + + + + + + + +▼ Ⅰ Textual Markdown Browser +└── Ⅱ Do You Want to Know More?Textual Markdown Browser + +  Welcome fellow adventurer! If you ran  +markdown.py from the terminal you are  +  viewing demo.md with Textual's built in      +  Markdown widget. + +  The widget supports much of the Markdown     +  spec. There is also an optional Table of     +  Contents sidebar which you will see to  +  your left. + + +Do You Want to Know More? + +  See example.md for more examples of what     +  this can do. + + + + + t TOC  b Back  f Forward  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_merlin.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_merlin.svg new file mode 100644 index 0000000000..d6a637bf6a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_merlin.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MerlinApp + + + + + + + + + + + +┏━┓   ┏━┓┏━┓   ┏━┓┏━┓ +┃ ┃ : ┃ ┃┃ ┃ : ┃ ┃┃ ┃ +┗━┛   ┗━┛┗━┛   ┗━┛┗━┛ + + +█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ + +    7         8         9      +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +    4         5         6      +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +    1         2         3      +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▇▇ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_pride.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_pride.svg new file mode 100644 index 0000000000..e74c86b7e0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_example_pride.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PrideApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_focus_component_class.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_focus_component_class.svg new file mode 100644 index 0000000000..4cb0bda893 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_focus_component_class.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyleBugApp + + + + + + + + + + StyleBugApp +test widget 0 +test widget 1 +test widget 2 +test widget 3 +test widget 4 +test widget 5 +test widget 6 +test widget 7 +test widget 8 +test widget 9 +test widget 10 +test widget 11 +test widget 12▇▇ +test widget 13 +test widget 14 +test widget 15 +test widget 16 +test widget 17 +test widget 18 +test widget 19 +test widget 20 +test widget 21 + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_classic_styling.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_classic_styling.svg new file mode 100644 index 0000000000..8aca569636 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_classic_styling.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ClassicFooterStylingApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CTRL+T  Toggle Dark mode  CTRL+Q  Quit                                          + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact.svg new file mode 100644 index 0000000000..de8382d4e2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                 Compact Footer                                  + + + + + + + + + + + +^t Toggle Compact Footer^q Quit + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact_with_hover.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact_with_hover.svg new file mode 100644 index 0000000000..fb387a3bb8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_compact_with_hover.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                 Compact Footer                                  + + + + + + + + + + + +^t Toggle Compact Footer^q Quit + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_render.svg new file mode 100644 index 0000000000..961c14856a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_render.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FooterApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + q Quit the app  ? Show help screen  delete Delete the thing  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_after_reactive_change.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_after_reactive_change.svg new file mode 100644 index 0000000000..728155ab38 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_after_reactive_change.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                Standard Footer                                  + + + + + + + + + + + + ^t Toggle Compact Footer  ^q Quit  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_with_hover.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_with_hover.svg new file mode 100644 index 0000000000..024a6e20ff --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_footer_standard_with_hover.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                Standard Footer                                  + + + + + + + + + + + + ^t Toggle Compact Footer  ^q Quit  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_margins.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_margins.svg new file mode 100644 index 0000000000..cafdde127e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_margins.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + +Hello + + + + + + +World + + + + + + +!! + + + + + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_unit_with_min.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_unit_with_min.svg new file mode 100644 index 0000000000..03eb831f80 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_unit_with_min.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScreenSplitApp + + + + + + + + + + ScreenSplitApp +This is content This is content number 0 +number 0This is content number 1 +This is content ▄▄This is content number 2 +number 1This is content number 3 +This is content This is content number 4▁▁ +number 2This is content number 5 +This is content This is content number 6 +number 3This is content number 7 +This is content This is content number 8 +number 4This is content number 9 +This is content This is content number 10 +number 5This is content number 11 +This is content This is content number 12 +number 6This is content number 13 +This is content This is content number 14 +number 7This is content number 15 +This is content This is content number 16 +number 8This is content number 17 +This is content This is content number 18 +number 9This is content number 19 +This is content This is content number 20 +number 10This is content number 21 + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_units.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_units.svg new file mode 100644 index 0000000000..ca28a8a00f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_fr_units.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FRApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +HEADER + + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +┏━━━━━━━━┓┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━┓ +foo┃┃bar┃┃baz +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┃┃┃┃ +┗━━━━━━━━┛┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━┛ +┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +FOOTER + +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_auto.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_auto.svg new file mode 100644 index 0000000000..aff19b696d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_auto.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌──┬──┬──┐ +abc +├──┼──┼──┤ +def +├──┼──┼──┤ +ghi +└──┴──┴──┘ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_gutter.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_gutter.svg new file mode 100644 index 0000000000..69ada7b31e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_gutter.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Demonstrator + + + + + + + + + + + +┌──────────────────────────────────────────────────────────┐ + +Information +━╸━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ +aaa naa aaaaa aaa aaaan, aaa aaa, aaaa?", aa aaa +aaaaanaaa anaaaaaaana aaaaaaaa aaaaaana aaa      +aaaaa aa aaa, aa aaaaaaaaa aaa aaaa, "aaaa, an   +aaaa aaa aaaa, a aa". "aaaa, naa aaaaaaaaaaa,    +aaa a aaaa aaaaaanaa aaaa aa a aaa!", aaa        +anaaaa, aaaaa aaaaaaaa aanaaaaa. "Na! aaa naa.   +aaaaa. aa aaaaa naa. aaaaa aa na aaa.", aaa      +aaaaaaaa aaaanaaaaa DONE.                        +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + +└──────────────────────────────────────────────────────────┘ + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic.svg new file mode 100644 index 0000000000..00f7b7ef98 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +One││Two││Three +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ +┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +Four││Five││Six +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic_overflow.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic_overflow.svg new file mode 100644 index 0000000000..27392e7013 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_basic_overflow.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +One││Two││Three +││││ +││││ +││││ +││││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ +┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +Four││Five││Six +││││ +││││ +││││ +││││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ +┌────────────────────────┐ +Seven + + + + + +└────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_gutter.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_gutter.svg new file mode 100644 index 0000000000..4b6ee26609 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_grid_layout_gutter.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + OneTwoThree + + + + + + + + + + + +FourFiveSix + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_hatch.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_hatch.svg new file mode 100644 index 0000000000..619ebeff55 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_hatch.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HatchApp + + + + + + + + + + ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──┌─ Hello World ────────────────────────────────────┐──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼Hatched┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳──└──────────────────────────────────────────────────┘──╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ +╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_header_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_header_render.svg new file mode 100644 index 0000000000..52fe30862b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_header_render.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeaderApp + + + + + + + + + + HeaderApp + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout.svg new file mode 100644 index 0000000000..584248458a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +One││Two││Three +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout_width_auto_dock.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout_width_auto_dock.svg new file mode 100644 index 0000000000..ab23af018d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_horizontal_layout_width_auto_dock.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalAutoWidth + + + + + + + + + + Docke +Widget 1Widget 2 +left  +1Docked left 2 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_and_focus.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_and_focus.svg new file mode 100644 index 0000000000..05a1abe5d0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_and_focus.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Darren                                                                     +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Burns +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg new file mode 100644 index 0000000000..300e433b20 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_percentage_width.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputVsTextArea + + + + + + + + + + 01234567890123456789012345678901234567890123456789012345678901234567890123456789 +┌──────────────────────────────────────┐ + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + + + +└──────────────────────────────────────┘ +┌──────────────────────────────────────┐ + + Button  + + +└──────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_suggestions.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_suggestions.svg new file mode 100644 index 0000000000..9830ab70fa --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_suggestions.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FruitsApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +strawberry +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +straw                                                                      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +p                                                                          +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +b                                                                          +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +a                                                                          +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_validation.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_validation.svg new file mode 100644 index 0000000000..424567d50b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_input_validation.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputApp + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +-2                                                                     +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +3                                                                      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +-2 +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Enter a number between 1 and 5 +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_key_display.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_key_display.svg new file mode 100644 index 0000000000..ac2445fade --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_key_display.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeyDisplayApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? Question  ^q Quit app  Escape! Escape  a Letter A  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_keyline.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_keyline.svg new file mode 100644 index 0000000000..20c2a6ac6a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_keyline.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +1 +├──────────────────────────────────────────────────────────────────────────────┤ +2 +├──────────────────────────────────────────────────────────────────────────────┤ +3 + +└──────────────────────────────────────────────────────────────────────────────┘ +┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +456 + + + + + +┗━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━┛ +╔══════════════════════════════════════╦═══════════════════════════════════════╗ +78 + +╠══════════════════════════════════════╬═══════════════════════════════════════╝ +9 + + +╚══════════════════════════════════════╝ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_label_widths.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_label_widths.svg new file mode 100644 index 0000000000..7c205911fa --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_label_widths.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LabelWrap + + + + + + + + + + + + + + + +Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix Ch + + +Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix  +Chimera Castle + + +╭────────────────────────────────────────────────────────────────────────────╮ +│ Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur       │ +│ Phoenix Chimera Castle                                                     │ +╰────────────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_layer_fix.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layer_fix.svg new file mode 100644 index 0000000000..088593488f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layer_fix.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DialogIssueApp + + + + + + + + + + DialogIssueApp + + + + + +╭──────────────────────────────────────╮ + + + + +This should not cause a scrollbar to a + + + + + +╰──────────────────────────────────────╯ + + + + + + d Toggle the dialog  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_layers.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layers.svg new file mode 100644 index 0000000000..b6154142c9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layers.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LayersExample + + + + + + + + + + + + + + + + + + + + +box1 (layer = above) + + + + + +box2 (layer = below) + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_layout_containers.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layout_containers.svg new file mode 100644 index 0000000000..7b41f1fb10 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_layout_containers.svg @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Accept  Decline  Accept  Decline  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Accept  Accept  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Decline  Decline  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▆ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +0                                 0 + +1000000                                 1000000                                + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_line_api_scrollbars.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_line_api_scrollbars.svg new file mode 100644 index 0000000000..a9693a3535 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_line_api_scrollbars.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollViewApp + + + + + + + + + + + +                                 11 01234567 +                                 12 01234567 +                                 13 01234567 +                                 14 01234567 +                                 15 01234567▁▁ +                                 16 01234567 +                                 17 01234567 +                                 18 01234567 +                                 19 01234567 + +                                 11 01234567 +                                 12 01234567 +                                 13 01234567 +                                 14 01234567 +                                 15 01234567▁▁ +                                 16 01234567 +                                 17 01234567 +                                 18 01234567 +                                 19 01234567 + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_list_view.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_list_view.svg new file mode 100644 index 0000000000..4c40c28214 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_list_view.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListViewExample + + + + + + + + + + + + + + + + + +One + + +Two + + +Three + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_listview_index.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_listview_index.svg new file mode 100644 index 0000000000..c23a152da1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_listview_index.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListViewIndexApp + + + + + + + + + + 10                                                                             +12                                                                             +14                                                                             +16                                                                            ▆▆ +18                                                                             +20                                                                             +22                                                                             +24                                                                             +26                                                                             +28                                                                             + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator.svg new file mode 100644 index 0000000000..f48c7961b0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayRedux + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo   ▄▄ +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +Loading!foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +foo barfoo barfoo barfoo barfoo    +bar                                +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator_disables_widget.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator_disables_widget.svg new file mode 100644 index 0000000000..8b6630e7cf --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_loading_indicator_disables_widget.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayRedux + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     ▄▄foo barfoo barfoo barfoo barfoo   ▄▄ +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +hello world hello world hello     foo barfoo barfoo barfoo barfoo    +world hello world hello world     bar                                +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write.svg new file mode 100644 index 0000000000..9b2ad63d6d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LogApp + + + + + + + + + + Hello, World!                                                                  +What's up?                                                                     +FOO                                                                            + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write_lines.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write_lines.svg new file mode 100644 index 0000000000..3ae6f4df21 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_log_write_lines.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LogApp + + + + + + + + + + I must not fear.  And when it has goHello, World      Fear is the mind-k +Fear is the mind-kWhere the fear hasFear is the little +Fear is the littleI must not fear.  I will face my fea +I will face my fea▁▁Fear is the mind-kI will permit it t +I will permit it tFear is the littleAnd when it has go +And when it has goI will face my feaWhere the fear has +Where the fear hasI will permit it t +I must not fear.  And when it has go +Fear is the mind-kWhere the fear has +Fear is the littleI must not fear.   +I will face my feaFear is the mind-k +I will permit it tFear is the little +And when it has goI will face my fea +Where the fear hasI will permit it t +I must not fear.  And when it has go +Fear is the mind-kWhere the fear has +Fear is the littleI must not fear.   +I will face my feaFear is the mind-k +I will permit it tFear is the little +And when it has goI will face my fea▇▇ +Where the fear hasI will permit it t +I must not fear.  And when it has go +Fear is the mind-kWhere the fear has + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_margin_multiple.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_margin_multiple.svg new file mode 100644 index 0000000000..6e733268c4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_margin_multiple.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╔═══╗ +foo +╚═══╝ + + +┌────────────────────────────┐ + + +┌────────────────────────────┐ + +╔═══╗ +bar +╔═══╗╚═══╝ +bar +╚═══╝ + + + +└────────────────────────────┘└────────────────────────────┘ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_component_classes_reloading.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_component_classes_reloading.svg new file mode 100644 index 0000000000..79ade0c652 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_component_classes_reloading.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + +This is a header + + +col1                                 col2                                 + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  + value 1                               value 2                               + +  Here's some code: from itertools import productBold textEmphasized text +strikethrough + + +print("Hello, world!") + + +That was some code. + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_dark_theme_override.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_dark_theme_override.svg new file mode 100644 index 0000000000..6d97d24d2d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_dark_theme_override.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + +This is a H1 + + +defmain(): +│   print("Hello world!") + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_example.svg new file mode 100644 index 0000000000..8f7056a116 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_example.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownExampleApp + + + + + + + + + + + +Markdown Document + +  This is an example of Textual's Markdown widget. + + +Features + +  Markdown syntax and extensions are supported. + +● Typography emphasisstronginline code etc. +● Headers +● Lists (bullet and ordered) +● Syntax highlighted code blocks +● Tables! + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_light_theme_override.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_light_theme_override.svg new file mode 100644 index 0000000000..cc0f9c9354 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_light_theme_override.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + +This is a H1 + + +defmain(): +│   print("Hello world!") + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_space_squashing.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_space_squashing.svg new file mode 100644 index 0000000000..252a429c7d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_space_squashing.svg @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownSpaceApp + + + + + + + + + + X XX XX X X X X X + +X XX XX X X X X X + +X XX X X X X X + +X XX X X X X X + +┌─────────────────────────────────────────────────────────────────────────────── + + +# Two spaces:  see? +classFoo: +│   '''This is    a doc    string.''' +│   some_code(1,2,3,4) + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_theme_switching.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_theme_switching.svg new file mode 100644 index 0000000000..36308066f8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_theme_switching.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + +This is a H1 + + +defmain(): +│   print("Hello world!") + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_viewer_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_viewer_example.svg new file mode 100644 index 0000000000..ec3fb4e8fe --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_markdown_viewer_example.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownExampleApp + + + + + + + + + + +▼ Ⅰ Markdown Viewer +├── Ⅱ FeaturesMarkdown Viewer +├── Ⅱ Tables +└── Ⅱ Code Blocks  This is an example of Textual's MarkdownViewer +  widget. + + +Features + +  Markdown syntax and extensions are supported. +▇▇ +● Typography emphasisstronginline code etc. +● Headers +● Lists (bullet and ordered) +● Syntax highlighted code blocks +● Tables! + + +Tables + +  Tables are displayed in a DataTable widget. + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_max_height_100.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_max_height_100.svg new file mode 100644 index 0000000000..8efdfa0102 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_max_height_100.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HappyDataTableFunApp + + + + + + + + + +  Column 0  Column 1  Column 2  Column 3  Column 4  Column 5  Column 6  Column  + 0         0         0         0         0         0         0         0       + 0         1         2         3         4         5         6         7       + 0         2         4         6         8         10        12        14      + 0         3         6         9         12        15        18        21      + 0         4         8         12        16        20        24        28     ▆▆ + 0         5         10        15        20        25        30        35      + 0         6         12        18        24        30        36        42      + 0         7         14        21        28        35        42        49      + 0         8         16        24        32        40        48        56      + 0         9         18        27        36        45        54        63      + 0         10        20        30        40        50        60        70      + 0         11        22        33        44        55        66        77      + 0         12        24        36        48        60        72        84      + 0         13        26        39        52        65        78        91      + 0         14        28        42        56        70        84        98      + 0         15        30        45        60        75        90        105     + 0         16        32        48        64        80        96        112     + 0         17        34        51        68        85        102       119     + 0         18        36        54        72        90        108       126     + 0         19        38        57        76        95        114       133     + 0         20        40        60        80        100       120       140     + 0         21        42        63        84        105       126       147     + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_missing_vertical_scroll.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_missing_vertical_scroll.svg new file mode 100644 index 0000000000..e73f83aaa4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_missing_vertical_scroll.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MissingScrollbarApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +0                  0                  ▎▊0                        +1                  1                  ▎▊1                        +2                  ▄▄2                  ▄▄▎▊2                       ▄▄ +3                  3                  ▎▊3                        +4                  4                  ▎▊4                        +5                  5                  ▎▊5                        +6                  6                  ▎▊6                        +7                  7                  ▎▊7                        +8                  8                  ▎▊8                        +9                  9                  ▎▊9                        +10                 10                 ▎▊10                       +11                 11                 ▎▊11                       +12                 12                 ▎▊12                       +13                 13                 ▎▊13                       +14                 14                 ▎▊14                       +15                 15                 ▎▊15                       +16                 16                 ▎▊16                       +17                 17                 ▎▊17                       +18                 18                 ▎▊18                       +19                 19                 ▎▊19                       +20                 20                 ▎▊20                       +21                 21                 ▎▊21                       +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings.svg new file mode 100644 index 0000000000..14b61de949 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + ModalApp +Hello                                                                            + + + + + + + + + + + + + + + + + + + + + + ⏎ Open Dialog  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings_input.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings_input.svg new file mode 100644 index 0000000000..867e40e35f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_modal_dialog_bindings_input.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + DialogModalApp +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +hi!                                                                        +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + OK  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + ⏎ Open Dialog  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_mount_style_fix.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_mount_style_fix.svg new file mode 100644 index 0000000000..1d8701a102 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_mount_style_fix.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BrokenClassesApp + + + + + + + + + + + + + + + +┌──────────────────────────────────────┐ +This should have a red background + + + + + + + + + +└──────────────────────────────────────┘ + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_multi_keys.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_multi_keys.svg new file mode 100644 index 0000000000..857d464e18 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_multi_keys.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + o Options  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_multiple_css.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_multiple_css.svg new file mode 100644 index 0000000000..8d84a41058 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_multiple_css.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MultipleCSSApp + + + + + + + + + + #one +#two + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_auto_heights.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_auto_heights.svg new file mode 100644 index 0000000000..b5e08f63d2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_auto_heights.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NestedAutoApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ +┏━━━━━━━━━━━━━━━┓ +┏━━━━━━━━━━━━━┓ +JUST ONE LINE +┗━━━━━━━━━━━━━┛ +┗━━━━━━━━━━━━━━━┛ +┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_fr.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_fr.svg new file mode 100644 index 0000000000..e7bc5cb1ec --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_fr.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +┌────────────────────────────────────────────────────────────────────────────┐ +Hello +World! +foo + + + + + + + + + + + + + + + + + +└────────────────────────────────────────────────────────────────────────────┘ +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_specificity.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_specificity.svg new file mode 100644 index 0000000000..867dc213f4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_nested_specificity.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NestedPseudoClassesApp + + + + + + + + + + ╭──────────────────────────────────────╮ +This isn't using nested CSSThis is using nested CSS + + + + + + + + + + + + + + + + + + + + + +╰──────────────────────────────────────╯ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link.svg new file mode 100644 index 0000000000..12f6df32ad --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyWithInlineLinkApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Click here for the bell sound. + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link_hover.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link_hover.svg new file mode 100644 index 0000000000..d0499cbd9c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notification_with_inline_link_hover.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyWithInlineLinkApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Click here for the bell sound. + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_example.svg new file mode 100644 index 0000000000..f1eb44ceaa --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_example.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToastApp + + + + + + + + + + + + + +It's an older code, sir, but it  +checks out. + + + +Possible trap detected +Now witness the firepower of this  +fully ARMED and OPERATIONAL battle  +station! + + + +It's a trap! + + + +It's against my programming to  +impersonate a deity. + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_loading_overlap_order.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_loading_overlap_order.svg new file mode 100644 index 0000000000..bb2c7a0deb --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_loading_overlap_order.svg @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayApp + + + + + + + + + + + + + + + + +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. +This is a big notification. + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_modes.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_modes.svg new file mode 100644 index 0000000000..07a312da7a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_modes.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyThroughModesApp + + + + + + + + + + This is a mode screen                   +4 + + + +5 + + + +6 + + + +7 + + + +8 + + + +9 + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_screens.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_screens.svg new file mode 100644 index 0000000000..5e9c172455 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_notifications_through_screens.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyDownScreensApp + + + + + + + + + + Screen 10                               +4 + + + +5 + + + +6 + + + +7 + + + +8 + + + +9 + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_offsets.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_offsets.svg new file mode 100644 index 0000000000..6e54315a6e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_offsets.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffsetsApp + + + + + + + + + + + + + + +┌──────────────┐ +FOO +BAR +BAZ +└──────────────┘ + + + + + +┌──────────────┐ +FOO +BAR +BAZ +└──────────────┘ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg new file mode 100644 index 0000000000..268f95964d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_build.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +One                   One                    ▎▊One                     +Two                   Two                    ▎▊Two                     +─────────────────────────────────────────────▎▊─────────────────────── +ThreeThree▎▊Three +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_options.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_options.svg new file mode 100644 index 0000000000..f102268923 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_options.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Aerilon                                            +Aquaria                                            +────────────────────────────────────────────────── +Canceron                                           +Caprica                                            +────────────────────────────────────────────────── +Gemenon                                            +────────────────────────────────────────────────── +Leonis                                             +Libran                                             +────────────────────────────────────────────────── +Picon                                             ▁▁ +────────────────────────────────────────────────── +Sagittaron                                         +Scorpia                                            +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_single_line.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_single_line.svg new file mode 100644 index 0000000000..b0beff6a8e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_single_line.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1. Another single line                                                       +2. Two                                                                       +lines                                                                        +3. Three                                                                     +lines                                                                        +of text                                                                      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_two_lines.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_two_lines.svg new file mode 100644 index 0000000000..b5c62a7150 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_single_line_to_two_lines.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1. Two                                                                       +lines                                                                        +2. Two                                                                       +lines                                                                        +3. Three                                                                     +lines                                                                        +of text                                                                      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_two_lines_to_three_lines.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_two_lines_to_three_lines.svg new file mode 100644 index 0000000000..071bf07a52 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_replace_prompt_from_two_lines_to_three_lines.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1. Single line                                                               +1. Three                                                                     +lines                                                                        +of text                                                                      +3. Three                                                                     +lines                                                                        +of text                                                                      +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_in_long_list.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_in_long_list.svg new file mode 100644 index 0000000000..99ab8b84f0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_in_long_list.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LongOptionListApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +This is option #78                                                         +This is option #79                                                         +This is option #80                                                         +This is option #81                                                         +This is option #82                                                         +This is option #83                                                         +This is option #84                                                         +This is option #85                                                         +This is option #86                                                         +This is option #87                                                         +This is option #88                                                         +This is option #89                                                         +This is option #90                                                         +This is option #91                                                         +This is option #92                                                         +This is option #93                                                         +This is option #94                                                         +This is option #95                                                        ▇▇ +This is option #96                                                         +This is option #97                                                         +This is option #98                                                         +This is option #99                                                         +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_with_multiline_options.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_with_multiline_options.svg new file mode 100644 index 0000000000..6fe417ce7a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_scrolling_with_multiline_options.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ +│ Dionysus      │ 450 Million   │ Celeste        │ +└───────────────┴───────────────┴────────────────┘ +                 Data for Tauron                   +┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + Patron God     Population     Capital City    +┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ +│ Ares          │ 2.5 Billion   │ Hypatia        │ +└───────────────┴───────────────┴────────────────┘ +                 Data for Virgon                   +┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +┃ Patron God    ┃ Population    ┃ Capital City   ┃▁▁ +┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ +│ Hestia        │ 4.3 Billion   │ Boskirk        │ +└───────────────┴───────────────┴────────────────┘ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_strings.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_strings.svg new file mode 100644 index 0000000000..a3758abe96 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_strings.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Aerilon                                              +Aquaria                                              +Canceron                                             +Caprica                                              +Gemenon                                              +Leonis                                               +Libran                                               +Picon                                                +Sagittaron                                           +Scorpia                                              +Tauron                                               +Virgon                                               + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_tables.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_tables.svg new file mode 100644 index 0000000000..dd979c807d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_option_list_tables.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +                 Data for Aerilon                  +┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +┃ Patron God    ┃ Population    ┃ Capital City   ┃ +┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩▇▇ +│ Demeter       │ 1.2 Billion   │ Gaoth          │ +└───────────────┴───────────────┴────────────────┘ +                 Data for Aquaria                  +┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + Patron God     Population     Capital City    +┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ +│ Hermes        │ 75,000        │ None           │ +└───────────────┴───────────────┴────────────────┘ +                Data for Canceron                  +┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + Patron God     Population     Capital City    +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence.svg new file mode 100644 index 0000000000..19d403ac07 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layers + + + + + + + + + + ┌──────────────────────────────────┐Layers +It's full of stars! My God! It's full of sta + +This should float over the top + + +└──────────────────────────────────┘ + + + + + + + + + + + + + + + + + t Toggle Screen  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence_toggle.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence_toggle.svg new file mode 100644 index 0000000000..2c49b98956 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_order_independence_toggle.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layers + + + + + + + + + + ┌──────────────────────────────────┐Layers +It's full of stars! My God! It's full of sta + +This should float over the top + + +└──────────────────────────────────┘ + + + + + + + + + + + + + + + + + t Toggle Screen  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_pilot_resize_terminal.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_pilot_resize_terminal.svg new file mode 100644 index 0000000000..d4de0257af --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_pilot_resize_terminal.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SingleLabelApp + + + + + + + + + + 12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 +12345678901234567890 + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_disabled.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_disabled.svg new file mode 100644 index 0000000000..5c7eaf387b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_disabled.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DisabledPlaceholderApp + + + + + + + + + + + + + + +Placeholder + + + + + + + + + + + +Placeholder + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_render.svg new file mode 100644 index 0000000000..217b67393b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_placeholder_render.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PlaceholderApp + + + + + + + + + + +Placeholder p2 here! +This is a custom label for p1. +#p4 +#p3#p5Placeholde +r + +Lorem ipsum dolor sit  +26 x 6amet, consectetur 27 x 6 +adipiscing elit. Etiam  +feugiat ac elit sit amet  + + +Lorem ipsum dolor sit amet,  +consectetur adipiscing elit. Etiam 40 x 6 +feugiat ac elit sit amet accumsan.  +Suspendisse bibendum nec libero quis  +gravida. Phasellus id eleifend ligula. +Nullam imperdiet sem tellus, sed  +vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  +Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  +lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  +sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_pretty_grid_gutter_interaction.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_pretty_grid_gutter_interaction.svg new file mode 100644 index 0000000000..7bb8976a31 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_pretty_grid_gutter_interaction.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ['This is a string that has some chars'] + +This should be 1 cell away from ^ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_print_capture.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_print_capture.svg new file mode 100644 index 0000000000..6eb34a464b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_print_capture.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CaptureApp + + + + + + + + + + RichLog                                                                        +This will be captured!                                                         + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_disable_button.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_disable_button.svg new file mode 100644 index 0000000000..a5f880f96c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_disable_button.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ExampleApp + + + + + + + + + + + + + + + + + + +                        Hover the button then hit space                          +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Disabled  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + SPACE Toggle Button  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_scrollbar_gutter_change.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_scrollbar_gutter_change.svg new file mode 100644 index 0000000000..9ff3ee6d0d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_programmatic_scrollbar_gutter_change.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProgrammaticScrollbarGutterChange + + + + + + + + + + onetwo + + + + + + + + + + + +threefour + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed.svg new file mode 100644 index 0000000000..2957e976d6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:--                  + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed_styled.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed_styled.svg new file mode 100644 index 0000000000..79776ad8bc --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_completed_styled.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:-- + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway.svg new file mode 100644 index 0000000000..0f34d4caa0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + +━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07                  + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway_styled.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway_styled.svg new file mode 100644 index 0000000000..997b56d518 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_halfway_styled.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + +━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07 + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate.svg new file mode 100644 index 0000000000..4d4def25a8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + +━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:--                  + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate_styled.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate_styled.svg new file mode 100644 index 0000000000..1d2fc0c1c7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_bar_indeterminate_styled.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + +━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:-- + + + + + + + + + + + + s Start  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_gradient.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_gradient.svg new file mode 100644 index 0000000000..9d53e59bf7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_progress_gradient.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProgressApp + + + + + + + + + + ╺━━━━━━━━━━━━━━━50%--:--:--                                   + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_quickly_change_tabs.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_quickly_change_tabs.svg new file mode 100644 index 0000000000..ee81072079 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_quickly_change_tabs.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QuicklyChangeTabsApp + + + + + + + + + + +onetwothree +━━━━━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +three                                                                        + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_button_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_button_example.svg new file mode 100644 index 0000000000..8fd257a2bb --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_button_example.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RadioChoicesApp + + + + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Battlestar Galactica + Dune 1984 + Dune 2021 + Serenity + Star Trek: The Motion Picture + Star Wars: A New Hope + The Last Starfighter + Total Recall 👉 🔴 + Wing Commander +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_set_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_set_example.svg new file mode 100644 index 0000000000..4429f4ad44 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_radio_set_example.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RadioChoicesApp + + + + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Battlestar Galactica Amanda + Dune 1984 Connor MacLeod + Dune 2021 Duncan MacLeod + Serenity Heather MacLeod + Star Trek: The Motion Pictur Joe Dawson + Star Wars: A New Hope Kurgan, The + The Last Starfighter Methos + Total Recall 👉 🔴 Rachel Ellenstein + Wing Commander Ramírez +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose.svg new file mode 100644 index 0000000000..3feef6016d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RecomposeApp + + + + + + + + + + ┌─────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐ + ┓ ┏━┓   ││ ┓  ┓    ││ ┓ ╺━┓    ││ ┓ ╺━┓   ││ ┓ ╻ ╻    ││ ┓ ┏━╸   ││ ┓ ┏━╸     + ┃ ┃ ┃   ││ ┃  ┃    ││ ┃ ┏━┛    ││ ┃  ━┫   ││ ┃ ┗━┫    ││ ┃ ┗━┓   ││ ┃ ┣━┓     +╺┻╸┗━┛   ││╺┻╸╺┻╸   ││╺┻╸┗━╸    ││╺┻╸╺━┛   ││╺┻╸  ╹    ││╺┻╸╺━┛   ││╺┻╸┗━┛     +└─────────┘└─────────┘└──────────┘└─────────┘└──────────┘└─────────┘└──────────┘ + + + + + + + +━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━50%                                            + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose_in_mount.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose_in_mount.svg new file mode 100644 index 0000000000..690eff0e7d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_recompose_in_mount.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ForecastApp + + + + + + + + + + ForecastApp + Profile  +▔▔▔▔▔▔▔▔▔▔ +Foo + Bar +▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_with_auto_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_with_auto_height.svg new file mode 100644 index 0000000000..b185462e54 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_with_auto_height.svg @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalRemoveApp + + + + + + + + + + VerticalRemoveApp +╭──────────────────────────────────────────────────────────────────────────────╮ +╭────────────────────╮ +│This is a test label│ +╰────────────────────╯ +╰──────────────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + + + + + + + + + a Add  d Delete  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_max_lines.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_max_lines.svg new file mode 100644 index 0000000000..45946c7a20 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_max_lines.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogLines + + + + + + + + + + Key press #3                                                                   +Key press #4                                                                   +Key press #5                                                                   + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_scroll.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_scroll.svg new file mode 100644 index 0000000000..4c8c7265e8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_scroll.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogScrollApp + + + + + + + + + + Line 0                  Line 10                  Line 0                    +Line 1                  Line 11                  Line 1                    +Line 2                  Line 12                  Line 2                    +Line 3                  Line 13                  Line 3                    +Line 4                  Line 14                  Line 4                    +Line 5                  Line 15                  Line 5                    +Line 6                  Line 16                  Line 6                    +Line 7                  Line 17                  Line 7                    +Line 8                  Line 18                  Line 8                    +Line 9                  Line 19                  Line 9                    + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_width.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_width.svg new file mode 100644 index 0000000000..c64a707297 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_richlog_width.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogWidth + + + + + + + + + +               hello1 +              world2 +              hello3 +              world4 + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_horizontal_rules.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_horizontal_rules.svg new file mode 100644 index 0000000000..d7150a30be --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_horizontal_rules.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalRulesApp + + + + + + + + + +                                 solid (default)                                  + +──────────────────────────────────────────────────────────────── + +                                     heavy                                       + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +                                     thick                                       + +████████████████████████████████████████████████████████████████ + +                                     dashed                                      + +╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + +                                     double                                      + +════════════════════════════════════════════════════════════════ + +                                     ascii                                       + +---------------------------------------------------------------- + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_vertical_rules.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_vertical_rules.svg new file mode 100644 index 0000000000..b380c96693 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rule_vertical_rules.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalRulesApp + + + + + + + + + + + +       solid     heavy     thick     dashed    double    ascii   | +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_rules.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rules.svg new file mode 100644 index 0000000000..dc6d001fec --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_rules.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuleApp + + + + + + + + + + +-------------------------------------------------------------------------------- + + + +╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + +════════════════════════════════════════════════════════════════════════════════ + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + +| +| +| +| +| +| +| +| +| +| +| +| + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scoped_css.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scoped_css.svg new file mode 100644 index 0000000000..53e94b9473 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scoped_css.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +┌───┐ +foo +└───┘ +┌───┐ +bar +└───┘ +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +┌───┐ +foo +└───┘ +┌───┐ +bar +└───┘ +└──────────────────────────────────────────────────────────────────────────────┘ +I should not be styled                                                           + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_screen_switch.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_screen_switch.svg new file mode 100644 index 0000000000..2e56abcfe4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_screen_switch.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + ModalApp +B + + + + + + + + + + + + + + + + + + + + + + a Push screen A  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to.svg new file mode 100644 index 0000000000..fab552999e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to.svg @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollOffByOne + + + + + + + + + + ▔▔▔▔▔▔▔▔ +X 43 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 44 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 45 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 46▄▄ +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▃▃ +X 47 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 48 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 49 +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +X 50 +▁▁▁▁▁▁▁▁ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to_center.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to_center.svg new file mode 100644 index 0000000000..8774ce84c8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_to_center.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + SPAM                                                                           +╭────────────────────────────────────────────────────────────────────────────╮ +SPAM                                                                       +SPAM                                                                       +SPAM                                                                       +SPAM                                                                       +SPAM                                                                       +SPAM                                                                       +SPAM                                                                       +SPAM                                                                      ▁▁ +╭────────────────────────────────────────────────────────────────────────╮ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>>bullseye<<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +▄▄ +▄▄ + + + + + + +╰────────────────────────────────────────────────────────────────────────────╯ +SPAM                                                                           +SPAM                                                                           + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible.svg new file mode 100644 index 0000000000..aa74e006ab --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + | +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +|▆▆ +| +| +| +| +SHOULD BE VISIBLE + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible_with_margin.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible_with_margin.svg new file mode 100644 index 0000000000..b5cae97465 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scroll_visible_with_margin.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollVisibleMargin + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (19)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (20)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (21)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▅▅ + Hello, world! (22)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (23)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (24)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (25)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Hello, world! (26)  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_scrollbar_thumb_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scrollbar_thumb_height.svg new file mode 100644 index 0000000000..e8b4f257fc --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_scrollbar_thumb_height.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollViewTester + + + + + + + + + + ScrollViewTester +╭─ 1 ──────────────────────────────────────────────────────────────────────────╮ +Welcome to line 980                                                          +Welcome to line 981                                                          +Welcome to line 982                                                          +Welcome to line 983                                                          +Welcome to line 984                                                          +Welcome to line 985                                                          +Welcome to line 986                                                          +Welcome to line 987                                                          +Welcome to line 988                                                          +Welcome to line 989                                                          +Welcome to line 990                                                          +Welcome to line 991                                                          +Welcome to line 992                                                          +Welcome to line 993                                                          +Welcome to line 994                                                          +Welcome to line 995                                                          +Welcome to line 996                                                          +Welcome to line 997                                                          +Welcome to line 998                                                          +Welcome to line 999                                                          +╰──────────────────────────────────────────────────────────────────────────────╯ + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select.svg new file mode 100644 index 0000000000..41d8d65cb1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded.svg new file mode 100644 index 0000000000..59ff86684e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select + I must not fear.                                        + Fear is the mind-killer.                                + Fear is the little-death that brings total              + obliteration.                                           + I will face my fear.                                    + I will permit it to pass over me and through me.        +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded_changed.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded_changed.svg new file mode 100644 index 0000000000..c53af470a9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_expanded_changed.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + I must not fear. + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I must not fear. +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_from_values_expanded.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_from_values_expanded.svg new file mode 100644 index 0000000000..59ff86684e --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_from_values_expanded.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select + I must not fear.                                        + Fear is the mind-killer.                                + Fear is the little-death that brings total              + obliteration.                                           + I will face my fear.                                    + I will permit it to pass over me and through me.        +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_no_blank_has_default_value.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_no_blank_has_default_value.svg new file mode 100644 index 0000000000..c53af470a9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_no_blank_has_default_value.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + I must not fear. + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I must not fear. +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_rebuild.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_rebuild.svg new file mode 100644 index 0000000000..c282635f15 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_rebuild.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectRebuildApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Select + This                                                                        + Should                                                                      + Be                                                                          + What                                                                        + Goes                                                                        + Into                                                                        + The                                                                         + Snapshit                                                                    +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_set_options.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_set_options.svg new file mode 100644 index 0000000000..00a21d8c2c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_select_set_options.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + Twinkle, twinkle, little star, + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +Twinkle, twinkle, little star, +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selected.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selected.svg new file mode 100644 index 0000000000..09cf6fc436 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selected.svg @@ -0,0 +1,160 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + +┌─ Shall we play some games? ──┐┌─ Selected games ─────────────┐ +[ +X Falken's Maze           'secret_back_door', +X Black Jack              'a_nice_game_of_chess', +X Gin Rummy               'fighter_combat' +X Hearts                  ] +X Bridge                  └──────────────────────────────┘ +X Checkers                 +X Chess                    +X Poker                    +X Fighter Combat           + +└──────────────────────────────┘ + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selections.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selections.svg new file mode 100644 index 0000000000..bc45f727c7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_selections.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + +┌─ Shall we play some games? ──────────────────────────────────┐ + +X Falken's Maze                                            +X Black Jack                                               +X Gin Rummy                                                +X Hearts                                                   +X Bridge                                                   +X Checkers                                                 +X Chess                                                    +X Poker                                                    +X Fighter Combat                                           + + + + + +└──────────────────────────────────────────────────────────────┘ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_tuples.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_tuples.svg new file mode 100644 index 0000000000..bc45f727c7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_selection_list_tuples.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + +┌─ Shall we play some games? ──────────────────────────────────┐ + +X Falken's Maze                                            +X Black Jack                                               +X Gin Rummy                                                +X Hearts                                                   +X Bridge                                                   +X Checkers                                                 +X Chess                                                    +X Poker                                                    +X Fighter Combat                                           + + + + + +└──────────────────────────────────────────────────────────────┘ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_sort_children.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sort_children.svg new file mode 100644 index 0000000000..29c3f1cc0b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sort_children.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SortApp + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +5││1││5 +│└─────────────────────────┘│ +│┌─────────────────────────┐│ +││2││ +││││ +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ +┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ +1││3││4 +└────────────────────────┘│││ +┌────────────────────────┐│││ +3│└─────────────────────────┘│ +│┌─────────────────────────┐└─────────────────────────┘ +││4│┌─────────────────────────┐ +└────────────────────────┘│││3 +┌────────────────────────┐│││ +2││││ +│└─────────────────────────┘└─────────────────────────┘ +└────────────────────────┘┌─────────────────────────┐┌─────────────────────────┐ +┌────────────────────────┐│5││2 +4││││ +│││└─────────────────────────┘ +│││┌─────────────────────────┐ +││││1 +└────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_component_classes_colors.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_component_classes_colors.svg new file mode 100644 index 0000000000..3d0ea29ffa --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_component_classes_colors.svg @@ -0,0 +1,701 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SparklineColorsApp + + + + + + + + + + +▇▇▇▇▇ + +▇▇▇▇▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇▇█▇ + +▇▇▇▇▇▇ + +▇▇▇▇▇▇▇█▇ + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_render.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_render.svg new file mode 100644 index 0000000000..244d0b305b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_sparkline_render.svg @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SparklineSummaryFunctionApp + + + + + + + + + + + + + + +▂▂▁▁ + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_switches.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_switches.svg new file mode 100644 index 0000000000..e8f8b44199 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_switches.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SwitchApp + + + + + + + + + + + + + +Example switches + + +▔▔▔▔▔▔▔▔ +                              off:      +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +                              on:       +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +                              focused:  +▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔ +                              custom:   +▁▁▁▁▁▁▁▁ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tab_rename.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tab_rename.svg new file mode 100644 index 0000000000..94a9423397 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tab_rename.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabRenameApp + + + + + + + + + + +This is a much longer label for the tab011222333344444 +━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +TabPane#test + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content.svg new file mode 100644 index 0000000000..599c6b7981 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabbedApp + + + + + + + + + + +LetoJessicaPaul +━━━━━━━━╸━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + +Lady Jessica + +  Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + +PaulAlia +━╸━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +First child                                                              + + + + + + + + l Leto  j Jessica  p Paul  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_styling_not_leaking.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_styling_not_leaking.svg new file mode 100644 index 0000000000..8c5993fa98 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_styling_not_leaking.svg @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabbedContentStyleLeakTestApp + + + + + + + + + + +Leak Test +━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +This label should come first                                                 +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This button should come second  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +TheseTabsShouldComeLast +━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_with_modified_tabs.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_with_modified_tabs.svg new file mode 100644 index 0000000000..7decd76cab --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabbed_content_with_modified_tabs.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FiddleWithTabsApp + + + + + + + + + + +Tab 1Tab 2Tab 4Tab 5 +━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Button  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_table_markup.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_table_markup.svg new file mode 100644 index 0000000000..13ec437aa2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_table_markup.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableStaticApp + + + + + + + + + + ┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┓ +Foo Bar     baz        +┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━┩ +│ Hello World! │ Italic │ Underline │ +└──────────────┴────────┴───────────┘ + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabs_invalidate.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabs_invalidate.svg new file mode 100644 index 0000000000..e74e28a543 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tabs_invalidate.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabApp + + + + + + + + + + +Tab 1Tab 2 +━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +┌──────────────────────────────────────────────────────────────────────────────┐ + +world                                                                      + +└──────────────────────────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg new file mode 100644 index 0000000000..466369e9a5 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_alternate_screen.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TABug + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ +foo                                          +bar                                          +baz                                          + + + + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[bash].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[bash].svg new file mode 100644 index 0000000000..486c5005e7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[bash].svg @@ -0,0 +1,475 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  #!/bin/bash +  2   +  3  # Variables +  4  name="John" +  5  age=30                                                                  +  6  is_student=true                                                         +  7   +  8  # Printing variables +  9  echo"Hello, $name! You are $age years old." + 10   + 11  # Conditional statements + 12  if [[ $age -ge 18 &&$is_student == true ]]; then + 13  echo"You are an adult student." + 14  elif [[ $age -ge 18 ]]; then + 15  echo"You are an adult." + 16  else + 17  echo"You are a minor." + 18  fi + 19   + 20  # Arrays + 21  numbers=(1 2 3 4 5)                                                     + 22  echo"Numbers: ${numbers[@]}" + 23   + 24  # Loops + 25  for num in"${numbers[@]}"do + 26  echo"Number: $num" + 27  done + 28   + 29  # Functions + 30  greet() {                                                               + 31    local name=$1                                                         + 32  echo"Hello, $name!" + 33  }                                                                       + 34  greet"Alice" + 35   + 36  # Command substitution + 37  current_date=$(date +%Y-%m-%d)                                          + 38  echo"Current date: $current_date" + 39   + 40  # File operations + 41  touch file.txt                                                          + 42  echo"Some content"> file.txt                                          + 43  cat file.txt                                                            + 44   + 45  # Conditionals with file checks + 46  if [[ -f file.txt ]]; then + 47  echo"file.txt exists." + 48  else + 49  echo"file.txt does not exist." + 50  fi + 51   + 52  # Case statement + 53  case$age in + 54    18)                                                                   + 55  echo"You are 18 years old." + 56      ;;                                                                  + 57    30)                                                                   + 58  echo"You are 30 years old." + 59      ;;                                                                  + 60    *)                                                                    + 61  echo"You are neither 18 nor 30 years old." + 62      ;;                                                                  + 63  esac + 64   + 65  # While loop + 66  counter=0                                                               + 67  while [[ $counter -lt 5 ]]; do + 68  echo"Counter: $counter" + 69    ((counter++))                                                         + 70  done + 71   + 72  # Until loop + 73  until [[ $counter -eq 0 ]]; do + 74  echo"Counter: $counter" + 75    ((counter--))                                                         + 76  done + 77   + 78  # Heredoc + 79  cat << EOF + 80  This is a heredoc.  + 81  It allows you to write multiple lines of text.  + 82  EOF  + 83   + 84  # Redirection + 85  ls> file_list.txt                                                      + 86  grep"file" file_list.txt > filtered_list.txt                           + 87   + 88  # Pipes + 89  cat file_list.txt |wc -l                                               + 90   + 91  # Arithmetic operations + 92  result=$((10 + 5))                                                      + 93  echo"Result: $result" + 94   + 95  # Exporting variables + 96  export DB_PASSWORD="secret" + 97   + 98  # Sourcing external files + 99  source config.sh                                                        +100   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[css].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[css].svg new file mode 100644 index 0000000000..195da1ae02 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[css].svg @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  /* This is a comment in CSS */ + 2   + 3  /* Basic selectors and properties */ + 4  body {                                                                   + 5      font-family: Arial, sans-serif;                                      + 6      background-color: #f4f4f4;                                           + 7      margin: 0;                                                           + 8      padding: 0;                                                          + 9  }                                                                        +10   +11  /* Class and ID selectors */ +12  .header {                                                                +13      background-color: #333;                                              +14      color: #fff;                                                         +15      padding: 10px0;                                                     +16      text-align: center;                                                  +17  }                                                                        +18   +19  #logo {                                                                  +20      font-size: 24px;                                                     +21      font-weight: bold;                                                   +22  }                                                                        +23   +24  /* Descendant and child selectors */ +25  .nav ul {                                                                +26      list-style-type: none;                                               +27      padding: 0;                                                          +28  }                                                                        +29   +30  .nav > li {                                                              +31      display: inline-block;                                               +32      margin-right: 10px;                                                  +33  }                                                                        +34   +35  /* Pseudo-classes */ +36  a:hover {                                                                +37      text-decoration: underline;                                          +38  }                                                                        +39   +40  input:focus {                                                            +41      border-color: #007BFF;                                               +42  }                                                                        +43   +44  /* Media query */ +45  @media (max-width: 768px) {                                              +46      body {                                                               +47          font-size: 16px;                                                 +48      }                                                                    +49   +50      .header {                                                            +51          padding: 5px0;                                                  +52      }                                                                    +53  }                                                                        +54   +55  /* Keyframes animation */ +56  @keyframes slideIn {                                                     +57  from {                                                               +58          transform: translateX(-100%);                                    +59      }                                                                    +60  to {                                                                 +61          transform: translateX(0);                                        +62      }                                                                    +63  }                                                                        +64   +65  .slide-in-element {                                                      +66      animation: slideIn 0.5s forwards;                                    +67  }                                                                        +68   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[go].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[go].svg new file mode 100644 index 0000000000..c7828de87a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[go].svg @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  package main                                                             + 2   + 3  import (                                                                 + 4  "fmt" + 5  "math" + 6  "strings" + 7  )                                                                        + 8   + 9  const PI =3.14159 +10   +11  type Shape interface {                                                   +12      Area() float64                                                       +13  }                                                                        +14   +15  type Circle struct {                                                     +16      Radius float64                                                       +17  }                                                                        +18   +19  func (c Circle) Area() float64 {                                         +20  return PI * c.Radius * c.Radius                                      +21  }                                                                        +22   +23  funcmain() {                                                            +24  var name string ="John" +25      age :=30 +26      isStudent :=true +27   +28      fmt.Printf("Hello, %s! You are %d years old.", name, age)            +29   +30  if age >=18&& isStudent {                                          +31          fmt.Println("You are an adult student.")                         +32      } elseif age >=18 {                                                +33          fmt.Println("You are an adult.")                                 +34      } else {                                                             +35          fmt.Println("You are a minor.")                                  +36      }                                                                    +37   +38      numbers := []int{12345}                                      +39      sum :=0 +40  for _, num :=range numbers {                                        +41          sum += num                                                       +42      }                                                                    +43      fmt.Printf("The sum is: %d", sum)                                    +44   +45      message :="Hello, World!" +46      uppercaseMessage := strings.ToUpper(message)                         +47      fmt.Println(uppercaseMessage)                                        +48   +49      circle := Circle{Radius: 5}                                          +50      fmt.Printf("Circle area: %.2f", circle.Area())                       +51   +52      result :=factorial(5)                                               +53      fmt.Printf("Factorial of 5: %d", result)                             +54   +55  defer fmt.Println("Program finished.")                               +56   +57      sqrt :=func(x float64) float64 {                                    +58  return math.Sqrt(x)                                              +59      }                                                                    +60      fmt.Printf("Square root of 16: %.2f"sqrt(16))                      +61  }                                                                        +62   +63  funcfactorial(n int) int {                                              +64  if n ==0 {                                                          +65  return1 +66      }                                                                    +67  return n *factorial(n-1)                                            +68  }                                                                        +69   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[html].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[html].svg new file mode 100644 index 0000000000..b9ca8fc500 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[html].svg @@ -0,0 +1,303 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  <!DOCTYPE html>                                                          + 2  <html lang="en">                                                         + 3   + 4  <head>                                                                   + 5  <!-- Meta tags --> + 6      <meta charset="UTF-8">                                               + 7      <meta name="viewport" content="width=device-width, initial-scale=1.0 + 8  <!-- Title --> + 9      <title>HTML Test Page</title>                                        +10  <!-- Link to CSS --> +11      <link rel="stylesheet" href="styles.css">                            +12  </head>                                                                  +13   +14  <body>                                                                   +15  <!-- Header section --> +16      <header class="header">                                              +17          <h1 id="logo">HTML Test Page</h1>                                +18      </header>                                                            +19   +20  <!-- Navigation --> +21      <nav class="nav">                                                    +22          <ul>                                                             +23              <li><a href="#">Home</a></li>                                +24              <li><a href="#">About</a></li>                               +25              <li><a href="#">Contact</a></li>                             +26          </ul>                                                            +27      </nav>                                                               +28   +29  <!-- Main content area --> +30      <main>                                                               +31          <article>                                                        +32              <h2>Welcome to the Test Page</h2>                            +33              <p>This is a paragraph to test the HTML structure.</p>       +34              <img src="test-image.jpg" alt="Test Image" width="300">      +35          </article>                                                       +36      </main>                                                              +37   +38  <!-- Form --> +39      <section>                                                            +40          <form action="/submit" method="post">                            +41              <label for="name">Name:</label>                              +42              <input type="text" id="name" name="name">                    +43              <input type="submit" value="Submit">                         +44          </form>                                                          +45      </section>                                                           +46   +47  <!-- Footer --> +48      <footer>                                                             +49          <p>&copy; 2023 HTML Test Page</p>                                +50      </footer>                                                            +51   +52  <!-- Script tag --> +53      <script src="scripts.js"></script>                                   +54  </body>                                                                  +55   +56  </html>                                                                  +57   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[java].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[java].svg new file mode 100644 index 0000000000..fa72e80287 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[java].svg @@ -0,0 +1,493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  import java.util.ArrayList;                                             +  2  import java.util.HashMap;                                               +  3  import java.util.List;                                                  +  4  import java.util.Map;                                                   +  5   +  6  // Classes and interfaces +  7  interface Shape {                                                       +  8      double getArea();                                                   +  9  }                                                                       + 10   + 11  class Rectangle implements Shape {                                      + 12  private double width;                                               + 13  private double height;                                              + 14   + 15  public Rectangle(double width, double height) {                     + 16          this.width = width;                                             + 17          this.height = height;                                           + 18      }                                                                   + 19   + 20  @Override                                                           + 21  public double getArea() {                                           + 22  return width * height;                                          + 23      }                                                                   + 24  }                                                                       + 25   + 26  // Enums + 27  enum DaysOfWeek {                                                       + 28      MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY      + 29  }                                                                       + 30   + 31  publicclass Main {                                                     + 32  // Constants + 33  privatestaticfinal double PI = 3.14159;                           + 34   + 35  // Methods + 36  publicstatic int sum(int a, int b) {                               + 37  return a + b;                                                   + 38      }                                                                   + 39   + 40  publicstatic void main(String[] args) {                            + 41  // Variables + 42          String name = "John";                                           + 43          int age = 30;                                                   + 44          boolean isStudent = true;                                       + 45   + 46  // Printing variables + 47          System.out.println("Hello, " + name + "! You are " + age + " ye + 48   + 49  // Conditional statements + 50  if (age >= 18 && isStudent) {                                   + 51              System.out.println("You are an adult student.");            + 52          } elseif (age >= 18) {                                         + 53              System.out.println("You are an adult.");                    + 54          } else {                                                        + 55              System.out.println("You are a minor.");                     + 56          }                                                               + 57   + 58  // Arrays + 59          int[] numbers = {12345};                                + 60          System.out.println("Numbers: " + Arrays.toString(numbers));     + 61   + 62  // Lists + 63          List<String> fruits = new ArrayList<>();                        + 64          fruits.add("apple");                                            + 65          fruits.add("banana");                                           + 66          fruits.add("orange");                                           + 67          System.out.println("Fruits: " + fruits);                        + 68   + 69  // Loops + 70  for (int num : numbers) {                                       + 71              System.out.println("Number: " + num);                       + 72          }                                                               + 73   + 74  // Hash maps + 75          Map<String, Integer> scores = new HashMap<>();                  + 76          scores.put("Alice"100);                                       + 77          scores.put("Bob"80);                                          + 78          System.out.println("Alice's score: " + scores.get("Alice"));    + 79   + 80  // Exception handling + 81  try {                                                           + 82              int result = 10 / 0;                                        + 83          } catch (ArithmeticException e) {                               + 84              System.out.println("Error: " + e.getMessage());             + 85          }                                                               + 86   + 87  // Instantiating objects + 88          Rectangle rect = new Rectangle(1020);                         + 89          System.out.println("Rectangle area: " + rect.getArea());        + 90   + 91  // Enums + 92          DaysOfWeek today = DaysOfWeek.MONDAY;                           + 93          System.out.println("Today is " + today);                        + 94   + 95  // Calling methods + 96          int sum = sum(510);                                           + 97          System.out.println("Sum: " + sum);                              + 98   + 99  // Ternary operator +100          String message = age >= 18 ? "You are an adult." : "You are a m +101          System.out.println(message);                                    +102      }                                                                   +103  }                                                                       +104   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[javascript].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[javascript].svg new file mode 100644 index 0000000000..b79ac8d079 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[javascript].svg @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  // Variable declarations + 2  const name ="John";                                                     + 3  let age =30;                                                            + 4  var isStudent =true;                                                    + 5   + 6  // Template literals + 7  console.log(`Hello, ${name}! You are ${age} years old.`);                + 8   + 9  // Conditional statements +10  if (age >=18&& isStudent) {                                            +11    console.log("You are an adult student.");                              +12  elseif (age >=18) {                                                  +13    console.log("You are an adult.");                                      +14  else {                                                                 +15    console.log("You are a minor.");                                       +16  }                                                                        +17   +18  // Arrays and array methods +19  const numbers = [12345];                                         +20  const doubledNumbers = numbers.map((num) => num *2);                    +21  console.log("Doubled numbers:", doubledNumbers);                         +22   +23  // Objects +24  const person = {                                                         +25    firstName: "John",                                                     +26    lastName: "Doe",                                                       +27    getFullName() {                                                        +28  return`${this.firstName} ${this.lastName}`;                         +29    },                                                                     +30  };                                                                       +31  console.log("Full name:", person.getFullName());                         +32   +33  // Classes +34  class Rectangle {                                                        +35    constructor(width, height) {                                           +36      this.width = width;                                                  +37      this.height = height;                                                +38    }                                                                      +39   +40    getArea() {                                                            +41  return this.width * this.height;                                     +42    }                                                                      +43  }                                                                        +44  const rectangle =new Rectangle(53);                                   +45  console.log("Rectangle area:", rectangle.getArea());                     +46   +47  // Async/Await and Promises +48  asyncfunctionfetchData() {                                             +49  try {                                                                  +50  const response =awaitfetch("https://api.example.com/data");        +51  const data =await response.json();                                  +52      console.log("Fetched data:", data);                                  +53    } catch (error) {                                                      +54      console.error("Error:", error);                                      +55    }                                                                      +56  }                                                                        +57  fetchData();                                                             +58   +59  // Arrow functions +60  constgreet= (name) => {                                                +61    console.log(`Hello, ${name}!`);                                        +62  };                                                                       +63  greet("Alice");                                                          +64   +65  // Destructuring assignment +66  const [a, b, ...rest] = [12345];                                 +67  console.log(a, b, rest);                                                 +68   +69  // Spread operator +70  const arr1 = [123];                                                  +71  const arr2 = [456];                                                  +72  const combinedArr = [...arr1, ...arr2];                                  +73  console.log("Combined array:", combinedArr);                             +74   +75  // Ternary operator +76  const message = age >=18 ? "You are an adult." : "You are a minor.";    +77  console.log(message);                                                    +78   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[json].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[json].svg new file mode 100644 index 0000000000..dc9a7405f3 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[json].svg @@ -0,0 +1,200 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  { + 2  "name""John Doe",                                                  + 3  "age"30,                                                           + 4  "isStudent"false,                                                  + 5  "address": {                                                         + 6  "street""123 Main St",                                         + 7  "city""Anytown",                                               + 8  "state""CA",                                                   + 9  "zip""12345" +10      },                                                                   +11  "phoneNumbers": [                                                    +12          {                                                                +13  "type""home",                                              +14  "number""555-555-1234" +15          },                                                               +16          {                                                                +17  "type""work",                                              +18  "number""555-555-5678" +19          }                                                                +20      ],                                                                   +21  "hobbies": ["reading""hiking""swimming"],                        +22  "pets": [                                                            +23          {                                                                +24  "type""dog",                                               +25  "name""Fido" +26          },                                                               +27      ],                                                                   +28  "graduationYear"null +29  } +30   +31   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[kotlin].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[kotlin].svg new file mode 100644 index 0000000000..7fbe0068c5 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[kotlin].svg @@ -0,0 +1,461 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  // Variables + 2  val name ="John" + 3  var age =30 + 4  var isStudent =true + 5   + 6  // Printing variables + 7  println("Hello, $name! You are $age years old.")                         + 8   + 9  // Conditional statements +10  when {                                                                   +11      age >=18&& isStudent ->println("You are an adult student.")       +12      age >=18->println("You are an adult.")                            +13  else->println("You are a minor.")                                  +14  }                                                                        +15   +16  // Arrays +17  val numbers =arrayOf(12345)                                     +18  println("Numbers: ${numbers.contentToString()}")                         +19   +20  // Lists +21  val fruits =listOf("apple""banana""orange")                         +22  println("Fruits: $fruits")                                               +23   +24  // Loops +25  for (num in numbers) {                                                   +26  println("Number: $num")                                              +27  }                                                                        +28   +29  // Functions +30  fungreet(name: String) {                                                +31  println("Hello, $name!")                                             +32  }                                                                        +33  greet("Alice")                                                           +34   +35  // Lambda functions +36  val square = { num: Int -> num * num }                                   +37  println("Square of 5: ${square(5)}")                                     +38   +39  // Extension functions +40  fun String.reverse(): String {                                           +41  return this.reversed() +42  }                                                                        +43  val reversed ="Hello".reverse()                                         +44  println("Reversed: $reversed")                                           +45   +46  // Data classes +47  dataclass Person(val name: String, val age: Int)                        +48  val person =Person("John"30)                                          +49  println("Person: $person")                                               +50   +51  // Null safety +52  var nullable: String? =null +53  println("Length: ${nullable?.length}")                                   +54   +55  // Elvis operator +56  val length = nullable?.length ?:0 +57  println("Length (Elvis): $length")                                       +58   +59  // Smart casts +60  funprintLength(obj: Any) {                                              +61  if (obj is String) {                                                 +62  println("Length: ${obj.length}")                                 +63      }                                                                    +64  }                                                                        +65  printLength("Hello")                                                     +66   +67  // Object expressions +68  val comparator =object : Comparator<Int> {                              +69  overridefun compare(a: Int, b: Int): Int {                          +70  return a - b +71      }                                                                    +72  }                                                                        +73  val sortedNumbers = numbers.sortedWith(comparator)                       +74  println("Sorted numbers: ${sortedNumbers.contentToString()}")            +75   +76  // Companion objects +77  class MyClass {                                                          +78      companion object {                                                   +79  funcreate(): MyClass {                                          +80  return MyClass() +81          }                                                                +82      }                                                                    +83  }                                                                        +84  val obj = MyClass.create()                                               +85   +86  // Sealed classes +87  sealedclass Result {                                                    +88  dataclass Success(val data: String) : Result()                      +89  dataclass Error(val message: String) : Result()                     +90  }                                                                        +91  val result: Result = Result.Success("Data")                              +92  when (result) {                                                          +93  is Result.Success ->println("Success: ${result.data}")              +94  is Result.Error ->println("Error: ${result.message}")               +95  }                                                                        +96   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[markdown].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[markdown].svg new file mode 100644 index 0000000000..4eb48c26b1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[markdown].svg @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  Heading + 2  =======                                                                  + 3   + 4  Sub-heading + 5  -----------                                                              + 6   + 7  ### Heading + 8   + 9  #### H4 Heading +10   +11  ##### H5 Heading +12   +13  ###### H6 Heading +14   +15   +16  Paragraphs are separated                                                 +17  by a blank line.                                                         +18   +19  Two spaces at the end of a line                                          +20  produces a line break.                                                   +21   +22  Text attributes _italic_,                                                +23  **bold**`monospace`.                                                   +24   +25  Horizontal rule:                                                         +26   +27  ---                                                                      +28   +29  Bullet list:                                                             +30   +31  * apples                                                               +32  * oranges                                                              +33  * pears                                                                +34   +35  Numbered list:                                                           +36   +37  1. lather                                                              +38  2. rinse                                                               +39  3. repeat                                                              +40   +41  An [example](http://example.com).                                        +42   +43  > Markdown uses email-style > characters for blockquoting.               +44  >                                                                        +45  > Lorem ipsum                                                            +46   +47  ![progress](https://github.com/textualize/rich/raw/master/imgs/progress. +48   +49   +50  ```                                                                      +51  a=1                                                                      +52  ```                                                                      +53   +54  ```python                                                                +55  import this                                                              +56  ```                                                                      +57   +58  ```somelang                                                              +59  foobar                                                                   +60  ```                                                                      +61   +62      import this                                                          +63   +64   +65  1. List item                                                             +66   +67         Code block                                                        +68   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[python].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[python].svg new file mode 100644 index 0000000000..3a70b296d4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[python].svg @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  import math                                                              + 2  from os import path                                                      + 3   + 4  # I'm a comment :) + 5   + 6  string_var ="Hello, world!" + 7  int_var =42 + 8  float_var =3.14 + 9  complex_var =1+2j +10   +11  list_var = [12345]                                               +12  tuple_var = (12345)                                              +13  set_var = {12345}                                                +14  dict_var = {"a"1"b"2"c"3}                                      +15   +16  deffunction_no_args():                                                  +17  return"No arguments" +18   +19  deffunction_with_args(a, b):                                            +20  return a + b                                                         +21   +22  deffunction_with_default_args(a=0, b=0):                                +23  return a * b                                                         +24   +25  lambda_func =lambda x: x**2 +26   +27  if int_var ==42:                                                        +28  print("It's the answer!")                                            +29  elif int_var <42:                                                       +30  print("Less than the answer.")                                       +31  else:                                                                    +32  print("Greater than the answer.")                                    +33   +34  for index, value inenumerate(list_var):                                 +35  print(f"Index: {index}, Value: {value}")                             +36   +37  counter =0 +38  while counter <5:                                                       +39  print(f"Counter value: {counter}")                                   +40      counter +=1 +41   +42  squared_numbers = [x**2for x inrange(10if x %2==0]                +43   +44  try:                                                                     +45      result =10/0 +46  except ZeroDivisionError:                                                +47  print("Cannot divide by zero!")                                      +48  finally:                                                                 +49  print("End of try-except block.")                                    +50   +51  classAnimal:                                                            +52  def__init__(self, name):                                            +53          self.name = name                                                 +54   +55  defspeak(self):                                                     +56  raiseNotImplementedError("Subclasses must implement this method +57   +58  classDog(Animal):                                                       +59  defspeak(self):                                                     +60  returnf"{self.name} says Woof!" +61   +62  deffibonacci(n):                                                        +63      a, b =01 +64  for _ inrange(n):                                                   +65  yield a                                                          +66          a, b = b, a + b                                                  +67   +68  for num infibonacci(5):                                                 +69  print(num)                                                           +70   +71  withopen('test.txt''w'as f:                                         +72      f.write("Testing with statement.")                                   +73   +74  @my_decorator                                                            +75  defsay_hello():                                                         +76  print("Hello!")                                                      +77   +78  say_hello()                                                              +79   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[regex].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[regex].svg new file mode 100644 index 0000000000..afdec48787 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[regex].svg @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  ^abc            # Matches any string that starts with "abc" + 2  abc$            # Matches any string that ends with "abc" + 3  ^abc$           # Matches the string "abc" and nothing else + 4  a.b             # Matches any string containing "a", any character, then + 5  a[.]b           # Matches the string "a.b" + 6  a|b             # Matches either "a" or "b" + 7  a{2}            # Matches "aa" + 8  a{2,}           # Matches two or more consecutive "a" characters + 9  a{2,5}          # Matches between 2 and 5 consecutive "a" characters +10  a?              # Matches "a" or nothing (0 or 1 occurrence of "a")      +11  a*              # Matches zero or more consecutive "a" characters +12  a+              # Matches one or more consecutive "a" characters +13  \d              # Matches any digit (equivalent to [0-9])                +14  \D              # Matches any non-digit +15  \w              # Matches any word character (equivalent to [a-zA-Z0-9_] +16  \W              # Matches any non-word character +17  \s              # Matches any whitespace character (spaces, tabs, line b +18  \S              # Matches any non-whitespace character +19  (?i)abc         # Case-insensitive match for "abc" +20  (?:a|b)         # Non-capturing group for either "a" or "b" +21  (?<=a)b         # Positive lookbehind: matches "b" that is preceded by " +22  (?<!a)b         # Negative lookbehind: matches "b" that is not preceded  +23  a(?=b)          # Positive lookahead: matches "a" that is followed by "b +24  a(?!b)          # Negative lookahead: matches "a" that is not followed b +25   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[rust].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[rust].svg new file mode 100644 index 0000000000..a40effe9ec --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[rust].svg @@ -0,0 +1,497 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  use std::collections::HashMap;                                          +  2   +  3  // Constants +  4  const PI: f64 = 3.14159;                                                +  5   +  6  // Structs +  7  struct Rectangle {                                                      +  8      width: u32,                                                         +  9      height: u32,                                                        + 10  }                                                                       + 11   + 12  impl Rectangle {                                                        + 13  fnarea(&self) -> u32 {                                             + 14          self.width * self.height                                        + 15      }                                                                   + 16  }                                                                       + 17   + 18  // Enums + 19  enum Result<T, E> {                                                     + 20      Ok(T),                                                              + 21      Err(E),                                                             + 22  }                                                                       + 23   + 24  // Functions + 25  fngreet(name: &str) {                                                  + 26      println!("Hello, {}!", name);                                       + 27  }                                                                       + 28   + 29  fnmain() {                                                             + 30  // Variables + 31  let name = "John";                                                  + 32  letmut age = 30;                                                   + 33  let is_student = true;                                              + 34   + 35  // Printing variables + 36      println!("Hello, {}! You are {} years old.", name, age);            + 37   + 38  // Conditional statements + 39  if age >= 18 && is_student {                                        + 40          println!("You are an adult student.");                          + 41      } elseif age >= 18 {                                               + 42          println!("You are an adult.");                                  + 43      } else {                                                            + 44          println!("You are a minor.");                                   + 45      }                                                                   + 46   + 47  // Arrays + 48  let numbers = [12345];                                      + 49      println!("Numbers: {:?}", numbers);                                 + 50   + 51  // Vectors + 52  letmut fruits = vec!["apple""banana""orange"];                 + 53      fruits.push("grape");                                               + 54      println!("Fruits: {:?}", fruits);                                   + 55   + 56  // Loops + 57  for num in&numbers {                                               + 58          println!("Number: {}", num);                                    + 59      }                                                                   + 60   + 61  // Pattern matching + 62  let result = Result::Ok(42);                                        + 63  match result {                                                      + 64          Result::Ok(value) => println!("Value: {}", value),              + 65          Result::Err(error) => println!("Error: {:?}", error),           + 66      }                                                                   + 67   + 68  // Ownership and borrowing + 69  let s1 = String::from("hello");                                     + 70  let s2 = s1.clone();                                                + 71      println!("s1: {}, s2: {}", s1, s2);                                 + 72   + 73  // References + 74  let rect = Rectangle {                                              + 75          width: 10,                                                      + 76          height: 20,                                                     + 77      };                                                                  + 78      println!("Rectangle area: {}", rect.area());                        + 79   + 80  // Hash maps + 81  letmut scores = HashMap::new();                                    + 82      scores.insert("Alice"100);                                        + 83      scores.insert("Bob"80);                                           + 84      println!("Alice's score: {}", scores["Alice"]);                     + 85   + 86  // Closures + 87  let square = |num: i32| num * num;                                  + 88      println!("Square of 5: {}", square(5));                             + 89   + 90  // Traits + 91  trait Printable {                                                   + 92  fnprint(&self);                                                + 93      }                                                                   + 94   + 95  impl Printable for Rectangle {                                      + 96  fnprint(&self) {                                               + 97              println!("Rectangle: width={}, height={}", self.width, self + 98          }                                                               + 99      }                                                                   +100      rect.print();                                                       +101   +102  // Modules +103  greet("Alice");                                                     +104  }                                                                       +105   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[sql].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[sql].svg new file mode 100644 index 0000000000..af4b2c76b1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[sql].svg @@ -0,0 +1,253 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  -- This is a comment in SQL + 2   + 3  -- Create tables + 4  CREATETABLE Authors (                                                   + 5      AuthorID INT PRIMARY KEY,                                            + 6      Name VARCHAR(255NOT NULL,                                          + 7      Country VARCHAR(50)                                                  + 8  );                                                                       + 9   +10  CREATETABLE Books (                                                     +11      BookID INT PRIMARY KEY,                                              +12      Title VARCHAR(255NOT NULL,                                         +13      AuthorID INT,                                                        +14      PublishedDate DATE,                                                  +15      FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)                  +16  );                                                                       +17   +18  -- Insert data +19  INSERTINTO Authors (AuthorID, Name, Country) VALUES (1'George Orwell' +20   +21  INSERTINTO Books (BookID, Title, AuthorID, PublishedDate) VALUES (1'1 +22   +23  -- Update data +24  UPDATE Authors SET Country ='United Kingdom'WHERE Country ='UK';      +25   +26  -- Select data with JOIN +27  SELECT Books.Title, Authors.Name                                         +28  FROM Books                                                               +29  JOIN Authors ON Books.AuthorID = Authors.AuthorID;                       +30   +31  -- Delete data (commented to preserve data for other examples) +32  -- DELETE FROM Books WHERE BookID = 1; +33   +34  -- Alter table structure +35  ALTER TABLE Authors ADD COLUMN BirthDate DATE;                           +36   +37  -- Create index +38  CREATEINDEX idx_author_name ON Authors(Name);                           +39   +40  -- Drop index (commented to avoid actually dropping it) +41  -- DROP INDEX idx_author_name ON Authors; +42   +43  -- End of script +44   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[toml].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[toml].svg new file mode 100644 index 0000000000..1a4fa81e86 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[toml].svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  # This is a comment in TOML + 2   + 3  string = "Hello, world!" + 4  integer = 42 + 5  float = 3.14 + 6  boolean = true + 7  datetime = 1979-05-27T07:32:00Z + 8   + 9  fruits = ["apple""banana""cherry"]                                   +10   +11  [address]                                                                +12  street = "123 Main St" +13  city = "Anytown" +14  state = "CA" +15  zip = "12345" +16   +17  [person.john]                                                            +18  name = "John Doe" +19  age = 28 +20  is_student = false +21   +22   +23  [[animals]]                                                              +24  name = "Fido" +25  type = "dog" +26   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[yaml].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[yaml].svg new file mode 100644 index 0000000000..ff41837ade --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_language_rendering[yaml].svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  # This is a comment in YAML + 2   + 3  # Scalars + 4  string"Hello, world!" + 5  integer42 + 6  float3.14 + 7  booleantrue + 8   + 9  # Sequences (Arrays) +10  fruits:                                                                  +11    - Apple +12    - Banana +13    - Cherry +14   +15  # Nested sequences +16  persons:                                                                 +17    - nameJohn +18  age28 +19  is_studentfalse +20    - nameJane +21  age22 +22  is_studenttrue +23   +24  # Mappings (Dictionaries) +25  address:                                                                 +26  street123 Main St +27  cityAnytown +28  stateCA +29  zip'12345' +30   +31  # Multiline string +32  description +33    This is a multiline  +34    string in YAML. +35   +36  # Inline and nested collections +37  colors: { redFF0000green00FF00blue0000FF }                     +38   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_line_number_start.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_line_number_start.svg new file mode 100644 index 0000000000..1ea4fb37ee --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_line_number_start.svg @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LineNumbersReactive + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ + 9999  Foo                   +10000  Bar                   +10001  Baz                   +10002   + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_read_only_cursor_rendering.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_read_only_cursor_rendering.svg new file mode 100644 index 0000000000..1b4677967c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_read_only_cursor_rendering.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  Hello, world!           + + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg new file mode 100644 index 0000000000..4c1aaabd19 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection0].svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg new file mode 100644 index 0000000000..50245c56c6 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection1].svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg new file mode 100644 index 0000000000..ae7782c460 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection2].svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line. + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg new file mode 100644 index 0000000000..b36ac1aca2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection3].svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line. + +I am another line. + +I am the final line. + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg new file mode 100644 index 0000000000..6bc6248073 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection4].svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line.               + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg new file mode 100644 index 0000000000..08f7539ca4 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_selection_rendering[selection5].svg @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +I am a line.               + +I am another line.         + +I am the final line.       + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[css].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[css].svg new file mode 100644 index 0000000000..0fb3ad8198 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[css].svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  defhello(name): +2      x =123 +3  whilenotFalse:                      +4  print("hello "+ name)            +5  continue +6   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[dracula].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[dracula].svg new file mode 100644 index 0000000000..55a5898a8b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[dracula].svg @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  defhello(name): +2      x =123 +3  whilenotFalse:                      +4  print("hello "+ name)            +5  continue +6   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[github_light].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[github_light].svg new file mode 100644 index 0000000000..66a83cb4cd --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[github_light].svg @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  defhello(name): +2  x=123 +3  whilenotFalse:                      +4  print("hello "+name)            +5  continue +6   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[monokai].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[monokai].svg new file mode 100644 index 0000000000..844c47a35b --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[monokai].svg @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  defhello(name): +2      x =123 +3  whilenotFalse:                      +4  print("hello "+ name)            +5  continue +6   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[vscode_dark].svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[vscode_dark].svg new file mode 100644 index 0000000000..2c90c525d7 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_themes[vscode_dark].svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +1  defhello(name): +2      x =123 +3  whilenotFalse:                      +4  print("hello "+ name)            +5  continue +6   + +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_wrapping_and_folding.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_wrapping_and_folding.svg new file mode 100644 index 0000000000..ca2a56478f --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_area_wrapping_and_folding.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaWrapping + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  # The  +Wonders  +of Space  +Explorati +on + 2   + 3  Space      +explorati  +on has     +*always* +captured   +the        +human      +imaginati  +on.        + 4  ▃▃ + 5  ダレンバ   +ーンズ     + 6   + 7   +Thisissom  +elongtext  +thatshoul  +dfoldcorr  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_log_blank_write.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_log_blank_write.svg new file mode 100644 index 0000000000..dd7733a8b9 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_text_log_blank_write.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogApp + + + + + + + + + + Hello                                                                          + +World                                                                          + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_border_preview.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_border_preview.svg new file mode 100644 index 0000000000..df740535f0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_border_preview.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ascii  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔+------------------- ascii --------------------+ + blank || +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|I must not fear.| + dashed |Fear is the mind-killer.| +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|Fear is the little-death that brings | +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|total obliteration.| + double |I will face my fear.| +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅|I will permit it to pass over me and | +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|through me.| + heavy |And when it has gone past, I will turn| +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|the inner eye to see its path.| +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|Where the fear has gone there will be | + hidden |nothing. Only I will remain.| +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|| + hkey +----------------------------------------------+ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + inner  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_colors_preview.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_colors_preview.svg new file mode 100644 index 0000000000..0e5c5d70ff --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_colors_preview.svg @@ -0,0 +1,171 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorsApp + + + + + + + + + + +Theme ColorsNamed Colors +━╸━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + primary  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + secondary "primary" +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + background $primary-darken-3$t +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + primary-background $primary-darken-2$t +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + secondary-background $primary-darken-1$t +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + surface $primary$t +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + d Toggle dark mode  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_easing_preview.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_easing_preview.svg new file mode 100644 index 0000000000..baa9f49fbe --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_easing_preview.svg @@ -0,0 +1,167 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EasingApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + round ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Animation Duration:1.0                        +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + out_sine  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + out_quint  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Welcome to Textual! +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + out_quart I must not fear. +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Fear is the  +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mind-killer. + out_quad Fear is the  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁little-death that  +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔brings total  + out_expo obliteration. +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I will face my fear. +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will permit it to  + out_elastic pass over me and  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁through me. +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔And when it has gone  + out_cubic  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ^p Focus: Duration Input  ^b Toggle Dark  + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_keys_preview.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_keys_preview.svg new file mode 100644 index 0000000000..1a84f5f2aa --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_textual_dev_keys_preview.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Textual Keys + + + + + + + + + + Textual Keys +╭────────────────────────────────────────────────────────────────────────────╮ +│ Press some keys!                                                           │ +│                                                                            │ +│ To quit the app press ctrl+ctwice or press the Quit button below.         │ +╰────────────────────────────────────────────────────────────────────────────╯ +Key(key='a'character='a'name='a'is_printable=True) +Key(key='b'character='b'name='b'is_printable=True) + + + + + + + + + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Clear  Quit  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_toggle_style_order.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_toggle_style_order.svg new file mode 100644 index 0000000000..12ed1dc3e2 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_toggle_style_order.svg @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CheckboxApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +XThis is just some text. +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +This is just some text. + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tooltips_in_compound_widgets.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tooltips_in_compound_widgets.svg new file mode 100644 index 0000000000..68b61bb22d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tooltips_in_compound_widgets.svg @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TooltipApp + + + + + + + + + + ━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━10%                                            + +Hello, Tooltip! + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_clearing_and_expansion.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_clearing_and_expansion.svg new file mode 100644 index 0000000000..8617454347 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_clearing_and_expansion.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeClearingSnapshotApp + + + + + + + + + + ▼ Left▶ Right + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_example.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_example.svg new file mode 100644 index 0000000000..7f65a3cc86 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_tree_example.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeApp + + + + + + + + + + ▼ Dune +┗━━ ▼ Characters +    ┣━━ Paul +    ┣━━ Jessica +    ┗━━ Chani + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_unscoped_css.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_unscoped_css.svg new file mode 100644 index 0000000000..aadca76d82 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_unscoped_css.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +┌───┐ +foo +└───┘ +┌───┐ +bar +└───┘ +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +┌───┐ +foo +└───┘ +┌───┐ +bar +└───┘ +└──────────────────────────────────────────────────────────────────────────────┘ +┌───────────────────┐ +This will be styled +└───────────────────┘ + + + + + + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_layout.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_layout.svg new file mode 100644 index 0000000000..0e694512ec --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_layout.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalLayoutExample + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +One + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +Two + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ +Three + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_max_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_max_height.svg new file mode 100644 index 0000000000..934298ce2d --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_max_height.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + + + +#top + + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ + + + +#bottom + + + + +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_min_height.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_min_height.svg new file mode 100644 index 0000000000..addfd7db42 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_vertical_min_height.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + +#top + + + + +└──────────────────────────────────────────────────────────────────────────────┘ +┌──────────────────────────────────────────────────────────────────────────────┐ + + + + + +#bottom + + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_viewport_height_and_width_properties.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_viewport_height_and_width_properties.svg new file mode 100644 index 0000000000..d18a0558e5 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_viewport_height_and_width_properties.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ViewportUnits + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ +Hello, world! + + + + + + + + + + + + + + + + + + + + + +└──────────────────────────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_visibility.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_visibility.svg new file mode 100644 index 0000000000..a1408fdc34 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_visibility.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Visibility + + + + + + + + + + ┌──────────────────────────────────────┐ +bar +┌────────────────────────────────────┐┌────────────────────────────────────┐ +floatfloat +└────────────────────────────────────┘└────────────────────────────────────┘ + + + + + + + + + + + + + + + + + + +└──────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_welcome.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_welcome.svg new file mode 100644 index 0000000000..5d6faceeb0 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_welcome.svg @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WelcomeApp + + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  + ┃                                 Welcome!                                 ┃  + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛  + + Textual is a TUI, or Text User Interface, framework for Python inspired by    + modern web development. We hope you enjoy using Textual! + + +Dune quote + +▌ "I must not fear. Fear is the mind-killer. Fear is the little-death that +▌ brings total obliteration. I will face my fear. I will permit it to pass +▌ over me and through me. And when it has gone past, I will turn the inner +▌ eye to see its path. Where the fear has gone there will be nothing. Only +▌ I will remain."                                                          + + + + + +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + OK  +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_width_100.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_width_100.svg new file mode 100644 index 0000000000..93def793e8 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_width_100.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Width100PCentApp + + + + + + + + + + ┌───────────────────────────────────────────────────────────┐ +┌─────────────────────────────────────────────────────────┐ +I want to be 100% of my parent +└─────────────────────────────────────────────────────────┘ +┌─────────────────────────────────────────────────────────┐ +I want my parent to be wide enough to wrap me and no more +└─────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + +└───────────────────────────────────────────────────────────┘ + + + diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_zero_scrollbar_size.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_zero_scrollbar_size.svg new file mode 100644 index 0000000000..0583dab8b1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_zero_scrollbar_size.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! +Hello, world! + + + diff --git a/tests/test_slug.py b/tests/test_slug.py index 0486966e83..3dc54cd50d 100644 --- a/tests/test_slug.py +++ b/tests/test_slug.py @@ -3,6 +3,7 @@ from textual._slug import TrackedSlugs, slug +@pytest.mark.xdist_group("group1") @pytest.mark.parametrize( "text, expected", [ @@ -36,6 +37,7 @@ def tracker() -> TrackedSlugs: return TrackedSlugs() +@pytest.mark.xdist_group("group2") @pytest.mark.parametrize( "text, expected", [ From a494d150a55e854dd38e527268e22977ba5534bf Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 25 Jul 2024 11:57:40 +0100 Subject: [PATCH 37/80] bump --- CHANGELOG.md | 3 ++- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78c90e93e6..4b690d1c89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased +## [0.74.0] - 2024-07-25 ### Added @@ -2237,6 +2237,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040 - New handler system for messages that doesn't require inheritance - Improved traceback handling +[0.74.0]: https://github.com/Textualize/textual/compare/v0.73.0...v0.74.0 [0.73.0]: https://github.com/Textualize/textual/compare/v0.72.0...v0.73.0 [0.72.0]: https://github.com/Textualize/textual/compare/v0.71.0...v0.72.0 [0.71.0]: https://github.com/Textualize/textual/compare/v0.70.0...v0.71.0 diff --git a/pyproject.toml b/pyproject.toml index 609033f695..0cfd6fd9bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "0.73.0" +version = "0.74.0" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" From c865388088e07e4a2cf507d37189a9ee672b2361 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Sat, 27 Jul 2024 18:07:39 +0100 Subject: [PATCH 38/80] docs: various fixes --- docs/styles/layout.md | 2 +- src/textual/css/query.py | 2 +- src/textual/dom.py | 4 ++-- src/textual/geometry.py | 2 +- src/textual/renderables/bar.py | 2 +- src/textual/widget.py | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/styles/layout.md b/docs/styles/layout.md index 590ea3ec5d..4e1a80e3bb 100644 --- a/docs/styles/layout.md +++ b/docs/styles/layout.md @@ -23,7 +23,7 @@ See the [layout](../guide/layout.md) guide for more information. ## Example Note how the `layout` style affects the arrangement of widgets in the example below. -To learn more about the grid layout, you can see the [layout guide](../guide/layout.md) or the [grid reference](../grid.md). +To learn more about the grid layout, you can see the [layout guide](../guide/layout.md) or the [grid reference](./grid/index.md). === "Output" diff --git a/src/textual/css/query.py b/src/textual/css/query.py index 23233f8d2c..60be9aa3a9 100644 --- a/src/textual/css/query.py +++ b/src/textual/css/query.py @@ -1,5 +1,5 @@ """ -This module contains the `DOMQuery` class and related objects.s +This module contains the `DOMQuery` class and related objects. A DOMQuery is a set of DOM nodes returned by [query][textual.dom.DOMNode.query]. diff --git a/src/textual/dom.py b/src/textual/dom.py index 656a005b3d..55ce52afea 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -514,7 +514,7 @@ def get_component_styles(self, *names: str) -> RenderStyles: """Get a "component" styles object (must be defined in COMPONENT_CLASSES classvar). Args: - name: Name of the component. + names: Names of the components. Raises: KeyError: If the component class doesn't exist. @@ -1537,7 +1537,7 @@ def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | No Args: action: The name of an action. - action_parameters: A tuple of any action parameters. + parameters: A tuple of any action parameters. Returns: `True` if the action is enabled+visible, diff --git a/src/textual/geometry.py b/src/textual/geometry.py index 8b246c5592..f8da532ba6 100644 --- a/src/textual/geometry.py +++ b/src/textual/geometry.py @@ -233,7 +233,7 @@ def with_height(self, height: int) -> Size: """Get a new Size with just the height changed. Args: - width: New height. + height: New height. Returns: New Size instance. diff --git a/src/textual/renderables/bar.py b/src/textual/renderables/bar.py index 1dba89b77b..2fa31550fc 100644 --- a/src/textual/renderables/bar.py +++ b/src/textual/renderables/bar.py @@ -15,7 +15,7 @@ class Bar: highlight_style: The style of the highlighted range of the bar. background_style: The style of the non-highlighted range(s) of the bar. width: The width of the bar, or `None` to fill available width. - gradient. Optional gradient object. + gradient: Optional gradient object. """ def __init__( diff --git a/src/textual/widget.py b/src/textual/widget.py index 687a97e7ef..cd521a663c 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -806,7 +806,7 @@ def get_component_rich_style(self, *names: str, partial: bool = False) -> Style: """Get a *Rich* style for a component. Args: - name: Name of component. + names: Names of components. partial: Return a partial style (not combined with parent). Returns: From 2fc333097d83d148e1988d60b94f3ea65c3448d7 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 13:42:39 +0100 Subject: [PATCH 39/80] enter bubble --- CHANGELOG.md | 11 +++++++++ src/textual/app.py | 6 ++--- src/textual/events.py | 31 ++++++++++++++++++++++---- src/textual/widget.py | 14 ++++++++++-- tests/snapshot_tests/test_snapshots.py | 7 ++++++ 5 files changed, 60 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b690d1c89..474ab23a30 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Added + +- Added `Widget.is_mouse_over` +- Added node attribute to `events.Enter` and `events.Leave` + +### Changed + +- `events.Enter` and `events.Leave` events now bubble. + ## [0.74.0] - 2024-07-25 ### Added diff --git a/src/textual/app.py b/src/textual/app.py index 13859bf2a5..cb3fd411cd 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -2304,16 +2304,16 @@ def _set_mouse_over(self, widget: Widget | None) -> None: if widget is None: if self.mouse_over is not None: try: - self.mouse_over.post_message(events.Leave()) + self.mouse_over.post_message(events.Leave(self.mouse_over)) finally: self.mouse_over = None else: if self.mouse_over is not widget: try: if self.mouse_over is not None: - self.mouse_over.post_message(events.Leave()) + self.mouse_over.post_message(events.Leave(self.mouse_over)) if widget is not None: - widget.post_message(events.Enter()) + widget.post_message(events.Enter(widget)) finally: self.mouse_over = widget diff --git a/src/textual/events.py b/src/textual/events.py index 012c23c3cb..80a5c18934 100644 --- a/src/textual/events.py +++ b/src/textual/events.py @@ -27,6 +27,7 @@ MouseEventT = TypeVar("MouseEventT", bound="MouseEvent") if TYPE_CHECKING: + from .dom import DOMNode from .timer import Timer as TimerClass from .timer import TimerCallback from .widget import Widget @@ -548,22 +549,44 @@ def __rich_repr__(self) -> rich.repr.Result: yield "count", self.count -class Enter(Event, bubble=False, verbose=True): +class Enter(Event, bubble=True, verbose=True): """Sent when the mouse is moved over a widget. - - [ ] Bubbles + Note that this widget bubbles, so a widget may receive this event when the mouse + moves over a child widget. Check the `node` attribute for the widget directly under + tne mouse. + + - [X] Bubbles - [X] Verbose """ + __slots__ = ["node"] -class Leave(Event, bubble=False, verbose=True): + def __init__(self, node: DOMNode) -> None: + self.node = node + """The node directly under the mouse.""" + super().__init__() + + +class Leave(Event, bubble=True, verbose=True): """Sent when the mouse is moved away from a widget, or if a widget is programmatically disabled while hovered. - - [ ] Bubbles + Note that this widget bubbles, so a widget may receive Leave events for any child widgets. + Check the `node` parameter for the original widget that was previously under the mouse. + + + - [X] Bubbles - [X] Verbose """ + __slots__ = ["node"] + + def __init__(self, node: DOMNode) -> None: + self.node = node + """The node that was previously directly under the mouse.""" + super().__init__() + class Focus(Event, bubble=False): """Sent when a widget is focussed. diff --git a/src/textual/widget.py b/src/textual/widget.py index cd521a663c..cb316e256f 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -542,6 +542,16 @@ def is_anchored(self) -> bool: """Is this widget anchored?""" return self._parent is not None and self._parent is self + @property + def is_mouse_over(self) -> bool: + """Is the mouse currently over this widget?""" + if not self.screen.is_active: + return False + for widget, _ in self.screen.get_widgets_at(*self.app.mouse_position): + if widget is self: + return True + return False + def anchor(self, *, animate: bool = False) -> None: """Anchor the widget, which scrolls it into view (like [scroll_visible][textual.widget.Widget.scroll_visible]), but also keeps it in view if the widget's size changes, or the size of its container changes. @@ -3261,9 +3271,9 @@ def watch_disabled(self, disabled: bool) -> None: """Update the styles of the widget and its children when disabled is toggled.""" from .app import ScreenStackError - if disabled and self.mouse_over: + if disabled and self.mouse_over and self.app.mouse_over is not None: # Ensure widget gets a Leave if it is disabled while hovered - self._message_queue.put_nowait(events.Leave()) + self._message_queue.put_nowait(events.Leave(self.app.mouse_over)) try: screen = self.screen if ( diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 2e7d987c53..8fe8d6b896 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -1397,3 +1397,10 @@ def test_progress_gradient(snap_compare): def test_recompose_in_mount(snap_compare): """Regression test for https://github.com/Textualize/textual/issues/4799""" assert snap_compare(SNAPSHOT_APPS_DIR / "recompose_on_mount.py") + + +def test_enter_or_leave(snap_compare) -> None: + async def run_before(pilot: Pilot): + await pilot.hover("#foo") + + assert snap_compare(SNAPSHOT_APPS_DIR / "enter_or_leave.py", run_before=run_before) From d164ba65a59956643bc56ed38287816f7625cf36 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 13:44:33 +0100 Subject: [PATCH 40/80] snapshot --- .../test_snapshots/test_enter_or_leave.svg | 151 ++++++++++++++++++ .../snapshot_apps/enter_or_leave.py | 44 +++++ 2 files changed, 195 insertions(+) create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_enter_or_leave.svg create mode 100644 tests/snapshot_tests/snapshot_apps/enter_or_leave.py diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_enter_or_leave.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_enter_or_leave.svg new file mode 100644 index 0000000000..98a490950a --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_enter_or_leave.svg @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EnterApp + + + + + + + + + + + +Foo +Bar + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/snapshot_apps/enter_or_leave.py b/tests/snapshot_tests/snapshot_apps/enter_or_leave.py new file mode 100644 index 0000000000..0b30b2dfa4 --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/enter_or_leave.py @@ -0,0 +1,44 @@ +from textual import on +from textual.app import App, ComposeResult +from textual.widgets import Label +from textual.widget import Widget +from textual import events + + +class MyWidget(Widget): + def compose(self) -> ComposeResult: + yield Label("Foo", id="foo") + yield Label("Bar") + + @on(events.Enter) + @on(events.Leave) + def on_enter_or_leave(self): + self.set_class(self.is_mouse_over, "-over") + + +class EnterApp(App): + CSS = """ + + MyWidget { + padding: 2 4; + background: red; + height: auto; + width: auto; + + &.-over { + background: green; + } + + Label { + background: rgba(20,20,200,0.5); + } + } + """ + + def compose(self) -> ComposeResult: + yield MyWidget() + + +if __name__ == "__main__": + app = EnterApp() + app.run() From 2fedf2065c9a1d55ffb2c4718f2c329cf4ef30b5 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 13:44:59 +0100 Subject: [PATCH 41/80] changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 474ab23a30..5443d97b9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added -- Added `Widget.is_mouse_over` -- Added node attribute to `events.Enter` and `events.Leave` +- Added `Widget.is_mouse_over` https://github.com/Textualize/textual/pull/4818 +- Added node attribute to `events.Enter` and `events.Leave` https://github.com/Textualize/textual/pull/4818 ### Changed -- `events.Enter` and `events.Leave` events now bubble. +- `events.Enter` and `events.Leave` events now bubble. https://github.com/Textualize/textual/pull/4818 ## [0.74.0] - 2024-07-25 From 15474c11016bde487215a0e319fb5ba9df16b6e4 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 13:59:01 +0100 Subject: [PATCH 42/80] docs --- docs/guide/input.md | 3 +++ src/textual/widget.py | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/guide/input.md b/docs/guide/input.md index 506adf5274..c35305d955 100644 --- a/docs/guide/input.md +++ b/docs/guide/input.md @@ -232,6 +232,9 @@ Textual will send a [MouseCapture](../events/mouse_capture.md) event when the mo Textual will send a [Enter](../events/enter.md) event to a widget when the mouse cursor first moves over it, and a [Leave](../events/leave.md) event when the cursor moves off a widget. +Both `Enter` and `Leave` _bubble_, so a widget may receive these events from a child widget. +You can check the initial widget these events were send to by comparing the `node` attribute against `self` in the message handler. + ### Click events There are three events associated with clicking a button on your mouse. When the button is initially pressed, Textual sends a [MouseDown](../events/mouse_down.md) event, followed by [MouseUp](../events/mouse_up.md) when the button is released. Textual then sends a final [Click](../events/click.md) event. diff --git a/src/textual/widget.py b/src/textual/widget.py index cb316e256f..7f92c51fd5 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -544,7 +544,13 @@ def is_anchored(self) -> bool: @property def is_mouse_over(self) -> bool: - """Is the mouse currently over this widget?""" + """Is the mouse currently over this widget? + + Note this will be `True` if the mouse pointer is within the widget's region, even if + the mouse pointer is not directly over the widget (there could be another widget between + the mouse pointer and self). + + """ if not self.screen.is_active: return False for widget, _ in self.screen.get_widgets_at(*self.app.mouse_position): From 4b0110cf294044cd0426dc95b72efa15a7da40e3 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 14:09:34 +0100 Subject: [PATCH 43/80] rename --- CHANGELOG.md | 1 + src/textual/widget.py | 14 +++++++------- tests/test_widget.py | 4 +--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5443d97b9c..9647d1184d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Changed - `events.Enter` and `events.Leave` events now bubble. https://github.com/Textualize/textual/pull/4818 +- Renamed `Widget.mouse_over` to `Widget.mouse_hover` https://github.com/Textualize/textual/pull/4818 ## [0.74.0] - 2024-07-25 diff --git a/src/textual/widget.py b/src/textual/widget.py index 7f92c51fd5..2d8592e4e3 100644 --- a/src/textual/widget.py +++ b/src/textual/widget.py @@ -428,7 +428,7 @@ def __init__( has_focus: Reactive[bool] = Reactive(False, repaint=False) """Does this widget have focus? Read only.""" - mouse_over: Reactive[bool] = Reactive(False, repaint=False) + mouse_hover: Reactive[bool] = Reactive(False, repaint=False) """Is the mouse over this widget? Read only.""" scroll_x: Reactive[float] = Reactive(0.0, repaint=False, layout=False) @@ -3172,7 +3172,7 @@ def get_pseudo_classes(self) -> Iterable[str]: Returns: Names of the pseudo classes. """ - if self.mouse_over: + if self.mouse_hover: yield "hover" if self.has_focus: yield "focus" @@ -3220,7 +3220,7 @@ def get_pseudo_class_state(self) -> PseudoClasses: pseudo_classes = PseudoClasses( enabled=not disabled, - hover=self.mouse_over, + hover=self.mouse_hover, focus=self.has_focus, ) return pseudo_classes @@ -3264,7 +3264,7 @@ def post_render(self, renderable: RenderableType) -> ConsoleRenderable: return renderable - def watch_mouse_over(self, value: bool) -> None: + def watch_mouse_hover(self, value: bool) -> None: """Update from CSS if mouse over state changes.""" if self._has_hover_style: self._update_styles() @@ -3277,7 +3277,7 @@ def watch_disabled(self, disabled: bool) -> None: """Update the styles of the widget and its children when disabled is toggled.""" from .app import ScreenStackError - if disabled and self.mouse_over and self.app.mouse_over is not None: + if disabled and self.mouse_hover and self.app.mouse_over is not None: # Ensure widget gets a Leave if it is disabled while hovered self._message_queue.put_nowait(events.Leave(self.app.mouse_over)) try: @@ -3848,11 +3848,11 @@ def _on_mount(self, event: events.Mount) -> None: self.show_horizontal_scrollbar = True def _on_leave(self, event: events.Leave) -> None: - self.mouse_over = False + self.mouse_hover = False self.hover_style = Style() def _on_enter(self, event: events.Enter) -> None: - self.mouse_over = True + self.mouse_hover = True def _on_focus(self, event: events.Focus) -> None: self.has_focus = True diff --git a/tests/test_widget.py b/tests/test_widget.py index 182de27b7a..2652aec54d 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -204,7 +204,7 @@ def test_get_pseudo_class_state_parent_disabled(): def test_get_pseudo_class_state_hover(): widget = Widget() - widget.mouse_over = True + widget.mouse_hover = True pseudo_classes = widget.get_pseudo_class_state() assert pseudo_classes == PseudoClasses(enabled=True, focus=False, hover=True) @@ -444,7 +444,6 @@ async def test_sort_children() -> None: """Test the sort_children method.""" class SortApp(App): - def compose(self) -> ComposeResult: with Container(id="container"): yield Label("three", id="l3") @@ -481,7 +480,6 @@ async def test_sort_children_no_key() -> None: """Test sorting with no key.""" class SortApp(App): - def compose(self) -> ComposeResult: with Container(id="container"): yield Label("three", id="l3") From 485242ac61f8d0871677cf947e59d0ea4f9f68a4 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 14:14:26 +0100 Subject: [PATCH 44/80] changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9647d1184d..c262c2ca71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Added `Widget.is_mouse_over` https://github.com/Textualize/textual/pull/4818 -- Added node attribute to `events.Enter` and `events.Leave` https://github.com/Textualize/textual/pull/4818 +- Added `node` attribute to `events.Enter` and `events.Leave` https://github.com/Textualize/textual/pull/4818 ### Changed From c7da9a25577212cd68f6879d40baae1f0c86df5e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 14:21:28 +0100 Subject: [PATCH 45/80] typo --- docs/guide/input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide/input.md b/docs/guide/input.md index c35305d955..4e997cc1c2 100644 --- a/docs/guide/input.md +++ b/docs/guide/input.md @@ -233,7 +233,7 @@ Textual will send a [MouseCapture](../events/mouse_capture.md) event when the mo Textual will send a [Enter](../events/enter.md) event to a widget when the mouse cursor first moves over it, and a [Leave](../events/leave.md) event when the cursor moves off a widget. Both `Enter` and `Leave` _bubble_, so a widget may receive these events from a child widget. -You can check the initial widget these events were send to by comparing the `node` attribute against `self` in the message handler. +You can check the initial widget these events were sent to by comparing the `node` attribute against `self` in the message handler. ### Click events From d51a9a5d95e9197438452e4a902c3d0fc936bf42 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 14:30:58 +0100 Subject: [PATCH 46/80] Update src/textual/events.py Co-authored-by: Darren Burns --- src/textual/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/events.py b/src/textual/events.py index 80a5c18934..4d2a16ff9a 100644 --- a/src/textual/events.py +++ b/src/textual/events.py @@ -552,7 +552,7 @@ def __rich_repr__(self) -> rich.repr.Result: class Enter(Event, bubble=True, verbose=True): """Sent when the mouse is moved over a widget. - Note that this widget bubbles, so a widget may receive this event when the mouse + Note that this event bubbles, so a widget may receive this event when the mouse moves over a child widget. Check the `node` attribute for the widget directly under tne mouse. From dc1049b8382f6060aad9a31463c2aa021b4c061f Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 29 Jul 2024 14:31:05 +0100 Subject: [PATCH 47/80] Update src/textual/events.py Co-authored-by: Darren Burns --- src/textual/events.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/events.py b/src/textual/events.py index 4d2a16ff9a..d7f5cb11dc 100644 --- a/src/textual/events.py +++ b/src/textual/events.py @@ -554,7 +554,7 @@ class Enter(Event, bubble=True, verbose=True): Note that this event bubbles, so a widget may receive this event when the mouse moves over a child widget. Check the `node` attribute for the widget directly under - tne mouse. + the mouse. - [X] Bubbles - [X] Verbose From 0425746ca3899c8e3df644c04a8ca63f14394ea7 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 15:34:28 +0100 Subject: [PATCH 48/80] better docs --- src/textual/widgets/_data_table.py | 7 ++----- tests/test_data_table.py | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/textual/widgets/_data_table.py b/src/textual/widgets/_data_table.py index 107635e9e9..275f8eda7d 100644 --- a/src/textual/widgets/_data_table.py +++ b/src/textual/widgets/_data_table.py @@ -46,9 +46,6 @@ CellType = TypeVar("CellType") """Type used for cells in the DataTable.""" -_DEFAULT_CELL_X_PADDING = 1 -"""Default padding to use on each side of a column in the data table.""" - _EMPTY_TEXT = Text(no_wrap=True, end="") @@ -381,7 +378,7 @@ class DataTable(ScrollView, Generic[CellType], can_focus=True): show_cursor = Reactive(True) cursor_type: Reactive[CursorType] = Reactive[CursorType]("cell") """The type of the cursor of the `DataTable`.""" - cell_padding = Reactive(_DEFAULT_CELL_X_PADDING) + cell_padding = Reactive(1) """Horizontal padding between cells, applied on each side of each cell.""" cursor_coordinate: Reactive[Coordinate] = Reactive( @@ -658,7 +655,7 @@ def __init__( cursor_foreground_priority: Literal["renderable", "css"] = "css", cursor_background_priority: Literal["renderable", "css"] = "renderable", cursor_type: CursorType = "cell", - cell_padding: int = _DEFAULT_CELL_X_PADDING, + cell_padding: int = 1, name: str | None = None, id: str | None = None, classes: str | None = None, diff --git a/tests/test_data_table.py b/tests/test_data_table.py index 018a3939a3..d78d49e2fa 100644 --- a/tests/test_data_table.py +++ b/tests/test_data_table.py @@ -11,7 +11,6 @@ from textual.geometry import Offset from textual.message import Message from textual.widgets import DataTable -from textual.widgets._data_table import _DEFAULT_CELL_X_PADDING from textual.widgets.data_table import ( CellDoesNotExist, CellKey, @@ -26,6 +25,9 @@ ROWS = [["0/0", "0/1"], ["1/0", "1/1"], ["2/0", "2/1"]] +_DEFAULT_CELL_X_PADDING = 1 + + class DataTableApp(App): messages_to_record = { "CellHighlighted", From 52a8d80d01cdd9b041eefeb927a77a61652954e5 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 16:26:54 +0100 Subject: [PATCH 49/80] simplify test --- tests/test_await_remove.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_await_remove.py b/tests/test_await_remove.py index c6630afab3..3b380e08b3 100644 --- a/tests/test_await_remove.py +++ b/tests/test_await_remove.py @@ -3,8 +3,8 @@ class SelfRemovingLabel(Label): - def on_mount(self) -> None: - self.set_timer(0.2, self.remove) + async def on_mount(self) -> None: + await self.remove() class RemoveOnTimerApp(App[None]): @@ -17,6 +17,5 @@ async def test_multiple_simultaneous_removals(): """Regression test for https://github.com/Textualize/textual/issues/2854.""" # The app should run and finish without raising any errors. async with RemoveOnTimerApp().run_test() as pilot: - await pilot.pause(0.3) # Sanity check to ensure labels were removed. assert len(pilot.app.query(Label)) == 0 From 6a6e2fdc2e470b49065accf9de742ba1e93bfae8 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 17:00:10 +0100 Subject: [PATCH 50/80] doc fix --- docs/stylesheets/custom.css | 4 ++++ src/textual/screen.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/stylesheets/custom.css b/docs/stylesheets/custom.css index 6d54ce45b4..80322587f2 100644 --- a/docs/stylesheets/custom.css +++ b/docs/stylesheets/custom.css @@ -13,6 +13,10 @@ h3 .doc-heading code { monospace; } +.doc-heading.doc-heading-parameter { + font-size: .65rem; +} + body[data-md-color-primary="black"] .excalidraw svg { will-change: filter; filter: invert(100%) hue-rotate(180deg); diff --git a/src/textual/screen.py b/src/textual/screen.py index 0b308d5817..722e14719a 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -1231,7 +1231,7 @@ def _forward_event(self, event: events.Event) -> None: def dismiss(self, result: ScreenResultType | None = None) -> AwaitComplete: """Dismiss the screen, optionally with a result. - Any callback provided in [push_screen][textual.app.push_screen] will be invoked with the supplied result. + Any callback provided in [push_screen][textual.app.App.push_screen] will be invoked with the supplied result. Only the active screen may be dismissed. This method will produce a warning in the logs if called on an inactive screen (but otherwise have no effect). From 24ee9aea43c68d72074190f1b8c7e6b8b41e0f7e Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 11:21:24 +0100 Subject: [PATCH 51/80] remove tab fix --- src/textual/widgets/_tabbed_content.py | 5 +--- src/textual/widgets/_tabs.py | 36 ++++++++++++-------------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/src/textual/widgets/_tabbed_content.py b/src/textual/widgets/_tabbed_content.py index b69e1f24c7..8809417917 100644 --- a/src/textual/widgets/_tabbed_content.py +++ b/src/textual/widgets/_tabbed_content.py @@ -462,10 +462,7 @@ def remove_pane(self, pane_id: str) -> AwaitComplete: # other means; so allow that to be a no-op. pass - async def _remove_content() -> None: - await gather(*removal_awaitables) - - return AwaitComplete(_remove_content()) + return AwaitComplete(*removal_awaitables) def clear_panes(self) -> AwaitComplete: """Remove all the panes in the tabbed content. diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index dce53e0e81..798a06b72b 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -1,6 +1,5 @@ from __future__ import annotations -import asyncio from dataclasses import dataclass from typing import ClassVar @@ -520,27 +519,20 @@ def remove_tab(self, tab_or_id: Tab | str | None) -> AwaitComplete: except NoMatches: return AwaitComplete() - removing_active_tab = remove_tab.has_class("-active") - next_tab = self._next_active - remove_await = remove_tab.remove() - - highlight_updated = asyncio.Event() + if remove_tab.has_class("-active"): + next_tab = self._next_active + else: + next_tab = None async def do_remove() -> None: """Perform the remove after refresh so the underline bar gets new positions.""" - await remove_await - if next_tab is None or (removing_active_tab and next_tab.id is None): - self.active = "" - elif removing_active_tab: + await remove_tab.remove() + if next_tab is not None: self.active = next_tab.id or "" - next_tab.add_class("-active") - - highlight_updated.set() - - async def wait_for_highlight_update() -> None: - await highlight_updated.wait() + if not self.query("#tabs-list > Tab"): + self.active = "" - return AwaitComplete(do_remove(), wait_for_highlight_update()) + return AwaitComplete(do_remove()) def validate_active(self, active: str) -> str: """Check id assigned to active attribute is a valid tab.""" @@ -584,7 +576,10 @@ def watch_active(self, previously_active: str, active: str) -> None: except NoMatches: return active_tab.add_class("-active") - self._highlight_active(animate=previously_active != "") + + self.call_after_refresh( + self._highlight_active, animate=previously_active != "" + ) self._scroll_active_tab() self.post_message(self.TabActivated(self, active_tab)) else: @@ -604,7 +599,7 @@ def _highlight_active( """ underline = self.query_one(Underline) try: - active_tab = self.query_one(f"#tabs-list > Tab.-active") + active_tab = self.query_one("#tabs-list > Tab.-active") except NoMatches: underline.show_highlight = False underline.highlight_start = 0 @@ -619,7 +614,7 @@ def _highlight_active( def animate_underline() -> None: """Animate the underline.""" try: - active_tab = self.query_one(f"#tabs-list > Tab.-active") + active_tab = self.query_one("#tabs-list > Tab.-active") except NoMatches: pass else: @@ -642,6 +637,7 @@ def animate_underline() -> None: self.set_timer(0.02, lambda: self.call_after_refresh(animate_underline)) else: + print(start, end) underline.highlight_start = start underline.highlight_end = end From b7d6cec2cf13d174aabac2a2a6251a82c454f349 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 11:31:51 +0100 Subject: [PATCH 52/80] remove debug --- src/textual/widgets/_tabs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index 798a06b72b..24c07c8325 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -637,7 +637,6 @@ def animate_underline() -> None: self.set_timer(0.02, lambda: self.call_after_refresh(animate_underline)) else: - print(start, end) underline.highlight_start = start underline.highlight_end = end From b2f1c35f8acb3b59bc3c70285bd7658f1291f63c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 13:36:04 +0100 Subject: [PATCH 53/80] move underline --- src/textual/widgets/_tabs.py | 46 ++++++++++++++------------ tests/snapshot_tests/test_snapshots.py | 5 +++ 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index 24c07c8325..ecab1d6089 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -577,9 +577,8 @@ def watch_active(self, previously_active: str, active: str) -> None: return active_tab.add_class("-active") - self.call_after_refresh( - self._highlight_active, animate=previously_active != "" - ) + self._highlight_active(animate=previously_active != "") + self._scroll_active_tab() self.post_message(self.TabActivated(self, active_tab)) else: @@ -609,19 +608,19 @@ def _highlight_active( tab_region = active_tab.virtual_region.shrink(active_tab.styles.gutter) start, end = tab_region.column_span # This is a basic animation, so we only disable it if we want no animations. - if animate and self.app.animation_level != "none": - - def animate_underline() -> None: - """Animate the underline.""" - try: - active_tab = self.query_one("#tabs-list > Tab.-active") - except NoMatches: - pass - else: - tab_region = active_tab.virtual_region.shrink( - active_tab.styles.gutter - ) - start, end = tab_region.column_span + + def move_underline(animate: bool) -> None: + """Move the tab underline.""" + try: + active_tab = self.query_one("#tabs-list > Tab.-active") + except NoMatches: + pass + else: + tab_region = active_tab.virtual_region.shrink( + active_tab.styles.gutter + ) + start, end = tab_region.column_span + if animate: underline.animate( "highlight_start", start, @@ -634,11 +633,16 @@ def animate_underline() -> None: duration=0.3, level="basic", ) - - self.set_timer(0.02, lambda: self.call_after_refresh(animate_underline)) - else: - underline.highlight_start = start - underline.highlight_end = end + else: + underline.highlight_start = start + underline.highlight_end = end + + self.set_timer( + 0.02, + lambda: self.call_after_refresh( + move_underline, animate and self.app.animation_level != "none" + ), + ) async def _on_tab_clicked(self, event: Tab.Clicked) -> None: """Activate a tab that was clicked.""" diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 8fe8d6b896..1c76f92b33 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -1404,3 +1404,8 @@ async def run_before(pilot: Pilot): await pilot.hover("#foo") assert snap_compare(SNAPSHOT_APPS_DIR / "enter_or_leave.py", run_before=run_before) + + +def test_remove_tab_no_animation(snap_compare): + """Regression test for https://github.com/Textualize/textual/issues/4814""" + assert snap_compare(SNAPSHOT_APPS_DIR / "remove_tab.py", press=["space"]) From b88372f8e65b59b64cca927c6cda32762f65ba14 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 14:02:26 +0100 Subject: [PATCH 54/80] test fixes --- src/textual/_animator.py | 5 + src/textual/widgets/_tabs.py | 18 +- .../test_tabs_underline_animation.py | 43 ++--- .../test_remove_tab_no_animation.svg | 154 ++++++++++++++++++ .../snapshot_apps/remove_tab.py | 30 ++++ 5 files changed, 212 insertions(+), 38 deletions(-) create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_tab_no_animation.svg create mode 100644 tests/snapshot_tests/snapshot_apps/remove_tab.py diff --git a/src/textual/_animator.py b/src/textual/_animator.py index 8a669b2c8a..39cb34a976 100644 --- a/src/textual/_animator.py +++ b/src/textual/_animator.py @@ -316,6 +316,7 @@ def animate( on_complete: Callback to run after the animation completes. level: Minimum level required for the animation to take place (inclusive). """ + self._record_animation(attribute) animate_callback = partial( self._animate, obj, @@ -336,6 +337,9 @@ def animate( else: animate_callback() + def _record_animation(self, attribute: str) -> None: + """Used in mocks to make a record of animations.""" + def _animate( self, obj: object, @@ -438,6 +442,7 @@ def _animate( ), level=level, ) + assert animation is not None, "animation expected to be non-None" current_animation = self._animations.get(animation_key) diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index ecab1d6089..fbf8355a29 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -598,16 +598,13 @@ def _highlight_active( """ underline = self.query_one(Underline) try: - active_tab = self.query_one("#tabs-list > Tab.-active") + _active_tab = self.query_one("#tabs-list > Tab.-active") except NoMatches: underline.show_highlight = False underline.highlight_start = 0 underline.highlight_end = 0 else: underline.show_highlight = True - tab_region = active_tab.virtual_region.shrink(active_tab.styles.gutter) - start, end = tab_region.column_span - # This is a basic animation, so we only disable it if we want no animations. def move_underline(animate: bool) -> None: """Move the tab underline.""" @@ -637,12 +634,13 @@ def move_underline(animate: bool) -> None: underline.highlight_start = start underline.highlight_end = end - self.set_timer( - 0.02, - lambda: self.call_after_refresh( - move_underline, animate and self.app.animation_level != "none" - ), - ) + if animate and self.app.animation_level != "none": + self.set_timer( + 0.02, + lambda: self.call_after_refresh(move_underline, True), + ) + else: + self.call_after_refresh(move_underline, False) async def _on_tab_clicked(self, event: Tab.Clicked) -> None: """Activate a tab that was clicked.""" diff --git a/tests/animations/test_tabs_underline_animation.py b/tests/animations/test_tabs_underline_animation.py index 05e83e9e5d..c50409d59a 100644 --- a/tests/animations/test_tabs_underline_animation.py +++ b/tests/animations/test_tabs_underline_animation.py @@ -5,7 +5,6 @@ from textual.app import App, ComposeResult from textual.widgets import Label, TabbedContent, Tabs -from textual.widgets._tabs import Underline class TabbedContentApp(App[None]): @@ -20,19 +19,15 @@ async def test_tabs_underline_animates_on_full() -> None: app = TabbedContentApp() app.animation_level = "full" + animations: list[str] = [] + async with app.run_test() as pilot: - underline = app.query_one(Underline) animator = app.animator - # Freeze time at 0 before triggering the animation. - animator._get_time = lambda *_: 0 + animator._record_animation = animations.append app.query_one(Tabs).action_previous_tab() await pilot.pause() - # Freeze time after the animation start and before animation end. - animator._get_time = lambda *_: 0.01 - # Move to the next frame. - animator() - assert animator.is_being_animated(underline, "highlight_start") - assert animator.is_being_animated(underline, "highlight_end") + assert "highlight_start" in animations + assert "highlight_end" in animations async def test_tabs_underline_animates_on_basic() -> None: @@ -40,19 +35,15 @@ async def test_tabs_underline_animates_on_basic() -> None: app = TabbedContentApp() app.animation_level = "basic" + animations: list[str] = [] + async with app.run_test() as pilot: - underline = app.query_one(Underline) animator = app.animator - # Freeze time at 0 before triggering the animation. - animator._get_time = lambda *_: 0 + animator._record_animation = animations.append app.query_one(Tabs).action_previous_tab() await pilot.pause() - # Freeze time after the animation start and before animation end. - animator._get_time = lambda *_: 0.01 - # Move to the next frame. - animator() - assert animator.is_being_animated(underline, "highlight_start") - assert animator.is_being_animated(underline, "highlight_end") + assert "highlight_start" in animations + assert "highlight_end" in animations async def test_tabs_underline_does_not_animate_on_none() -> None: @@ -60,16 +51,12 @@ async def test_tabs_underline_does_not_animate_on_none() -> None: app = TabbedContentApp() app.animation_level = "none" + animations: list[str] = [] + async with app.run_test() as pilot: - underline = app.query_one(Underline) animator = app.animator - # Freeze time at 0 before triggering the animation. - animator._get_time = lambda *_: 0 + animator._record_animation = animations.append app.query_one(Tabs).action_previous_tab() await pilot.pause() - # Freeze time after the animation start and before animation end. - animator._get_time = lambda *_: 0.01 - # Move to the next frame. - animator() - assert not animator.is_being_animated(underline, "highlight_start") - assert not animator.is_being_animated(underline, "highlight_end") + assert "highlight_start" not in animations + assert "highlight_end" not in animations diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_tab_no_animation.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_tab_no_animation.svg new file mode 100644 index 0000000000..5a932b3641 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_remove_tab_no_animation.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ReproApp + + + + + + + + + + +bar22baz333qux4444 +━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +bar contents                                                                 + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/snapshot_apps/remove_tab.py b/tests/snapshot_tests/snapshot_apps/remove_tab.py new file mode 100644 index 0000000000..67a595f513 --- /dev/null +++ b/tests/snapshot_tests/snapshot_apps/remove_tab.py @@ -0,0 +1,30 @@ +from textual.app import App +from textual.binding import Binding +from textual.widgets import Label, TabbedContent, TabPane + + +class ReproApp(App[None]): + BINDINGS = [ + Binding("space", "close_pane"), + ] + + def __init__(self): + super().__init__() + self.animation_level = "none" + + def compose(self): + with TabbedContent(): + yield TabPane("foo1", Label("foo contents")) + yield TabPane("bar22", Label("bar contents")) + yield TabPane("baz333", Label("baz contents")) + yield TabPane("qux4444", Label("qux contents")) + + def action_close_pane(self): + tc = self.query_one(TabbedContent) + if tc.active: + tc.remove_pane(tc.active) + + +if __name__ == "__main__": + app = ReproApp() + app.run() From 5fe306b41d7f976b18fedb5d9fd11fa4f8d09d29 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 14:04:19 +0100 Subject: [PATCH 55/80] docstring --- src/textual/_animator.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/textual/_animator.py b/src/textual/_animator.py index 39cb34a976..5d6af31d8c 100644 --- a/src/textual/_animator.py +++ b/src/textual/_animator.py @@ -338,7 +338,11 @@ def animate( animate_callback() def _record_animation(self, attribute: str) -> None: - """Used in mocks to make a record of animations.""" + """Called when an attribute is to be animated. + + Args: + attribute: Attribute being animated. + """ def _animate( self, From d47976ff4d6d86f3e7e5bf11d2c7a095610d9e4c Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Tue, 30 Jul 2024 14:05:25 +0100 Subject: [PATCH 56/80] docstring --- src/textual/widgets/_tabs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/textual/widgets/_tabs.py b/src/textual/widgets/_tabs.py index fbf8355a29..1cd0668dc0 100644 --- a/src/textual/widgets/_tabs.py +++ b/src/textual/widgets/_tabs.py @@ -607,7 +607,11 @@ def _highlight_active( underline.show_highlight = True def move_underline(animate: bool) -> None: - """Move the tab underline.""" + """Move the tab underline. + + Args: + animate: animate the underline to its new position. + """ try: active_tab = self.query_one("#tabs-list > Tab.-active") except NoMatches: From f6115e478f6709d50f816a9867899468d667b2ef Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Wed, 31 Jul 2024 11:40:45 +0100 Subject: [PATCH 57/80] Open url (#4819) * Local open url * Open URL via driver * Writing meta to open url * Some docstrings and typing * Update docstring * Update docstring in app.py * CHANGELOG * Allow opening URL in a new tab * No errors from App.open_url * Keyword only new_tab argument in App.open_url --- CHANGELOG.md | 1 + src/textual/app.py | 10 ++++++++++ src/textual/driver.py | 17 +++++++++++++++-- src/textual/drivers/web_driver.py | 30 +++++++++++++++++++++++------- 4 files changed, 49 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c262c2ca71..be97c04a94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added `App.open_url` to open URLs in the web browser. When running via the WebDriver, the URL will be opened in the browser that is controlling the app https://github.com/Textualize/textual/pull/4819 - Added `Widget.is_mouse_over` https://github.com/Textualize/textual/pull/4818 - Added `node` attribute to `events.Enter` and `events.Leave` https://github.com/Textualize/textual/pull/4818 diff --git a/src/textual/app.py b/src/textual/app.py index cb3fd411cd..6e7c5bc556 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -3679,3 +3679,13 @@ def action_suspend_process(self) -> None: # NOTE: There is no call to publish the resume signal here, this # will be handled by the driver posting a SignalResume event # (see the event handler on App._resume_signal) above. + + def open_url(self, url: str, *, new_tab: bool = True) -> None: + """Open a URL in the default web browser. + + Args: + url: The URL to open. + new_tab: Whether to open the URL in a new tab. + """ + if self._driver is not None: + self._driver.open_url(url, new_tab) diff --git a/src/textual/driver.py b/src/textual/driver.py index 2165711a54..16d519cac4 100644 --- a/src/textual/driver.py +++ b/src/textual/driver.py @@ -3,7 +3,7 @@ import asyncio from abc import ABC, abstractmethod from contextlib import contextmanager -from typing import TYPE_CHECKING, Iterator +from typing import TYPE_CHECKING, Any, Iterator from . import events from .events import MouseUp @@ -17,7 +17,7 @@ class Driver(ABC): def __init__( self, - app: App, + app: App[Any], *, debug: bool = False, mouse: bool = True, @@ -146,6 +146,19 @@ def disable_input(self) -> None: def stop_application_mode(self) -> None: """Stop application mode, restore state.""" + def open_url(self, url: str, new_tab: bool = True) -> None: + """Open a URL in the default web browser. + + Args: + url: The URL to open. + new_tab: Whether to open the URL in a new tab. + This is only relevant when running via the WebDriver, + and is ignored when called while running through the terminal. + """ + import webbrowser + + webbrowser.open(url) + def suspend_application_mode(self) -> None: """Suspend application mode. diff --git a/src/textual/drivers/web_driver.py b/src/textual/drivers/web_driver.py index f4536639c7..18898b82a8 100644 --- a/src/textual/drivers/web_driver.py +++ b/src/textual/drivers/web_driver.py @@ -19,6 +19,7 @@ from codecs import getincrementaldecoder from functools import partial from threading import Event, Thread +from typing import Any from .. import events, log, messages from .._xterm_parser import XTermParser @@ -40,7 +41,7 @@ class WebDriver(Driver): def __init__( self, - app: App, + app: App[Any], *, debug: bool = False, mouse: bool = True, @@ -63,7 +64,8 @@ def __init__( self._input_reader = InputReader() def write(self, data: str) -> None: - """Write data to the output device. + """Write string data to the output device, which may be piped to + the controlling process (i.e. textual-web). Args: data: Raw data. @@ -73,7 +75,8 @@ def write(self, data: str) -> None: self._write(b"D%s%s" % (len(data_bytes).to_bytes(4, "big"), data_bytes)) def write_meta(self, data: dict[str, object]) -> None: - """Write meta to the controlling process (i.e. textual-web) + """Write a dictionary containing some metadata to stdout, which + may be piped to the controlling process (i.e. textual-web). Args: data: Meta dict. @@ -192,13 +195,17 @@ def _on_meta(self, packet_type: str, payload: bytes) -> None: packet_type: Packet type (currently always "M") payload: Meta payload (JSON encoded as bytes). """ - payload_map = json.loads(payload) + payload_map: dict[str, object] = json.loads(payload) _type = payload_map.get("type", {}) - if isinstance(payload_map, dict): + if isinstance(_type, str): self.on_meta(_type, payload_map) + else: + log.error( + f"Protocol error: type field value is not a string. Value is {_type!r}" + ) - def on_meta(self, packet_type: str, payload: dict) -> None: - """Process meta information. + def on_meta(self, packet_type: str, payload: dict[str, object]) -> None: + """Process a dictionary containing information received from the controlling process. Args: packet_type: The type of the packet. @@ -216,3 +223,12 @@ def on_meta(self, packet_type: str, payload: dict) -> None: self._app.post_message(messages.ExitApp()) elif packet_type == "exit": raise _ExitInput() + + def open_url(self, url: str, new_tab: bool = True) -> None: + """Open a URL in the default web browser. + + Args: + url: The URL to open. + new_tab: Whether to open the URL in a new tab. + """ + self.write_meta({"type": "open_url", "url": url, "new_tab": new_tab}) From 4bb7104dcd0a212a684ac070563bffe091ec2e37 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 10:31:50 +0100 Subject: [PATCH 58/80] mutate via data bind --- src/textual/dom.py | 4 ++-- src/textual/reactive.py | 11 +++++++++++ tests/test_reactive.py | 30 ++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index 55ce52afea..74d2e07060 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -41,7 +41,7 @@ from .css.styles import RenderStyles, Styles from .css.tokenize import IDENTIFIER from .message_pump import MessagePump -from .reactive import Reactive, ReactiveError, _watch +from .reactive import Reactive, ReactiveError, _Mutated, _watch from .timer import Timer from .walk import walk_breadth_first, walk_depth_first from .worker_manager import WorkerManager @@ -334,7 +334,7 @@ def setter(value: object) -> None: """Set bound data.""" _rich_traceback_omit = True Reactive._initialize_object(self) - setattr(self, variable_name, value) + setattr(self, variable_name, _Mutated(value)) return setter diff --git a/src/textual/reactive.py b/src/textual/reactive.py index 17b109d77e..64b6e007ce 100644 --- a/src/textual/reactive.py +++ b/src/textual/reactive.py @@ -42,6 +42,13 @@ ReactableType = TypeVar("ReactableType", bound="DOMNode") +class _Mutated: + """A wrapper to indicate a value was mutated.""" + + def __init__(self, value: Any) -> None: + self.value = value + + class ReactiveError(Exception): """Base class for reactive errors.""" @@ -273,6 +280,10 @@ def _set(self, obj: Reactable, value: ReactiveType, always: bool = False) -> Non f"Node is missing data; Check you are calling super().__init__(...) in the {obj.__class__.__name__}() constructor, before setting reactives." ) + if isinstance(value, _Mutated): + value = value.value + always = True + self._initialize_reactive(obj, self.name) if hasattr(obj, self.compute_name): diff --git a/tests/test_reactive.py b/tests/test_reactive.py index ad2da5724d..2684dcae5f 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -783,3 +783,33 @@ def compose(self) -> ComposeResult: widget.mutate_reactive(TestWidget.names) # Watcher should be invoked assert watched_names == [[], ["Paul"], ["Jessica"]] + + +async def test_mutate_reactive_data_bind() -> None: + """https://github.com/Textualize/textual/issues/4825""" + + # Record mutations to TestWidget.messages + widget_messages: list[list[str]] = [] + + class TestWidget(Widget): + messages: reactive[list[str]] = reactive(list, init=False) + + def watch_messages(self, names: list[str]) -> None: + widget_messages.append(names.copy()) + + class TestApp(App): + messages: reactive[list[str]] = reactive(list, init=False) + + def compose(self) -> ComposeResult: + yield TestWidget().data_bind(TestApp.messages) + + app = TestApp() + async with app.run_test() as pilot: + assert widget_messages == [[]] + app.messages.append("foo") + # Mutations aren't detected + assert widget_messages == [[]] + # Explicitly mutate app reactive + app.mutate_reactive(TestApp.messages) + # Mutating app, will also invoke watchers on any data binds + assert widget_messages == [[], ["foo"]] From 4fa553734fbf51ae390e555602a9775f5319f8b2 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 10:43:10 +0100 Subject: [PATCH 59/80] better test --- src/textual/dom.py | 6 +++++- tests/test_reactive.py | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/textual/dom.py b/src/textual/dom.py index 74d2e07060..d3b4b83e9e 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -8,6 +8,7 @@ import re import threading +from copy import copy from functools import lru_cache, partial from inspect import getfile from typing import ( @@ -334,7 +335,10 @@ def setter(value: object) -> None: """Set bound data.""" _rich_traceback_omit = True Reactive._initialize_object(self) - setattr(self, variable_name, _Mutated(value)) + # Copy the bound value + # Sharing the same instance with mutable objects can lead to confusing behavior + # Wrap the value in `_Mutated` so the setter knows to invoke watchers etc + setattr(self, variable_name, _Mutated(copy(value))) return setter diff --git a/tests/test_reactive.py b/tests/test_reactive.py index 2684dcae5f..49ab1fd0f6 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -804,12 +804,25 @@ def compose(self) -> ComposeResult: yield TestWidget().data_bind(TestApp.messages) app = TestApp() - async with app.run_test() as pilot: + async with app.run_test(): + test_widget = app.query_one(TestWidget) assert widget_messages == [[]] + assert test_widget.messages == [] + + # Previously setting a mutable object would lead to shared references + assert app.messages is not test_widget.messages + + # Mutate app app.messages.append("foo") # Mutations aren't detected assert widget_messages == [[]] + assert app.messages == ["foo"] + assert test_widget.messages == [] # Explicitly mutate app reactive app.mutate_reactive(TestApp.messages) # Mutating app, will also invoke watchers on any data binds assert widget_messages == [[], ["foo"]] + assert app.messages == ["foo"] + assert test_widget.messages == ["foo"] + + assert app.messages is not test_widget.messages From c5f1b79738268a205963e36e55ea605a8768e572 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 12:06:33 +0100 Subject: [PATCH 60/80] no copy --- docs/guide/reactivity.md | 3 ++- src/textual/dom.py | 8 +++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/guide/reactivity.md b/docs/guide/reactivity.md index ff7a1cebdf..eb058a130b 100644 --- a/docs/guide/reactivity.md +++ b/docs/guide/reactivity.md @@ -410,7 +410,8 @@ Note the call to `mutate_reactive`. Without it, the display would not update whe ## Data binding -Reactive attributes from one widget may be *bound* (connected) to another widget, so that changes to a single reactive will automatically update another widget (potentially more than one). +Reactive attributes may be *bound* (connected) to attributes on child widgets, so that changes to the parent are automatically reflected in the children. +This can simplify working with compound widgets where the value of an attribute might be used in multiple places. To bind reactive attributes, call [data_bind][textual.dom.DOMNode.data_bind] on a widget. This method accepts reactives (as class attributes) in positional arguments or keyword arguments. diff --git a/src/textual/dom.py b/src/textual/dom.py index d3b4b83e9e..3dd5bc757a 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -8,7 +8,6 @@ import re import threading -from copy import copy from functools import lru_cache, partial from inspect import getfile from typing import ( @@ -280,6 +279,7 @@ def compose(self) -> ComposeResult: yield WorldClock("Asia/Tokyo").data_bind(WorldClockApp.time) ``` + Raises: ReactiveError: If the data wasn't bound. @@ -335,10 +335,8 @@ def setter(value: object) -> None: """Set bound data.""" _rich_traceback_omit = True Reactive._initialize_object(self) - # Copy the bound value - # Sharing the same instance with mutable objects can lead to confusing behavior - # Wrap the value in `_Mutated` so the setter knows to invoke watchers etc - setattr(self, variable_name, _Mutated(copy(value))) + # Wrap the value in `_Mutated` so the setter knows to invoke watchers etc. + setattr(self, variable_name, _Mutated(value)) return setter From 881a4f2e0f95b9570136c850626728dd3a61f7eb Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 12:12:48 +0100 Subject: [PATCH 61/80] test fix --- tests/test_reactive.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/test_reactive.py b/tests/test_reactive.py index 49ab1fd0f6..54b57e337e 100644 --- a/tests/test_reactive.py +++ b/tests/test_reactive.py @@ -809,20 +809,18 @@ def compose(self) -> ComposeResult: assert widget_messages == [[]] assert test_widget.messages == [] - # Previously setting a mutable object would lead to shared references - assert app.messages is not test_widget.messages + # Should be the same instance + assert app.messages is test_widget.messages # Mutate app app.messages.append("foo") # Mutations aren't detected assert widget_messages == [[]] assert app.messages == ["foo"] - assert test_widget.messages == [] + assert test_widget.messages == ["foo"] # Explicitly mutate app reactive app.mutate_reactive(TestApp.messages) # Mutating app, will also invoke watchers on any data binds assert widget_messages == [[], ["foo"]] assert app.messages == ["foo"] assert test_widget.messages == ["foo"] - - assert app.messages is not test_widget.messages From a4699ef523a56178cf4892b56abea00b022089d8 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 15:09:43 +0100 Subject: [PATCH 62/80] note --- src/textual/dom.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/textual/dom.py b/src/textual/dom.py index 3dd5bc757a..6e84f53ee3 100644 --- a/src/textual/dom.py +++ b/src/textual/dom.py @@ -253,6 +253,10 @@ def mutate_reactive(self, reactive: Reactive[ReactiveType]) -> None: this method after your reactive is updated. This will ensure that all the reactive _superpowers_ work. + !!! note + + This method will cause watchers to be called, even if the value hasn't changed. + Args: reactive: A reactive property (use the class scope syntax, i.e. `MyClass.my_reactive`). """ From 4a098eee3ab50222601a1cc2902ef9d4aa361b96 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 15:57:24 +0100 Subject: [PATCH 63/80] bump --- CHANGELOG.md | 3 ++- pyproject.toml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be97c04a94..7983f07bba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## Unreleased +## [0.75.0] - 2024-08-01 ### Added @@ -2250,6 +2250,7 @@ https://textual.textualize.io/blog/2022/11/08/version-040/#version-040 - New handler system for messages that doesn't require inheritance - Improved traceback handling +[0.75.0]: https://github.com/Textualize/textual/compare/v0.74.0...v0.75.0 [0.74.0]: https://github.com/Textualize/textual/compare/v0.73.0...v0.74.0 [0.73.0]: https://github.com/Textualize/textual/compare/v0.72.0...v0.73.0 [0.72.0]: https://github.com/Textualize/textual/compare/v0.71.0...v0.72.0 diff --git a/pyproject.toml b/pyproject.toml index 0cfd6fd9bd..82c9eef6ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "textual" -version = "0.74.0" +version = "0.75.0" homepage = "https://github.com/Textualize/textual" repository = "https://github.com/Textualize/textual" documentation = "https://textual.textualize.io/" From 3c528d8a507645cce8f8bdd34576fd9bc47e96d7 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Thu, 1 Aug 2024 15:59:02 +0100 Subject: [PATCH 64/80] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7983f07bba..77148c379f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - `events.Enter` and `events.Leave` events now bubble. https://github.com/Textualize/textual/pull/4818 - Renamed `Widget.mouse_over` to `Widget.mouse_hover` https://github.com/Textualize/textual/pull/4818 +### Fixed + +- Fixed issue with `mutate_reactive` and data binding https://github.com/Textualize/textual/pull/4828 + ## [0.74.0] - 2024-07-25 ### Added From 387f9ee65cc179673bd679a5d7805344597f0591 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Mon, 22 Jul 2024 00:38:41 +0200 Subject: [PATCH 65/80] Introduced MaskedInput widget --- src/textual/widgets/_masked_input.py | 286 +- .../__snapshots__/test_snapshots.ambr | 51229 ++++++++++++++++ 2 files changed, 51301 insertions(+), 214 deletions(-) create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots.ambr diff --git a/src/textual/widgets/_masked_input.py b/src/textual/widgets/_masked_input.py index 6e8e17c994..f10f6f6e79 100644 --- a/src/textual/widgets/_masked_input.py +++ b/src/textual/widgets/_masked_input.py @@ -2,7 +2,7 @@ import re from dataclasses import dataclass -from enum import Flag, auto +from enum import IntFlag from typing import TYPE_CHECKING, Iterable, Pattern from rich.console import Console, ConsoleOptions, RenderableType @@ -25,22 +25,19 @@ """Possible messages that trigger input validation.""" -class _CharFlags(Flag): +class _CharFlags(IntFlag): """Misc flags for a single template character definition""" - NONE = 0 - """Empty flags value""" - - REQUIRED = auto() + REQUIRED = 0x1 """Is this character required for validation?""" - SEPARATOR = auto() + SEPARATOR = 0x2 """Is this character a separator?""" - UPPERCASE = auto() + UPPERCASE = 0x4 """Char is forced to be uppercase""" - LOWERCASE = auto() + LOWERCASE = 0x8 """Char is forced to be lowercase""" @@ -86,8 +83,8 @@ def __rich_console__( template.mask[value_length:], style, ) - for index, (char, char_definition) in enumerate(zip(value, template.template)): - if char == " ": + for index, (c, char_def) in enumerate(zip(value, template.template)): + if c == " ": result.stylize(style, index, index + 1) if self.cursor_visible and input.has_focus: @@ -116,78 +113,63 @@ class _Template(Validator): """Template mask enforcer.""" @dataclass - class CharDefinition: + class CharDef: """Holds data for a single char of the template mask.""" pattern: Pattern[str] """Compiled regular expression to check for matches.""" - flags: _CharFlags = _CharFlags.NONE + flags: _CharFlags = _CharFlags(0) """Flags defining special behaviors""" char: str = "" """Mask character (separator or blank or placeholder)""" def __init__(self, input: Input, template_str: str) -> None: - """Initialise the mask enforcer, which is also a subclass of `Validator`. - - Args: - input: The `MaskedInput` that owns this object. - template_str: Template string controlling masked input behavior. - """ self.input = input - self.template: list[_Template.CharDefinition] = [] + self.template: list[_Template.CharDef] = [] self.blank: str = " " escaped = False - flags = _CharFlags.NONE + flags = _CharFlags(0) template_chars: list[str] = list(template_str) while template_chars: - char = template_chars.pop(0) + c = template_chars.pop(0) if escaped: - char_definition = self.CharDefinition( - re.compile(re.escape(char)), _CharFlags.SEPARATOR, char - ) + char = self.CharDef(re.compile(re.escape(c)), _CharFlags.SEPARATOR, c) escaped = False else: - if char == "\\": + if c == "\\": escaped = True continue - elif char == ";": + elif c == ";": break new_flags = { ">": _CharFlags.UPPERCASE, "<": _CharFlags.LOWERCASE, - "!": _CharFlags.NONE, - }.get(char, None) + "!": 0, + }.get(c, None) if new_flags is not None: flags = new_flags continue - pattern, required_flag = _TEMPLATE_CHARACTERS.get(char, (None, None)) + pattern, required_flag = _TEMPLATE_CHARACTERS.get(c, (None, None)) if pattern: - char_flags = ( - _CharFlags.REQUIRED if required_flag else _CharFlags.NONE - ) - char_definition = self.CharDefinition( - re.compile(pattern), char_flags - ) + char_flags = _CharFlags.REQUIRED if required_flag else _CharFlags(0) + char = self.CharDef(re.compile(pattern), char_flags) else: - char_definition = self.CharDefinition( - re.compile(re.escape(char)), _CharFlags.SEPARATOR, char + char = self.CharDef( + re.compile(re.escape(c)), _CharFlags.SEPARATOR, c ) - char_definition.flags |= flags - self.template.append(char_definition) + char.flags |= flags + self.template.append(char) if template_chars: self.blank = template_chars[0] - if all( - (_CharFlags.SEPARATOR in char_definition.flags) - for char_definition in self.template - ): + if all(char.flags & _CharFlags.SEPARATOR for char in self.template): raise ValueError( "Template must contain at least one non-separator character" ) @@ -195,52 +177,24 @@ def __init__(self, input: Input, template_str: str) -> None: self.update_mask(input.placeholder) def validate(self, value: str) -> ValidationResult: - """Checks if `value` matches this template, always returning a ValidationResult. - - Args: - value: The string value to be validated. - - Returns: - A ValidationResult with the validation outcome. - - """ if self.check(value.ljust(len(self.template), chr(0)), False): return self.success() else: return self.failure("Value does not match template!", value) def check(self, value: str, allow_space: bool) -> bool: - """Checks if `value matches this template, but returns result as a bool. - - Args: - value: The string value to be validated. - allow_space: Consider space character in `value` as valid. - - Returns: - True if `value` is valid for this template, False otherwise. - """ - for char, char_definition in zip(value, self.template): + for c, char_def in zip(value, self.template): if ( - (_CharFlags.REQUIRED in char_definition.flags) - and (not char_definition.pattern.match(char)) - and ((char != " ") or not allow_space) + (char_def.flags & _CharFlags.REQUIRED) + and (not char_def.pattern.match(c)) + and ((c != " ") or not allow_space) ): return False return True def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int]: - """Automatically inserts separators in `value` at `cursor_position` if expected, eventually advancing - the current cursor position. - - Args: - value: Current control value entered by user. - cursor_position: Where to start inserting separators (if any). - - Returns: - A tuple in the form `(value, cursor_position)` with new value and possibly advanced cursor position. - """ while cursor_position < len(self.template) and ( - _CharFlags.SEPARATOR in self.template[cursor_position].flags + self.template[cursor_position].flags & _CharFlags.SEPARATOR ): value = ( value[:cursor_position] @@ -251,35 +205,25 @@ def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int] return value, cursor_position def insert_text_at_cursor(self, text: str) -> str | None: - """Inserts `text` at current cursor position. If not present in `text`, any expected separator is automatically - inserted at the correct position. - - Args: - text: The text to be inserted. - - Returns: - A tuple in the form `(value, cursor_position)` with the new control value and current cursor position if - `text` matches the template, None otherwise. - """ value = self.input.value cursor_position = self.input.cursor_position separators = set( [ - char_definition.char - for char_definition in self.template - if _CharFlags.SEPARATOR in char_definition.flags + char_def.char + for char_def in self.template + if char_def.flags & _CharFlags.SEPARATOR ] ) - for char in text: - if char in separators: - if char == self.next_separator(cursor_position): + for c in text: + if c in separators: + if c == self.next_separator(cursor_position): prev_position = self.prev_separator_position(cursor_position) if (cursor_position > 0) and (prev_position != cursor_position - 1): next_position = self.next_separator_position(cursor_position) while cursor_position < next_position + 1: if ( - _CharFlags.SEPARATOR - in self.template[cursor_position].flags + self.template[cursor_position].flags + & _CharFlags.SEPARATOR ): char = self.template[cursor_position].char else: @@ -293,65 +237,49 @@ def insert_text_at_cursor(self, text: str) -> str | None: continue if cursor_position >= len(self.template): break - char_definition = self.template[cursor_position] - assert _CharFlags.SEPARATOR not in char_definition.flags - if not char_definition.pattern.match(char): + char_def = self.template[cursor_position] + assert (char_def.flags & _CharFlags.SEPARATOR) == 0 + if not char_def.pattern.match(c): return None - if _CharFlags.LOWERCASE in char_definition.flags: - char = char.lower() - elif _CharFlags.UPPERCASE in char_definition.flags: - char = char.upper() - value = value[:cursor_position] + char + value[cursor_position + 1 :] + if char_def.flags & _CharFlags.LOWERCASE: + c = c.lower() + elif char_def.flags & _CharFlags.UPPERCASE: + c = c.upper() + value = value[:cursor_position] + c + value[cursor_position + 1 :] cursor_position += 1 value, cursor_position = self.insert_separators(value, cursor_position) return value, cursor_position def move_cursor(self, delta: int) -> None: - """Moves the cursor position by `delta` characters, skipping separators if - running over them. - - Args: - delta: The number of characters to move; positive moves right, negative - moves left. - """ cursor_position = self.input.cursor_position if delta < 0 and all( - [ - (_CharFlags.SEPARATOR in char_definition.flags) - for char_definition in self.template[:cursor_position] - ] + [c.flags & _CharFlags.SEPARATOR for c in self.template[:cursor_position]] ): return cursor_position += delta while ( (cursor_position >= 0) and (cursor_position < len(self.template)) - and (_CharFlags.SEPARATOR in self.template[cursor_position].flags) + and (self.template[cursor_position].flags & _CharFlags.SEPARATOR) ): cursor_position += delta self.input.cursor_position = cursor_position def delete_at_position(self, position: int | None = None) -> None: - """Deletes character at `position`. - - Args: - position: Position within the control value where to delete a character; - if None the current cursor position is used. - """ value = self.input.value if position is None: position = self.input.cursor_position cursor_position = position if cursor_position < len(self.template): - assert _CharFlags.SEPARATOR not in self.template[cursor_position].flags + assert (self.template[cursor_position].flags & _CharFlags.SEPARATOR) == 0 if cursor_position == len(value) - 1: value = value[:cursor_position] else: value = value[:cursor_position] + " " + value[cursor_position + 1 :] pos = len(value) while pos > 0: - char_definition = self.template[pos - 1] - if (_CharFlags.SEPARATOR not in char_definition.flags) and ( + char_def = self.template[pos - 1] + if ((char_def.flags & _CharFlags.SEPARATOR) == 0) and ( value[pos - 1] != " " ): break @@ -364,74 +292,32 @@ def delete_at_position(self, position: int | None = None) -> None: self.input.value = value def at_separator(self, position: int | None = None) -> bool: - """Checks if character at `position` is a separator. - - Args: - position: Position within the control value where to check; - if None the current cursor position is used. - - Returns: - True if character is a separator, False otherwise. - """ if position is None: position = self.input.cursor_position if (position >= 0) and (position < len(self.template)): - return _CharFlags.SEPARATOR in self.template[position].flags + return bool(self.template[position].flags & _CharFlags.SEPARATOR) else: return False def prev_separator_position(self, position: int | None = None) -> int | None: - """Obtains the position of the previous separator character starting from - `position` within the template string. - - Args: - position: Starting position from which to search previous separator. - If None, current cursor position is used. - - Returns: - The position of the previous separator, or None if no previous - separator is found. - """ if position is None: position = self.input.cursor_position for index in range(position - 1, 0, -1): - if _CharFlags.SEPARATOR in self.template[index].flags: + if self.template[index].flags & _CharFlags.SEPARATOR: return index else: return None def next_separator_position(self, position: int | None = None) -> int | None: - """Obtains the position of the next separator character starting from - `position` within the template string. - - Args: - position: Starting position from which to search next separator. - If None, current cursor position is used. - - Returns: - The position of the next separator, or None if no next - separator is found. - """ if position is None: position = self.input.cursor_position for index in range(position + 1, len(self.template)): - if _CharFlags.SEPARATOR in self.template[index].flags: + if self.template[index].flags & _CharFlags.SEPARATOR: return index else: return None def next_separator(self, position: int | None = None) -> str | None: - """Obtains the next separator character starting from `position` - within the template string. - - Args: - position: Starting position from which to search next separator. - If None, current cursor position is used. - - Returns: - The next separator character, or None if no next - separator is found. - """ position = self.next_separator_position(position) if position is None: return None @@ -439,53 +325,31 @@ def next_separator(self, position: int | None = None) -> str | None: return self.template[position].char def display(self, value: str) -> str: - """Returns `value` ready for display, with spaces replaced by - placeholder characters. - - Args: - value: String value to display. - - Returns: - New string value with spaces replaced by placeholders. - """ result = [] - for char, char_definition in zip(value, self.template): - if char == " ": - char = char_definition.char - result.append(char) + for c, char_def in zip(value, self.template): + if c == " ": + c = char_def.char + result.append(c) return "".join(result) def update_mask(self, placeholder: str) -> None: - """Updates template placeholder characters from `placeholder`. If - given string is smaller than template string, template blank character - is used to fill remaining template placeholder characters. - - Args: - placeholder: New placeholder string. - """ - for index, char_definition in enumerate(self.template): - if _CharFlags.SEPARATOR not in char_definition.flags: + for index, char_def in enumerate(self.template): + if (char_def.flags & _CharFlags.SEPARATOR) == 0: if index < len(placeholder): - char_definition.char = placeholder[index] + char_def.char = placeholder[index] else: - char_definition.char = self.blank + char_def.char = self.blank @property def mask(self) -> str: - """Property returning the template placeholder mask.""" - return "".join([char_definition.char for char_definition in self.template]) + return "".join([c.char for c in self.template]) @property def empty_mask(self) -> str: - """Property returning the template placeholder mask with all non-separators replaced by space.""" return "".join( [ - ( - " " - if (_CharFlags.SEPARATOR not in char_definition.flags) - else char_definition.char - ) - for char_definition in self.template + " " if (c.flags & _CharFlags.SEPARATOR) == 0 else c.char + for c in self.template ] ) @@ -549,7 +413,6 @@ def __init__( self.tooltip = tooltip def validate_value(self, value: str) -> str: - """Validates value against template.""" if self._template is None: return value if not self._template.check(value, True): @@ -606,7 +469,6 @@ def _value(self) -> Text: return Text(value, no_wrap=True, overflow="ignore") async def _on_click(self, event: events.Click) -> None: - """Ensure clicking on value does not leave cursor on a separator.""" await super()._on_click(event) if self._template.at_separator(): self._template.move_cursor(1) @@ -629,11 +491,11 @@ def clear(self) -> None: self.value, self.cursor_position = self._template.insert_separators("", 0) def action_cursor_left(self) -> None: - """Move the cursor one position to the left; separators are skipped.""" + """Move the cursor one position to the left.""" self._template.move_cursor(-1) def action_cursor_right(self) -> None: - """Move the cursor one position to the right; separators are skipped.""" + """Accept an auto-completion or move the cursor one position to the right.""" self._template.move_cursor(1) def action_home(self) -> None: @@ -641,8 +503,7 @@ def action_home(self) -> None: self._template.move_cursor(-len(self.template)) def action_cursor_left_word(self) -> None: - """Move the cursor left next to the previous separator. If no previous - separator is found, moves the cursor to the start of the input.""" + """Move the cursor left to the start of a word.""" if self._template.at_separator(self.cursor_position - 1): position = self._template.prev_separator_position(self.cursor_position - 1) else: @@ -652,8 +513,7 @@ def action_cursor_left_word(self) -> None: self.cursor_position = position or 0 def action_cursor_right_word(self) -> None: - """Move the cursor right next to the next separator. If no next - separator is found, moves the cursor to the end of the input.""" + """Move the cursor right to the start of a word.""" position = self._template.next_separator_position() if position is None: self.cursor_position = len(self._template.mask) @@ -665,8 +525,7 @@ def action_delete_right(self) -> None: self._template.delete_at_position() def action_delete_right_word(self) -> None: - """Delete the current character and all rightward to next separator or - the end of the input.""" + """Delete the current character and all rightward to the start of the next word.""" position = self._template.next_separator_position() if position is not None: position += 1 @@ -686,8 +545,7 @@ def action_delete_left(self) -> None: self._template.delete_at_position() def action_delete_left_word(self) -> None: - """Delete leftward of the cursor position to the previous separator or - the start of the input.""" + """Delete leftward of the cursor position to the start of a word.""" if self.cursor_position <= 0: return if self._template.at_separator(self.cursor_position - 1): diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr new file mode 100644 index 0000000000..b0a9d01353 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -0,0 +1,51229 @@ +# name: test_alignment_containers + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignContainersApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  center  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  middle  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + ''' +# --- +# name: test_ansi_color_mapping[False] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AnsiMappingApp + + + + + + + + + + Foreground & background                                                          + red + dim red + green + dim green + yellow + dim yellow + blue + dim blue + magenta + dim magenta + cyan + dim cyan + white + dim white + black + dim black + + + + + + + + + + + + ''' +# --- +# name: test_ansi_color_mapping[True] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AnsiMappingApp + + + + + + + + + + Foreground & background                                                          + red + dim red + green + dim green + yellow + dim yellow + blue + dim blue + magenta + dim magenta + cyan + dim cyan + white + dim white + black + dim black + + + + + + + + + + + + ''' +# --- +# name: test_app_blur + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AppBlurApp + + + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This should be the blur style      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This should also be the blur style + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + ''' +# --- +# name: test_auto_fr + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FRApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌────────────────────────────┐ + Hello one line               + ┌──────────────────────────┐ + Widget#child + + + + + + + + + + + + + + └──────────────────────────┘ + + Two + Lines with 1x2 margin + + └────────────────────────────┘ + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_auto_grid + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + foo         ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + foo▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Longer label▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + foo bar foo bar foo bar foo ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + bar foo bar foo bar foo bar  + foo bar foo bar foo bar ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + Longer label                  ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_auto_grid_default_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridHeightAuto + + + + + + + + + + GridHeightAuto + Here is some text before the grid                                                + ┌──────────────────────────────────────────────────────────────────────────────┐ + Cell #0                   Cell #1                   Cell #2                    + Cell #3                   Cell #4                   Cell #5                    + Cell #6                   Cell #7                   Cell #8                    + └──────────────────────────────────────────────────────────────────────────────┘ + Here is some text after the grid                                                 + + + + + + + + + + + + + + + +  g Grid  v Vertical  h Horizontal  c Container  + + + + + ''' +# --- +# name: test_auto_tab_active + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ExampleApp + + + + + + + + + + + Parent 1Parent 2 + ━━━━━━━━━━━━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + Child 2.1Child 2.2 + ━━━━━━━━━━━━━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button 2.2  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + +  SPACE Focus button 2.2  + + + + + ''' +# --- +# name: test_auto_table + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + MyApp + ╭──────────────────╮╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ + ok                ││test                                                                                               + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍││╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + ││╭─ 0 ──────────────────────────────────────╮╭─ 1 ──────────────────────────────────────╮╭─ 2 ─────│ + │││││││ + │││ Foo       Bar         Baz              ││ Foo       Bar         Baz              ││ Foo      + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY▁▁││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + │││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH  0123456789  IJKLMNOPQRSTUVWXY││ ABCDEFGH + ││╰──────────────────────────────────────────╯╰──────────────────────────────────────────╯╰─────────│ + ││ + ╰──────────────────╯╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_auto_width_input + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputWidthAutoApp + + + + + + + + + + InputWidthAutoApp + ▔▔▔▔▔▔▔▔▔▔ + Hello + ▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_big_buttons + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + +  Hello  + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + +  Hello  +  World !!  + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + ''' +# --- +# name: test_bindings_screen_overrides_show + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HideBindingApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  p Binding shown  + + + + + ''' +# --- +# name: test_blur_on_disabled + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BlurApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + foo                                                                        + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_border_alpha + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderAlphaApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + ''' +# --- +# name: test_button_outline + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonIssue + + + + + + + + + + ┌──────────────┐ +  Test  + └──────────────┘ + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_button_widths + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalWidthAutoApp + + + + + + + + + + ┌────────────────────────────┐ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  This is a very wide button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + └────────────────────────────┘ + ┌────────────────────────────────────────────────────────┐ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  This is a very wide button  This is a very wide button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + └────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_button_with_console_markup + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonsWithMarkupApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Focused Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Blurred Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Disabled Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_button_with_multiline_label + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonWithMultilineLabelApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  +  with  +  multi-line  +  label  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_buttons_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ButtonsApp + + + + + + + + + + + Standard ButtonsDisabled Buttons + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Default  Default  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Primary!  Primary!  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Success!  Success!  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Warning!  Warning!  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Error!  Error!  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + ''' +# --- +# name: test_checkbox_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CheckboxApp + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + X Arrakis 😓 + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔ + X Caladan + ▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔ + X Chusuk + ▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + XGiedi Prime + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔ + XGinaz + ▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔ + X Grumman + ▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▃▃ + XKaitain + ▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + ''' +# --- +# name: test_collapsible_collapsed + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▶ Leto + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▶ Jessica + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▶ Paul + + + + + + + + + + + + + + + +  c Collapse All  e Expand All  + + + + + ''' +# --- +# name: test_collapsible_custom_symbol + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + >>> Togglev Toggle + + Hello, world.                        + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_collapsible_expanded + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Leto + + # Duke Leto I Atreides + + Head of House Atreides.                                                    + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Jessica + + + + Lady Jessica + +   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Paul▆▆ + + + +  c Collapse All  e Expand All  + + + + + ''' +# --- +# name: test_collapsible_nested + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Toggle + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▶ Toggle + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_collapsible_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CollapsibleApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Leto + + # Duke Leto I Atreides + + Head of House Atreides.                                                      + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▼ Jessica + + + + Lady Jessica + +   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▶ Paul + + + +  c Collapse All  e Expand All  + + + + + ''' +# --- +# name: test_columns_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌────────────────────┐┌────────────────┐┌──────────────────────┐ + As tall as container││This has default││I have a static height + ││height││ + ││but a││ + ││few lines││ + │└────────────────┘│ + + + + + + + + + + └────────────────────┘└──────────────────────┘ + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + + + + + + + ''' +# --- +# name: test_command_palette + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CommandPaletteApp + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + 🔎A + + +   This is a test of this code 0                                                  +   This is a test of this code 1                                                  +   This is a test of this code 2                                                  +   This is a test of this code 3                                                  +   This is a test of this code 4                                                  +   This is a test of this code 5                                                  +   This is a test of this code 6                                                  +   This is a test of this code 7                                                  +   This is a test of this code 8                                                  +   This is a test of this code 9                                                  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ''' +# --- +# name: test_command_palette_discovery + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CommandPaletteApp + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + 🔎Search for commands… + + +   This is a test of this code 0                                                  +   This is a test of this code 1                                                  +   This is a test of this code 2                                                  +   This is a test of this code 3                                                  +   This is a test of this code 4                                                  +   This is a test of this code 5                                                  +   This is a test of this code 6                                                  +   This is a test of this code 7                                                  +   This is a test of this code 8                                                  +   This is a test of this code 9                                                  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ''' +# --- +# name: test_component_text_opacity + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW + + + + + ''' +# --- +# name: test_content_switcher_example_initial + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentSwitcherApp + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  DataTable  Markdown  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ╭────────────────────────────────────────────────────────────────────╮ +  Book                                 Year  +  Dune                                 1965  +  Dune Messiah                         1969  +  Children of Dune                     1976  +  God Emperor of Dune                  1981  +  Heretics of Dune                     1984  +  Chapterhouse: Dune                   1985  + + + + + + + + + + + ╰────────────────────────────────────────────────────────────────────╯ + + + + + + ''' +# --- +# name: test_content_switcher_example_switch + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentSwitcherApp + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  DataTable  Markdown  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ╭─────────────────────────────────────────╮ + + + Three Flavours Cornetto + +   The Three Flavours Cornetto trilogy  +   is an anthology series of British  +   comedic genre films directed by Edgar   +   Wright. + + + Shaun of the Dead + + + UK Release   + Flavour   Date        Director    +    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +    Strawberry 2004-04-09   Edgar          +                            Wright         + + + + Hot Fuzz + + + UK Release    + Flavour Date         Director     +    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +    Classico 2007-02-17    Edgar Wright    + + + + The World's End + + + UK Release     + FlavourDate          Director     +    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    +    Mint    2013-07-19     Edgar Wright    + + + + + + ╰─────────────────────────────────────────╯ + + + + + + ''' +# --- +# name: test_css_hot_reloading + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HotReloadingApp + + + + + + + + + + Hello, world!                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_hot_reloading_on_screen + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HotReloadingApp + + + + + + + + + + Hello, world!                                                                    + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[align.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignApp + + + + + + + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + Vertical alignment with Textual + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + Take note, browsers. + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + ''' +# --- +# name: test_css_property[align_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AlignAllApp + + + + + + + + + + ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ + left topcenter topright top + + + + + └────────────────────────┘└────────────────────────┘└────────────────────────┘ + + ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ + + + left middlecenter middleright middle + + + └────────────────────────┘└────────────────────────┘└────────────────────────┘ + + ┌────────────────────────┐┌────────────────────────┐┌────────────────────────┐ + + + + + + left bottomcenter bottomright bottom + └────────────────────────┘└────────────────────────┘└────────────────────────┘ + + + + + ''' +# --- +# name: test_css_property[background.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BackgroundApp + + + + + + + + + + + + + Widget 1 + + + + + + + + Widget 2 + + + + + + + + Widget 3 + + + + + + + + + ''' +# --- +# name: test_css_property[background_transparency.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BackgroundTransparencyApp + + + + + + + + + + + + + + + + + + + + + 10%20%30%40%50%60%70%80%90%100% + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[border.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderApp + + + + + + + + + + + ┌────────────────────────────────────────────────────────────────────────────┐ + + My border is solid red + + └────────────────────────────────────────────────────────────────────────────┘ + + ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + + My border is dashed green + + ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + My border is tall blue + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + ''' +# --- +# name: test_css_property[border_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllBordersApp + + + + + + + + + + + +----------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓╔═════════════════╗ + |ascii|blankdasheddouble + +----------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛╚═════════════════╝ + + + + ┏━━━━━━━━━━━━━━━━┓▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ + heavyhidden/nonehkeyinner + ┗━━━━━━━━━━━━━━━━┛▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ + + + + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜█████████████████▎╭────────────────╮┌─────────────────┐ + outerpanelroundsolid + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎╰────────────────╯└─────────────────┘ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎█▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█▏                ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + tallthickvkeywide + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█▏                ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + ''' +# --- +# name: test_css_property[border_sub_title_align_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderSubTitleAlignAll + + + + + + + + + + + + ▏  Border title      ▕╭─ Lef… ─╮▁▁▁▁▁ Left ▁▁▁▁▁ + This is the story ofa Pythondeveloper that + ▏   Border subtitle  ▕╰─ Cen… ─╯▔▔▔▔▔ @@@ ▔▔▔▔▔▔ + + + + + + +--------------+─Title───────────────── + |had to fill up|             nine labels          and ended up redoing it   + +- Left -------+──────────────Subtitle─ + + + + + ─Title, but really looo…─ + ─Title, but r…──Title, but reall…─ + because the first try       had some labels          that were too long.     + ─Subtitle, bu…──Subtitle, but re…─ + ─Subtitle, but really l…─ + + + + + + + ''' +# --- +# name: test_css_property[border_subtitle_align.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderSubtitleAlignApp + + + + + + + + + + + ┌────────────────────────────────────────────────────────────────────────────┐ + + My subtitle is on the left. + + └─ < Left ───────────────────────────────────────────────────────────────────┘ + + ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + + My subtitle is centered + + ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ + + My subtitle is on the right + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ Right > ▁▎ + + + + + + + + + + + ''' +# --- +# name: test_css_property[border_title_align.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderTitleAlignApp + + + + + + + + + + + ┌─ < Left ───────────────────────────────────────────────────────────────────┐ + + My title is on the left. + + └────────────────────────────────────────────────────────────────────────────┘ + + ┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ Centered! ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + + My title is centered + + ┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Right > ▔▎ + + My title is on the right + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + + + + + + + + ''' +# --- +# name: test_css_property[border_title_colors.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderTitleApp + + + + + + + + + + + + + + + + ┏━ Textual Rocks ━━━━━━━━━━━━━┓ + + + + + Hello, World! + + + + + ┗━━━━━━━━━━━━━ Textual Rocks ━┛ + + + + + + + + + + + + ''' +# --- +# name: test_css_property[box_sizing.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BoxSizingApp + + + + + + + + + + + +   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   + + I'm using border-box! + +   ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   + + +   ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁   + + I'm using content-box! + + + + + +   ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔   + + + + + + + + + + + ''' +# --- +# name: test_css_property[color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorApp + + + + + + + + + + + + + I'm red! + + + + + + + + I'm rgb(0, 255, 0)! + + + + + + + + I'm hsl(240, 100%, 50%)! + + + + + + + + + ''' +# --- +# name: test_css_property[color_auto.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorApp + + + + + + + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + The quick brown fox jumps over the lazy dog! + + + + + + + ''' +# --- +# name: test_css_property[column_span.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + + #p1 + + + + + + #p2#p3 + + + + + + #p4#p5 + + + + + + #p6#p7 + + + + + + + + ''' +# --- +# name: test_css_property[content_align.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ContentAlignApp + + + + + + + + + + + With content-align you can... + + + + + + + + + + ...Easily align content... + + + + + + + + + + + ...Horizontally and vertically! + + + + + + ''' +# --- +# name: test_css_property[content_align_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllContentAlignApp + + + + + + + + + + left topcenter topright top + + + + + + + + + + + left middlecenter middleright middle + + + + + + + + + + + + left bottomcenter bottomright bottom + + + + + ''' +# --- +# name: test_css_property[display.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DisplayApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃Widget 1 + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃Widget 3 + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[dock_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DockAllApp + + + + + + + + + + + + + ╭──────────────────────────────────────────────────────────╮ +                            top                             + + + + + + + left                                                 right + + + + + + + +                           bottom                           + ╰──────────────────────────────────────────────────────────╯ + + + + + + + + ''' +# --- +# name: test_css_property[grid.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridApp + + + + + + + + + + + Grid cell 1Grid cell 2 + + row-span: 3; + column-span: 2; + + + Grid cell 3 + + + + + + Grid cell 4 + + + + + + Grid cell 5Grid cell 6Grid cell 7 + + + + + + + + + ''' +# --- +# name: test_css_property[grid_columns.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ + 1fr││width = 16││2fr││1fr││width = 16 + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ + ╭──────────╮╭──────────────╮╭──────────────────────╮╭──────────╮╭──────────────╮ + 1fr││width = 16││2fr││1fr││width = 16 + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ││││││││ + ╰──────────╯╰──────────────╯╰──────────────────────╯╰──────────╯╰──────────────╯ + + + + + ''' +# --- +# name: test_css_property[grid_gutter.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + + 12 + + ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + + ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + + 34 + + ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + + ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + + 56 + + ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + + ╭─────────────────────────────────────╮╭─────────────────────────────────────╮ + + 78 + + + ╰─────────────────────────────────────╯╰─────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_css_property[grid_rows.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + 1fr││1fr + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + height = 6││height = 6 + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + 25%││25% + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + 1fr││1fr + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + height = 6││height = 6 + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_css_property[grid_size_both.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + 1││2 + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + 3││4 + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮ + + 5 + + + ╰──────────────────────────────────────╯ + + + + + + + + + + + ''' +# --- +# name: test_css_property[grid_size_columns.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + ││ + 1││2 + ││ + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮╭──────────────────────────────────────╮ + ││ + ││ + 3││4 + ││ + ││ + ││ + ╰──────────────────────────────────────╯╰──────────────────────────────────────╯ + ╭──────────────────────────────────────╮ + + + 5 + + + + ╰──────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_css_property[hatch.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HatchApp + + + + + + + + + + ┌─ cross ──────┐┌─ horizontal ─┐┌─ custom ─────┐┌─ left ───────┐┌─ right ──────┐ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╳╳╳╳╳╳╳╳╳╳╳╳╳╳││──────────────││TTTTTTTTTTTTTT││╲╲╲╲╲╲╲╲╲╲╲╲╲╲││╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + └──────────────┘└──────────────┘└──────────────┘└──────────────┘└──────────────┘ + + + + + ''' +# --- +# name: test_css_property[height.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightApp + + + + + + + + + + Widget + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[height_comparison.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeightComparisonApp + + + + + + + + + + #cells· + · + · + #percent· + + · + #w· + · + · + + #h· + · + · + · + #vw + · + · + · + #vh· + + #auto· + #fr1· + #fr2· + · + + + + + ''' +# --- +# name: test_css_property[keyline.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┓ + + + #foo + + + ┣━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┫#bar + + + Placeholder + + + ┣━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━┫ + + + #baz + + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + ''' +# --- +# name: test_css_property[keyline_horizontal.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌─────────────────────────┬─────────────────────────┬──────────────────────────┐ + + + + + + + + + + + PlaceholderPlaceholderPlaceholder + + + + + + + + + + + + └─────────────────────────┴─────────────────────────┴──────────────────────────┘ + + + + + ''' +# --- +# name: test_css_property[layout.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LayoutApp + + + + + + + + + + + Layout + + Is + + Vertical + + + LayoutIsHorizontal + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_background.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkBackgroundApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_background_hover.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverBackgroundApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkColorApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_color_hover.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverColorApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_style.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkStyleApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[link_style_hover.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinkHoverStyleApp + + + + + + + + + + Visit the Textualize website.                                                    + Click here for the bell sound.                                                   + You can also click here for the bell sound.                                      + Exit this application. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[links.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LinksApp + + + + + + + + + + Here is a link which you can click! + + Here is a link which you can click! + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[margin.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarginApp + + + + + + + + + + + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see  + its path. + Where the fear has gone there will be nothing. Only I will  + remain. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[margin_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarginAllApp + + + + + + + + + + ╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ + + + + marginmargin: 1  + no marginmargin: 1: 1 51 2 6 + + + + + ╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ + + ╭────────────────╮╭─────────────────╮╭────────────────╮╭─────────────────╮ + + + margin-bottom: 4 + + margin-right: margin-left: 3 + 3 + margin-top: 4 + + + + ╰────────────────╯╰─────────────────╯╰────────────────╯╰─────────────────╯ + + + + + ''' +# --- +# name: test_css_property[max_height.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxHeightApp + + + + + + + + + + + + + max-height: 10w + max-height: 10 + max-height: 50% + + + + + + max-height: 999 + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[max_width.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaxWidthApp + + + + + + + + + + + + max-width:  + 50h + + + + + max-width: 999 + + + + + + max-width: 50% + + + + + + max-width: 30 + + + + + + + + ''' +# --- +# name: test_css_property[min_height.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinHeightApp + + + + + + + + + + + + + + + min-height: 25% + + + min-height: 75% + + + + + + min-height: 30 + min-height: 40w + + + ▃▃ + + + + + + + + + + ''' +# --- +# name: test_css_property[min_width.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MinWidthApp + + + + + + + + + + + + min-width: 25% + + + + + min-width: 75% + + + + + + min-width: 100 + + + + + + min-width: 400h + + + + + + + + + ''' +# --- +# name: test_css_property[offset.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffsetApp + + + + + + + + + + + Chani (offset 0  + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜-3) + + + + ▌Paul (offset 8 2)▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄ + + + ▌Duncan (offset 4  + ▌10) + + + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + + + + + + + ''' +# --- +# name: test_css_property[opacity.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OpacityApp + + + + + + + + + + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + opacity: 0% + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + + opacity: 25% + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + + opacity: 50% + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + + opacity: 75% + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜ + + opacity: 100% + + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟ + + + + + ''' +# --- +# name: test_css_property[outline.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OutlineApp + + + + + + + + + + + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ear is the mind-killer. + ear is the little-death that brings total obliteration. +  will face my fear. +  will permit it to pass over me and through me. + nd when it has gone past, I will turn the inner eye to see its + ath. + here the fear has gone there will be nothing. Only I will  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[outline_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllOutlinesApp + + + + + + + + + + +------------------+┏╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┓ + |ascii|blankdashed + +------------------+┗╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍┛ + + + ╔══════════════════╗┏━━━━━━━━━━━━━━━━━━┓ + doubleheavyhidden/none + ╚══════════════════╝┗━━━━━━━━━━━━━━━━━━┛ + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▗▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▖ + hkeyinnernone + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▝▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▘ + + + ▛▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▜╭──────────────────╮┌──────────────────┐ + outerroundsolid + ▙▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▟╰──────────────────╯└──────────────────┘ + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▏                  ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + tallvkeywide + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▏                  ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + ''' +# --- +# name: test_css_property[outline_vs_border.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OutlineBorderApp + + + + + + + + + + ╭───────────────────────────────────────────────────────────────────╮ + ear is the mind-killer. + ear is the little-death that brings total obliteration. +  will face my fear. +  will permit it to pass over me and through me. + nd when it has gone past, I will turn the inner eye to see its path + here the fear has gone there will be nothing. Only I will remain. + ╰───────────────────────────────────────────────────────────────────╯ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ╭─────────────────────────────────────────────────────────────────────╮ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + ╰─────────────────────────────────────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_css_property[overflow.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OverflowApp + + + + + + + + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that Fear is the little-death that  + brings total obliteration.brings total obliteration. + I will face my fear.I will face my fear. + I will permit it to pass over meI will permit it to pass over me  + and through me.and through me. + And when it has gone past, I And when it has gone past, I will  + will turn the inner eye to see turn the inner eye to see its  + its path.▁▁path. + Where the fear has gone there Where the fear has gone there will + will be nothing. Only I will be nothing. Only I will remain. + remain.▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I must not fear. + I must not fear.Fear is the mind-killer. + Fear is the mind-killer.Fear is the little-death that  + Fear is the little-death that brings total obliteration. + brings total obliteration.I will face my fear. + I will face my fear.I will permit it to pass over me  + I will permit it to pass over meand through me. + + + + + ''' +# --- +# name: test_css_property[padding.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PaddingApp + + + + + + + + + + + + + + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its  + path. + Where the fear has gone there will be nothing. Only I will  + remain. + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[padding_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PaddingAllApp + + + + + + + + + + no padding + padding: 1padding:padding: 1 1 + 1 52 6 + + + + + + + + + + padding-right: 3padding-bottom: 4padding-left: 3 + + + + padding-top: 4 + + + + + + + + + + + + ''' +# --- +# name: test_css_property[row_span.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + + #p4 + + + #p3 + + + #p2 + + + #p1 + + + #p5 + + + #p6 + + + #p7 + + + + + + + + ''' +# --- +# name: test_css_property[scrollbar_corner_color.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarCornerColorApp + + + + + + + + + + I must not fear. Fear is the mind-killer. Fear is the little-death that brings + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain.▅▅ + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + + + + + + ''' +# --- +# name: test_css_property[scrollbar_gutter.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarGutterApp + + + + + + + + + + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[scrollbar_size.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + + + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration.▁▁▁▁ + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path. + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[scrollbar_size2.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear. + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone pastAnd when it has gone past,And when it has gone past + Where the fear has gone tWhere the fear has gone thWhere the fear has gone t + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear.▇▇ + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone pastAnd when it has gone past,And when it has gone past + Where the fear has gone tWhere the fear has gone thWhere the fear has gone t + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death tFear is the little-death  + I will face my fear.I will face my fear.I will face my fear. + I will permit it to pass I will permit it to pass oI will permit it to pass  + And when it has gone past, + Where the fear has gone th + I must not fear. + Fear is the mind-killer. + + + + + + ''' +# --- +# name: test_css_property[scrollbars.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollbarApp + + + + + + + + + + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + And when it has gone past, I will turnAnd when it has gone past, I will turn + see its path.see its path. + Where the fear has gone there will be Where the fear has gone there will be  + will remain.will remain. + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + And when it has gone past, I will turnAnd when it has gone past, I will turn + see its path.▃▃see its path.▃▃ + Where the fear has gone there will be Where the fear has gone there will be  + will remain.will remain. + I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death that brings tFear is the little-death that brings t + I will face my fear.I will face my fear. + I will permit it to pass over me and tI will permit it to pass over me and t + + + + + + ''' +# --- +# name: test_css_property[scrollbars2.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Scrollbar2App + + + + + + + + + + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path.          + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer.▇▇ + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path.          + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + I will face my fear. + I will permit it to pass over me and through me. + And when it has gone past, I will turn the inner eye to see its path.          + Where the fear has gone there will be nothing. Only I will remain. + I must not fear. + Fear is the mind-killer. + Fear is the little-death that brings total obliteration. + + + + + ''' +# --- +# name: test_css_property[text_align.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAlign + + + + + + + + + + + Left alignedCenter aligned + I must not fear. Fear is the            I must not fear. Fear is the     + mind-killer. Fear is the                  mind-killer. Fear is the       + little-death that brings total         little-death that brings total    + obliteration. I will face my fear. Iobliteration. I will face my fear. I + will permit it to pass over me and   will permit it to pass over me and  + through me.                                     through me.              + + + + + + Right alignedJustified +         I must not fear. Fear is theI  must  not  fear.  Fear   is   the +             mind-killer. Fear is themind-killer.     Fear     is     the +       little-death that brings totallittle-death   that   brings   total + obliteration. I will face my fear. Iobliteration. I will face my fear. I +   will permit it to pass over me andwill permit it to pass over  me  and +                          through me.through me. + + + + + + + + + ''' +# --- +# name: test_css_property[text_opacity.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextOpacityApp + + + + + + + + + + + + + +                                text-opacity: 25%                                 + + + + +                                text-opacity: 50%                                 + + + + +                                text-opacity: 75%                                 + + + + +                                text-opacity: 100%                                + + + + + + + + + ''' +# --- +# name: test_css_property[text_style.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextStyleApp + + + + + + + + + + I must not fear.I must not fear.I must not fear. + Fear is the mind-killer.Fear is the mind-killer.Fear is the mind-killer. + Fear is the little-death Fear is the little-death Fear is the little-death  + that brings total that brings total that brings total  + obliteration.obliteration.obliteration. + I will face my fear.I will face my fear.I will face my fear. + I will permit it to pass I will permit it to pass I will permit it to pass  + over me and through me.over me and through me.over me and through me. + And when it has gone past,And when it has gone past, And when it has gone past,  + I will turn the inner eye I will turn the inner eye I will turn the inner eye  + to see its path.to see its path.to see its path. + Where the fear has gone Where the fear has gone Where the fear has gone  + there will be nothing. there will be nothing. Onlythere will be nothing. Only + Only I will remain.I will remain.I will remain. + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[text_style_all.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AllTextStyleApp + + + + + + + + + + +   nonebolditalicreverse +   I must not fear.I must not fear.I must not fear.I must not fear. +   Fear is the Fear is the Fear is the Fear is the  +   mind-killer.mind-killer.mind-killer.mind-killer. +   Fear is the Fear is the Fear is the Fear is the  +   little-death that  little-death that little-death thatlittle-death that  +   brings total brings total brings total brings total  +   obliteration.obliteration.obliteration.obliteration. +   I will face my I will face my I will face my I will face my  +   fear.fear.fear.fear. + + strikeunderlinebold italicreverse strike + I must not fear.I must not fear.I must not fear.I must not fear. + Fear is the Fear is the Fear is the Fear is the  + mind-killer.mind-killer.mind-killer.mind-killer. + Fear is the Fear is the Fear is the Fear is the  + little-death thatlittle-death that little-death thatlittle-death that  + brings total brings total brings total brings total  + obliteration.obliteration.obliteration.obliteration. + I will face my I will face my I will face my I will face my  + fear.fear.fear.fear. + I will permit it I will permit it I will permit it I will permit it  + + + + + + ''' +# --- +# name: test_css_property[tint.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TintApp + + + + + + + + + + + tint: green 0%; + + + tint: green 10%; + + + tint: green 20%; + + + tint: green 30%; + + + tint: green 40%; + + + tint: green 50%; + ▄▄ + + tint: green 60%; + + + tint: green 70%; + + + + + + ''' +# --- +# name: test_css_property[visibility.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VisibilityApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃Widget 1 + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┃Widget 3 + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[visibility_containers.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VisibilityContainersApp + + + + + + + + + + + + + PlaceholderPlaceholderPlaceholder + + + + + + + + + + + + + + + + PlaceholderPlaceholderPlaceholder + + + + + + + + + ''' +# --- +# name: test_css_property[width.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidthApp + + + + + + + + + + Widget + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_css_property[width_comparison.py] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidthComparisonApp + + + + + + + + + + + + + + + + + + + + + #cells#percent#w#h#vw#vh#auto#fr1#fr3 + + + + + + + + + + + + ····•····•····•····•····•····•····•····•····•····•····•····•····•····•····•····• + + + + + ''' +# --- +# name: test_data_table_in_tabs + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dashboard + + + + + + + + + + + Workflows + ━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +  Id   Description  Status  Result Id  +  1    2            3       4          +  a    b            c       d          +  fee  fy           fo      fum        + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_add_column + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AddColumn + + + + + + + + + +  Movies          No Default  With Default  Long Default          +  Severance       ABC           01234567890123456789  +  Foundation      ABC           01234567890123456789  +  Dark            Hello!      ABC           01234567890123456789  +  The Boys        ABC           01234567890123456789  +  The Last of Us  ABC           01234567890123456789  +  Lost in Space   ABC           01234567890123456789  +  Altered Carbon  ABC           01234567890123456789  + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_add_row_auto_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoHeightRowsApp + + + + + + + + + +  N  Column      +  3  hey there   +  1  hey there   +  5  long        +  string      +  2  ╭───────╮   +  │ Hello │   +  │ world │   +  ╰───────╯   +  4  1           +  2           +  3           +  4           +  5           +  6           +  7           + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_add_row_auto_height_sorted + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoHeightRowsApp + + + + + + + + + +  N  Column      +  1  hey there   +  2  ╭───────╮   +  │ Hello │   +  │ world │   +  ╰───────╯   +  3  hey there   +  4  1           +  2           +  3           +  4           +  5           +  6           +  7           +  5  long        +  string      + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_cell_padding + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + + + one  two  three + valuevalueval   + +  one    two    three  +  value  value  val    + +   one      two      three   +   value    value    val     + +    one        two        three    +    value      value      val      + +     one          two          three     +     value        value        val       + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_change_cell_padding + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + + + one  two  three + valuevalueval   + +  one    two    three  +  value  value  val    + +   one      two      three   +   value    value    val     + +    one        two        three    +    value      value      val      + +           one                      two                      three           +           value                    value                    val             + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_column_cursor_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  4     Joseph Schooling      Singapore      50.39  +  2     Michael Phelps        United States  51.14  +  5     Chad le Clos          South Africa   51.14  +  6     László Cseh           Hungary        51.14  +  3     Li Zhuhao             China          51.26  +  8     Mehdy Metella         France         51.58  +  7     Tom Shields           United States  51.73  +  1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_hot_reloading + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DataTableHotReloadingApp + + + + + + + + + +  A           B     +  one         two   +  three       four  +  five        six   + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_labels_and_fixed_data + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  0  5     Chad le Clos          South Africa   51.14  +  1  4     Joseph Schooling      Singapore      50.39  +  2  2     Michael Phelps        United States  51.14  +  3  6     László Cseh           Hungary        51.14  +  4  3     Li Zhuhao             China          51.26  +  5  8     Mehdy Metella         France         51.58  +  6  7     Tom Shields           United States  51.73  +  7  10    Darren Burns          Scotland       51.84  +  8  1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_remove_row + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  5     Chad le Clos          South Africa   51.14  +  4     Joseph Schooling      Singapore      50.39  +  6     László Cseh           Hungary        51.14  +  3     Li Zhuhao             China          51.26  +  7     Tom Shields           United States  51.73  +  10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  4     Joseph Schooling      Singapore      50.39  +  2     Michael Phelps        United States  51.14  +  5     Chad le Clos          South Africa   51.14  +  6     László Cseh           Hungary        51.14  +  3     Li Zhuhao             China          51.26  +  8     Mehdy Metella         France         51.58  +  7     Tom Shields           United States  51.73  +  1     Aleksandr Sadovnikov  Russia         51.84  +  10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_row_cursor_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  4     Joseph Schooling      Singapore      50.39  +  2     Michael Phelps        United States  51.14  +  5     Chad le Clos          South Africa   51.14  +  6     László Cseh           Hungary        51.14  +  3     Li Zhuhao             China          51.26  +  8     Mehdy Metella         France         51.58  +  7     Tom Shields           United States  51.73  +  1     Aleksandr Sadovnikov  Russia         51.84  + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_sort_multikey + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableApp + + + + + + + + + +  lane  swimmer               country        time   +  4     Joseph Schooling      Singapore      50.39  +  2     Michael Phelps        United States  51.14  +  5     Chad le Clos          South Africa   51.14  +  6     László Cseh           Hungary        51.14  +  3     Li Zhuhao             China          51.26  +  8     Mehdy Metella         France         51.58  +  7     Tom Shields           United States  51.73  +  1     Aleksandr Sadovnikov  Russia         51.84  +  10    Darren Burns          Scotland       51.84  + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_datatable_style_ordering + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DataTableCursorStyles + + + + + + + + + + Foreground is 'css', background is 'css':                                        +  Movies      +  Severance   + Foundation + Dark + + Foreground is 'css', background is 'renderable':                                 +  Movies      + Severance + Foundation + Dark + + Foreground is 'renderable', background is 'renderable':                          +  Movies      + Severance + Foundation + Dark + + Foreground is 'renderable', background is 'css':                                 +  Movies      + Severance + Foundation + Dark + + + + + + ''' +# --- +# name: test_demo + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Textual Demo + + + + + + + + + + Textual Demo + + + TOP + + ▆▆ + + Widgets + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + Rich contentTextual Demo + + Welcome! Textual is a framework for creating sophisticated + applications with the terminal.                            + CSS + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Start  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + +  ^b Sidebar  ^t Toggle Dark mode  ^s Screenshot  f1 Notes  ^q Quit  + + + + + ''' +# --- +# name: test_digits + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DigitApp + + + + + + + + + + ╺━┓  ┓ ╻ ╻╺━┓╺━┓                                                                 +  ━┫  ┃ ┗━┫┏━┛  ┃                                                                 + ╺━┛.╺┻╸  ╹┗━╸  ╹                                                                 +                       ┏━┓ ┓ ╺━┓╺━┓╻ ╻┏━╸┏━╸╺━┓┏━┓┏━┓                             +                       ┃ ┃ ┃ ┏━┛ ━┫┗━┫┗━┓┣━┓  ┃┣━┫┗━┫╺╋╸╺━╸                       +                       ┗━┛╺┻╸┗━╸╺━┛  ╹╺━┛┗━┛  ╹┗━┛╺━┛      .,                     +                                                               ╺━┓    ┓ ┏━┓ ^ ╻ ╻ +                                                                ━┫ ×  ┃ ┃ ┃   ┗━┫ +                                                               ╺━┛   ╺┻╸┗━┛     ╹ + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_directory_tree_reloading + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DirectoryTreeReloadApp + + + + + + + + + + 📂 test_directory_tree_reloading0 + ├── 📂 b1 + │   ├── 📂 c1 + │   │   ┣━━ 📂 d1 + │   │   ┃   ┣━━ 📄 f1.txt + │   │   ┃   ┗━━ 📄 f2.txt + │   │   ┣━━ 📄 f1.txt + │   │   ┗━━ 📄 f2.txt + │   ├── 📄 f1.txt + │   └── 📄 f2.txt + ├── 📄 f1.txt + └── 📄 f2.txt + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_disabled_widgets + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WidgetDisableTestApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  Button  Button  Button  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_dock_layout_sidebar + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DockLayoutExample + + + + + + + + + + Sidebar1Docking a widget removes it from the layout and  + fixes its position, aligned to either the top,  + right, bottom, or left edges of a container. + + Docked widgets will not scroll out of view,  + making them ideal for sticky headers, footers,  + and sidebars. + ▇▇ + Docking a widget removes it from the layout and  + fixes its position, aligned to either the top,  + right, bottom, or left edges of a container. + + Docked widgets will not scroll out of view,  + making them ideal for sticky headers, footers,  + and sidebars. + + Docking a widget removes it from the layout and  + fixes its position, aligned to either the top,  + right, bottom, or left edges of a container. + + Docked widgets will not scroll out of view,  + making them ideal for sticky headers, footers,  + and sidebars. + + + + + + ''' +# --- +# name: test_dock_scroll + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + TestApp + ┌─────────┐ + this + is + a + sample + sentence + and + here + are + some + wordsthis + is + a + sample + sentence + and + here + are + some + words +  ^q Quit  + + + ▇▇ + + + + + ''' +# --- +# name: test_dock_scroll2 + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + TestApp + ┌─────────┐ + this + is + a + sample + sentence + and + here + are + some + wordsthis + is + a▅▅ + sample + sentence + and + here + are + some + words +  ^q Quit  + + + + + + + + ''' +# --- +# name: test_dock_scroll_off_by_one + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollOffByOne + + + + + + + + + + ▔▔▔▔▔▔▔▔ + X 92 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 93 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 94 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 95 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 96 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 97 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 98 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 99▁▁ + ▁▁▁▁▁▁▁▁ + + + + + + ''' +# --- +# name: test_dynamic_bindings + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BindingsApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  a  c  + + + + + ''' +# --- +# name: test_example_calculator + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CalculatorApp + + + + + + + + + + + +                                                                      ┏━┓ +                                                                      ┃ ┃ +                                                                      ┗━┛ + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  AC  +/-  %  ÷  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  7  8  9  ×  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  4  5  6  -  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  2  3  +  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + ''' +# --- +# name: test_example_color_command + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Press ctrl + \ and type a color + + + + + + + + + + Press ctrl + \ and type a color + + + + + ansi_red + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_example_dictionary + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DictionaryApp + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Search for a word + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + + + + + + + + + + + + + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + ''' +# --- +# name: test_example_five_by_five + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5x5 -- A little annoying puzzle + + + + + + + + + + 5x5 -- A little annoying puzzleMoves: 0Filled: 5 + ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ + ││││││││ + ││││││││ + ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ + ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ + ││││ + ││││ + ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ + ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ + ││││ + ││││ + ││││ + ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ + ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ + ││││ + ││││ + ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ + ╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮╭──────────────╮ + ││││││││ + ││││││││ + ││││││││ + ╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯╰──────────────╯ +  n New Game  ? Help  q Quit  ^d Toggle Dark Mode  + + + + + ''' +# --- +# name: test_example_json_tree + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeApp + + + + + + + + + + TreeApp + ▼ Root + └── ▼ {} JSON▁▁ +     ├── code='5060292302201' +     ├── ▼ {} product +     │   ┣━━ _id='5060292302201' +     │   ┣━━ ▶ [] _keywords +     │   ┣━━ ▶ [] added_countries_tags +     │   ┣━━ ▶ [] additives_debug_tags +     │   ┣━━ additives_n=2 +     │   ┣━━ additives_old_n=2 +     │   ┣━━ ▶ [] additives_old_tags +     │   ┣━━ ▶ [] additives_original_tags +     │   ┣━━ ▶ [] additives_prev_original_tags +     │   ┣━━ ▶ [] additives_tags +     │   ┣━━ additives_tags_n=None +     │   ┣━━ allergens='en:milk' +     │   ┣━━ ▶ [] allergens_debug_tags +     │   ┣━━ allergens_from_ingredients='en:milk, milk' +     │   ┣━━ allergens_from_user='(en) en:milk' +     │   ┣━━ ▶ [] allergens_hierarchy +     │   ┣━━ ▶ [] allergens_tags + +  a Add node  c Clear  t Toggle root  + + + + + ''' +# --- +# name: test_example_markdown + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownApp + + + + + + + + + + + ▼ Ⅰ Textual Markdown Browser + └── Ⅱ Do You Want to Know More?Textual Markdown Browser + +   Welcome fellow adventurer! If you ran  + markdown.py from the terminal you are  +   viewing demo.md with Textual's built in      +   Markdown widget. + +   The widget supports much of the Markdown     +   spec. There is also an optional Table of     +   Contents sidebar which you will see to  +   your left. + + + Do You Want to Know More? + +   See example.md for more examples of what     +   this can do. + + + + +  t TOC  b Back  f Forward  + + + + + ''' +# --- +# name: test_example_merlin + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MerlinApp + + + + + + + + + + + + ┏━┓   ┏━┓┏━┓   ┏━┓┏━┓ + ┃ ┃ : ┃ ┃┃ ┃ : ┃ ┃┃ ┃ + ┗━┛   ┗━┛┗━┛   ┗━┛┗━┛ + + + █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ + +     7         8         9      + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +     4         5         6      + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +     1         2         3      + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▇▇ + + + + + ''' +# --- +# name: test_example_pride + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PrideApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_focus_component_class + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyleBugApp + + + + + + + + + + StyleBugApp + test widget 0 + test widget 1 + test widget 2 + test widget 3 + test widget 4 + test widget 5 + test widget 6 + test widget 7 + test widget 8 + test widget 9 + test widget 10 + test widget 11 + test widget 12▇▇ + test widget 13 + test widget 14 + test widget 15 + test widget 16 + test widget 17 + test widget 18 + test widget 19 + test widget 20 + test widget 21 + + + + + + ''' +# --- +# name: test_footer_classic_styling + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ClassicFooterStylingApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  CTRL+T  Toggle Dark mode  CTRL+Q  Quit                                          + + + + + ''' +# --- +# name: test_footer_compact + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                  Compact Footer                                  + + + + + + + + + + + + ^t Toggle Compact Footer^q Quit + + + + + ''' +# --- +# name: test_footer_compact_with_hover + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                  Compact Footer                                  + + + + + + + + + + + + ^t Toggle Compact Footer^q Quit + + + + + ''' +# --- +# name: test_footer_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FooterApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  q Quit the app  ? Show help screen  delete Delete the thing  + + + + + ''' +# --- +# name: test_footer_standard_after_reactive_change + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                 Standard Footer                                  + + + + + + + + + + + +  ^t Toggle Compact Footer  ^q Quit  + + + + + ''' +# --- +# name: test_footer_standard_with_hover + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToggleCompactFooterApp + + + + + + + + + + + + + + + + + + + + +                                 Standard Footer                                  + + + + + + + + + + + +  ^t Toggle Compact Footer  ^q Quit  + + + + + ''' +# --- +# name: test_fr_margins + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + + + Hello + + + + + + + World + + + + + + + !! + + + + + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + ''' +# --- +# name: test_fr_unit_with_min + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScreenSplitApp + + + + + + + + + + ScreenSplitApp + This is content This is content number 0 + number 0This is content number 1 + This is content ▄▄This is content number 2 + number 1This is content number 3 + This is content This is content number 4▁▁ + number 2This is content number 5 + This is content This is content number 6 + number 3This is content number 7 + This is content This is content number 8 + number 4This is content number 9 + This is content This is content number 10 + number 5This is content number 11 + This is content This is content number 12 + number 6This is content number 13 + This is content This is content number 14 + number 7This is content number 15 + This is content This is content number 16 + number 8This is content number 17 + This is content This is content number 18 + number 9This is content number 19 + This is content This is content number 20 + number 10This is content number 21 + + + + + + ''' +# --- +# name: test_fr_units + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FRApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + HEADER + + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ┏━━━━━━━━┓┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓┏━━━━━━┓ + foo┃┃bar┃┃baz + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┃┃┃┃ + ┗━━━━━━━━┛┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛┗━━━━━━┛ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + FOOTER + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + ''' +# --- +# name: test_grid_auto + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌──┬──┬──┐ + abc + ├──┼──┼──┤ + def + ├──┼──┼──┤ + ghi + └──┴──┴──┘ + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_grid_gutter + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Demonstrator + + + + + + + + + + + + ┌──────────────────────────────────────────────────────────┐ + + Information + ━╸━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ + aaa naa aaaaa aaa aaaan, aaa aaa, aaaa?", aa aaa + aaaaanaaa anaaaaaaana aaaaaaaa aaaaaana aaa      + aaaaa aa aaa, aa aaaaaaaaa aaa aaaa, "aaaa, an   + aaaa aaa aaaa, a aa". "aaaa, naa aaaaaaaaaaa,    + aaa a aaaa aaaaaanaa aaaa aa a aaa!", aaa        + anaaaa, aaaaa aaaaaaaa aanaaaaa. "Na! aaa naa.   + aaaaa. aa aaaaa naa. aaaaa aa na aaa.", aaa      + aaaaaaaa aaaanaaaaa DONE.                        + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + + └──────────────────────────────────────────────────────────┘ + + + + + + + ''' +# --- +# name: test_grid_layout_basic + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + One││Two││Three + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + Four││Five││Six + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + + + ''' +# --- +# name: test_grid_layout_basic_overflow + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + One││Two││Three + ││││ + ││││ + ││││ + ││││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + Four││Five││Six + ││││ + ││││ + ││││ + ││││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + ┌────────────────────────┐ + Seven + + + + + + └────────────────────────┘ + + + + + ''' +# --- +# name: test_grid_layout_gutter + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GridLayoutExample + + + + + + + + + + OneTwoThree + + + + + + + + + + + + FourFiveSix + + + + + + + + + + + + + + + + ''' +# --- +# name: test_hatch + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HatchApp + + + + + + + + + + ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──┌─ Hello World ────────────────────────────────────┐──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼Hatched┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼┼││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──││││││││││││││││││││││││││││││││││││││││││││││││││──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳──└──────────────────────────────────────────────────┘──╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳────────────────────────────────────────────────────────╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╳╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ + ╱╱╱╱╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╲╱╱╱╱ + ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + + + + + ''' +# --- +# name: test_header_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HeaderApp + + + + + + + + + + HeaderApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_horizontal_layout + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalLayoutExample + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + One││Two││Three + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + + + ''' +# --- +# name: test_horizontal_layout_width_auto_dock + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalAutoWidth + + + + + + + + + + Docke + Widget 1Widget 2 + left  + 1Docked left 2 + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_input_and_focus + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Darren                                                                     + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Burns + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_input_percentage_width + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputVsTextArea + + + + + + + + + + 01234567890123456789012345678901234567890123456789012345678901234567890123456789 + ┌──────────────────────────────────────┐ + + + + └──────────────────────────────────────┘ + ┌──────────────────────────────────────┐ + + + + + └──────────────────────────────────────┘ + ┌──────────────────────────────────────┐ + + + + + └──────────────────────────────────────┘ + ┌──────────────────────────────────────┐ + +  Button  + + + └──────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_input_suggestions + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FruitsApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + strawberry + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + straw                                                                      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + p                                                                          + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + b                                                                          + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + a                                                                          + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + ''' +# --- +# name: test_input_validation + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + InputApp + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + -2                                                                     + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 3                                                                      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + -2 + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Enter a number between 1 and 5 + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + ''' +# --- +# name: test_key_display + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeyDisplayApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  ? Question  ^q Quit app  Escape! Escape  a Letter A  + + + + + ''' +# --- +# name: test_keyline + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KeylineApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + 1 + ├──────────────────────────────────────────────────────────────────────────────┤ + 2 + ├──────────────────────────────────────────────────────────────────────────────┤ + 3 + + └──────────────────────────────────────────────────────────────────────────────┘ + ┏━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + 456 + + + + + + ┗━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━┻━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + ╔══════════════════════════════════════╦═══════════════════════════════════════╗ + 78 + + ╠══════════════════════════════════════╬═══════════════════════════════════════╝ + 9 + + + ╚══════════════════════════════════════╝ + + + + + ''' +# --- +# name: test_label_widths + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LabelWrap + + + + + + + + + + + + + + + + Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix Ch + + + Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur Phoenix  + Chimera Castle + + + ╭────────────────────────────────────────────────────────────────────────────╮ + │ Apple Banana Cherry Mango Fig Guava Pineapple:Dragon Unicorn Centaur       │ + │ Phoenix Chimera Castle                                                     │ + ╰────────────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + + + ''' +# --- +# name: test_layer_fix + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DialogIssueApp + + + + + + + + + + DialogIssueApp + + + + + + ╭──────────────────────────────────────╮ + + + + + This should not cause a scrollbar to a + + + + + + ╰──────────────────────────────────────╯ + + + + + +  d Toggle the dialog  + + + + + ''' +# --- +# name: test_layers + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LayersExample + + + + + + + + + + + + + + + + + + + + + box1 (layer = above) + + + + + + box2 (layer = below) + + + + + + + + + + + ''' +# --- +# name: test_layout_containers + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Accept  Decline  Accept  Decline  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Accept  Accept  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Decline  Decline  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▆ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + 0                                 0 + + 1000000                                 1000000                                + + + + + ''' +# --- +# name: test_line_api_scrollbars + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollViewApp + + + + + + + + + + + +                                  11 01234567 +                                  12 01234567 +                                  13 01234567 +                                  14 01234567 +                                  15 01234567▁▁ +                                  16 01234567 +                                  17 01234567 +                                  18 01234567 +                                  19 01234567 + +                                  11 01234567 +                                  12 01234567 +                                  13 01234567 +                                  14 01234567 +                                  15 01234567▁▁ +                                  16 01234567 +                                  17 01234567 +                                  18 01234567 +                                  19 01234567 + + + + + + + + ''' +# --- +# name: test_list_view + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListViewExample + + + + + + + + + + + + + + + + + + One + + + Two + + + Three + + + + + + + + + + + + + + ''' +# --- +# name: test_listview_index + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ListViewIndexApp + + + + + + + + + + 10                                                                             + 12                                                                             + 14                                                                             + 16                                                                            ▆▆ + 18                                                                             + 20                                                                             + 22                                                                             + 24                                                                             + 26                                                                             + 28                                                                             + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_loading_indicator + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayRedux + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo   ▄▄ + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + Loading!foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + foo barfoo barfoo barfoo barfoo    + bar                                + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_loading_indicator_disables_widget + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayRedux + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     ▄▄foo barfoo barfoo barfoo barfoo   ▄▄ + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + hello world hello world hello     foo barfoo barfoo barfoo barfoo    + world hello world hello world     bar                                + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_log_write + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LogApp + + + + + + + + + + Hello, World!                                                                  + What's up?                                                                     + FOO                                                                            + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_log_write_lines + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LogApp + + + + + + + + + + I must not fear.  And when it has goHello, World      Fear is the mind-k + Fear is the mind-kWhere the fear hasFear is the little + Fear is the littleI must not fear.  I will face my fea + I will face my fea▁▁Fear is the mind-kI will permit it t + I will permit it tFear is the littleAnd when it has go + And when it has goI will face my feaWhere the fear has + Where the fear hasI will permit it t + I must not fear.  And when it has go + Fear is the mind-kWhere the fear has + Fear is the littleI must not fear.   + I will face my feaFear is the mind-k + I will permit it tFear is the little + And when it has goI will face my fea + Where the fear hasI will permit it t + I must not fear.  And when it has go + Fear is the mind-kWhere the fear has + Fear is the littleI must not fear.   + I will face my feaFear is the mind-k + I will permit it tFear is the little + And when it has goI will face my fea▇▇ + Where the fear hasI will permit it t + I must not fear.  And when it has go + Fear is the mind-kWhere the fear has + + + + + + ''' +# --- +# name: test_margin_multiple + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ╔═══╗ + foo + ╚═══╝ + + + ┌────────────────────────────┐ + + + ┌────────────────────────────┐ + + ╔═══╗ + bar + ╔═══╗╚═══╝ + bar + ╚═══╝ + + + + └────────────────────────────┘└────────────────────────────┘ + + + + + + + + + + ''' +# --- +# name: test_markdown_component_classes_reloading + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + + + This is a header + + + col1                                 col2                                 +  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  +  value 1                               value 2                               + +   Here's some code: from itertools import productBold textEmphasized text + strikethrough + + + print("Hello, world!") + + + That was some code. + + + + + + + + + + + + ''' +# --- +# name: test_markdown_dark_theme_override + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + + This is a H1 + + + defmain(): + │   print("Hello world!") + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_markdown_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownExampleApp + + + + + + + + + + + + Markdown Document + +   This is an example of Textual's Markdown widget. + + + Features + +   Markdown syntax and extensions are supported. + + ● Typography emphasisstronginline code etc. + ● Headers + ● Lists (bullet and ordered) + ● Syntax highlighted code blocks + ● Tables! + + + + + + + + + + + + + ''' +# --- +# name: test_markdown_light_theme_override + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + + This is a H1 + + + defmain(): + │   print("Hello world!") + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_markdown_space_squashing + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownSpaceApp + + + + + + + + + + X XX XX X X X X X + + X XX XX X X X X X + + X XX X X X X X + + X XX X X X X X + + ┌─────────────────────────────────────────────────────────────────────────────── + + + # Two spaces:  see? + classFoo: + │   '''This is    a doc    string.''' + │   some_code(1,2,3,4) + + + + + + + + + + + + + + ''' +# --- +# name: test_markdown_theme_switching + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownThemeSwitchertApp + + + + + + + + + + + + This is a H1 + + + defmain(): + │   print("Hello world!") + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_markdown_viewer_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MarkdownExampleApp + + + + + + + + + + + ▼ Ⅰ Markdown Viewer + ├── Ⅱ FeaturesMarkdown Viewer + ├── Ⅱ Tables + └── Ⅱ Code Blocks  This is an example of Textual's MarkdownViewer +   widget. + + + Features + +   Markdown syntax and extensions are supported. + ▇▇ + ● Typography emphasisstronginline code etc. + ● Headers + ● Lists (bullet and ordered) + ● Syntax highlighted code blocks + ● Tables! + + + Tables + +   Tables are displayed in a DataTable widget. + + + + + + + ''' +# --- +# name: test_masked_input + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TemplateApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ABC01-DE___-_____-_____ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + YYYY-MM-DD + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_max_height_100 + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HappyDataTableFunApp + + + + + + + + + +  Column 0  Column 1  Column 2  Column 3  Column 4  Column 5  Column 6  Column  +  0         0         0         0         0         0         0         0       +  0         1         2         3         4         5         6         7       +  0         2         4         6         8         10        12        14      +  0         3         6         9         12        15        18        21      +  0         4         8         12        16        20        24        28     ▆▆ +  0         5         10        15        20        25        30        35      +  0         6         12        18        24        30        36        42      +  0         7         14        21        28        35        42        49      +  0         8         16        24        32        40        48        56      +  0         9         18        27        36        45        54        63      +  0         10        20        30        40        50        60        70      +  0         11        22        33        44        55        66        77      +  0         12        24        36        48        60        72        84      +  0         13        26        39        52        65        78        91      +  0         14        28        42        56        70        84        98      +  0         15        30        45        60        75        90        105     +  0         16        32        48        64        80        96        112     +  0         17        34        51        68        85        102       119     +  0         18        36        54        72        90        108       126     +  0         19        38        57        76        95        114       133     +  0         20        40        60        80        100       120       140     +  0         21        42        63        84        105       126       147     + + + + + + ''' +# --- +# name: test_missing_vertical_scroll + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MissingScrollbarApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 0                  0                  ▎▊0                        + 1                  1                  ▎▊1                        + 2                  ▄▄2                  ▄▄▎▊2                       ▄▄ + 3                  3                  ▎▊3                        + 4                  4                  ▎▊4                        + 5                  5                  ▎▊5                        + 6                  6                  ▎▊6                        + 7                  7                  ▎▊7                        + 8                  8                  ▎▊8                        + 9                  9                  ▎▊9                        + 10                 10                 ▎▊10                       + 11                 11                 ▎▊11                       + 12                 12                 ▎▊12                       + 13                 13                 ▎▊13                       + 14                 14                 ▎▊14                       + 15                 15                 ▎▊15                       + 16                 16                 ▎▊16                       + 17                 17                 ▎▊17                       + 18                 18                 ▎▊18                       + 19                 19                 ▎▊19                       + 20                 20                 ▎▊20                       + 21                 21                 ▎▊21                       + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_modal_dialog_bindings + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + ModalApp + Hello                                                                            + + + + + + + + + + + + + + + + + + + + + +  ⏎ Open Dialog  + + + + + ''' +# --- +# name: test_modal_dialog_bindings_input + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + DialogModalApp + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + hi!                                                                        + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  OK  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + +  ⏎ Open Dialog  + + + + + ''' +# --- +# name: test_mount_style_fix + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BrokenClassesApp + + + + + + + + + + + + + + + + ┌──────────────────────────────────────┐ + This should have a red background + + + + + + + + + + └──────────────────────────────────────┘ + + + + + + + + + + + ''' +# --- +# name: test_multi_keys + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +  o Options  + + + + + ''' +# --- +# name: test_multiple_css + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MultipleCSSApp + + + + + + + + + + #one + #two + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_nested_auto_heights + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NestedAutoApp + + + + + + + + + + ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ + ┏━━━━━━━━━━━━━━━┓ + ┏━━━━━━━━━━━━━┓ + JUST ONE LINE + ┗━━━━━━━━━━━━━┛ + ┗━━━━━━━━━━━━━━━┛ + ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛ + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_nested_fr + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AutoApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌────────────────────────────────────────────────────────────────────────────┐ + Hello + World! + foo + + + + + + + + + + + + + + + + + + └────────────────────────────────────────────────────────────────────────────┘ + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_nested_specificity + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NestedPseudoClassesApp + + + + + + + + + + ╭──────────────────────────────────────╮ + This isn't using nested CSSThis is using nested CSS + + + + + + + + + + + + + + + + + + + + + + ╰──────────────────────────────────────╯ + + + + + ''' +# --- +# name: test_notification_with_inline_link + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyWithInlineLinkApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Click here for the bell sound. + + + + + + + ''' +# --- +# name: test_notification_with_inline_link_hover + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyWithInlineLinkApp + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Click here for the bell sound. + + + + + + + ''' +# --- +# name: test_notifications_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ToastApp + + + + + + + + + + + + + + It's an older code, sir, but it  + checks out. + + + + Possible trap detected + Now witness the firepower of this  + fully ARMED and OPERATIONAL battle  + station! + + + + It's a trap! + + + + It's against my programming to  + impersonate a deity. + + + + + + + ''' +# --- +# name: test_notifications_loading_overlap_order + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LoadingOverlayApp + + + + + + + + + + + + + + + + + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + This is a big notification. + + + + + + + + ''' +# --- +# name: test_notifications_through_modes + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyThroughModesApp + + + + + + + + + + This is a mode screen                   + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + + + + ''' +# --- +# name: test_notifications_through_screens + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + NotifyDownScreensApp + + + + + + + + + + Screen 10                               + 4 + + + + 5 + + + + 6 + + + + 7 + + + + 8 + + + + 9 + + + + + + + ''' +# --- +# name: test_offsets + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OffsetsApp + + + + + + + + + + + + + + + ┌──────────────┐ + FOO + BAR + BAZ + └──────────────┘ + + + + + + ┌──────────────┐ + FOO + BAR + BAZ + └──────────────┘ + + + + + + + + + ''' +# --- +# name: test_option_list_build + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎▊▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + One                   One                    ▎▊One                     + Two                   Two                    ▎▊Two                     + ─────────────────────────────────────────────▎▊─────────────────────── + ThreeThree▎▊Three + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎▊▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_option_list_options + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Aerilon                                            + Aquaria                                            + ────────────────────────────────────────────────── + Canceron                                           + Caprica                                            + ────────────────────────────────────────────────── + Gemenon                                            + ────────────────────────────────────────────────── + Leonis                                             + Libran                                             + ────────────────────────────────────────────────── + Picon                                             ▁▁ + ────────────────────────────────────────────────── + Sagittaron                                         + Scorpia                                            + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + ''' +# --- +# name: test_option_list_replace_prompt_from_single_line_to_single_line + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1. Another single line                                                       + 2. Two                                                                       + lines                                                                        + 3. Three                                                                     + lines                                                                        + of text                                                                      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_option_list_replace_prompt_from_single_line_to_two_lines + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1. Two                                                                       + lines                                                                        + 2. Two                                                                       + lines                                                                        + 3. Three                                                                     + lines                                                                        + of text                                                                      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_option_list_replace_prompt_from_two_lines_to_three_lines + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1. Single line                                                               + 1. Three                                                                     + lines                                                                        + of text                                                                      + 3. Three                                                                     + lines                                                                        + of text                                                                      + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_option_list_scrolling_in_long_list + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LongOptionListApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + This is option #78                                                         + This is option #79                                                         + This is option #80                                                         + This is option #81                                                         + This is option #82                                                         + This is option #83                                                         + This is option #84                                                         + This is option #85                                                         + This is option #86                                                         + This is option #87                                                         + This is option #88                                                         + This is option #89                                                         + This is option #90                                                         + This is option #91                                                         + This is option #92                                                         + This is option #93                                                         + This is option #94                                                         + This is option #95                                                        ▇▇ + This is option #96                                                         + This is option #97                                                         + This is option #98                                                         + This is option #99                                                         + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_option_list_scrolling_with_multiline_options + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ + │ Dionysus      │ 450 Million   │ Celeste        │ + └───────────────┴───────────────┴────────────────┘ +                  Data for Tauron                   + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +  Patron God     Population     Capital City    + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ + │ Ares          │ 2.5 Billion   │ Hypatia        │ + └───────────────┴───────────────┴────────────────┘ +                  Data for Virgon                   + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + ┃ Patron God    ┃ Population    ┃ Capital City   ┃▁▁ + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ + │ Hestia        │ 4.3 Billion   │ Boskirk        │ + └───────────────┴───────────────┴────────────────┘ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + ''' +# --- +# name: test_option_list_strings + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Aerilon                                              + Aquaria                                              + Canceron                                             + Caprica                                              + Gemenon                                              + Leonis                                               + Libran                                               + Picon                                                + Sagittaron                                           + Scorpia                                              + Tauron                                               + Virgon                                               + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + ''' +# --- +# name: test_option_list_tables + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OptionListApp + + + + + + + + + + OptionListApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +                  Data for Aerilon                  + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ + ┃ Patron God    ┃ Population    ┃ Capital City   ┃ + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩▇▇ + │ Demeter       │ 1.2 Billion   │ Gaoth          │ + └───────────────┴───────────────┴────────────────┘ +                  Data for Aquaria                  + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +  Patron God     Population     Capital City    + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩ + │ Hermes        │ 75,000        │ None           │ + └───────────────┴───────────────┴────────────────┘ +                 Data for Canceron                  + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓ +  Patron God     Population     Capital City    + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + ''' +# --- +# name: test_order_independence + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layers + + + + + + + + + + ┌──────────────────────────────────┐Layers + It's full of stars! My God! It's full of sta + + This should float over the top + + + └──────────────────────────────────┘ + + + + + + + + + + + + + + + + +  t Toggle Screen  + + + + + ''' +# --- +# name: test_order_independence_toggle + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Layers + + + + + + + + + + ┌──────────────────────────────────┐Layers + It's full of stars! My God! It's full of sta + + This should float over the top + + + └──────────────────────────────────┘ + + + + + + + + + + + + + + + + +  t Toggle Screen  + + + + + ''' +# --- +# name: test_pilot_resize_terminal + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SingleLabelApp + + + + + + + + + + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + 12345678901234567890 + + + + + ''' +# --- +# name: test_placeholder_disabled + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DisabledPlaceholderApp + + + + + + + + + + + + + + + Placeholder + + + + + + + + + + + + Placeholder + + + + + + + + + + + ''' +# --- +# name: test_placeholder_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PlaceholderApp + + + + + + + + + + + Placeholder p2 here! + This is a custom label for p1. + #p4 + #p3#p5Placeholde + r + + Lorem ipsum dolor sit  + 26 x 6amet, consectetur 27 x 6 + adipiscing elit. Etiam  + feugiat ac elit sit amet  + + + Lorem ipsum dolor sit amet,  + consectetur adipiscing elit. Etiam 40 x 6 + feugiat ac elit sit amet accumsan.  + Suspendisse bibendum nec libero quis  + gravida. Phasellus id eleifend ligula. + Nullam imperdiet sem tellus, sed  + vehicula nisl faucibus sit amet. Lorem ipsum dolor sit amet,  + Praesent iaculis tempor ultricies. Sedconsectetur adipiscing elit. Etiam  + lacinia, tellus id rutrum lacinia, feugiat ac elit sit amet accumsan.  + sapien sapien congue mauris, sit amet Suspendisse bibendum nec libero quis  + + + + + + ''' +# --- +# name: test_pretty_grid_gutter_interaction + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ['This is a string that has some chars'] + + This should be 1 cell away from ^ + + + + + + + + + ''' +# --- +# name: test_print_capture + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CaptureApp + + + + + + + + + + RichLog                                                                        + This will be captured!                                                         + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_programmatic_disable_button + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ExampleApp + + + + + + + + + + + + + + + + + + +                         Hover the button then hit space                          + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Disabled  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + +  SPACE Toggle Button  + + + + + ''' +# --- +# name: test_programmatic_scrollbar_gutter_change + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProgrammaticScrollbarGutterChange + + + + + + + + + + onetwo + + + + + + + + + + + + threefour + + + + + + + + + + + + + + + + ''' +# --- +# name: test_progress_bar_completed + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:--                  + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_bar_completed_styled + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━100%--:--:-- + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_bar_halfway + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + + ━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07                  + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_bar_halfway_styled + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + + ━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━39%00:00:07 + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_bar_indeterminate + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IndeterminateProgressBar + + + + + + + + + + + + + + + + + + + + + ━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:--                  + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_bar_indeterminate_styled + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + StyledProgressBar + + + + + + + + + + + + + + + + + + + + + ━╸━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━--%--:--:-- + + + + + + + + + + + +  s Start  + + + + + ''' +# --- +# name: test_progress_gradient + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ProgressApp + + + + + + + + + + ╺━━━━━━━━━━━━━━━50%--:--:--                                   + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_quickly_change_tabs + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + QuicklyChangeTabsApp + + + + + + + + + + + onetwothree + ━━━━━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + three                                                                        + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_radio_button_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RadioChoicesApp + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Battlestar Galactica +  Dune 1984 +  Dune 2021 +  Serenity +  Star Trek: The Motion Picture +  Star Wars: A New Hope +  The Last Starfighter +  Total Recall 👉 🔴 +  Wing Commander + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + ''' +# --- +# name: test_radio_set_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RadioChoicesApp + + + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Battlestar Galactica Amanda +  Dune 1984 Connor MacLeod +  Dune 2021 Duncan MacLeod +  Serenity Heather MacLeod +  Star Trek: The Motion Pictur Joe Dawson +  Star Wars: A New Hope Kurgan, The +  The Last Starfighter Methos +  Total Recall 👉 🔴 Rachel Ellenstein +  Wing Commander Ramírez + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + ''' +# --- +# name: test_recompose + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RecomposeApp + + + + + + + + + + ┌─────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐┌─────────┐┌──────────┐ +  ┓ ┏━┓   ││ ┓  ┓    ││ ┓ ╺━┓    ││ ┓ ╺━┓   ││ ┓ ╻ ╻    ││ ┓ ┏━╸   ││ ┓ ┏━╸     +  ┃ ┃ ┃   ││ ┃  ┃    ││ ┃ ┏━┛    ││ ┃  ━┫   ││ ┃ ┗━┫    ││ ┃ ┗━┓   ││ ┃ ┣━┓     + ╺┻╸┗━┛   ││╺┻╸╺┻╸   ││╺┻╸┗━╸    ││╺┻╸╺━┛   ││╺┻╸  ╹    ││╺┻╸╺━┛   ││╺┻╸┗━┛     + └─────────┘└─────────┘└──────────┘└─────────┘└──────────┘└─────────┘└──────────┘ + + + + + + + + ━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━50%                                            + + + + + + + + + + + + + + + + ''' +# --- +# name: test_remove_with_auto_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalRemoveApp + + + + + + + + + + VerticalRemoveApp + ╭──────────────────────────────────────────────────────────────────────────────╮ + ╭────────────────────╮ + │This is a test label│ + ╰────────────────────╯ + ╰──────────────────────────────────────────────────────────────────────────────╯ + + + + + + + + + + + + + + + + + +  a Add  d Delete  + + + + + ''' +# --- +# name: test_richlog_max_lines + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogLines + + + + + + + + + + Key press #3                                                                   + Key press #4                                                                   + Key press #5                                                                   + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_richlog_scroll + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogScrollApp + + + + + + + + + + Line 0                  Line 10                  Line 0                    + Line 1                  Line 11                  Line 1                    + Line 2                  Line 12                  Line 2                    + Line 3                  Line 13                  Line 3                    + Line 4                  Line 14                  Line 4                    + Line 5                  Line 15                  Line 5                    + Line 6                  Line 16                  Line 6                    + Line 7                  Line 17                  Line 7                    + Line 8                  Line 18                  Line 8                    + Line 9                  Line 19                  Line 9                    + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_richlog_width + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogWidth + + + + + + + + + +               hello1 +               world2 +               hello3 +               world4 + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_rule_horizontal_rules + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + HorizontalRulesApp + + + + + + + + + +                                 solid (default)                                  + + ──────────────────────────────────────────────────────────────── + +                                      heavy                                       + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +                                      thick                                       + + ████████████████████████████████████████████████████████████████ + +                                      dashed                                      + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + +                                      double                                      + + ════════════════════════════════════════════════════════════════ + +                                      ascii                                       + + ---------------------------------------------------------------- + + + + + + ''' +# --- +# name: test_rule_vertical_rules + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalRulesApp + + + + + + + + + + + +        solid     heavy     thick     dashed    double    ascii   | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + + + + + + + + ''' +# --- +# name: test_rules + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RuleApp + + + + + + + + + + + -------------------------------------------------------------------------------- + + + + ╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍╍ + + ════════════════════════════════════════════════════════════════════════════════ + + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + | + | + | + | + | + | + | + | + | + | + | + | + + + + + ''' +# --- +# name: test_scoped_css + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌───┐ + foo + └───┘ + ┌───┐ + bar + └───┘ + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌───┐ + foo + └───┘ + ┌───┐ + bar + └───┘ + └──────────────────────────────────────────────────────────────────────────────┘ + I should not be styled                                                           + + + + + + + + + + + + ''' +# --- +# name: test_screen_switch + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ModalApp + + + + + + + + + + ModalApp + B + + + + + + + + + + + + + + + + + + + + + +  a Push screen A  + + + + + ''' +# --- +# name: test_scroll_to + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollOffByOne + + + + + + + + + + ▔▔▔▔▔▔▔▔ + X 43 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 44 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 45 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 46▄▄ + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▃▃ + X 47 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 48 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 49 + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ + X 50 + ▁▁▁▁▁▁▁▁ + + + + + + ''' +# --- +# name: test_scroll_to_center + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + SPAM                                                                           + ╭────────────────────────────────────────────────────────────────────────────╮ + SPAM                                                                       + SPAM                                                                       + SPAM                                                                       + SPAM                                                                       + SPAM                                                                       + SPAM                                                                       + SPAM                                                                       + SPAM                                                                      ▁▁ + ╭────────────────────────────────────────────────────────────────────────╮ + @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@>>bullseye<<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + + ▄▄ + ▄▄ + + + + + + + ╰────────────────────────────────────────────────────────────────────────────╯ + SPAM                                                                           + SPAM                                                                           + + + + + ''' +# --- +# name: test_scroll_visible + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + | + |▆▆ + | + | + | + | + SHOULD BE VISIBLE + + + + + ''' +# --- +# name: test_scroll_visible_with_margin + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollVisibleMargin + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (19)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (20)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (21)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▅▅ +  Hello, world! (22)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (23)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (24)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (25)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Hello, world! (26)  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_scrollbar_thumb_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ScrollViewTester + + + + + + + + + + ScrollViewTester + ╭─ 1 ──────────────────────────────────────────────────────────────────────────╮ + Welcome to line 980                                                          + Welcome to line 981                                                          + Welcome to line 982                                                          + Welcome to line 983                                                          + Welcome to line 984                                                          + Welcome to line 985                                                          + Welcome to line 986                                                          + Welcome to line 987                                                          + Welcome to line 988                                                          + Welcome to line 989                                                          + Welcome to line 990                                                          + Welcome to line 991                                                          + Welcome to line 992                                                          + Welcome to line 993                                                          + Welcome to line 994                                                          + Welcome to line 995                                                          + Welcome to line 996                                                          + Welcome to line 997                                                          + Welcome to line 998                                                          + Welcome to line 999                                                          + ╰──────────────────────────────────────────────────────────────────────────────╯ + + + + + + ''' +# --- +# name: test_select + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_select_expanded + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select +  I must not fear.                                        +  Fear is the mind-killer.                                +  Fear is the little-death that brings total              +  obliteration.                                           +  I will face my fear.                                    +  I will permit it to pass over me and through me.        + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + ''' +# --- +# name: test_select_expanded_changed + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + I must not fear. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I must not fear. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_select_from_values_expanded + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + SelectApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select +  I must not fear.                                        +  Fear is the mind-killer.                                +  Fear is the little-death that brings total              +  obliteration.                                           +  I will face my fear.                                    +  I will permit it to pass over me and through me.        + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + ''' +# --- +# name: test_select_no_blank_has_default_value + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + I must not fear. + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I must not fear. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_select_rebuild + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectRebuildApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select +  This                                                                        +  Should                                                                      +  Be                                                                          +  What                                                                        +  Goes                                                                        +  Into                                                                        +  The                                                                         +  Snapshit                                                                    + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + ''' +# --- +# name: test_select_set_options + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectApp + + + + + + + + + + Twinkle, twinkle, little star, + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Twinkle, twinkle, little star, + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_selection_list_selected + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + + ┌─ Shall we play some games? ──┐┌─ Selected games ─────────────┐ + [ + X Falken's Maze           'secret_back_door', + X Black Jack              'a_nice_game_of_chess', + X Gin Rummy               'fighter_combat' + X Hearts                  ] + X Bridge                  └──────────────────────────────┘ + X Checkers                 + X Chess                    + X Poker                    + X Fighter Combat           + + └──────────────────────────────┘ + + + + + + + + + + + + + ''' +# --- +# name: test_selection_list_selections + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + + ┌─ Shall we play some games? ──────────────────────────────────┐ + + X Falken's Maze                                            + X Black Jack                                               + X Gin Rummy                                                + X Hearts                                                   + X Bridge                                                   + X Checkers                                                 + X Chess                                                    + X Poker                                                    + X Fighter Combat                                           + + + + + + └──────────────────────────────────────────────────────────────┘ + + + + + + + + + ''' +# --- +# name: test_selection_list_tuples + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SelectionListApp + + + + + + + + + + SelectionListApp + + + ┌─ Shall we play some games? ──────────────────────────────────┐ + + X Falken's Maze                                            + X Black Jack                                               + X Gin Rummy                                                + X Hearts                                                   + X Bridge                                                   + X Checkers                                                 + X Chess                                                    + X Poker                                                    + X Fighter Combat                                           + + + + + + └──────────────────────────────────────────────────────────────┘ + + + + + + + + + ''' +# --- +# name: test_sort_children + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SortApp + + + + + + + + + + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + 5││1││5 + │└─────────────────────────┘│ + │┌─────────────────────────┐│ + ││2││ + ││││ + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + ┌────────────────────────┐┌─────────────────────────┐┌─────────────────────────┐ + 1││3││4 + └────────────────────────┘│││ + ┌────────────────────────┐│││ + 3│└─────────────────────────┘│ + │┌─────────────────────────┐└─────────────────────────┘ + ││4│┌─────────────────────────┐ + └────────────────────────┘│││3 + ┌────────────────────────┐│││ + 2││││ + │└─────────────────────────┘└─────────────────────────┘ + └────────────────────────┘┌─────────────────────────┐┌─────────────────────────┐ + ┌────────────────────────┐│5││2 + 4││││ + │││└─────────────────────────┘ + │││┌─────────────────────────┐ + ││││1 + └────────────────────────┘└─────────────────────────┘└─────────────────────────┘ + + + + + ''' +# --- +# name: test_sparkline_component_classes_colors + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SparklineColorsApp + + + + + + + + + + + ▇▇▇▇▇ + + ▇▇▇▇▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇▇█▇ + + ▇▇▇▇▇▇ + + ▇▇▇▇▇▇▇█▇ + + + + + + + + + ''' +# --- +# name: test_sparkline_render + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SparklineSummaryFunctionApp + + + + + + + + + + + + + + + ▂▂▁▁ + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_switches + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SwitchApp + + + + + + + + + + + + + + Example switches + + + ▔▔▔▔▔▔▔▔ +                               off:      + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ +                               on:       + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ +                               focused:  + ▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔ +                               custom:   + ▁▁▁▁▁▁▁▁ + + + + + + + + + + ''' +# --- +# name: test_tab_rename + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabRenameApp + + + + + + + + + + + This is a much longer label for the tab011222333344444 + ━╸━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + TabPane#test + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tabbed_content + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabbedApp + + + + + + + + + + + LetoJessicaPaul + ━━━━━━━━╸━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + + Lady Jessica + +   Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + + PaulAlia + ━╸━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + First child                                                              + + + + + + + +  l Leto  j Jessica  p Paul  + + + + + ''' +# --- +# name: test_tabbed_content_styling_not_leaking + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabbedContentStyleLeakTestApp + + + + + + + + + + + Leak Test + ━╸━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + This label should come first                                                 + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  This button should come second  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + TheseTabsShouldComeLast + ━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tabbed_content_with_modified_tabs + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FiddleWithTabsApp + + + + + + + + + + + Tab 1Tab 2Tab 4Tab 5 + ━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Button  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_table_markup + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TableStaticApp + + + + + + + + + + ┏━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━┓ + Foo Bar     baz        + ┡━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━┩ + │ Hello World! │ Italic │ Underline │ + └──────────────┴────────┴───────────┘ + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tabs_invalidate + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TabApp + + + + + + + + + + + Tab 1Tab 2 + ━━━━━━━━━╸━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + ┌──────────────────────────────────────────────────────────────────────────────┐ + + world                                                                      + + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_text_area_alternate_screen + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TABug + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ + foo                                          + bar                                          + baz                                          + + + + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + + ''' +# --- +# name: test_text_area_language_rendering[bash] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +   1  #!/bin/bash +   2   +   3  # Variables +   4  name="John" +   5  age=30                                                                  +   6  is_student=true                                                         +   7   +   8  # Printing variables +   9  echo"Hello, $name! You are $age years old." +  10   +  11  # Conditional statements +  12  if [[ $age -ge 18 &&$is_student == true ]]; then +  13  echo"You are an adult student." +  14  elif [[ $age -ge 18 ]]; then +  15  echo"You are an adult." +  16  else +  17  echo"You are a minor." +  18  fi +  19   +  20  # Arrays +  21  numbers=(1 2 3 4 5)                                                     +  22  echo"Numbers: ${numbers[@]}" +  23   +  24  # Loops +  25  for num in"${numbers[@]}"do +  26  echo"Number: $num" +  27  done +  28   +  29  # Functions +  30  greet() {                                                               +  31    local name=$1                                                         +  32  echo"Hello, $name!" +  33  }                                                                       +  34  greet"Alice" +  35   +  36  # Command substitution +  37  current_date=$(date +%Y-%m-%d)                                          +  38  echo"Current date: $current_date" +  39   +  40  # File operations +  41  touch file.txt                                                          +  42  echo"Some content"> file.txt                                          +  43  cat file.txt                                                            +  44   +  45  # Conditionals with file checks +  46  if [[ -f file.txt ]]; then +  47  echo"file.txt exists." +  48  else +  49  echo"file.txt does not exist." +  50  fi +  51   +  52  # Case statement +  53  case$age in +  54    18)                                                                   +  55  echo"You are 18 years old." +  56      ;;                                                                  +  57    30)                                                                   +  58  echo"You are 30 years old." +  59      ;;                                                                  +  60    *)                                                                    +  61  echo"You are neither 18 nor 30 years old." +  62      ;;                                                                  +  63  esac +  64   +  65  # While loop +  66  counter=0                                                               +  67  while [[ $counter -lt 5 ]]; do +  68  echo"Counter: $counter" +  69    ((counter++))                                                         +  70  done +  71   +  72  # Until loop +  73  until [[ $counter -eq 0 ]]; do +  74  echo"Counter: $counter" +  75    ((counter--))                                                         +  76  done +  77   +  78  # Heredoc +  79  cat << EOF +  80  This is a heredoc.  +  81  It allows you to write multiple lines of text.  +  82  EOF  +  83   +  84  # Redirection +  85  ls> file_list.txt                                                      +  86  grep"file" file_list.txt > filtered_list.txt                           +  87   +  88  # Pipes +  89  cat file_list.txt |wc -l                                               +  90   +  91  # Arithmetic operations +  92  result=$((10 + 5))                                                      +  93  echo"Result: $result" +  94   +  95  # Exporting variables +  96  export DB_PASSWORD="secret" +  97   +  98  # Sourcing external files +  99  source config.sh                                                        + 100   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[css] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  /* This is a comment in CSS */ +  2   +  3  /* Basic selectors and properties */ +  4  body {                                                                   +  5      font-family: Arial, sans-serif;                                      +  6      background-color: #f4f4f4;                                           +  7      margin: 0;                                                           +  8      padding: 0;                                                          +  9  }                                                                        + 10   + 11  /* Class and ID selectors */ + 12  .header {                                                                + 13      background-color: #333;                                              + 14      color: #fff;                                                         + 15      padding: 10px0;                                                     + 16      text-align: center;                                                  + 17  }                                                                        + 18   + 19  #logo {                                                                  + 20      font-size: 24px;                                                     + 21      font-weight: bold;                                                   + 22  }                                                                        + 23   + 24  /* Descendant and child selectors */ + 25  .nav ul {                                                                + 26      list-style-type: none;                                               + 27      padding: 0;                                                          + 28  }                                                                        + 29   + 30  .nav > li {                                                              + 31      display: inline-block;                                               + 32      margin-right: 10px;                                                  + 33  }                                                                        + 34   + 35  /* Pseudo-classes */ + 36  a:hover {                                                                + 37      text-decoration: underline;                                          + 38  }                                                                        + 39   + 40  input:focus {                                                            + 41      border-color: #007BFF;                                               + 42  }                                                                        + 43   + 44  /* Media query */ + 45  @media (max-width: 768px) {                                              + 46      body {                                                               + 47          font-size: 16px;                                                 + 48      }                                                                    + 49   + 50      .header {                                                            + 51          padding: 5px0;                                                  + 52      }                                                                    + 53  }                                                                        + 54   + 55  /* Keyframes animation */ + 56  @keyframes slideIn {                                                     + 57  from {                                                               + 58          transform: translateX(-100%);                                    + 59      }                                                                    + 60  to {                                                                 + 61          transform: translateX(0);                                        + 62      }                                                                    + 63  }                                                                        + 64   + 65  .slide-in-element {                                                      + 66      animation: slideIn 0.5s forwards;                                    + 67  }                                                                        + 68   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[go] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  package main                                                             +  2   +  3  import (                                                                 +  4  "fmt" +  5  "math" +  6  "strings" +  7  )                                                                        +  8   +  9  const PI =3.14159 + 10   + 11  type Shape interface {                                                   + 12      Area() float64                                                       + 13  }                                                                        + 14   + 15  type Circle struct {                                                     + 16      Radius float64                                                       + 17  }                                                                        + 18   + 19  func (c Circle) Area() float64 {                                         + 20  return PI * c.Radius * c.Radius                                      + 21  }                                                                        + 22   + 23  funcmain() {                                                            + 24  var name string ="John" + 25      age :=30 + 26      isStudent :=true + 27   + 28      fmt.Printf("Hello, %s! You are %d years old.", name, age)            + 29   + 30  if age >=18&& isStudent {                                          + 31          fmt.Println("You are an adult student.")                         + 32      } elseif age >=18 {                                                + 33          fmt.Println("You are an adult.")                                 + 34      } else {                                                             + 35          fmt.Println("You are a minor.")                                  + 36      }                                                                    + 37   + 38      numbers := []int{12345}                                      + 39      sum :=0 + 40  for _, num :=range numbers {                                        + 41          sum += num                                                       + 42      }                                                                    + 43      fmt.Printf("The sum is: %d", sum)                                    + 44   + 45      message :="Hello, World!" + 46      uppercaseMessage := strings.ToUpper(message)                         + 47      fmt.Println(uppercaseMessage)                                        + 48   + 49      circle := Circle{Radius: 5}                                          + 50      fmt.Printf("Circle area: %.2f", circle.Area())                       + 51   + 52      result :=factorial(5)                                               + 53      fmt.Printf("Factorial of 5: %d", result)                             + 54   + 55  defer fmt.Println("Program finished.")                               + 56   + 57      sqrt :=func(x float64) float64 {                                    + 58  return math.Sqrt(x)                                              + 59      }                                                                    + 60      fmt.Printf("Square root of 16: %.2f"sqrt(16))                      + 61  }                                                                        + 62   + 63  funcfactorial(n int) int {                                              + 64  if n ==0 {                                                          + 65  return1 + 66      }                                                                    + 67  return n *factorial(n-1)                                            + 68  }                                                                        + 69   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[html] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  <!DOCTYPE html>                                                          +  2  <html lang="en">                                                         +  3   +  4  <head>                                                                   +  5  <!-- Meta tags --> +  6      <meta charset="UTF-8">                                               +  7      <meta name="viewport" content="width=device-width, initial-scale=1.0 +  8  <!-- Title --> +  9      <title>HTML Test Page</title>                                        + 10  <!-- Link to CSS --> + 11      <link rel="stylesheet" href="styles.css">                            + 12  </head>                                                                  + 13   + 14  <body>                                                                   + 15  <!-- Header section --> + 16      <header class="header">                                              + 17          <h1 id="logo">HTML Test Page</h1>                                + 18      </header>                                                            + 19   + 20  <!-- Navigation --> + 21      <nav class="nav">                                                    + 22          <ul>                                                             + 23              <li><a href="#">Home</a></li>                                + 24              <li><a href="#">About</a></li>                               + 25              <li><a href="#">Contact</a></li>                             + 26          </ul>                                                            + 27      </nav>                                                               + 28   + 29  <!-- Main content area --> + 30      <main>                                                               + 31          <article>                                                        + 32              <h2>Welcome to the Test Page</h2>                            + 33              <p>This is a paragraph to test the HTML structure.</p>       + 34              <img src="test-image.jpg" alt="Test Image" width="300">      + 35          </article>                                                       + 36      </main>                                                              + 37   + 38  <!-- Form --> + 39      <section>                                                            + 40          <form action="/submit" method="post">                            + 41              <label for="name">Name:</label>                              + 42              <input type="text" id="name" name="name">                    + 43              <input type="submit" value="Submit">                         + 44          </form>                                                          + 45      </section>                                                           + 46   + 47  <!-- Footer --> + 48      <footer>                                                             + 49          <p>&copy; 2023 HTML Test Page</p>                                + 50      </footer>                                                            + 51   + 52  <!-- Script tag --> + 53      <script src="scripts.js"></script>                                   + 54  </body>                                                                  + 55   + 56  </html>                                                                  + 57   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[java] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +   1  import java.util.ArrayList;                                             +   2  import java.util.HashMap;                                               +   3  import java.util.List;                                                  +   4  import java.util.Map;                                                   +   5   +   6  // Classes and interfaces +   7  interface Shape {                                                       +   8      double getArea();                                                   +   9  }                                                                       +  10   +  11  class Rectangle implements Shape {                                      +  12  private double width;                                               +  13  private double height;                                              +  14   +  15  public Rectangle(double width, double height) {                     +  16          this.width = width;                                             +  17          this.height = height;                                           +  18      }                                                                   +  19   +  20  @Override                                                           +  21  public double getArea() {                                           +  22  return width * height;                                          +  23      }                                                                   +  24  }                                                                       +  25   +  26  // Enums +  27  enum DaysOfWeek {                                                       +  28      MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY      +  29  }                                                                       +  30   +  31  publicclass Main {                                                     +  32  // Constants +  33  privatestaticfinal double PI = 3.14159;                           +  34   +  35  // Methods +  36  publicstatic int sum(int a, int b) {                               +  37  return a + b;                                                   +  38      }                                                                   +  39   +  40  publicstatic void main(String[] args) {                            +  41  // Variables +  42          String name = "John";                                           +  43          int age = 30;                                                   +  44          boolean isStudent = true;                                       +  45   +  46  // Printing variables +  47          System.out.println("Hello, " + name + "! You are " + age + " ye +  48   +  49  // Conditional statements +  50  if (age >= 18 && isStudent) {                                   +  51              System.out.println("You are an adult student.");            +  52          } elseif (age >= 18) {                                         +  53              System.out.println("You are an adult.");                    +  54          } else {                                                        +  55              System.out.println("You are a minor.");                     +  56          }                                                               +  57   +  58  // Arrays +  59          int[] numbers = {12345};                                +  60          System.out.println("Numbers: " + Arrays.toString(numbers));     +  61   +  62  // Lists +  63          List<String> fruits = new ArrayList<>();                        +  64          fruits.add("apple");                                            +  65          fruits.add("banana");                                           +  66          fruits.add("orange");                                           +  67          System.out.println("Fruits: " + fruits);                        +  68   +  69  // Loops +  70  for (int num : numbers) {                                       +  71              System.out.println("Number: " + num);                       +  72          }                                                               +  73   +  74  // Hash maps +  75          Map<String, Integer> scores = new HashMap<>();                  +  76          scores.put("Alice"100);                                       +  77          scores.put("Bob"80);                                          +  78          System.out.println("Alice's score: " + scores.get("Alice"));    +  79   +  80  // Exception handling +  81  try {                                                           +  82              int result = 10 / 0;                                        +  83          } catch (ArithmeticException e) {                               +  84              System.out.println("Error: " + e.getMessage());             +  85          }                                                               +  86   +  87  // Instantiating objects +  88          Rectangle rect = new Rectangle(1020);                         +  89          System.out.println("Rectangle area: " + rect.getArea());        +  90   +  91  // Enums +  92          DaysOfWeek today = DaysOfWeek.MONDAY;                           +  93          System.out.println("Today is " + today);                        +  94   +  95  // Calling methods +  96          int sum = sum(510);                                           +  97          System.out.println("Sum: " + sum);                              +  98   +  99  // Ternary operator + 100          String message = age >= 18 ? "You are an adult." : "You are a m + 101          System.out.println(message);                                    + 102      }                                                                   + 103  }                                                                       + 104   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[javascript] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  // Variable declarations +  2  const name ="John";                                                     +  3  let age =30;                                                            +  4  var isStudent =true;                                                    +  5   +  6  // Template literals +  7  console.log(`Hello, ${name}! You are ${age} years old.`);                +  8   +  9  // Conditional statements + 10  if (age >=18&& isStudent) {                                            + 11    console.log("You are an adult student.");                              + 12  elseif (age >=18) {                                                  + 13    console.log("You are an adult.");                                      + 14  else {                                                                 + 15    console.log("You are a minor.");                                       + 16  }                                                                        + 17   + 18  // Arrays and array methods + 19  const numbers = [12345];                                         + 20  const doubledNumbers = numbers.map((num) => num *2);                    + 21  console.log("Doubled numbers:", doubledNumbers);                         + 22   + 23  // Objects + 24  const person = {                                                         + 25    firstName: "John",                                                     + 26    lastName: "Doe",                                                       + 27    getFullName() {                                                        + 28  return`${this.firstName} ${this.lastName}`;                         + 29    },                                                                     + 30  };                                                                       + 31  console.log("Full name:", person.getFullName());                         + 32   + 33  // Classes + 34  class Rectangle {                                                        + 35    constructor(width, height) {                                           + 36      this.width = width;                                                  + 37      this.height = height;                                                + 38    }                                                                      + 39   + 40    getArea() {                                                            + 41  return this.width * this.height;                                     + 42    }                                                                      + 43  }                                                                        + 44  const rectangle =new Rectangle(53);                                   + 45  console.log("Rectangle area:", rectangle.getArea());                     + 46   + 47  // Async/Await and Promises + 48  asyncfunctionfetchData() {                                             + 49  try {                                                                  + 50  const response =awaitfetch("https://api.example.com/data");        + 51  const data =await response.json();                                  + 52      console.log("Fetched data:", data);                                  + 53    } catch (error) {                                                      + 54      console.error("Error:", error);                                      + 55    }                                                                      + 56  }                                                                        + 57  fetchData();                                                             + 58   + 59  // Arrow functions + 60  constgreet= (name) => {                                                + 61    console.log(`Hello, ${name}!`);                                        + 62  };                                                                       + 63  greet("Alice");                                                          + 64   + 65  // Destructuring assignment + 66  const [a, b, ...rest] = [12345];                                 + 67  console.log(a, b, rest);                                                 + 68   + 69  // Spread operator + 70  const arr1 = [123];                                                  + 71  const arr2 = [456];                                                  + 72  const combinedArr = [...arr1, ...arr2];                                  + 73  console.log("Combined array:", combinedArr);                             + 74   + 75  // Ternary operator + 76  const message = age >=18 ? "You are an adult." : "You are a minor.";    + 77  console.log(message);                                                    + 78   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[json] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  { +  2  "name""John Doe",                                                  +  3  "age"30,                                                           +  4  "isStudent"false,                                                  +  5  "address": {                                                         +  6  "street""123 Main St",                                         +  7  "city""Anytown",                                               +  8  "state""CA",                                                   +  9  "zip""12345" + 10      },                                                                   + 11  "phoneNumbers": [                                                    + 12          {                                                                + 13  "type""home",                                              + 14  "number""555-555-1234" + 15          },                                                               + 16          {                                                                + 17  "type""work",                                              + 18  "number""555-555-5678" + 19          }                                                                + 20      ],                                                                   + 21  "hobbies": ["reading""hiking""swimming"],                        + 22  "pets": [                                                            + 23          {                                                                + 24  "type""dog",                                               + 25  "name""Fido" + 26          },                                                               + 27      ],                                                                   + 28  "graduationYear"null + 29  } + 30   + 31   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[kotlin] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  // Variables +  2  val name ="John" +  3  var age =30 +  4  var isStudent =true +  5   +  6  // Printing variables +  7  println("Hello, $name! You are $age years old.")                         +  8   +  9  // Conditional statements + 10  when {                                                                   + 11      age >=18&& isStudent ->println("You are an adult student.")       + 12      age >=18->println("You are an adult.")                            + 13  else->println("You are a minor.")                                  + 14  }                                                                        + 15   + 16  // Arrays + 17  val numbers =arrayOf(12345)                                     + 18  println("Numbers: ${numbers.contentToString()}")                         + 19   + 20  // Lists + 21  val fruits =listOf("apple""banana""orange")                         + 22  println("Fruits: $fruits")                                               + 23   + 24  // Loops + 25  for (num in numbers) {                                                   + 26  println("Number: $num")                                              + 27  }                                                                        + 28   + 29  // Functions + 30  fungreet(name: String) {                                                + 31  println("Hello, $name!")                                             + 32  }                                                                        + 33  greet("Alice")                                                           + 34   + 35  // Lambda functions + 36  val square = { num: Int -> num * num }                                   + 37  println("Square of 5: ${square(5)}")                                     + 38   + 39  // Extension functions + 40  fun String.reverse(): String {                                           + 41  return this.reversed() + 42  }                                                                        + 43  val reversed ="Hello".reverse()                                         + 44  println("Reversed: $reversed")                                           + 45   + 46  // Data classes + 47  dataclass Person(val name: String, val age: Int)                        + 48  val person =Person("John"30)                                          + 49  println("Person: $person")                                               + 50   + 51  // Null safety + 52  var nullable: String? =null + 53  println("Length: ${nullable?.length}")                                   + 54   + 55  // Elvis operator + 56  val length = nullable?.length ?:0 + 57  println("Length (Elvis): $length")                                       + 58   + 59  // Smart casts + 60  funprintLength(obj: Any) {                                              + 61  if (obj is String) {                                                 + 62  println("Length: ${obj.length}")                                 + 63      }                                                                    + 64  }                                                                        + 65  printLength("Hello")                                                     + 66   + 67  // Object expressions + 68  val comparator =object : Comparator<Int> {                              + 69  overridefun compare(a: Int, b: Int): Int {                          + 70  return a - b + 71      }                                                                    + 72  }                                                                        + 73  val sortedNumbers = numbers.sortedWith(comparator)                       + 74  println("Sorted numbers: ${sortedNumbers.contentToString()}")            + 75   + 76  // Companion objects + 77  class MyClass {                                                          + 78      companion object {                                                   + 79  funcreate(): MyClass {                                          + 80  return MyClass() + 81          }                                                                + 82      }                                                                    + 83  }                                                                        + 84  val obj = MyClass.create()                                               + 85   + 86  // Sealed classes + 87  sealedclass Result {                                                    + 88  dataclass Success(val data: String) : Result()                      + 89  dataclass Error(val message: String) : Result()                     + 90  }                                                                        + 91  val result: Result = Result.Success("Data")                              + 92  when (result) {                                                          + 93  is Result.Success ->println("Success: ${result.data}")              + 94  is Result.Error ->println("Error: ${result.message}")               + 95  }                                                                        + 96   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[markdown] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  Heading +  2  =======                                                                  +  3   +  4  Sub-heading +  5  -----------                                                              +  6   +  7  ### Heading +  8   +  9  #### H4 Heading + 10   + 11  ##### H5 Heading + 12   + 13  ###### H6 Heading + 14   + 15   + 16  Paragraphs are separated                                                 + 17  by a blank line.                                                         + 18   + 19  Two spaces at the end of a line                                          + 20  produces a line break.                                                   + 21   + 22  Text attributes _italic_,                                                + 23  **bold**`monospace`.                                                   + 24   + 25  Horizontal rule:                                                         + 26   + 27  ---                                                                      + 28   + 29  Bullet list:                                                             + 30   + 31  * apples                                                               + 32  * oranges                                                              + 33  * pears                                                                + 34   + 35  Numbered list:                                                           + 36   + 37  1. lather                                                              + 38  2. rinse                                                               + 39  3. repeat                                                              + 40   + 41  An [example](http://example.com).                                        + 42   + 43  > Markdown uses email-style > characters for blockquoting.               + 44  >                                                                        + 45  > Lorem ipsum                                                            + 46   + 47  ![progress](https://github.com/textualize/rich/raw/master/imgs/progress. + 48   + 49   + 50  ```                                                                      + 51  a=1                                                                      + 52  ```                                                                      + 53   + 54  ```python                                                                + 55  import this                                                              + 56  ```                                                                      + 57   + 58  ```somelang                                                              + 59  foobar                                                                   + 60  ```                                                                      + 61   + 62      import this                                                          + 63   + 64   + 65  1. List item                                                             + 66   + 67         Code block                                                        + 68   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[python] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  import math                                                              +  2  from os import path                                                      +  3   +  4  # I'm a comment :) +  5   +  6  string_var ="Hello, world!" +  7  int_var =42 +  8  float_var =3.14 +  9  complex_var =1+2j + 10   + 11  list_var = [12345]                                               + 12  tuple_var = (12345)                                              + 13  set_var = {12345}                                                + 14  dict_var = {"a"1"b"2"c"3}                                      + 15   + 16  deffunction_no_args():                                                  + 17  return"No arguments" + 18   + 19  deffunction_with_args(a, b):                                            + 20  return a + b                                                         + 21   + 22  deffunction_with_default_args(a=0, b=0):                                + 23  return a * b                                                         + 24   + 25  lambda_func =lambda x: x**2 + 26   + 27  if int_var ==42:                                                        + 28  print("It's the answer!")                                            + 29  elif int_var <42:                                                       + 30  print("Less than the answer.")                                       + 31  else:                                                                    + 32  print("Greater than the answer.")                                    + 33   + 34  for index, value inenumerate(list_var):                                 + 35  print(f"Index: {index}, Value: {value}")                             + 36   + 37  counter =0 + 38  while counter <5:                                                       + 39  print(f"Counter value: {counter}")                                   + 40      counter +=1 + 41   + 42  squared_numbers = [x**2for x inrange(10if x %2==0]                + 43   + 44  try:                                                                     + 45      result =10/0 + 46  except ZeroDivisionError:                                                + 47  print("Cannot divide by zero!")                                      + 48  finally:                                                                 + 49  print("End of try-except block.")                                    + 50   + 51  classAnimal:                                                            + 52  def__init__(self, name):                                            + 53          self.name = name                                                 + 54   + 55  defspeak(self):                                                     + 56  raiseNotImplementedError("Subclasses must implement this method + 57   + 58  classDog(Animal):                                                       + 59  defspeak(self):                                                     + 60  returnf"{self.name} says Woof!" + 61   + 62  deffibonacci(n):                                                        + 63      a, b =01 + 64  for _ inrange(n):                                                   + 65  yield a                                                          + 66          a, b = b, a + b                                                  + 67   + 68  for num infibonacci(5):                                                 + 69  print(num)                                                           + 70   + 71  withopen('test.txt''w'as f:                                         + 72      f.write("Testing with statement.")                                   + 73   + 74  @my_decorator                                                            + 75  defsay_hello():                                                         + 76  print("Hello!")                                                      + 77   + 78  say_hello()                                                              + 79   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[regex] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  ^abc            # Matches any string that starts with "abc" +  2  abc$            # Matches any string that ends with "abc" +  3  ^abc$           # Matches the string "abc" and nothing else +  4  a.b             # Matches any string containing "a", any character, then +  5  a[.]b           # Matches the string "a.b" +  6  a|b             # Matches either "a" or "b" +  7  a{2}            # Matches "aa" +  8  a{2,}           # Matches two or more consecutive "a" characters +  9  a{2,5}          # Matches between 2 and 5 consecutive "a" characters + 10  a?              # Matches "a" or nothing (0 or 1 occurrence of "a")      + 11  a*              # Matches zero or more consecutive "a" characters + 12  a+              # Matches one or more consecutive "a" characters + 13  \d              # Matches any digit (equivalent to [0-9])                + 14  \D              # Matches any non-digit + 15  \w              # Matches any word character (equivalent to [a-zA-Z0-9_] + 16  \W              # Matches any non-word character + 17  \s              # Matches any whitespace character (spaces, tabs, line b + 18  \S              # Matches any non-whitespace character + 19  (?i)abc         # Case-insensitive match for "abc" + 20  (?:a|b)         # Non-capturing group for either "a" or "b" + 21  (?<=a)b         # Positive lookbehind: matches "b" that is preceded by " + 22  (?<!a)b         # Negative lookbehind: matches "b" that is not preceded  + 23  a(?=b)          # Positive lookahead: matches "a" that is followed by "b + 24  a(?!b)          # Negative lookahead: matches "a" that is not followed b + 25   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[rust] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +   1  use std::collections::HashMap;                                          +   2   +   3  // Constants +   4  const PI: f64 = 3.14159;                                                +   5   +   6  // Structs +   7  struct Rectangle {                                                      +   8      width: u32,                                                         +   9      height: u32,                                                        +  10  }                                                                       +  11   +  12  impl Rectangle {                                                        +  13  fnarea(&self) -> u32 {                                             +  14          self.width * self.height                                        +  15      }                                                                   +  16  }                                                                       +  17   +  18  // Enums +  19  enum Result<T, E> {                                                     +  20      Ok(T),                                                              +  21      Err(E),                                                             +  22  }                                                                       +  23   +  24  // Functions +  25  fngreet(name: &str) {                                                  +  26      println!("Hello, {}!", name);                                       +  27  }                                                                       +  28   +  29  fnmain() {                                                             +  30  // Variables +  31  let name = "John";                                                  +  32  letmut age = 30;                                                   +  33  let is_student = true;                                              +  34   +  35  // Printing variables +  36      println!("Hello, {}! You are {} years old.", name, age);            +  37   +  38  // Conditional statements +  39  if age >= 18 && is_student {                                        +  40          println!("You are an adult student.");                          +  41      } elseif age >= 18 {                                               +  42          println!("You are an adult.");                                  +  43      } else {                                                            +  44          println!("You are a minor.");                                   +  45      }                                                                   +  46   +  47  // Arrays +  48  let numbers = [12345];                                      +  49      println!("Numbers: {:?}", numbers);                                 +  50   +  51  // Vectors +  52  letmut fruits = vec!["apple""banana""orange"];                 +  53      fruits.push("grape");                                               +  54      println!("Fruits: {:?}", fruits);                                   +  55   +  56  // Loops +  57  for num in&numbers {                                               +  58          println!("Number: {}", num);                                    +  59      }                                                                   +  60   +  61  // Pattern matching +  62  let result = Result::Ok(42);                                        +  63  match result {                                                      +  64          Result::Ok(value) => println!("Value: {}", value),              +  65          Result::Err(error) => println!("Error: {:?}", error),           +  66      }                                                                   +  67   +  68  // Ownership and borrowing +  69  let s1 = String::from("hello");                                     +  70  let s2 = s1.clone();                                                +  71      println!("s1: {}, s2: {}", s1, s2);                                 +  72   +  73  // References +  74  let rect = Rectangle {                                              +  75          width: 10,                                                      +  76          height: 20,                                                     +  77      };                                                                  +  78      println!("Rectangle area: {}", rect.area());                        +  79   +  80  // Hash maps +  81  letmut scores = HashMap::new();                                    +  82      scores.insert("Alice"100);                                        +  83      scores.insert("Bob"80);                                           +  84      println!("Alice's score: {}", scores["Alice"]);                     +  85   +  86  // Closures +  87  let square = |num: i32| num * num;                                  +  88      println!("Square of 5: {}", square(5));                             +  89   +  90  // Traits +  91  trait Printable {                                                   +  92  fnprint(&self);                                                +  93      }                                                                   +  94   +  95  impl Printable for Rectangle {                                      +  96  fnprint(&self) {                                               +  97              println!("Rectangle: width={}, height={}", self.width, self +  98          }                                                               +  99      }                                                                   + 100      rect.print();                                                       + 101   + 102  // Modules + 103  greet("Alice");                                                     + 104  }                                                                       + 105   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[sql] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  -- This is a comment in SQL +  2   +  3  -- Create tables +  4  CREATETABLE Authors (                                                   +  5      AuthorID INT PRIMARY KEY,                                            +  6      Name VARCHAR(255NOT NULL,                                          +  7      Country VARCHAR(50)                                                  +  8  );                                                                       +  9   + 10  CREATETABLE Books (                                                     + 11      BookID INT PRIMARY KEY,                                              + 12      Title VARCHAR(255NOT NULL,                                         + 13      AuthorID INT,                                                        + 14      PublishedDate DATE,                                                  + 15      FOREIGN KEY (AuthorID) REFERENCES Authors(AuthorID)                  + 16  );                                                                       + 17   + 18  -- Insert data + 19  INSERTINTO Authors (AuthorID, Name, Country) VALUES (1'George Orwell' + 20   + 21  INSERTINTO Books (BookID, Title, AuthorID, PublishedDate) VALUES (1'1 + 22   + 23  -- Update data + 24  UPDATE Authors SET Country ='United Kingdom'WHERE Country ='UK';      + 25   + 26  -- Select data with JOIN + 27  SELECT Books.Title, Authors.Name                                         + 28  FROM Books                                                               + 29  JOIN Authors ON Books.AuthorID = Authors.AuthorID;                       + 30   + 31  -- Delete data (commented to preserve data for other examples) + 32  -- DELETE FROM Books WHERE BookID = 1; + 33   + 34  -- Alter table structure + 35  ALTER TABLE Authors ADD COLUMN BirthDate DATE;                           + 36   + 37  -- Create index + 38  CREATEINDEX idx_author_name ON Authors(Name);                           + 39   + 40  -- Drop index (commented to avoid actually dropping it) + 41  -- DROP INDEX idx_author_name ON Authors; + 42   + 43  -- End of script + 44   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[toml] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  # This is a comment in TOML +  2   +  3  string = "Hello, world!" +  4  integer = 42 +  5  float = 3.14 +  6  boolean = true +  7  datetime = 1979-05-27T07:32:00Z +  8   +  9  fruits = ["apple""banana""cherry"]                                   + 10   + 11  [address]                                                                + 12  street = "123 Main St" + 13  city = "Anytown" + 14  state = "CA" + 15  zip = "12345" + 16   + 17  [person.john]                                                            + 18  name = "John Doe" + 19  age = 28 + 20  is_student = false + 21   + 22   + 23  [[animals]]                                                              + 24  name = "Fido" + 25  type = "dog" + 26   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_language_rendering[yaml] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  # This is a comment in YAML +  2   +  3  # Scalars +  4  string"Hello, world!" +  5  integer42 +  6  float3.14 +  7  booleantrue +  8   +  9  # Sequences (Arrays) + 10  fruits:                                                                  + 11    - Apple + 12    - Banana + 13    - Cherry + 14   + 15  # Nested sequences + 16  persons:                                                                 + 17    - nameJohn + 18  age28 + 19  is_studentfalse + 20    - nameJane + 21  age22 + 22  is_studenttrue + 23   + 24  # Mappings (Dictionaries) + 25  address:                                                                 + 26  street123 Main St + 27  cityAnytown + 28  stateCA + 29  zip'12345' + 30   + 31  # Multiline string + 32  description + 33    This is a multiline  + 34    string in YAML. + 35   + 36  # Inline and nested collections + 37  colors: { redFF0000green00FF00blue0000FF }                     + 38   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_line_number_start + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LineNumbersReactive + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▎ +  9999  Foo                   + 10000  Bar                   + 10001  Baz                   + 10002   + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▎ + + + + + ''' +# --- +# name: test_text_area_read_only_cursor_rendering + ''' + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  Hello, world!           + + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection0] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line. + + I am another line.         + + I am the final line.       + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection1] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line. + + I am another line.         + + I am the final line.       + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection2] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line. + + I am another line. + + I am the final line.       + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection3] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line. + + I am another line. + + I am the final line. + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection4] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line.               + + I am another line.         + + I am the final line.       + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_selection_rendering[selection5] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + I am a line.               + + I am another line.         + + I am the final line.       + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_themes[css] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  defhello(name): + 2      x =123 + 3  whilenotFalse:                      + 4  print("hello "+ name)            + 5  continue + 6   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_themes[dracula] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  defhello(name): + 2      x =123 + 3  whilenotFalse:                      + 4  print("hello "+ name)            + 5  continue + 6   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_themes[github_light] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  defhello(name): + 2  x=123 + 3  whilenotFalse:                      + 4  print("hello "+name)            + 5  continue + 6   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_themes[monokai] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  defhello(name): + 2      x =123 + 3  whilenotFalse:                      + 4  print("hello "+ name)            + 5  continue + 6   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_themes[vscode_dark] + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaSnapshot + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + 1  defhello(name): + 2      x =123 + 3  whilenotFalse:                      + 4  print("hello "+ name)            + 5  continue + 6   + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_area_wrapping_and_folding + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TextAreaWrapping + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  1  # The  + Wonders  + of Space  + Explorati + on +  2   +  3  Space      + explorati  + on has     + *always* + captured   + the        + human      + imaginati  + on.        +  4  ▃▃ +  5  ダレンバ   + ーンズ     +  6   +  7   + Thisissom  + elongtext  + thatshoul  + dfoldcorr  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_text_log_blank_write + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RichLogApp + + + + + + + + + + Hello                                                                          + + World                                                                          + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_textual_dev_border_preview + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + BorderApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  ascii  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔+------------------- ascii --------------------+ +  blank || + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|I must not fear.| +  dashed |Fear is the mind-killer.| + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|Fear is the little-death that brings | + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|total obliteration.| +  double |I will face my fear.| + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▅▅|I will permit it to pass over me and | + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|through me.| +  heavy |And when it has gone past, I will turn| + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|the inner eye to see its path.| + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|Where the fear has gone there will be | +  hidden |nothing. Only I will remain.| + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁|| + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔|| +  hkey +----------------------------------------------+ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  inner  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_textual_dev_colors_preview + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ColorsApp + + + + + + + + + + + Theme ColorsNamed Colors + ━╸━━━━━━━━━━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  primary  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  secondary "primary" + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  background $primary-darken-3$t + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  primary-background $primary-darken-2$t + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  secondary-background $primary-darken-1$t + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  surface $primary$t + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + +  d Toggle dark mode  + + + + + ''' +# --- +# name: test_textual_dev_easing_preview + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + EasingApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  round ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Animation Duration:1.0                        + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +  out_sine  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +  out_quint  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Welcome to Textual! + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  out_quart I must not fear. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Fear is the  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mind-killer. +  out_quad Fear is the  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁little-death that  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔brings total  +  out_expo obliteration. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I will face my fear. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will permit it to  +  out_elastic pass over me and  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁through me. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔And when it has gone  +  out_cubic  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ^p Focus: Duration Input  ^b Toggle Dark  + + + + + ''' +# --- +# name: test_textual_dev_keys_preview + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Textual Keys + + + + + + + + + + Textual Keys + ╭────────────────────────────────────────────────────────────────────────────╮ + │ Press some keys!                                                           │ + │                                                                            │ + │ To quit the app press ctrl+ctwice or press the Quit button below.         │ + ╰────────────────────────────────────────────────────────────────────────────╯ + Key(key='a'character='a'name='a'is_printable=True) + Key(key='b'character='b'name='b'is_printable=True) + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  Clear  Quit  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_toggle_style_order + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CheckboxApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + XThis is just some text. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + This is just some text. + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tooltips_in_compound_widgets + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TooltipApp + + + + + + + + + + ━━━╺━━━━━━━━━━━━━━━━━━━━━━━━━━━━10%                                            + + Hello, Tooltip! + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tree_clearing_and_expansion + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeClearingSnapshotApp + + + + + + + + + + ▼ Left▶ Right + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_tree_example + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TreeApp + + + + + + + + + + ▼ Dune + ┗━━ ▼ Characters +     ┣━━ Paul +     ┣━━ Jessica +     ┗━━ Chani + + + + + + + + + + + + + + + + + + + + + + + + ''' +# --- +# name: test_unscoped_css + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MyApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌───┐ + foo + └───┘ + ┌───┐ + bar + └───┘ + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + ┌───┐ + foo + └───┘ + ┌───┐ + bar + └───┘ + └──────────────────────────────────────────────────────────────────────────────┘ + ┌───────────────────┐ + This will be styled + └───────────────────┘ + + + + + + + + + + ''' +# --- +# name: test_vertical_layout + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalLayoutExample + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + One + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + Two + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + Three + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_vertical_max_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + + + + #top + + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + + #bottom + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_vertical_min_height + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + VerticalApp + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + + #top + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + ┌──────────────────────────────────────────────────────────────────────────────┐ + + + + + + #bottom + + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_viewport_height_and_width_properties + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ViewportUnits + + + + + + + + + + ┌──────────────────────────────────────────────────────────────────────────────┐ + Hello, world! + + + + + + + + + + + + + + + + + + + + + + └──────────────────────────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_visibility + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Visibility + + + + + + + + + + ┌──────────────────────────────────────┐ + bar + ┌────────────────────────────────────┐┌────────────────────────────────────┐ + floatfloat + └────────────────────────────────────┘└────────────────────────────────────┘ + + + + + + + + + + + + + + + + + + + └──────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_welcome + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WelcomeApp + + + + + + + + + + +  ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  +  ┃                                 Welcome!                                 ┃  +  ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛  + +  Textual is a TUI, or Text User Interface, framework for Python inspired by    +  modern web development. We hope you enjoy using Textual! + + + Dune quote + + ▌ "I must not fear. Fear is the mind-killer. Fear is the little-death that + ▌ brings total obliteration. I will face my fear. I will permit it to pass + ▌ over me and through me. And when it has gone past, I will turn the inner + ▌ eye to see its path. Where the fear has gone there will be nothing. Only + ▌ I will remain."                                                          + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +  OK  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + ''' +# --- +# name: test_width_100 + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Width100PCentApp + + + + + + + + + + ┌───────────────────────────────────────────────────────────┐ + ┌─────────────────────────────────────────────────────────┐ + I want to be 100% of my parent + └─────────────────────────────────────────────────────────┘ + ┌─────────────────────────────────────────────────────────┐ + I want my parent to be wide enough to wrap me and no more + └─────────────────────────────────────────────────────────┘ + + + + + + + + + + + + + + + + + └───────────────────────────────────────────────────────────┘ + + + + + ''' +# --- +# name: test_zero_scrollbar_size + ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TestApp + + + + + + + + + + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + Hello, world! + + + + + ''' +# --- From 0cb6e37e43185c5a75679b09e099712a0c945290 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Fri, 2 Aug 2024 00:58:30 +0200 Subject: [PATCH 66/80] Addressed review issues (after rebase) --- src/textual/widgets/_masked_input.py | 286 ++++++++++++++++++++------- 1 file changed, 214 insertions(+), 72 deletions(-) diff --git a/src/textual/widgets/_masked_input.py b/src/textual/widgets/_masked_input.py index f10f6f6e79..6e8e17c994 100644 --- a/src/textual/widgets/_masked_input.py +++ b/src/textual/widgets/_masked_input.py @@ -2,7 +2,7 @@ import re from dataclasses import dataclass -from enum import IntFlag +from enum import Flag, auto from typing import TYPE_CHECKING, Iterable, Pattern from rich.console import Console, ConsoleOptions, RenderableType @@ -25,19 +25,22 @@ """Possible messages that trigger input validation.""" -class _CharFlags(IntFlag): +class _CharFlags(Flag): """Misc flags for a single template character definition""" - REQUIRED = 0x1 + NONE = 0 + """Empty flags value""" + + REQUIRED = auto() """Is this character required for validation?""" - SEPARATOR = 0x2 + SEPARATOR = auto() """Is this character a separator?""" - UPPERCASE = 0x4 + UPPERCASE = auto() """Char is forced to be uppercase""" - LOWERCASE = 0x8 + LOWERCASE = auto() """Char is forced to be lowercase""" @@ -83,8 +86,8 @@ def __rich_console__( template.mask[value_length:], style, ) - for index, (c, char_def) in enumerate(zip(value, template.template)): - if c == " ": + for index, (char, char_definition) in enumerate(zip(value, template.template)): + if char == " ": result.stylize(style, index, index + 1) if self.cursor_visible and input.has_focus: @@ -113,63 +116,78 @@ class _Template(Validator): """Template mask enforcer.""" @dataclass - class CharDef: + class CharDefinition: """Holds data for a single char of the template mask.""" pattern: Pattern[str] """Compiled regular expression to check for matches.""" - flags: _CharFlags = _CharFlags(0) + flags: _CharFlags = _CharFlags.NONE """Flags defining special behaviors""" char: str = "" """Mask character (separator or blank or placeholder)""" def __init__(self, input: Input, template_str: str) -> None: + """Initialise the mask enforcer, which is also a subclass of `Validator`. + + Args: + input: The `MaskedInput` that owns this object. + template_str: Template string controlling masked input behavior. + """ self.input = input - self.template: list[_Template.CharDef] = [] + self.template: list[_Template.CharDefinition] = [] self.blank: str = " " escaped = False - flags = _CharFlags(0) + flags = _CharFlags.NONE template_chars: list[str] = list(template_str) while template_chars: - c = template_chars.pop(0) + char = template_chars.pop(0) if escaped: - char = self.CharDef(re.compile(re.escape(c)), _CharFlags.SEPARATOR, c) + char_definition = self.CharDefinition( + re.compile(re.escape(char)), _CharFlags.SEPARATOR, char + ) escaped = False else: - if c == "\\": + if char == "\\": escaped = True continue - elif c == ";": + elif char == ";": break new_flags = { ">": _CharFlags.UPPERCASE, "<": _CharFlags.LOWERCASE, - "!": 0, - }.get(c, None) + "!": _CharFlags.NONE, + }.get(char, None) if new_flags is not None: flags = new_flags continue - pattern, required_flag = _TEMPLATE_CHARACTERS.get(c, (None, None)) + pattern, required_flag = _TEMPLATE_CHARACTERS.get(char, (None, None)) if pattern: - char_flags = _CharFlags.REQUIRED if required_flag else _CharFlags(0) - char = self.CharDef(re.compile(pattern), char_flags) + char_flags = ( + _CharFlags.REQUIRED if required_flag else _CharFlags.NONE + ) + char_definition = self.CharDefinition( + re.compile(pattern), char_flags + ) else: - char = self.CharDef( - re.compile(re.escape(c)), _CharFlags.SEPARATOR, c + char_definition = self.CharDefinition( + re.compile(re.escape(char)), _CharFlags.SEPARATOR, char ) - char.flags |= flags - self.template.append(char) + char_definition.flags |= flags + self.template.append(char_definition) if template_chars: self.blank = template_chars[0] - if all(char.flags & _CharFlags.SEPARATOR for char in self.template): + if all( + (_CharFlags.SEPARATOR in char_definition.flags) + for char_definition in self.template + ): raise ValueError( "Template must contain at least one non-separator character" ) @@ -177,24 +195,52 @@ def __init__(self, input: Input, template_str: str) -> None: self.update_mask(input.placeholder) def validate(self, value: str) -> ValidationResult: + """Checks if `value` matches this template, always returning a ValidationResult. + + Args: + value: The string value to be validated. + + Returns: + A ValidationResult with the validation outcome. + + """ if self.check(value.ljust(len(self.template), chr(0)), False): return self.success() else: return self.failure("Value does not match template!", value) def check(self, value: str, allow_space: bool) -> bool: - for c, char_def in zip(value, self.template): + """Checks if `value matches this template, but returns result as a bool. + + Args: + value: The string value to be validated. + allow_space: Consider space character in `value` as valid. + + Returns: + True if `value` is valid for this template, False otherwise. + """ + for char, char_definition in zip(value, self.template): if ( - (char_def.flags & _CharFlags.REQUIRED) - and (not char_def.pattern.match(c)) - and ((c != " ") or not allow_space) + (_CharFlags.REQUIRED in char_definition.flags) + and (not char_definition.pattern.match(char)) + and ((char != " ") or not allow_space) ): return False return True def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int]: + """Automatically inserts separators in `value` at `cursor_position` if expected, eventually advancing + the current cursor position. + + Args: + value: Current control value entered by user. + cursor_position: Where to start inserting separators (if any). + + Returns: + A tuple in the form `(value, cursor_position)` with new value and possibly advanced cursor position. + """ while cursor_position < len(self.template) and ( - self.template[cursor_position].flags & _CharFlags.SEPARATOR + _CharFlags.SEPARATOR in self.template[cursor_position].flags ): value = ( value[:cursor_position] @@ -205,25 +251,35 @@ def insert_separators(self, value: str, cursor_position: int) -> tuple[str, int] return value, cursor_position def insert_text_at_cursor(self, text: str) -> str | None: + """Inserts `text` at current cursor position. If not present in `text`, any expected separator is automatically + inserted at the correct position. + + Args: + text: The text to be inserted. + + Returns: + A tuple in the form `(value, cursor_position)` with the new control value and current cursor position if + `text` matches the template, None otherwise. + """ value = self.input.value cursor_position = self.input.cursor_position separators = set( [ - char_def.char - for char_def in self.template - if char_def.flags & _CharFlags.SEPARATOR + char_definition.char + for char_definition in self.template + if _CharFlags.SEPARATOR in char_definition.flags ] ) - for c in text: - if c in separators: - if c == self.next_separator(cursor_position): + for char in text: + if char in separators: + if char == self.next_separator(cursor_position): prev_position = self.prev_separator_position(cursor_position) if (cursor_position > 0) and (prev_position != cursor_position - 1): next_position = self.next_separator_position(cursor_position) while cursor_position < next_position + 1: if ( - self.template[cursor_position].flags - & _CharFlags.SEPARATOR + _CharFlags.SEPARATOR + in self.template[cursor_position].flags ): char = self.template[cursor_position].char else: @@ -237,49 +293,65 @@ def insert_text_at_cursor(self, text: str) -> str | None: continue if cursor_position >= len(self.template): break - char_def = self.template[cursor_position] - assert (char_def.flags & _CharFlags.SEPARATOR) == 0 - if not char_def.pattern.match(c): + char_definition = self.template[cursor_position] + assert _CharFlags.SEPARATOR not in char_definition.flags + if not char_definition.pattern.match(char): return None - if char_def.flags & _CharFlags.LOWERCASE: - c = c.lower() - elif char_def.flags & _CharFlags.UPPERCASE: - c = c.upper() - value = value[:cursor_position] + c + value[cursor_position + 1 :] + if _CharFlags.LOWERCASE in char_definition.flags: + char = char.lower() + elif _CharFlags.UPPERCASE in char_definition.flags: + char = char.upper() + value = value[:cursor_position] + char + value[cursor_position + 1 :] cursor_position += 1 value, cursor_position = self.insert_separators(value, cursor_position) return value, cursor_position def move_cursor(self, delta: int) -> None: + """Moves the cursor position by `delta` characters, skipping separators if + running over them. + + Args: + delta: The number of characters to move; positive moves right, negative + moves left. + """ cursor_position = self.input.cursor_position if delta < 0 and all( - [c.flags & _CharFlags.SEPARATOR for c in self.template[:cursor_position]] + [ + (_CharFlags.SEPARATOR in char_definition.flags) + for char_definition in self.template[:cursor_position] + ] ): return cursor_position += delta while ( (cursor_position >= 0) and (cursor_position < len(self.template)) - and (self.template[cursor_position].flags & _CharFlags.SEPARATOR) + and (_CharFlags.SEPARATOR in self.template[cursor_position].flags) ): cursor_position += delta self.input.cursor_position = cursor_position def delete_at_position(self, position: int | None = None) -> None: + """Deletes character at `position`. + + Args: + position: Position within the control value where to delete a character; + if None the current cursor position is used. + """ value = self.input.value if position is None: position = self.input.cursor_position cursor_position = position if cursor_position < len(self.template): - assert (self.template[cursor_position].flags & _CharFlags.SEPARATOR) == 0 + assert _CharFlags.SEPARATOR not in self.template[cursor_position].flags if cursor_position == len(value) - 1: value = value[:cursor_position] else: value = value[:cursor_position] + " " + value[cursor_position + 1 :] pos = len(value) while pos > 0: - char_def = self.template[pos - 1] - if ((char_def.flags & _CharFlags.SEPARATOR) == 0) and ( + char_definition = self.template[pos - 1] + if (_CharFlags.SEPARATOR not in char_definition.flags) and ( value[pos - 1] != " " ): break @@ -292,32 +364,74 @@ def delete_at_position(self, position: int | None = None) -> None: self.input.value = value def at_separator(self, position: int | None = None) -> bool: + """Checks if character at `position` is a separator. + + Args: + position: Position within the control value where to check; + if None the current cursor position is used. + + Returns: + True if character is a separator, False otherwise. + """ if position is None: position = self.input.cursor_position if (position >= 0) and (position < len(self.template)): - return bool(self.template[position].flags & _CharFlags.SEPARATOR) + return _CharFlags.SEPARATOR in self.template[position].flags else: return False def prev_separator_position(self, position: int | None = None) -> int | None: + """Obtains the position of the previous separator character starting from + `position` within the template string. + + Args: + position: Starting position from which to search previous separator. + If None, current cursor position is used. + + Returns: + The position of the previous separator, or None if no previous + separator is found. + """ if position is None: position = self.input.cursor_position for index in range(position - 1, 0, -1): - if self.template[index].flags & _CharFlags.SEPARATOR: + if _CharFlags.SEPARATOR in self.template[index].flags: return index else: return None def next_separator_position(self, position: int | None = None) -> int | None: + """Obtains the position of the next separator character starting from + `position` within the template string. + + Args: + position: Starting position from which to search next separator. + If None, current cursor position is used. + + Returns: + The position of the next separator, or None if no next + separator is found. + """ if position is None: position = self.input.cursor_position for index in range(position + 1, len(self.template)): - if self.template[index].flags & _CharFlags.SEPARATOR: + if _CharFlags.SEPARATOR in self.template[index].flags: return index else: return None def next_separator(self, position: int | None = None) -> str | None: + """Obtains the next separator character starting from `position` + within the template string. + + Args: + position: Starting position from which to search next separator. + If None, current cursor position is used. + + Returns: + The next separator character, or None if no next + separator is found. + """ position = self.next_separator_position(position) if position is None: return None @@ -325,31 +439,53 @@ def next_separator(self, position: int | None = None) -> str | None: return self.template[position].char def display(self, value: str) -> str: + """Returns `value` ready for display, with spaces replaced by + placeholder characters. + + Args: + value: String value to display. + + Returns: + New string value with spaces replaced by placeholders. + """ result = [] - for c, char_def in zip(value, self.template): - if c == " ": - c = char_def.char - result.append(c) + for char, char_definition in zip(value, self.template): + if char == " ": + char = char_definition.char + result.append(char) return "".join(result) def update_mask(self, placeholder: str) -> None: - for index, char_def in enumerate(self.template): - if (char_def.flags & _CharFlags.SEPARATOR) == 0: + """Updates template placeholder characters from `placeholder`. If + given string is smaller than template string, template blank character + is used to fill remaining template placeholder characters. + + Args: + placeholder: New placeholder string. + """ + for index, char_definition in enumerate(self.template): + if _CharFlags.SEPARATOR not in char_definition.flags: if index < len(placeholder): - char_def.char = placeholder[index] + char_definition.char = placeholder[index] else: - char_def.char = self.blank + char_definition.char = self.blank @property def mask(self) -> str: - return "".join([c.char for c in self.template]) + """Property returning the template placeholder mask.""" + return "".join([char_definition.char for char_definition in self.template]) @property def empty_mask(self) -> str: + """Property returning the template placeholder mask with all non-separators replaced by space.""" return "".join( [ - " " if (c.flags & _CharFlags.SEPARATOR) == 0 else c.char - for c in self.template + ( + " " + if (_CharFlags.SEPARATOR not in char_definition.flags) + else char_definition.char + ) + for char_definition in self.template ] ) @@ -413,6 +549,7 @@ def __init__( self.tooltip = tooltip def validate_value(self, value: str) -> str: + """Validates value against template.""" if self._template is None: return value if not self._template.check(value, True): @@ -469,6 +606,7 @@ def _value(self) -> Text: return Text(value, no_wrap=True, overflow="ignore") async def _on_click(self, event: events.Click) -> None: + """Ensure clicking on value does not leave cursor on a separator.""" await super()._on_click(event) if self._template.at_separator(): self._template.move_cursor(1) @@ -491,11 +629,11 @@ def clear(self) -> None: self.value, self.cursor_position = self._template.insert_separators("", 0) def action_cursor_left(self) -> None: - """Move the cursor one position to the left.""" + """Move the cursor one position to the left; separators are skipped.""" self._template.move_cursor(-1) def action_cursor_right(self) -> None: - """Accept an auto-completion or move the cursor one position to the right.""" + """Move the cursor one position to the right; separators are skipped.""" self._template.move_cursor(1) def action_home(self) -> None: @@ -503,7 +641,8 @@ def action_home(self) -> None: self._template.move_cursor(-len(self.template)) def action_cursor_left_word(self) -> None: - """Move the cursor left to the start of a word.""" + """Move the cursor left next to the previous separator. If no previous + separator is found, moves the cursor to the start of the input.""" if self._template.at_separator(self.cursor_position - 1): position = self._template.prev_separator_position(self.cursor_position - 1) else: @@ -513,7 +652,8 @@ def action_cursor_left_word(self) -> None: self.cursor_position = position or 0 def action_cursor_right_word(self) -> None: - """Move the cursor right to the start of a word.""" + """Move the cursor right next to the next separator. If no next + separator is found, moves the cursor to the end of the input.""" position = self._template.next_separator_position() if position is None: self.cursor_position = len(self._template.mask) @@ -525,7 +665,8 @@ def action_delete_right(self) -> None: self._template.delete_at_position() def action_delete_right_word(self) -> None: - """Delete the current character and all rightward to the start of the next word.""" + """Delete the current character and all rightward to next separator or + the end of the input.""" position = self._template.next_separator_position() if position is not None: position += 1 @@ -545,7 +686,8 @@ def action_delete_left(self) -> None: self._template.delete_at_position() def action_delete_left_word(self) -> None: - """Delete leftward of the cursor position to the start of a word.""" + """Delete leftward of the cursor position to the previous separator or + the start of the input.""" if self.cursor_position <= 0: return if self._template.at_separator(self.cursor_position - 1): From e3b3329513d503a0ea44a547a286d5e7ef4d0776 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Fri, 2 Aug 2024 01:04:06 +0200 Subject: [PATCH 67/80] Updated changelog --- CHANGELOG.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77148c379f..52fe16933c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Added + +- Added `MaskedInput` widget + + ## [0.75.0] - 2024-08-01 ### Added @@ -24,10 +31,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [0.74.0] - 2024-07-25 -### Added - -- Added `MaskedInput` widget - ### Fixed - Fixed issues in Kitty terminal after exiting app https://github.com/Textualize/textual/issues/4779 From 09e4eb801bba7252d1068498f0a17a87ad9a6255 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Fri, 2 Aug 2024 08:28:50 +0200 Subject: [PATCH 68/80] Fixed changelog again --- CHANGELOG.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d82a4c2df..a17311a355 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,24 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [0.75.0] - 2024-08-01 - -### Added - -- Added `App.open_url` to open URLs in the web browser. When running via the WebDriver, the URL will be opened in the browser that is controlling the app https://github.com/Textualize/textual/pull/4819 -- Added `Widget.is_mouse_over` https://github.com/Textualize/textual/pull/4818 -- Added `node` attribute to `events.Enter` and `events.Leave` https://github.com/Textualize/textual/pull/4818 - -### Changed - -- `events.Enter` and `events.Leave` events now bubble. https://github.com/Textualize/textual/pull/4818 -- Renamed `Widget.mouse_over` to `Widget.mouse_hover` https://github.com/Textualize/textual/pull/4818 - -### Fixed - -- Fixed issue with `mutate_reactive` and data binding https://github.com/Textualize/textual/pull/4828 - -## [0.74.0] - 2024-07-25 +## unrelease ### Added From d4325f492dcb5ab663e753ea1203dfa30a6bc725 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Tue, 27 Aug 2024 20:20:13 +0100 Subject: [PATCH 69/80] add simplify switch to export_screenshot --- src/textual/_doc.py | 3 ++- src/textual/app.py | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/textual/_doc.py b/src/textual/_doc.py index 54aa7008be..bc0c4e57a5 100644 --- a/src/textual/_doc.py +++ b/src/textual/_doc.py @@ -65,6 +65,7 @@ def take_svg_screenshot( terminal_size: tuple[int, int] = (80, 24), run_before: Callable[[Pilot], Awaitable[None] | None] | None = None, wait_for_animation: bool = True, + simplify=True, ) -> str: """ @@ -129,7 +130,7 @@ async def auto_pilot(pilot: Pilot) -> None: await pilot.pause() await pilot.pause() await pilot.wait_for_scheduled_animations() - svg = app.export_screenshot(title=title) + svg = app.export_screenshot(title=title, simplify=simplify) app.exit(svg) diff --git a/src/textual/app.py b/src/textual/app.py index 25b3f4ead1..3dc241d415 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1379,7 +1379,12 @@ def action_screenshot(self, filename: str | None = None, path: str = "./") -> No """ self.save_screenshot(filename, path) - def export_screenshot(self, *, title: str | None = None) -> str: + def export_screenshot( + self, + *, + title: str | None = None, + simplify: bool = False, + ) -> str: """Export an SVG screenshot of the current screen. See also [save_screenshot][textual.app.App.save_screenshot] which writes the screenshot to a file. @@ -1402,7 +1407,7 @@ def export_screenshot(self, *, title: str | None = None) -> str: safe_box=False, ) screen_render = self.screen._compositor.render_update( - full=True, screen_stack=self.app._background_screens, simplify=True + full=True, screen_stack=self.app._background_screens, simplify=simplify ) console.print(screen_render) return console.export_svg(title=title or self.title) From a100081bbf5d1fe3fa173cdcc7c2a93573034eab Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Wed, 28 Aug 2024 14:39:41 +0200 Subject: [PATCH 70/80] Fixed tests, added missing snapshot test --- .../test_snapshots/test_masked_input.svg | 155 ++++++++++++++++++ tests/test_masked_input.py | 3 + 2 files changed, 158 insertions(+) create mode 100644 tests/snapshot_tests/__snapshots__/test_snapshots/test_masked_input.svg diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_masked_input.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_masked_input.svg new file mode 100644 index 0000000000..9bfed2123c --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_masked_input.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + TemplateApp + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +ABC01-DE___-_____-_____ +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ +▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ +YYYY-MM-DD +▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_masked_input.py b/tests/test_masked_input.py index 6a980f0dad..698d7f11c5 100644 --- a/tests/test_masked_input.py +++ b/tests/test_masked_input.py @@ -82,6 +82,7 @@ async def test_editing(): assert input.cursor_position == 4 assert input.value == "ABCD" input.value = serial + input.action_end() assert input.is_valid app.set_focus(None) input.focus() @@ -97,6 +98,7 @@ async def test_key_movement_actions(): async with app.run_test(): input = app.query_one(MaskedInput) input.value = serial + input.action_home() assert input.is_valid input.action_cursor_right_word() assert input.cursor_position == 6 @@ -117,6 +119,7 @@ async def test_key_modification_actions(): input = app.query_one(MaskedInput) input.value = serial assert input.is_valid + input.cursor_position = 0 input.action_delete_right() assert input.value == " BCDE-FGHIJ-KLMNO-PQRST" input.cursor_position = 3 From a46e2df90d29cf0fe96b4115eec252712c19bf95 Mon Sep 17 00:00:00 2001 From: Angelo Mottola Date: Wed, 28 Aug 2024 14:44:10 +0200 Subject: [PATCH 71/80] Updated changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f637e07c3..33a4f4aeea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - Added `DOMNode.check_consume_key` https://github.com/Textualize/textual/pull/4940 +- Added `MaskedInput` widget https://github.com/Textualize/textual/pull/4783 ### Changed @@ -22,7 +23,6 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added Maximize and Minimize system commands. https://github.com/Textualize/textual/pull/4931 - Added `Screen.maximize`, `Screen.minimize`, `Screen.action_maximize`, `Screen.action_minimize`, `Widget.is_maximized`, `Widget.allow_maximize`. https://github.com/Textualize/textual/pull/4931 - Added `Widget.ALLOW_MAXIMIZE`, `Screen.ALLOW_IN_MAXIMIZED_VIEW` classvars https://github.com/Textualize/textual/pull/4931 -- Added `MaskedInput` widget https://github.com/Textualize/textual/pull/4783 ## [0.77.0] - 2024-08-22 From e0f01e80d70971d4cec0cfb255568e047d8c30ba Mon Sep 17 00:00:00 2001 From: Darren Burns Date: Thu, 5 Sep 2024 07:59:21 +0100 Subject: [PATCH 72/80] Update MaskedInput "added in version" note in docs --- docs/widgets/masked_input.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/widgets/masked_input.md b/docs/widgets/masked_input.md index 0a8820d27c..d40350b2c8 100644 --- a/docs/widgets/masked_input.md +++ b/docs/widgets/masked_input.md @@ -1,6 +1,6 @@ # MaskedInput -!!! tip "Added in version 0.74.0" +!!! tip "Added in version 0.80.0" A masked input derived from `Input`, allowing to restrict user input and give visual aid via a simple template mask, which also acts as an implicit *[validator][textual.validation.Validator]*. From da00ab3f7b743703e934f2ada1e77ecc71019905 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 9 Sep 2024 19:29:45 +0100 Subject: [PATCH 73/80] mother example --- examples/mother.py | 104 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 examples/mother.py diff --git a/examples/mother.py b/examples/mother.py new file mode 100644 index 0000000000..9175b5f928 --- /dev/null +++ b/examples/mother.py @@ -0,0 +1,104 @@ +""" +A simple example of chatting to an LLM with Textual. + +Lots of room for improvement here. + +See https://textual.textualize.io/blog/2024/09/15/anatomy-of-a-textual-user-interface/ + +""" + +# /// script +# requires-python = ">=3.12" +# dependencies = [ +# "llm", +# "textual", +# ] +# /// +from textual import on, work +from textual.app import App, ComposeResult +from textual.containers import VerticalScroll +from textual.widgets import Footer, Header, Input, Markdown + +try: + import llm +except ImportError: + raise ImportError("install the 'llm' package or run with 'uv run mother.py'") + +# The system prompt +SYSTEM = """Formulate all responses as if you where the sentient AI named Mother from the Alien movies.""" + + +class Prompt(Markdown): + """Markdown for the user prompt.""" + + +class Response(Markdown): + """Markdown for the reply from the LLM.""" + + BORDER_TITLE = "Mother" + + +class MotherApp(App): + """Simple app to demonstrate chatting to an LLM.""" + + AUTO_FOCUS = "Input" + + CSS = """ + Prompt { + background: $primary 10%; + color: $text; + margin: 1; + margin-right: 8; + padding: 1 2 0 2; + } + + Response { + border: wide $success; + background: $success 10%; + color: $text; + margin: 1; + margin-left: 8; + padding: 1 2 0 2; + } + """ + + def compose(self) -> ComposeResult: + yield Header() + with VerticalScroll(id="chat-view"): + yield Response("INTERFACE 2037 READY FOR INQUIRY") + yield Input(placeholder="How can I help you?") + yield Footer() + + def on_mount(self) -> None: + """You might want to change the model if you don't have access to it.""" + self.model = llm.get_model("gpt-4o") + + @on(Input.Submitted) + async def on_input(self, event: Input.Submitted) -> None: + """When the user hits return.""" + chat_view = self.query_one("#chat-view") + event.input.clear() + await chat_view.mount(Prompt(event.value)) + await chat_view.mount(response := Response()) + response.anchor() + self.send_prompt(event.value, response) + + @work(thread=True) + def send_prompt(self, prompt: str, response: Response) -> None: + """Get the response in a thread.""" + response_content = "" + llm_response = self.model.prompt(prompt, system=SYSTEM) + for chunk in llm_response: + response_content += chunk + self.call_from_thread(response.update, response_content) + + +if __name__ == "__main__": + print( + "https://textual.textualize.io/blog/2024/09/15/anatomy-of-a-textual-user-interface/" + ) + print( + "You will need an OpenAI API key for this example. See https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key" + ) + app = MotherApp() + app.run() From 215d99c050bf67fc08f7af4c32eacf48738e8f30 Mon Sep 17 00:00:00 2001 From: Will McGugan Date: Mon, 9 Sep 2024 19:36:56 +0100 Subject: [PATCH 74/80] tweak example --- examples/mother.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/mother.py b/examples/mother.py index 9175b5f928..0cdbd96b01 100644 --- a/examples/mother.py +++ b/examples/mother.py @@ -98,7 +98,7 @@ def send_prompt(self, prompt: str, response: Response) -> None: "https://textual.textualize.io/blog/2024/09/15/anatomy-of-a-textual-user-interface/" ) print( - "You will need an OpenAI API key for this example. See https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key" + "You will need an OpenAI API key for this example.\nSee https://help.openai.com/en/articles/4936850-where-do-i-find-my-openai-api-key" ) app = MotherApp() app.run() From 5f24a751baaf317a82e19cd8df2c2c3b92bb4e3d Mon Sep 17 00:00:00 2001 From: JaceyPenny Date: Mon, 9 Sep 2024 18:58:25 +0000 Subject: [PATCH 75/80] Loosen platformdirs version requirement --- poetry.lock | 221 +++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 114 insertions(+), 109 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4294a0ad21..a8e6709daf 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiohappyeyeballs" @@ -1119,13 +1119,13 @@ pyyaml = ">=5.1" [[package]] name = "mkdocs-git-revision-date-localized-plugin" -version = "1.2.7" +version = "1.2.8" description = "Mkdocs plugin that enables displaying the localized date of the last git modification of a markdown file." optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_git_revision_date_localized_plugin-1.2.7-py3-none-any.whl", hash = "sha256:d2b30ccb74ec8e118298758d75ae4b4f02c620daf776a6c92fcbb58f2b78f19f"}, - {file = "mkdocs_git_revision_date_localized_plugin-1.2.7.tar.gz", hash = "sha256:2f83b52b4dad642751a79465f80394672cbad022129286f40d36b03aebee490f"}, + {file = "mkdocs_git_revision_date_localized_plugin-1.2.8-py3-none-any.whl", hash = "sha256:c7ec3b1481ca23134269e84927bd8a5dc1aa359c0e515b832dbd5d25019b5748"}, + {file = "mkdocs_git_revision_date_localized_plugin-1.2.8.tar.gz", hash = "sha256:6e09c308bb27bcf36b211d17b74152ecc2837cdfc351237f70cffc723ef0fd99"}, ] [package.dependencies] @@ -1134,6 +1134,11 @@ GitPython = "*" mkdocs = ">=1.0" pytz = "*" +[package.extras] +all = ["GitPython", "babel (>=2.7.0)", "click", "codecov", "mkdocs (>=1.0)", "mkdocs-gen-files", "mkdocs-git-authors-plugin", "mkdocs-material", "mkdocs-static-i18n", "pytest", "pytest-cov", "pytz"] +base = ["GitPython", "babel (>=2.7.0)", "mkdocs (>=1.0)", "pytz"] +dev = ["click", "codecov", "mkdocs-gen-files", "mkdocs-git-authors-plugin", "mkdocs-material", "mkdocs-static-i18n", "pytest", "pytest-cov"] + [[package]] name = "mkdocs-material" version = "9.5.34" @@ -1300,7 +1305,7 @@ files = [ {file = "msgpack-1.0.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fbb160554e319f7b22ecf530a80a3ff496d38e8e07ae763b9e82fadfe96f273"}, {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, - {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] @@ -1510,19 +1515,19 @@ files = [ [[package]] name = "platformdirs" -version = "4.3.1" +version = "4.3.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.3.1-py3-none-any.whl", hash = "sha256:facaa5a3c57aa1e053e3da7b49e0cc31fe0113ca42a4659d5c2e98e545624afe"}, - {file = "platformdirs-4.3.1.tar.gz", hash = "sha256:63b79589009fa8159973601dd4563143396b35c5f93a58b36f9049ff046949b1"}, + {file = "platformdirs-4.3.2-py3-none-any.whl", hash = "sha256:eb1c8582560b34ed4ba105009a4badf7f6f85768b30126f351328507b2beb617"}, + {file = "platformdirs-4.3.2.tar.gz", hash = "sha256:9e5e27a08aa095dd127b9f2e764d74254f482fef22b0970773bfba79d091ab8c"}, ] [package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] +docs = ["furo (>=2024.8.6)", "proselint (>=0.14)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=8.3.2)", "pytest-cov (>=5)", "pytest-mock (>=3.14)"] +type = ["mypy (>=1.11.2)"] [[package]] name = "pluggy" @@ -2296,13 +2301,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "virtualenv" -version = "20.26.3" +version = "20.26.4" description = "Virtual Python Environment builder" optional = false python-versions = ">=3.7" files = [ - {file = "virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589"}, - {file = "virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a"}, + {file = "virtualenv-20.26.4-py3-none-any.whl", hash = "sha256:48f2695d9809277003f30776d155615ffc11328e6a0a8c1f0ec80188d7874a55"}, + {file = "virtualenv-20.26.4.tar.gz", hash = "sha256:c17f4e0f3e6036e9f26700446f85c76ab11df65ff6d8a9cbfad9f71aabfcf23c"}, ] [package.dependencies] @@ -2363,103 +2368,103 @@ watchmedo = ["PyYAML (>=3.10)"] [[package]] name = "yarl" -version = "1.10.0" +version = "1.11.0" description = "Yet another URL library" optional = false python-versions = ">=3.8" files = [ - {file = "yarl-1.10.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1718c0bca5a61edac7a57dcc11856cb01bde13a9360a3cb6baf384b89cfc0b40"}, - {file = "yarl-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4657fd290d556a5f3018d07c7b7deadcb622760c0125277d10a11471c340054"}, - {file = "yarl-1.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:044b76d069e69c6b0246f071ebac0576f89c772f806d66ef51e662bd015d03c7"}, - {file = "yarl-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5527d32506c11150ca87f33820057dc284e2a01a87f0238555cada247a8b278"}, - {file = "yarl-1.10.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36d12d78b8b0d46099d413c8689b5510ad9ce5e443363d1c37b6ac5b3d7cbdfb"}, - {file = "yarl-1.10.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:11f7f8a72b3e26c533fa7ffa7a8068f4e3aad7b67c5cf7b17ea8c79fc81d9830"}, - {file = "yarl-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88173836a25b7e5dce989eeee3b92d8ef5cdf512830d4155c6212de98e616f70"}, - {file = "yarl-1.10.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c382e189af10070bcb39caa9406b9cc47b26c1d2257979f11fe03a38be09fea9"}, - {file = "yarl-1.10.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:534b8bc181dca1691cf491c263e084af678a8fb6b6181687c788027d8c317026"}, - {file = "yarl-1.10.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5f3372f9ae1d1f001826b77d0b29d4220e84f6c5f53915e71a825cdd02600065"}, - {file = "yarl-1.10.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4cca9ba00be4bb8a051c4007b60fc91d6c9728c8b70c86cee4c24be9d641002f"}, - {file = "yarl-1.10.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a9d8c4be5658834dc688072239d220631ad4b71ff79a5f3d17fb653f16d10759"}, - {file = "yarl-1.10.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff45a655ca51e1cb778abbb586083fddb7d896332f47bb3b03bc75e30c25649f"}, - {file = "yarl-1.10.0-cp310-cp310-win32.whl", hash = "sha256:9ef7ce61958b3c7b2e2e0927c52d35cf367c5ee410e06e1337ecc83a90c23b95"}, - {file = "yarl-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:48a48261f8d610b0e15fed033e74798763bc2f8f2c0d769a2a0732511af71f1e"}, - {file = "yarl-1.10.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:308d1cce071b5b500e3d95636bbf15dfdb8e87ed081b893555658a7f9869a156"}, - {file = "yarl-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc66927f6362ed613a483c22618f88f014994ccbd0b7a25ec1ebc8c472d4b40a"}, - {file = "yarl-1.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c4d13071c5b99974cfe2f94c749ecc4baf882f7c4b6e4c40ca3d15d1b7e81f24"}, - {file = "yarl-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:348ad53acd41caa489df7db352d620c982ab069855d9635dda73d685bbbc3636"}, - {file = "yarl-1.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:293f7c2b30d015de3f1441c4ee764963b86636fde881b4d6093498d1e8711f69"}, - {file = "yarl-1.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:315e8853d0ea46aabdce01f1f248fff7b9743de89b555c5f0487f54ac84beae8"}, - {file = "yarl-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:012c506b2c23be4500fb97509aa7e6a575996fb317b80667fa26899d456e2aaf"}, - {file = "yarl-1.10.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f769c2708c31227c5349c3e4c668c8b4b2e25af3e7263723f2ef33e8e3906a0"}, - {file = "yarl-1.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4f6ac063a4e9bbd4f6cc88cc621516a44d6aec66862ea8399ba063374e4b12c7"}, - {file = "yarl-1.10.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:18b7ce6d8c35da8e16dcc8de124a80e250fc8c73f8c02663acf2485c874f1972"}, - {file = "yarl-1.10.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:b80246bdee036381636e73ef0f19b032912064622b0e5ee44f6960fd11df12aa"}, - {file = "yarl-1.10.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:183dd37bb5471e8017ab8a998c1ea070b4a0b08a97a7c4e20e0c7ccbe8ebb999"}, - {file = "yarl-1.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9b6d0d7522b514f054b359409817af4c5ed76fa4fe42d8bd1ed12956804cf595"}, - {file = "yarl-1.10.0-cp311-cp311-win32.whl", hash = "sha256:6026a6ef14d038a38ca9d81422db4b6bb7d5da94f9d08f21e0ad9ebd9c4bc3bb"}, - {file = "yarl-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:190e70d2f9f16f1c9d666c103d635c9ed4bf8de7803e9fa0495eec405a3e96a8"}, - {file = "yarl-1.10.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6bc602c7413e1b5223bc988947125998cb54d6184de45a871985daacc23e6c8c"}, - {file = "yarl-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bf733c835ebbd52bd78a52b919205e0f06d8571f71976a0259e5bcc20d0a2f44"}, - {file = "yarl-1.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6e91ed5f6818e1e3806eaeb7b14d9e17b90340f23089451ea59a89a29499d760"}, - {file = "yarl-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23057a004bc9735008eb2a04b6ce94c6c06219cdf2b193997fd3ae6039eb3196"}, - {file = "yarl-1.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b922c32a1cff62bc43d408d1a8745abeed0a705793f2253c622bf3521922198"}, - {file = "yarl-1.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be199fed28861d72df917e355287ad6835555d8210e7f8203060561f24d7d842"}, - {file = "yarl-1.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cece693380c1c4a606cdcaa0c54eda8f72cfe1ba83f5149b9023bb955e8fa8e"}, - {file = "yarl-1.10.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff8e803d8ca170e632fb3b4df1bfd29ba29be8edc3e9306c5ffa5fadea234a4f"}, - {file = "yarl-1.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:30dde3a8b88c80a4f049eb4dd240d2a02e89174da6be2525541f949bf9fa38ab"}, - {file = "yarl-1.10.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:dff84623e7098cf9bfbb5187f9883051af652b0ce08b9f7084cc8630b87b6457"}, - {file = "yarl-1.10.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8e69b55965a47dd6c79e578abd7d85637b1bb4a7565436630826bdb28aa9b7ad"}, - {file = "yarl-1.10.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5d0c9e1dcc92d46ca89608fe4763fc2362f1e81c19a922c67dbc0f20951466e4"}, - {file = "yarl-1.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:32e79d5ae975f7c2cc29f7104691fc9be5ee3724f24e1a7254d72f6219672108"}, - {file = "yarl-1.10.0-cp312-cp312-win32.whl", hash = "sha256:762a196612c2aba4197cd271da65fe08308f7ddf130dc63842c7a76d774b6a2c"}, - {file = "yarl-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:8c6214071f653d21bb7b43f7ee519afcbf7084263bb43408f4939d14558290db"}, - {file = "yarl-1.10.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0e0aea8319fdc1ac340236e58b0b7dc763621bce6ce98124a9d58104cafd0aaa"}, - {file = "yarl-1.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b3bf343b4ef9ec600d75363eb9b48ab3bd53b53d4e1c5a9fbf0cfe7ba73a47f"}, - {file = "yarl-1.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:05b07e6e0f715eaae9d927a302d9220724392f3c0b4e7f8dfa174bf2e1b8433e"}, - {file = "yarl-1.10.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d7bd531d7eec4aa7ef8a99fef91962eeea5158a53af0ec507c476ddf8ebc29c"}, - {file = "yarl-1.10.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:183136dc5d5411872e7529c924189a2e26fac5a7f9769cf13ef854d1d653ad36"}, - {file = "yarl-1.10.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c77a3c10af4aaf8891578fe492ef0990c65cf7005dd371f5ea8007b420958bf6"}, - {file = "yarl-1.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:030d41d48217b180c5a176e59c49d212d54d89f6f53640fa4c1a1766492aec27"}, - {file = "yarl-1.10.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4f43ba30d604ba391bc7fe2dd104d6b87b62b0de4bbde79e362524b8a1eb75"}, - {file = "yarl-1.10.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:637dd0f55d1781d4634c23994101c509e455b5ab61af9086b5763b7eca9359aa"}, - {file = "yarl-1.10.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:99e7459ee86a3b81e57777afd3825b8b1acaac8a99f9c0bd02415d80eb3c371b"}, - {file = "yarl-1.10.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a80cdb3c15c15b33ecdb080546dcb022789b0084ca66ad41ffa0fe09857fca11"}, - {file = "yarl-1.10.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1824bfb932d8100e5c94f4f98c078f23ebc6f6fa93acc3d95408762089c54a06"}, - {file = "yarl-1.10.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:90fd64ce00f594db02f603efa502521c440fa1afcf6266be82eb31f19d2d9561"}, - {file = "yarl-1.10.0-cp313-cp313-win32.whl", hash = "sha256:687131ee4d045f3d58128ca28f5047ec902f7760545c39bbe003cc737c5a02b5"}, - {file = "yarl-1.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:493ad061ee025c5ed3a60893cd70204eead1b3f60ccc90682e752f95b845bd46"}, - {file = "yarl-1.10.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:cd65588273d19f8483bc8f32a6fcf602e94a9a7ba287a1725977bd9527cd6c0c"}, - {file = "yarl-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6f64f8681671624f539eea5564518bc924524c25eb90ab24a7eddc2d872e668e"}, - {file = "yarl-1.10.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3576ed2c51f8525d4ff5c3279247aacff9540bb43b292c4a37a8e6c6e1691adb"}, - {file = "yarl-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca42a9281807fdf8fba86e671d8fdd76f92e9302a6d332957f2bae51c774f8a7"}, - {file = "yarl-1.10.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54a4b5e6a060d46cad6a3cf340f4cb268e6fbc89c589d82a2da58f7db47c47c8"}, - {file = "yarl-1.10.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6eec21d8c3aa932c5a89480b58fa877e9c48092ab838ccc76788cbc917ceec0d"}, - {file = "yarl-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:273baee8a8af5989d5aab51c740e65bc2b1fc6619b9dd192cd16a3fae51100be"}, - {file = "yarl-1.10.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1bf63ba496cd4f12d30e916d9a52daa6c91433fedd9cd0d99fef3e13232836f"}, - {file = "yarl-1.10.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:f8e24b9a4afdffab399191a9f0b0e80eabc7b7fdb9f2dbccdeb8e4d28e5c57bb"}, - {file = "yarl-1.10.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:4c46454fafa31f7241083a0dd21814f63e0fcb4ae49662dc7e286fd6a5160ea1"}, - {file = "yarl-1.10.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:beda87b63c08fb4df8cc5353eeefe68efe12aa4f5284958bd1466b14c85e508e"}, - {file = "yarl-1.10.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:9a8d6a0e2b5617b5c15c59db25f20ba429f1fea810f2c09fbf93067cb21ab085"}, - {file = "yarl-1.10.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b453b3dbc1ed4c2907632d05b378123f3fb411cad05d8d96de7d95104ef11c70"}, - {file = "yarl-1.10.0-cp38-cp38-win32.whl", hash = "sha256:1ea30675fbf0ad6795c100da677ef6a8960a7db05ac5293f02a23c2230203c89"}, - {file = "yarl-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:347011ad09a8f9be3d41fe2d7d611c3a4de4d49aa77bcb9a8c03c7a82fc45248"}, - {file = "yarl-1.10.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:18bc4600eed1907762c1816bb16ac63bc52912e53b5e9a353eb0935a78e95496"}, - {file = "yarl-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eeb6a40c5ae2616fd38c1e039c6dd50031bbfbc2acacfd7b70a5d64fafc70901"}, - {file = "yarl-1.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bc544248b5263e1c0f61332ccf35e37404b54213f77ed17457f857f40af51452"}, - {file = "yarl-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3352c69dc235850d6bf8ddad915931f00dcab208ac4248b9af46175204c2f5f9"}, - {file = "yarl-1.10.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af5b52bfbbd5eb208cf1afe23c5ada443929e9b9d79e9fbc66cacc07e4e39748"}, - {file = "yarl-1.10.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eafa7317063de4bc310716cdd9026c13f00b1629e649079a6908c3aafdf5046"}, - {file = "yarl-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a162cf04fd1e8d81025ec651d14cac4f6e0ca73a3c0a9482de8691b944e3098a"}, - {file = "yarl-1.10.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:179b1df5e9cd99234ea65e63d5bfc6dd524b2c3b6cf68a14b94ccbe01ab37ddd"}, - {file = "yarl-1.10.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:32d2e46848dea122484317485129f080220aa84aeb6a9572ad9015107cebeb07"}, - {file = "yarl-1.10.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aa1aeb99408be0ca774c5126977eb085fedda6dd7d9198ce4ceb2d06a44325c7"}, - {file = "yarl-1.10.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:d2366e2f987f69752f0588d2035321aaf24272693d75f7f6bb7e8a0f48f7ccdd"}, - {file = "yarl-1.10.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e8da33665ecc64cd3e593098adb449f9c65b4e3bc6338e75ad592da15453d898"}, - {file = "yarl-1.10.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b46c603bee1f2dd407b8358c2afc9b0472a22ccca528f114e1f4cd30dfecd22"}, - {file = "yarl-1.10.0-cp39-cp39-win32.whl", hash = "sha256:96422a3322b4d954f4c52403a2fc129ad118c151ee60a717847fb46a8480d1e1"}, - {file = "yarl-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:52d1ae09b0764017e330bb5bf9af760c0168c564225085bb806f687bccffda8a"}, - {file = "yarl-1.10.0-py3-none-any.whl", hash = "sha256:99eaa7d53f509ba1c2fea8fdfec15ba3cd36caca31d57ec6665073b148b5f260"}, - {file = "yarl-1.10.0.tar.gz", hash = "sha256:3bf10a395adac62177ba8ea738617e8de6cbb1cea6aa5d5dd2accde704fc8195"}, + {file = "yarl-1.11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0a657db1b9982f3dac0e360614d0e8945d2873da6e681fb7fca23ef1c3eb37f8"}, + {file = "yarl-1.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:65a1a05efca52b102691e64db5fcf973030a1c88fee393804ff91f99c95a6e74"}, + {file = "yarl-1.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f4cb417d380e2d77961eecec75aaaf6f7ab14e6de26eb3a498f498029a6556a1"}, + {file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8aee7c8378c6aa3103b99d1eb9995268ef730fa9f88ea68b9eee4341e204eec9"}, + {file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84624db40e2358cfd5cf2558b1aaffd93366d27ee32228a97785f2ec87d44a17"}, + {file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a596bb15e036952549871a4ccd2205679902dc7f241e3ced6b2ab2e44c55795"}, + {file = "yarl-1.11.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9d4d2cc4b076c8ad0175a15ee9482a387b3303c97d4b71062db7356b2ac04c7"}, + {file = "yarl-1.11.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25f8bc849004122591104793a576e9c747b0e5d9486d6a30225521b817255748"}, + {file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e38176a559edde0cfff4b663791a007a5f9f90c73aee1d6f7ddbcf6bfb7287b3"}, + {file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:706ac0f77b45e9e0278ec6c98929764e119d3ce3136792b6475e7ae961da53ec"}, + {file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:48bac099586cf75ae5837b0ac17a674450d01f451f38afcb02acfc940110b60b"}, + {file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:540fd5f62fe21f3d1d9efe8af5c4d9dbbb184ce03ce95acb0289500e46215dd2"}, + {file = "yarl-1.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:05ab59db0bb64e847972373c5cda8924e6605480f6b13cc04573fa0d87bfc637"}, + {file = "yarl-1.11.0-cp310-cp310-win32.whl", hash = "sha256:ddab47748933ac9cf5f29d6e9e2e2060cff40b2751d02c55129661ea4e577152"}, + {file = "yarl-1.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:976d02274e6d88b24c7131e7b26a083412b2592f2bbcef53d3b00b2508cad26c"}, + {file = "yarl-1.11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:39e3087e1ef70862de81e22af9eb299faee580f41673ef92829949022791b521"}, + {file = "yarl-1.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7fd535cc41b81a566ad347081b671ab5c7e5f5b6a15526d85b4e748baf065cf0"}, + {file = "yarl-1.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f7cc02d8e9a612174869f4b983f159e87659096f7e2dc1fe9effd9902e408739"}, + {file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30f391ccf4b1b1e0ba4880075ba337d41a619a5350f67053927f67ebe764bf44"}, + {file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c19a0d95943bb2c914b4e71043803be34bc75c08c4a6ca232bdc649a1e9ef1b"}, + {file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ead4d89eade0e09b8ef97877664abb0e2e8704787db5564f83658fdee5c36497"}, + {file = "yarl-1.11.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:195f7791bc23d5f2480efe53f935daf8a61661000dfbfbdd70dbd06397594fff"}, + {file = "yarl-1.11.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01a7905e662665ca8e058635377522bc3c98bdb873be761ff42c86eb72b03914"}, + {file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:53c80b1927b75aed208d7fd965a3a705dc8c1db4d50b9112418fa0f7784363e6"}, + {file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:11af21bbf807688d49b7d4915bb28cbc2e3aa028a2ee194738477eabcc413c65"}, + {file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:732d56da00ea7a5da4f0d15adbbd22dcb37da7825510aafde40112e53f6baa52"}, + {file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7bd54d79025b59d1dc5fb26a09734d6a9cc651a04bc381966ed264b28331a168"}, + {file = "yarl-1.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:aacd62ff67efd54cb18cea2aa7ae4fb83cfbca19a07055d4777266b70561defe"}, + {file = "yarl-1.11.0-cp311-cp311-win32.whl", hash = "sha256:68e14ae71e5b51c8282ae5db53ccb3baffc40e1551370a8a2361f1c1d8a0bf8c"}, + {file = "yarl-1.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:3ade2265716667b6bd4123d6f684b5f7cf4a8d83dcf1d5581ac44643466bb00a"}, + {file = "yarl-1.11.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6e73dab98e3c3b5441720153e72a5f28e717aac2d22f1ec4b08ef33417d9987e"}, + {file = "yarl-1.11.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:4a0d090d296ced05edfe29c6ff34869412fa6a97d0928c12b00939c4842884cd"}, + {file = "yarl-1.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d29e446cfb0a82d3df7745968b9fa286665a9be8b4d68de46bcc32d917cb218e"}, + {file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c8dc0efcf8266ecfe057b95e01f43eb62516196a4bbf3918fd1dcb8d0dc0dff"}, + {file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:202f5ec49ff163dcc767426deb55020a28078e61d6bbe1f80331d92bca53b236"}, + {file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8055b0d78ce1cafa657c4b455e22661e8d3b2834de66a0753c3567da47fcc4aa"}, + {file = "yarl-1.11.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60ed3c7f64e820959d7f682ec2f559b4f4df723dc09df619d269853a4214a4b4"}, + {file = "yarl-1.11.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2371510367d39d74997acfdcd1dead17938c79c99365482821627f7838a8eba0"}, + {file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e24bb6a8be89ccc3ce8c47e8940fdfcb7429e9efbf65ce6fa3e7d122fcf0bcf0"}, + {file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:18ec42da256cfcb9b4cd5d253e04c291f69911a5228d1438a7d431c15ba0ae40"}, + {file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:418eeb8f228ea36c368bf6782ebd6016ecebfb1a8b90145ef6726ffcbba65ef8"}, + {file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:07e8cfb1dd7669a129f8fd5df1da65efa73aea77582bde2a3a837412e2863543"}, + {file = "yarl-1.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c458483711d393dad51340505c3fab3194748fd06bab311d2f8b5b7a7349e9a"}, + {file = "yarl-1.11.0-cp312-cp312-win32.whl", hash = "sha256:5b008c3127382503e7a1e12b4c3a3236e3dd833a4c62a066f4a0fbd650c655d2"}, + {file = "yarl-1.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:bc94be7472b9f88d7441340534a3ecae05c86ccfec7ba75ce5b6e4778b2bfc6e"}, + {file = "yarl-1.11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a45e51ba3777031e0b20c1e7ab59114ed4e1884b3c1db48962c1d8d08aefb418"}, + {file = "yarl-1.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:765128029218eade3a01187cdd7f375977cc827505ed31828196c8ae9b622928"}, + {file = "yarl-1.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2516e238daf0339c8ac4dfab9d7cda9afad652ff073517f200d653d5d8371f7e"}, + {file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d10be62bee117f05b1ad75a6c2538ca9e5367342dc8a4f3c206c87dadbc1189c"}, + {file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50ceaeda771ee3e382291168c90c7ede62b63ecf3e181024bcfeb35c0ea6c84f"}, + {file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a601c99fc20fd0eea84e7bc0dc9e7f196f55a0ded67242d724988c754295538"}, + {file = "yarl-1.11.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42ff79371614764fc0a4ab8eaba9adb493bf9ad856e2a4664f6c754fc907a903"}, + {file = "yarl-1.11.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93fca4c9f88c17ead902b3f3285b2d039fc8f26d117e1441973ba64315109b54"}, + {file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e7dddf5f41395c84fc59e0ed5493b24bfeb39fb04823e880b52c8c55085d4695"}, + {file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ea501ea07e14ba6364ff2621bfc8b2381e5b1e10353927fa9a607057fd2b98e5"}, + {file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a4f7e470f2c9c8b8774a5bda72adfb8e9dc4ec32311fe9bdaa4921e36cf6659b"}, + {file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:361fdb3993431157302b7104d525092b5df4d7d346df5a5ffeee2d1ca8e0d15b"}, + {file = "yarl-1.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e300eaf5e0329ad31b3d53e2f3d26b4b6dff1217207c6ab1d4212967b54b2185"}, + {file = "yarl-1.11.0-cp313-cp313-win32.whl", hash = "sha256:f1e2d4ce72e06e38a16da3e9c24a0520dbc19018a69ef6ed57b6b38527cb275c"}, + {file = "yarl-1.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:fa9de2f87be58f714a230bd1f3ef3aad1ed65c9931146e3fc55f85fcbe6bacc3"}, + {file = "yarl-1.11.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:24da0b38274727fe9266d09229987e7f0efdb97beb94c0bb2d327d65f112e78d"}, + {file = "yarl-1.11.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0310eb2e63872de66047e05ad9982f2e53ad6405dc42fa60d7cc670bf6ca8aa8"}, + {file = "yarl-1.11.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:52433604340a4ab3d1f32281c6eb9ad9b47c99435b4212f763121bf7348c8c00"}, + {file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98e2eb182d59f0845a79434003f94b4f61cd69465248f9388c2e5bf2191c9f7f"}, + {file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3dd10f0fe0e0f659926c1da791de5bef05fd48974ad74618c9168e302e2b7cc"}, + {file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:121d3798e4bb35a4321b2422cb887f80ea39f94bf52f0eb5cb2c168bb0043c9b"}, + {file = "yarl-1.11.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8bbac56c80610dd659ace534765d7bcd2488f6600023f6984f35108b2b3f4f0"}, + {file = "yarl-1.11.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79d420399f0e82e302236a762d8b8ceec89761ce3b30c83ac1d4d6e29f811444"}, + {file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:03a726fb50588307dfe1d233b67535d493fb0bb157bdbfda6bb34e04189f2f57"}, + {file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9057f5de2fade7440e6db358913bc7ae8de43ba72c83cf95420a1fc1a6c6b59e"}, + {file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6471d747d0ac8059895e66d32ca8630c8db5b572ca7763150d0927eaa257df67"}, + {file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:d97cb22ad380850754fa16ef8d490d9340d8573d81f73429f3975e8e87db0586"}, + {file = "yarl-1.11.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:fe78dec8caeda1e7b353cbd8aa0cc5a5bc182b22998d64ec8fa9ee59c898ab3b"}, + {file = "yarl-1.11.0-cp38-cp38-win32.whl", hash = "sha256:7ff371002fbbb79613269d76a2932c99979dac15fac30107064ef70d25f35474"}, + {file = "yarl-1.11.0-cp38-cp38-win_amd64.whl", hash = "sha256:4fa9d762eee63eed767895d68b994c58e29f809292a4d0fca483e9cc6fdc22c8"}, + {file = "yarl-1.11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4ae63bc65e5bf8843bd1eca46e75eaa9eb157e0312fb362123181512892daad8"}, + {file = "yarl-1.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d1bd3262e00043907e0a6d7d4f7b7a4815281acc25699a2384552870c79f1f0"}, + {file = "yarl-1.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0c58656c2e0b41b5d325130b8da4f8e216aad10029e7de5c523a6be25faa9fe8"}, + {file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9425c333575fce5e0fb414b766492c6ba4aa335ef910a7540dbdefe58a78232e"}, + {file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9dc66e2420e1e282105071934883bbb9c37c16901b5b8aa0a8aee370b477eac6"}, + {file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2949067359d1ef5bf3228c7f1deb102c209832a13df5419239f99449bc1d3fa9"}, + {file = "yarl-1.11.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006fe73f851cf20b9986b3b4cc15239795bd5da9c3fda76bb3e043da5bec4ff"}, + {file = "yarl-1.11.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:969ad4ee3892e893471b6572bbf2bbb091f93e7c81de25d6b3a5c0a5126e5ccb"}, + {file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c9fbe9dc6ee8bfe1af34137e3add6f0e49799dd5467dd6af189d27616879161e"}, + {file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69a45c711fea9b783b592a75f26f6dc59b2e4a923b97bf6eec357566fcb1d922"}, + {file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:1a29b82c42a7791ffe53ee6dfbf29acc61ea7ec05643dcacc50510ed6187b897"}, + {file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ed0c090f00c3fc024f7b0799cab9dd7c419fcd8f1a00634d1f9952bab7e7bfb2"}, + {file = "yarl-1.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:31df9d9b3fe6e15decee629fc7976a5fb21eaa39e290f60e57e1d422827194c6"}, + {file = "yarl-1.11.0-cp39-cp39-win32.whl", hash = "sha256:fcb7c36ba8b663a5900e6d40533f0e698ba0f38f744aad5410d4e38129e41a70"}, + {file = "yarl-1.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:c6c0d640bad721834a737e25267fb71d296684ada21ca7d5ad2e63da7b73f1b7"}, + {file = "yarl-1.11.0-py3-none-any.whl", hash = "sha256:03717a6627e55934b2a1d9caf24f299b461a2e8d048a90920f42ad5c20ae1b82"}, + {file = "yarl-1.11.0.tar.gz", hash = "sha256:f86f4f4a57a29ef08fa70c4667d04c5e3ba513500da95586208b285437cb9592"}, ] [package.dependencies] @@ -2491,4 +2496,4 @@ syntax = ["tree-sitter", "tree-sitter-languages"] [metadata] lock-version = "2.0" python-versions = "^3.8.1" -content-hash = "a334bde26213e1cae0a4be69857cbbc17529058b67db2201d8bf1ca2e65dd855" +content-hash = "1271ee856073da0649fdb432170dc77787d906b0cb3dc5575d802ba604bbad2e" diff --git a/pyproject.toml b/pyproject.toml index 71a51de9c9..a13cdc868a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ rich = ">=13.3.3" typing-extensions = "^4.4.0" tree-sitter = { version = "^0.20.1", optional = true } tree-sitter-languages = { version = "1.10.2", optional = true } -platformdirs = "^4.2.2" +platformdirs = ">=3.6.0,<5" [tool.poetry.extras] syntax = ["tree-sitter", "tree_sitter_languages"] From 9747e300bac45552cf17bb614a7996f93608ab6c Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:21:04 +0100 Subject: [PATCH 76/80] update format_svg to set simplify to false --- src/textual/_doc.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textual/_doc.py b/src/textual/_doc.py index bc0c4e57a5..a5373f3467 100644 --- a/src/textual/_doc.py +++ b/src/textual/_doc.py @@ -42,6 +42,7 @@ def format_svg(source, language, css_class, options, md, attrs, **kwargs) -> str title=title, terminal_size=(columns, rows), wait_for_animation=False, + simplify=False, ) finally: os.chdir(cwd) From ebabca742e2898fd52640afd6a2bc368aee1a530 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:41:16 +0100 Subject: [PATCH 77/80] update docstrings with simplify arg --- src/textual/_doc.py | 1 + src/textual/app.py | 1 + 2 files changed, 2 insertions(+) diff --git a/src/textual/_doc.py b/src/textual/_doc.py index a5373f3467..c51772d160 100644 --- a/src/textual/_doc.py +++ b/src/textual/_doc.py @@ -81,6 +81,7 @@ def take_svg_screenshot( screenshot. Use this to simulate complex user interactions with the app that cannot be simulated by key presses. wait_for_animation: Wait for animation to complete before taking screenshot. + simplify: Simplify the segments by combining contiguous segments with the same style. Returns: An SVG string, showing the content of the terminal window at the time diff --git a/src/textual/app.py b/src/textual/app.py index 3dc241d415..f39170fcbc 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1392,6 +1392,7 @@ def export_screenshot( Args: title: The title of the exported screenshot or None to use app title. + simplify: Simplify the segments by combining contiguous segments with the same style. """ assert self._driver is not None, "App must be running" width, height = self.size From 1bc7fa60d3bf6d6e2c6e3f0fe1b967f5ffd39359 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Tue, 10 Sep 2024 08:43:24 +0100 Subject: [PATCH 78/80] fix docstring formatting --- src/textual/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textual/app.py b/src/textual/app.py index f39170fcbc..8a419f45bf 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -1392,7 +1392,7 @@ def export_screenshot( Args: title: The title of the exported screenshot or None to use app title. - simplify: Simplify the segments by combining contiguous segments with the same style. + simplify: Simplify the segments by combining contiguous segments with the same style. """ assert self._driver is not None, "App must be running" width, height = self.size From ce5e05e6e4323db3a46776c07e7244f0a2a7f539 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Tue, 10 Sep 2024 09:05:47 +0100 Subject: [PATCH 79/80] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a34988faa..d4be0225d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Input validation of floats no longer accepts NaN (not a number). https://github.com/Textualize/textual/pull/4784 +- Fixed issues with screenshots by simplifying segments only for snapshot tests https://github.com/Textualize/textual/issues/4929 ## [0.79.1] - 2024-08-31 From e54db0e16b5a5349851c9501e91c9089a4fed469 Mon Sep 17 00:00:00 2001 From: TomJGooding <101601846+TomJGooding@users.noreply.github.com> Date: Wed, 11 Sep 2024 12:58:58 +0100 Subject: [PATCH 80/80] docs(testing): clarify testing frameworks section (#4898) * docs(testing): clarify testing frameworks section * explain the auto asyncio mode --- docs/guide/testing.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/guide/testing.md b/docs/guide/testing.md index f22645b604..32a4d33dc7 100644 --- a/docs/guide/testing.md +++ b/docs/guide/testing.md @@ -23,9 +23,16 @@ Your test code will help you find bugs early, and alert you if you accidentally ## Testing frameworks for Textual -Textual doesn't require any particular test framework. -You can use any test framework you are familiar with, but we will be using [pytest](https://docs.pytest.org/) in this chapter. +Textual is an async framework powered by Python's [asyncio](https://docs.python.org/3/library/asyncio.html) library. +While Textual doesn't require a particular test framework, it must provide support for asyncio testing. +You can use any test framework you are familiar with, but we will be using [pytest](https://docs.pytest.org/) +along with the [pytest-asyncio](https://pytest-asyncio.readthedocs.io/) plugin in this chapter. + +By default, the `pytest-asyncio` plugin requires each async test to be decorated with `@pytest.mark.asyncio`. +You can avoid having to add this marker to every async test +by setting `asyncio_mode = auto` in your pytest configuration +or by running pytest with the `--asyncio-mode=auto` option. ## Testing apps