43 lines
1.3 KiB
Python
43 lines
1.3 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from typing import Callable
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class HeaderButton:
|
|
"""A prominent header link pointing to a local page or an external URL."""
|
|
|
|
label: str
|
|
page: str | int | float | Callable[..., object] | None = None
|
|
href: str | None = None
|
|
section: str | int | float | None = None
|
|
new_tab: bool = False
|
|
|
|
def __post_init__(self) -> None:
|
|
label = str(self.label).strip()
|
|
if not label:
|
|
raise ValueError("Header button label cannot be empty")
|
|
object.__setattr__(self, "label", label)
|
|
if (self.page is None) == (self.href is None):
|
|
raise ValueError("HeaderButton requires exactly one of page= or href=")
|
|
if self.href is not None and not str(self.href).strip():
|
|
raise ValueError("Header button href cannot be empty")
|
|
|
|
@classmethod
|
|
def local(
|
|
cls,
|
|
label: str,
|
|
page: str | int | float | Callable[..., object],
|
|
*,
|
|
section: str | int | float | None = None,
|
|
) -> HeaderButton:
|
|
return cls(label=label, page=page, section=section)
|
|
|
|
@classmethod
|
|
def external(cls, label: str, href: str, *, new_tab: bool = True) -> HeaderButton:
|
|
return cls(label=label, href=href, new_tab=new_tab)
|
|
|
|
|
|
__all__ = ["HeaderButton"]
|
|
|