reflex/reflex/components/core/breakpoints.py
Masen Furer 2883e541a9
Bring back py3.9 support with a deprecation warning. (#3976)
* Revert "ruff formatting to unbreak `main` CI (#3964)"

This reverts commit f9be184b86.

* Revert "bump python>=3.10 for 0.6.0 (#3956)"

This reverts commit fe1833c5e1.

* drop python3.8 support

* relock dependencies

* Raise warning when < py310 is used

* Move python version check to reflex version check function

Avoid spammy deprecation warnings by only emitting warning once per project,
per reflex version, per reinit.

* Remove other references to python3.8
2024-09-23 18:15:16 -07:00

96 lines
2.6 KiB
Python

"""Breakpoints utility."""
from __future__ import annotations
from typing import Dict, Tuple, TypeVar, Union
breakpoints_values = ["30em", "48em", "62em", "80em", "96em"]
breakpoint_names = ["xs", "sm", "md", "lg", "xl"]
def set_breakpoints(values: Tuple[str, str, str, str, str]):
"""Overwrite default breakpoint values.
Args:
values: CSS values in order defining the breakpoints of responsive layouts
"""
breakpoints_values.clear()
breakpoints_values.extend(values)
K = TypeVar("K")
V = TypeVar("V")
class Breakpoints(Dict[K, V]):
"""A responsive styling helper."""
def factorize(self):
"""Removes references to breakpoints names and instead replaces them with their corresponding values.
Returns:
The factorized breakpoints.
"""
return Breakpoints(
{
(
breakpoints_values[breakpoint_names.index(k)]
if k in breakpoint_names
else ("0px" if k == "initial" else k)
): v
for k, v in self.items()
if v is not None
}
)
@classmethod
def create(
cls,
custom: Dict[K, V] | None = None,
initial: V | None = None,
xs: V | None = None,
sm: V | None = None,
md: V | None = None,
lg: V | None = None,
xl: V | None = None,
):
"""Create a new instance of the helper. Only provide a custom component OR use named props.
Args:
custom: Custom mapping using CSS values or variables.
initial: Styling when in the inital width
xs: Styling when in the extra-small width
sm: Styling when in the small width
md: Styling when in the medium width
lg: Styling when in the large width
xl: Styling when in the extra-large width
Raises:
ValueError: If both custom and any other named parameters are provided.
Returns:
The responsive mapping.
"""
thresholds = [initial, xs, sm, md, lg, xl]
if custom is not None:
if any((threshold is not None for threshold in thresholds)):
raise ValueError("Named props cannot be used with custom thresholds")
return Breakpoints(custom)
else:
return Breakpoints(
{
k: v
for k, v in zip(["initial", *breakpoint_names], thresholds)
if v is not None
}
)
breakpoints = Breakpoints.create
T = TypeVar("T")
Responsive = Union[T, Breakpoints[str, T]]