Repository: Textualize/textual

Issue:
Setting `show_root` to `True` raises a `KeyError`
```py
    def compose(self):
        dir_tree = DirectoryTree("./src/routes")
        dir_tree.show_root = True
        yield Header()
        with Horizontal():
            yield Logo()
            with TabbedContent("Config", "Routes", "Server"):
                yield Config(self.config)
                yield dir_tree
                yield Label("hello")
        yield Footer()
```
setting `show_root` to `True`. raises the following error:
`KeyError: "No 'directory-tree--folder' key in COMPONENT_CLASSES"`


Diagnose output:

# Textual Diagnostics

## Versions

| Name    | Value  |
|---------|--------|
| Textual | 0.20.1 |
| Rich    | 13.3.3 |

## Python

| Name           | Value                                                                                                    |
|----------------|----------------------------------------------------------------------------------------------------------|
| Version        | 3.11.0                                                                                                   |
| Implementation | CPython                                                                                                  |
| Compiler       | Clang 14.0.0 (clang-1400.0.29.202)                                                                       |
| Executable     | /Users/felixingram/Library/Application Support/hatch/env/virtual/sanic-kit/1YPPa8fF/sanic-kit/bin/python |

## Operating System

| Name    | Value                                                                                                 |
|---------|-------------------------------------------------------------------------------------------------------|
| System  | Darwin                                                                                                |
| Release | 22.4.0                                                                                                |
| Version | Darwin Kernel Version 22.4.0: Mon Mar  6 21:00:41 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T8103 |

## Terminal

| Name                 | Value                              |
|----------------------|------------------------------------|
| Terminal Application | WezTerm (20230326-111934-3666303c) |
| TERM                 | xterm-256color                     |
| COLORTERM            | truecolor                          |
| FORCE_COLOR          | *Not set*                          |
| NO_COLOR             | *Not set*                          |

## Rich Console options

| Name           | Value                |
|----------------|----------------------|
| size           | width=203, height=46 |
| legacy_windows | False                |
| min_width      | 1                    |
| max_width      | 203                  |
| is_terminal    | False                |
| encoding       | utf-8                |
| max_height     | 46                   |
| justify        | None                 |
| overflow       | None                 |
| no_wrap        | False                |
| highlight      | None                 |
| markup         | None                 |
| height         | None                 |



Discussion:
To narrow it down a wee but, this only happens if `show_root` is changed before the DOM is fully-loaded (for example, doing the same in `on_mount` is fine). Looks like `watch_show_root` is a bit too eager.

Resolving patch:
diff --git a/src/textual/widgets/_directory_tree.py b/src/textual/widgets/_directory_tree.py
--- a/src/textual/widgets/_directory_tree.py
+++ b/src/textual/widgets/_directory_tree.py
@@ -295,6 +295,11 @@ def render_label(
         node_label = node._label.copy()
         node_label.stylize(style)
 
+        # If the tree isn't mounted yet we can't use component classes to stylize
+        # the label fully, so we return early.
+        if not self.is_mounted:
+            return node_label
+
         if node._allow_expand:
             prefix = ("📂 " if node.is_expanded else "📁 ", base_style + TOGGLE_STYLE)
             node_label.stylize_before(


Test patch:
diff --git a/tests/directory_tree/test_early_show_root.py b/tests/directory_tree/test_early_show_root.py
new file mode 100644
--- /dev/null
+++ b/tests/directory_tree/test_early_show_root.py
@@ -0,0 +1,16 @@
+from textual.app import App, ComposeResult
+from textual.widgets import DirectoryTree
+
+
+class DirectoryTreeApp(App[None]):
+    def compose(self) -> ComposeResult:
+        tree = DirectoryTree(".")
+        tree.show_root = True
+        yield tree
+
+
+async def test_managed_to_set_show_root_before_mounted() -> None:
+    """https://github.com/Textualize/textual/issues/2363"""
+    async with DirectoryTreeApp().run_test() as pilot:
+        assert isinstance(pilot.app.query_one(DirectoryTree), DirectoryTree)
+        assert pilot.app.query_one(DirectoryTree).show_root is True