updated Panel implementation
This commit is contained in:
@@ -737,43 +737,63 @@ codebase.
|
|||||||
|
|
||||||
```
|
```
|
||||||
Div(id="{id}", cls="mf-panel")
|
Div(id="{id}", cls="mf-panel")
|
||||||
├── Div(id="{id}_panel_left", cls="mf-panel-left [mf-hidden]")
|
├── Div(id="{id}_pl", cls="mf-panel-left [mf-hidden]")
|
||||||
│ ├── Div(id="{id}_content_left")
|
│ ├── Div (hide icon)
|
||||||
│ │ ├── Div (hide icon)
|
│ ├── Div(id="{id}_cl")
|
||||||
│ │ └── [Left content]
|
│ │ └── [Left content]
|
||||||
│ └── Div (resizer-left)
|
│ └── Div (resizer-left)
|
||||||
├── Div(cls="mf-panel-main")
|
├── Div(cls="mf-panel-main")
|
||||||
│ ├── Div(id="{id}_show_left", cls="hidden|mf-panel-show-icon-left")
|
│ ├── Div(id="{id}_show_left", cls="hidden|mf-panel-show-icon-left")
|
||||||
│ ├── [Main content]
|
│ ├── Div(id="{id}_m", cls="mf-panel-main")
|
||||||
|
│ │ └── [Main content]
|
||||||
│ └── Div(id="{id}_show_right", cls="hidden|mf-panel-show-icon-right")
|
│ └── Div(id="{id}_show_right", cls="hidden|mf-panel-show-icon-right")
|
||||||
├── Div(id="{id}_panel_right", cls="mf-panel-right [mf-hidden]")
|
├── Div(id="{id}_pr", cls="mf-panel-right [mf-hidden]")
|
||||||
│ ├── Div (resizer-right)
|
│ ├── Div (resizer-right)
|
||||||
│ └── Div(id="{id}_content_right")
|
│ ├── Div (hide icon)
|
||||||
│ ├── Div (hide icon)
|
│ └── Div(id="{id}_cr")
|
||||||
│ └── [Right content]
|
│ └── [Right content]
|
||||||
└── Script # initResizer('{id}')
|
└── Script # initResizer('{id}')
|
||||||
```
|
```
|
||||||
|
|
||||||
**Note:**
|
**Note:**
|
||||||
|
|
||||||
- Left panel: content then resizer (resizer on right edge)
|
- Left panel: hide icon, then content, then resizer (resizer on right edge)
|
||||||
- Right panel: resizer then content (resizer on left edge)
|
- Right panel: resizer, then hide icon, then content (resizer on left edge)
|
||||||
|
- Hide icons are positioned at panel root level (not inside content div)
|
||||||
|
- Main content has an outer wrapper and inner content div with ID
|
||||||
- `[mf-hidden]` class is conditionally applied when panel is hidden
|
- `[mf-hidden]` class is conditionally applied when panel is hidden
|
||||||
|
|
||||||
### Element IDs
|
### Element IDs
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|----------------------|-------------------------------------|
|
|------------------|-------------------------------------|
|
||||||
| `{id}` | Root panel container |
|
| `{id}` | Root panel container |
|
||||||
| `{id}_panel_left` | Left panel container |
|
| `{id}_pl` | Left panel container |
|
||||||
| `{id}_panel_right` | Right panel container |
|
| `{id}_pr` | Right panel container |
|
||||||
| `{id}_content_left` | Left panel content wrapper |
|
| `{id}_cl` | Left panel content wrapper |
|
||||||
| `{id}_content_right` | Right panel content wrapper |
|
| `{id}_cr` | Right panel content wrapper |
|
||||||
| `{id}_show_left` | Show icon for left panel (in main) |
|
| `{id}_m` | Main content wrapper |
|
||||||
| `{id}_show_right` | Show icon for right panel (in main) |
|
| `{id}_show_left` | Show icon for left panel (in main) |
|
||||||
|
| `{id}_show_right`| Show icon for right panel (in main) |
|
||||||
|
|
||||||
**Note:** `{id}` is the Panel instance ID (auto-generated UUID or custom `_id`).
|
**Note:** `{id}` is the Panel instance ID (auto-generated UUID or custom `_id`).
|
||||||
|
|
||||||
|
**ID Management:**
|
||||||
|
|
||||||
|
The Panel component uses the `PanelIds` helper class to manage element IDs consistently. Access IDs programmatically:
|
||||||
|
|
||||||
|
```python
|
||||||
|
panel = Panel(parent=root_instance)
|
||||||
|
|
||||||
|
# Access IDs via get_ids()
|
||||||
|
panel.get_ids().panel("left") # Returns "{id}_pl"
|
||||||
|
panel.get_ids().panel("right") # Returns "{id}_pr"
|
||||||
|
panel.get_ids().left # Returns "{id}_cl"
|
||||||
|
panel.get_ids().right # Returns "{id}_cr"
|
||||||
|
panel.get_ids().main # Returns "{id}_m"
|
||||||
|
panel.get_ids().content("left") # Returns "{id}_cl"
|
||||||
|
```
|
||||||
|
|
||||||
### Internal Methods
|
### Internal Methods
|
||||||
|
|
||||||
These methods are used internally for rendering:
|
These methods are used internally for rendering:
|
||||||
|
|||||||
@@ -439,7 +439,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: var(--color-base-100);
|
background-color: var(--color-base-100);
|
||||||
padding: 1rem;
|
padding: 0.5rem;
|
||||||
border-top: 1px solid var(--color-border-primary);
|
border-top: 1px solid var(--color-border-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,6 +673,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
transition: width 0.3s ease, min-width 0.3s ease, max-width 0.3s ease;
|
transition: width 0.3s ease, min-width 0.3s ease, max-width 0.3s ease;
|
||||||
|
padding-top: 25px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Left panel specific */
|
/* Left panel specific */
|
||||||
@@ -683,6 +684,7 @@
|
|||||||
/* Right panel specific */
|
/* Right panel specific */
|
||||||
.mf-panel-right {
|
.mf-panel-right {
|
||||||
border-left: 1px solid var(--color-border-primary);
|
border-left: 1px solid var(--color-border-primary);
|
||||||
|
padding-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mf-panel-main {
|
.mf-panel-main {
|
||||||
@@ -700,6 +702,7 @@
|
|||||||
max-width: 0;
|
max-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border: none;
|
border: none;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No transition during manual resize - common for both panels */
|
/* No transition during manual resize - common for both panels */
|
||||||
@@ -712,10 +715,10 @@
|
|||||||
.mf-panel-hide-icon,
|
.mf-panel-hide-icon,
|
||||||
.mf-panel-show-icon {
|
.mf-panel-show-icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5rem;
|
top: 0;
|
||||||
|
right: 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
padding: 0.25rem;
|
|
||||||
border-radius: 0.25rem;
|
border-radius: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -724,11 +727,6 @@
|
|||||||
background-color: var(--color-bg-hover, rgba(0, 0, 0, 0.05));
|
background-color: var(--color-bg-hover, rgba(0, 0, 0, 0.05));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hide icon always on the right */
|
|
||||||
.mf-panel-hide-icon {
|
|
||||||
right: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Show icon positioning */
|
/* Show icon positioning */
|
||||||
.mf-panel-show-icon-left {
|
.mf-panel-show-icon-left {
|
||||||
left: 0.5rem;
|
left: 0.5rem;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ class InstancesDebugger(SingleInstance):
|
|||||||
self._command = Command("ShowInstance",
|
self._command = Command("ShowInstance",
|
||||||
"Display selected Instance",
|
"Display selected Instance",
|
||||||
self,
|
self,
|
||||||
self.on_network_event).htmx(target=f"#{self._panel.get_id()}_r")
|
self.on_network_event).htmx(target=f"#{self._panel.get_ids().right}")
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
nodes, edges = self._get_nodes_and_edges()
|
nodes, edges = self._get_nodes_and_edges()
|
||||||
|
|||||||
@@ -13,6 +13,31 @@ from myfasthtml.icons.fluent_p1 import more_horizontal20_regular
|
|||||||
from myfasthtml.icons.fluent_p2 import subtract20_regular
|
from myfasthtml.icons.fluent_p2 import subtract20_regular
|
||||||
|
|
||||||
|
|
||||||
|
class PanelIds:
|
||||||
|
def __init__(self, owner):
|
||||||
|
self._owner = owner
|
||||||
|
|
||||||
|
@property
|
||||||
|
def main(self):
|
||||||
|
return f"{self._owner.get_id()}_m"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def right(self):
|
||||||
|
""" Right panel's content"""
|
||||||
|
return f"{self._owner.get_id()}_cr"
|
||||||
|
|
||||||
|
@property
|
||||||
|
def left(self):
|
||||||
|
""" Left panel's content"""
|
||||||
|
return f"{self._owner.get_id()}_cl"
|
||||||
|
|
||||||
|
def panel(self, side: Literal["left", "right"]):
|
||||||
|
return f"{self._owner.get_id()}_pl" if side == "left" else f"{self._owner.get_id()}_pr"
|
||||||
|
|
||||||
|
def content(self, side: Literal["left", "right"]):
|
||||||
|
return self.left if side == "left" else self.right
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PanelConf:
|
class PanelConf:
|
||||||
left: bool = True
|
left: bool = True
|
||||||
@@ -35,7 +60,7 @@ class Commands(BaseCommands):
|
|||||||
f"Toggle {side} side panel",
|
f"Toggle {side} side panel",
|
||||||
self._owner,
|
self._owner,
|
||||||
self._owner.toggle_side,
|
self._owner.toggle_side,
|
||||||
args=[side, visible]).htmx(target=f"#{self._id}_panel_{side}")
|
args=[side, visible]).htmx(target=f"#{self._owner.get_ids().panel(side)}")
|
||||||
|
|
||||||
def update_side_width(self, side: Literal["left", "right"]):
|
def update_side_width(self, side: Literal["left", "right"]):
|
||||||
"""
|
"""
|
||||||
@@ -51,7 +76,7 @@ class Commands(BaseCommands):
|
|||||||
f"Update {side} side panel width",
|
f"Update {side} side panel width",
|
||||||
self._owner,
|
self._owner,
|
||||||
self._owner.update_side_width,
|
self._owner.update_side_width,
|
||||||
args=[side]).htmx(target=f"#{self._id}_panel_{side}")
|
args=[side]).htmx(target=f"#{self._owner.get_ids().panel(side)}")
|
||||||
|
|
||||||
|
|
||||||
class Panel(MultipleInstance):
|
class Panel(MultipleInstance):
|
||||||
@@ -72,6 +97,10 @@ class Panel(MultipleInstance):
|
|||||||
self._main = None
|
self._main = None
|
||||||
self._right = None
|
self._right = None
|
||||||
self._left = None
|
self._left = None
|
||||||
|
self._ids = PanelIds(self)
|
||||||
|
|
||||||
|
def get_ids(self):
|
||||||
|
return self._ids
|
||||||
|
|
||||||
def update_side_width(self, side, width):
|
def update_side_width(self, side, width):
|
||||||
if side == "left":
|
if side == "left":
|
||||||
@@ -95,11 +124,11 @@ class Panel(MultipleInstance):
|
|||||||
|
|
||||||
def set_right(self, right):
|
def set_right(self, right):
|
||||||
self._right = right
|
self._right = right
|
||||||
return Div(self._right, id=f"{self._id}_r")
|
return Div(self._right, id=self._ids.right)
|
||||||
|
|
||||||
def set_left(self, left):
|
def set_left(self, left):
|
||||||
self._left = left
|
self._left = left
|
||||||
return Div(self._left, id=f"{self._id}_l")
|
return Div(self._left, id=self._ids.left)
|
||||||
|
|
||||||
def _mk_panel(self, side: Literal["left", "right"]):
|
def _mk_panel(self, side: Literal["left", "right"]):
|
||||||
enabled = self.conf.left if side == "left" else self.conf.right
|
enabled = self.conf.left if side == "left" else self.conf.right
|
||||||
@@ -130,19 +159,29 @@ class Panel(MultipleInstance):
|
|||||||
# Right panel: resizer then content (resizer on the left)
|
# Right panel: resizer then content (resizer on the left)
|
||||||
if side == "left":
|
if side == "left":
|
||||||
return Div(
|
return Div(
|
||||||
Div(hide_icon, content, id=f"{self._id}_content_{side}"),
|
hide_icon,
|
||||||
|
Div(content, id=self._ids.content(side)),
|
||||||
resizer,
|
resizer,
|
||||||
cls=panel_cls,
|
cls=panel_cls,
|
||||||
id=f"{self._id}_panel_{side}"
|
id=self._ids.panel(side)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return Div(
|
return Div(
|
||||||
resizer,
|
resizer,
|
||||||
Div(hide_icon, content, id=f"{self._id}_content_{side}"),
|
hide_icon,
|
||||||
|
Div(content, id=self._ids.content(side)),
|
||||||
cls=panel_cls,
|
cls=panel_cls,
|
||||||
id=f"{self._id}_panel_{side}"
|
id=self._ids.panel(side)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def _mk_main(self):
|
||||||
|
return Div(
|
||||||
|
self._mk_show_icon("left"),
|
||||||
|
Div(self._main, id=self._ids.main, cls="mf-panel-main"),
|
||||||
|
self._mk_show_icon("right"),
|
||||||
|
cls="mf-panel-main"
|
||||||
|
),
|
||||||
|
|
||||||
def _mk_show_icon(self, side: Literal["left", "right"]):
|
def _mk_show_icon(self, side: Literal["left", "right"]):
|
||||||
"""
|
"""
|
||||||
Create show icon for a panel side if it's hidden.
|
Create show icon for a panel side if it's hidden.
|
||||||
@@ -170,12 +209,7 @@ class Panel(MultipleInstance):
|
|||||||
def render(self):
|
def render(self):
|
||||||
return Div(
|
return Div(
|
||||||
self._mk_panel("left"),
|
self._mk_panel("left"),
|
||||||
Div(
|
self._mk_main(),
|
||||||
self._mk_show_icon("left"),
|
|
||||||
self._main,
|
|
||||||
self._mk_show_icon("right"),
|
|
||||||
cls="mf-panel-main"
|
|
||||||
),
|
|
||||||
self._mk_panel("right"),
|
self._mk_panel("right"),
|
||||||
Script(f"initResizer('{self._id}');"),
|
Script(f"initResizer('{self._id}');"),
|
||||||
cls="mf-panel",
|
cls="mf-panel",
|
||||||
|
|||||||
@@ -233,13 +233,14 @@ class TestPanelRender:
|
|||||||
- id: Required for HTMX targeting during toggle/resize operations
|
- id: Required for HTMX targeting during toggle/resize operations
|
||||||
- cls Contains "mf-panel-left": CSS class for left panel styling
|
- cls Contains "mf-panel-left": CSS class for left panel styling
|
||||||
"""
|
"""
|
||||||
left_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_left"))
|
left_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("left")))
|
||||||
|
|
||||||
# Step 1: Validate left panel global structure
|
# Step 1: Validate left panel global structure
|
||||||
expected = Div(
|
expected = Div(
|
||||||
Div(id=f"{panel._id}_content_left"), # content div, tested in detail later
|
TestIcon("subtract20_regular"),
|
||||||
|
Div(id=panel.get_ids().left), # content div, tested in detail later
|
||||||
Div(cls=Contains("mf-resizer-left")), # resizer
|
Div(cls=Contains("mf-resizer-left")), # resizer
|
||||||
id=f"{panel._id}_panel_left",
|
id=panel.get_ids().panel("left"),
|
||||||
cls=Contains("mf-panel-left")
|
cls=Contains("mf-panel-left")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -252,7 +253,7 @@ class TestPanelRender:
|
|||||||
- cls Contains "mf-hidden": CSS class required for width animation
|
- cls Contains "mf-hidden": CSS class required for width animation
|
||||||
"""
|
"""
|
||||||
panel._state.left_visible = False
|
panel._state.left_visible = False
|
||||||
left_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_left"))
|
left_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("left")))
|
||||||
|
|
||||||
expected = Div(cls=Contains("mf-hidden"))
|
expected = Div(cls=Contains("mf-hidden"))
|
||||||
|
|
||||||
@@ -268,7 +269,7 @@ class TestPanelRender:
|
|||||||
rendered = panel.render()
|
rendered = panel.render()
|
||||||
|
|
||||||
# Verify left panel is not present
|
# Verify left panel is not present
|
||||||
left_panels = find(rendered, Div(id=f"{panel._id}_panel_left"))
|
left_panels = find(rendered, Div(id=panel.get_ids().panel("left")))
|
||||||
assert len(left_panels) == 0, "Left panel should not be present when conf.left=False"
|
assert len(left_panels) == 0, "Left panel should not be present when conf.left=False"
|
||||||
|
|
||||||
# 3. Right panel
|
# 3. Right panel
|
||||||
@@ -277,17 +278,18 @@ class TestPanelRender:
|
|||||||
"""Test that right panel has resizer before content div.
|
"""Test that right panel has resizer before content div.
|
||||||
|
|
||||||
Why these elements matter:
|
Why these elements matter:
|
||||||
- Order (resizer then content): Critical for positioning resizer on the left side
|
- Order (resizer then hide icon then content): Critical for positioning resizer on the left side
|
||||||
- id: Required for HTMX targeting during toggle/resize operations
|
- id: Required for HTMX targeting during toggle/resize operations
|
||||||
- cls Contains "mf-panel-right": CSS class for right panel styling
|
- cls Contains "mf-panel-right": CSS class for right panel styling
|
||||||
"""
|
"""
|
||||||
right_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_right"))
|
right_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("right")))
|
||||||
|
|
||||||
# Step 1: Validate right panel global structure
|
# Step 1: Validate right panel global structure
|
||||||
expected = Div(
|
expected = Div(
|
||||||
Div(cls=Contains("mf-resizer-right")), # resizer
|
Div(cls=Contains("mf-resizer-right")), # resizer
|
||||||
Div(id=f"{panel._id}_content_right"), # content div, tested in detail later
|
TestIcon("subtract20_regular"), # hide icon
|
||||||
id=f"{panel._id}_panel_right",
|
Div(id=panel.get_ids().right), # content div, tested in detail later
|
||||||
|
id=panel.get_ids().panel("right"),
|
||||||
cls=Contains("mf-panel-right")
|
cls=Contains("mf-panel-right")
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -300,7 +302,7 @@ class TestPanelRender:
|
|||||||
- cls Contains "mf-hidden": CSS class required for width animation
|
- cls Contains "mf-hidden": CSS class required for width animation
|
||||||
"""
|
"""
|
||||||
panel._state.right_visible = False
|
panel._state.right_visible = False
|
||||||
right_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_right"))
|
right_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("right")))
|
||||||
|
|
||||||
expected = Div(cls=Contains("mf-hidden"))
|
expected = Div(cls=Contains("mf-hidden"))
|
||||||
|
|
||||||
@@ -316,7 +318,7 @@ class TestPanelRender:
|
|||||||
rendered = panel.render()
|
rendered = panel.render()
|
||||||
|
|
||||||
# Verify right panel is not present
|
# Verify right panel is not present
|
||||||
right_panels = find(rendered, Div(id=f"{panel._id}_panel_right"))
|
right_panels = find(rendered, Div(id=panel.get_ids().panel("right")))
|
||||||
assert len(right_panels) == 0, "Right panel should not be present when conf.right=False"
|
assert len(right_panels) == 0, "Right panel should not be present when conf.right=False"
|
||||||
|
|
||||||
# 4. Resizers
|
# 4. Resizers
|
||||||
@@ -330,7 +332,7 @@ class TestPanelRender:
|
|||||||
- cls Contains "mf-resizer": Base CSS class for resizer styling
|
- cls Contains "mf-resizer": Base CSS class for resizer styling
|
||||||
- cls Contains "mf-resizer-left": Left-specific CSS class for positioning
|
- cls Contains "mf-resizer-left": Left-specific CSS class for positioning
|
||||||
"""
|
"""
|
||||||
left_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_left"))
|
left_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("left")))
|
||||||
resizer = find_one(left_panel, Div(cls=Contains("mf-resizer-left")))
|
resizer = find_one(left_panel, Div(cls=Contains("mf-resizer-left")))
|
||||||
|
|
||||||
expected = Div(
|
expected = Div(
|
||||||
@@ -351,7 +353,7 @@ class TestPanelRender:
|
|||||||
- cls Contains "mf-resizer": Base CSS class for resizer styling
|
- cls Contains "mf-resizer": Base CSS class for resizer styling
|
||||||
- cls Contains "mf-resizer-right": Right-specific CSS class for positioning
|
- cls Contains "mf-resizer-right": Right-specific CSS class for positioning
|
||||||
"""
|
"""
|
||||||
right_panel = find_one(panel.render(), Div(id=f"{panel._id}_panel_right"))
|
right_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("right")))
|
||||||
resizer = find_one(right_panel, Div(cls=Contains("mf-resizer-right")))
|
resizer = find_one(right_panel, Div(cls=Contains("mf-resizer-right")))
|
||||||
|
|
||||||
expected = Div(
|
expected = Div(
|
||||||
@@ -372,10 +374,10 @@ class TestPanelRender:
|
|||||||
- TestIconNotStr("subtract20_regular"): Verify correct icon is used for hiding
|
- TestIconNotStr("subtract20_regular"): Verify correct icon is used for hiding
|
||||||
- cls Contains "mf-panel-hide-icon": CSS class for hide icon positioning
|
- cls Contains "mf-panel-hide-icon": CSS class for hide icon positioning
|
||||||
"""
|
"""
|
||||||
left_content = find_one(panel.render(), Div(id=f"{panel._id}_content_left"))
|
left_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("left")))
|
||||||
|
|
||||||
# Find the hide icon (should be wrapped by mk.icon)
|
# Find the hide icon (should be wrapped by mk.icon)
|
||||||
hide_icons = find(left_content, Div(cls=Contains("mf-panel-hide-icon")))
|
hide_icons = find(left_panel, Div(cls=Contains("mf-panel-hide-icon")))
|
||||||
assert len(hide_icons) == 1, "Left panel should contain exactly one hide icon"
|
assert len(hide_icons) == 1, "Left panel should contain exactly one hide icon"
|
||||||
|
|
||||||
# Verify it contains the subtract icon
|
# Verify it contains the subtract icon
|
||||||
@@ -392,10 +394,10 @@ class TestPanelRender:
|
|||||||
- TestIconNotStr("subtract20_regular"): Verify correct icon is used for hiding
|
- TestIconNotStr("subtract20_regular"): Verify correct icon is used for hiding
|
||||||
- cls Contains "mf-panel-hide-icon": CSS class for hide icon positioning
|
- cls Contains "mf-panel-hide-icon": CSS class for hide icon positioning
|
||||||
"""
|
"""
|
||||||
right_content = find_one(panel.render(), Div(id=f"{panel._id}_content_right"))
|
right_panel = find_one(panel.render(), Div(id=panel.get_ids().panel("right")))
|
||||||
|
|
||||||
# Find the hide icon (should be wrapped by mk.icon)
|
# Find the hide icon (should be wrapped by mk.icon)
|
||||||
hide_icons = find(right_content, Div(cls=Contains("mf-panel-hide-icon")))
|
hide_icons = find(right_panel, Div(cls=Contains("mf-panel-hide-icon")))
|
||||||
assert len(hide_icons) == 1, "Right panel should contain exactly one hide icon"
|
assert len(hide_icons) == 1, "Right panel should contain exactly one hide icon"
|
||||||
|
|
||||||
# Verify it contains the subtract icon
|
# Verify it contains the subtract icon
|
||||||
@@ -412,8 +414,7 @@ class TestPanelRender:
|
|||||||
- cls Contains "hidden": Tailwind class to hide icon when panel is visible
|
- cls Contains "hidden": Tailwind class to hide icon when panel is visible
|
||||||
- id: Required for HTMX swap-oob targeting
|
- id: Required for HTMX swap-oob targeting
|
||||||
"""
|
"""
|
||||||
main_panel = find_one(panel.render(), Div(cls=Contains("mf-panel-main")))
|
show_icon = find_one(panel.render(), Div(id=f"{panel._id}_show_left"))
|
||||||
show_icon = find_one(main_panel, Div(id=f"{panel._id}_show_left"))
|
|
||||||
|
|
||||||
expected = Div(
|
expected = Div(
|
||||||
cls=Contains("hidden"),
|
cls=Contains("hidden"),
|
||||||
@@ -430,8 +431,7 @@ class TestPanelRender:
|
|||||||
- TestIconNotStr("more_horizontal20_regular"): Verify correct icon is used for showing
|
- TestIconNotStr("more_horizontal20_regular"): Verify correct icon is used for showing
|
||||||
"""
|
"""
|
||||||
panel._state.left_visible = False
|
panel._state.left_visible = False
|
||||||
main_panel = find_one(panel.render(), Div(cls=Contains("mf-panel-main")))
|
show_icon = find_one(panel.render(), Div(id=f"{panel._id}_show_left"))
|
||||||
show_icon = find_one(main_panel, Div(id=f"{panel._id}_show_left"))
|
|
||||||
|
|
||||||
expected = Div(
|
expected = Div(
|
||||||
TestIconNotStr("more_horizontal20_regular"),
|
TestIconNotStr("more_horizontal20_regular"),
|
||||||
@@ -449,8 +449,7 @@ class TestPanelRender:
|
|||||||
- TestIconNotStr("more_horizontal20_regular"): Verify correct icon is used for showing
|
- TestIconNotStr("more_horizontal20_regular"): Verify correct icon is used for showing
|
||||||
"""
|
"""
|
||||||
panel._state.right_visible = False
|
panel._state.right_visible = False
|
||||||
main_panel = find_one(panel.render(), Div(cls=Contains("mf-panel-main")))
|
show_icon = find_one(panel.render(), Div(id=f"{panel._id}_show_right"))
|
||||||
show_icon = find_one(main_panel, Div(id=f"{panel._id}_show_right"))
|
|
||||||
|
|
||||||
expected = Div(
|
expected = Div(
|
||||||
TestIconNotStr("more_horizontal20_regular"),
|
TestIconNotStr("more_horizontal20_regular"),
|
||||||
@@ -466,16 +465,22 @@ class TestPanelRender:
|
|||||||
"""Test that main panel contains show icons and content in correct order.
|
"""Test that main panel contains show icons and content in correct order.
|
||||||
|
|
||||||
Why these elements matter:
|
Why these elements matter:
|
||||||
- 3 children: show_icon_left + content + show_icon_right
|
- 3 children: show_icon_left + inner main div + show_icon_right
|
||||||
- Order: Show icons must be positioned correctly (left then right)
|
- Order: Show icons must be positioned correctly (left then right)
|
||||||
- cls="mf-panel-main": CSS class for main panel styling
|
- cls="mf-panel-main": CSS class for main panel styling
|
||||||
|
- Inner div with id: Main content wrapper for HTMX targeting
|
||||||
"""
|
"""
|
||||||
main_panel = find_one(panel.render(), Div(cls=Contains("mf-panel-main")))
|
# Find all Divs with cls="mf-panel-main" (there are 2: outer wrapper and inner content)
|
||||||
|
main_panels = find(panel.render(), Div(cls=Contains("mf-panel-main")))
|
||||||
|
assert len(main_panels) == 2, "Should find outer wrapper and inner content div"
|
||||||
|
|
||||||
|
# The outer wrapper is the first one (depth-first search)
|
||||||
|
main_panel = main_panels[0]
|
||||||
|
|
||||||
# Step 1: Validate main panel structure
|
# Step 1: Validate main panel structure
|
||||||
expected = Div(
|
expected = Div(
|
||||||
Div(id=f"{panel._id}_show_left"), # show icon left
|
Div(id=f"{panel._id}_show_left"), # show icon left
|
||||||
Div("Main content"), # actual content
|
Div(id=panel.get_ids().main), # inner main content wrapper
|
||||||
Div(id=f"{panel._id}_show_right"), # show icon right
|
Div(id=f"{panel._id}_show_right"), # show icon right
|
||||||
cls="mf-panel-main"
|
cls="mf-panel-main"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user