fh-pydantic-form 0.3.4__py3-none-any.whl → 0.3.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of fh-pydantic-form might be problematic. Click here for more details.
- fh_pydantic_form/__init__.py +3 -0
- fh_pydantic_form/defaults.py +6 -0
- fh_pydantic_form/field_renderers.py +62 -1
- {fh_pydantic_form-0.3.4.dist-info → fh_pydantic_form-0.3.5.dist-info}/METADATA +1 -1
- {fh_pydantic_form-0.3.4.dist-info → fh_pydantic_form-0.3.5.dist-info}/RECORD +7 -7
- {fh_pydantic_form-0.3.4.dist-info → fh_pydantic_form-0.3.5.dist-info}/WHEEL +0 -0
- {fh_pydantic_form-0.3.4.dist-info → fh_pydantic_form-0.3.5.dist-info}/licenses/LICENSE +0 -0
fh_pydantic_form/__init__.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import datetime
|
|
2
|
+
import decimal
|
|
2
3
|
from enum import Enum
|
|
3
4
|
from typing import Literal, get_origin
|
|
4
5
|
|
|
@@ -17,6 +18,7 @@ from fh_pydantic_form.field_renderers import (
|
|
|
17
18
|
BaseModelFieldRenderer,
|
|
18
19
|
BooleanFieldRenderer,
|
|
19
20
|
DateFieldRenderer,
|
|
21
|
+
DecimalFieldRenderer,
|
|
20
22
|
EnumFieldRenderer,
|
|
21
23
|
ListFieldRenderer,
|
|
22
24
|
LiteralFieldRenderer,
|
|
@@ -55,6 +57,7 @@ def register_default_renderers() -> None:
|
|
|
55
57
|
FieldRendererRegistry.register_type_renderer(bool, BooleanFieldRenderer)
|
|
56
58
|
FieldRendererRegistry.register_type_renderer(int, NumberFieldRenderer)
|
|
57
59
|
FieldRendererRegistry.register_type_renderer(float, NumberFieldRenderer)
|
|
60
|
+
FieldRendererRegistry.register_type_renderer(decimal.Decimal, DecimalFieldRenderer)
|
|
58
61
|
FieldRendererRegistry.register_type_renderer(datetime.date, DateFieldRenderer)
|
|
59
62
|
FieldRendererRegistry.register_type_renderer(datetime.time, TimeFieldRenderer)
|
|
60
63
|
|
fh_pydantic_form/defaults.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import datetime as _dt
|
|
4
|
+
import decimal
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from typing import Any, Literal, get_args, get_origin
|
|
6
7
|
|
|
@@ -25,6 +26,7 @@ _SIMPLE_DEFAULTS = {
|
|
|
25
26
|
int: 0,
|
|
26
27
|
float: 0.0,
|
|
27
28
|
bool: False,
|
|
29
|
+
decimal.Decimal: decimal.Decimal("0"),
|
|
28
30
|
_dt.date: lambda: _today(), # callable - gets current date (late-bound)
|
|
29
31
|
_dt.time: lambda: _dt.time(0, 0), # callable - midnight
|
|
30
32
|
}
|
|
@@ -52,6 +54,10 @@ def default_for_annotation(annotation: Any) -> Any:
|
|
|
52
54
|
if _is_optional_type(annotation):
|
|
53
55
|
return None
|
|
54
56
|
|
|
57
|
+
# List[T] → []
|
|
58
|
+
if origin is list:
|
|
59
|
+
return []
|
|
60
|
+
|
|
55
61
|
# Literal[...] → first literal value
|
|
56
62
|
if origin is Literal:
|
|
57
63
|
return _first_literal_choice(annotation)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import re
|
|
3
3
|
from datetime import date, time
|
|
4
|
+
from decimal import Decimal
|
|
4
5
|
from enum import Enum
|
|
5
6
|
from typing import (
|
|
6
7
|
Any,
|
|
@@ -510,7 +511,7 @@ class BaseFieldRenderer(MetricsRendererMixin):
|
|
|
510
511
|
label_text_span = fh.Span(label_text, **span_attrs)
|
|
511
512
|
|
|
512
513
|
# Prepare label attributes
|
|
513
|
-
label_attrs = {"
|
|
514
|
+
label_attrs = {"for": self.field_name}
|
|
514
515
|
|
|
515
516
|
# Build label classes with tokenized gap
|
|
516
517
|
label_gap_class = spacing("label_gap", self.spacing)
|
|
@@ -705,6 +706,66 @@ class NumberFieldRenderer(BaseFieldRenderer):
|
|
|
705
706
|
return mui.Input(**input_attrs)
|
|
706
707
|
|
|
707
708
|
|
|
709
|
+
class DecimalFieldRenderer(BaseFieldRenderer):
|
|
710
|
+
"""Renderer for decimal.Decimal fields"""
|
|
711
|
+
|
|
712
|
+
def __init__(self, *args, **kwargs):
|
|
713
|
+
"""Initialize decimal field renderer, passing all arguments to parent"""
|
|
714
|
+
super().__init__(*args, **kwargs)
|
|
715
|
+
|
|
716
|
+
def render_input(self) -> FT:
|
|
717
|
+
"""
|
|
718
|
+
Render input element for decimal fields
|
|
719
|
+
|
|
720
|
+
Returns:
|
|
721
|
+
A NumberInput component appropriate for decimal values
|
|
722
|
+
"""
|
|
723
|
+
# Determine if field is required
|
|
724
|
+
has_default = get_default(self.field_info) is not _UNSET
|
|
725
|
+
is_field_required = not self.is_optional and not has_default
|
|
726
|
+
|
|
727
|
+
placeholder_text = f"Enter {self.original_field_name.replace('_', ' ')}"
|
|
728
|
+
if self.is_optional:
|
|
729
|
+
placeholder_text += " (Optional)"
|
|
730
|
+
|
|
731
|
+
input_cls_parts = ["w-full"]
|
|
732
|
+
input_spacing_cls = spacing_many(
|
|
733
|
+
["input_size", "input_padding", "input_line_height", "input_font_size"],
|
|
734
|
+
self.spacing,
|
|
735
|
+
)
|
|
736
|
+
if input_spacing_cls:
|
|
737
|
+
input_cls_parts.append(input_spacing_cls)
|
|
738
|
+
|
|
739
|
+
# Convert Decimal value to string for display
|
|
740
|
+
if isinstance(self.value, Decimal):
|
|
741
|
+
# Use format to avoid scientific notation
|
|
742
|
+
display_value = format(self.value, "f")
|
|
743
|
+
# Normalize zero values to display as "0"
|
|
744
|
+
if self.value == 0:
|
|
745
|
+
display_value = "0"
|
|
746
|
+
elif self.value is not None:
|
|
747
|
+
display_value = str(self.value)
|
|
748
|
+
else:
|
|
749
|
+
display_value = ""
|
|
750
|
+
|
|
751
|
+
input_attrs = {
|
|
752
|
+
"value": display_value,
|
|
753
|
+
"id": self.field_name,
|
|
754
|
+
"name": self.field_name,
|
|
755
|
+
"type": "number",
|
|
756
|
+
"placeholder": placeholder_text,
|
|
757
|
+
"required": is_field_required,
|
|
758
|
+
"cls": " ".join(input_cls_parts),
|
|
759
|
+
"step": "any", # Allow arbitrary decimal precision
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
# Only add the disabled attribute if the field should actually be disabled
|
|
763
|
+
if self.disabled:
|
|
764
|
+
input_attrs["disabled"] = True
|
|
765
|
+
|
|
766
|
+
return mui.Input(**input_attrs)
|
|
767
|
+
|
|
768
|
+
|
|
708
769
|
class BooleanFieldRenderer(BaseFieldRenderer):
|
|
709
770
|
"""Renderer for boolean fields"""
|
|
710
771
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fh-pydantic-form
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.5
|
|
4
4
|
Summary: a library to turn any pydantic BaseModel object into a fasthtml/monsterui input form
|
|
5
5
|
Project-URL: Homepage, https://github.com/Marcura/fh-pydantic-form
|
|
6
6
|
Project-URL: Repository, https://github.com/Marcura/fh-pydantic-form
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
fh_pydantic_form/__init__.py,sha256=
|
|
1
|
+
fh_pydantic_form/__init__.py,sha256=uPN0pwErHoe69tDoCDdIYD_iCslMKRgfYw6pvL4McHE,4608
|
|
2
2
|
fh_pydantic_form/color_utils.py,sha256=M0HSXX0i-lSHkcsgesxw7d3PEAnLsZ46i_STymZAM_k,18271
|
|
3
3
|
fh_pydantic_form/comparison_form.py,sha256=Y-OKAjTxMiixBC05SK1ofZ_A3zkvjUFp8tTE-_wUn60,21660
|
|
4
4
|
fh_pydantic_form/constants.py,sha256=-N9wzkibFNn-V6cO8iWTQ7_xBvwSr2hBdq-m3apmW4M,169
|
|
5
|
-
fh_pydantic_form/defaults.py,sha256=
|
|
6
|
-
fh_pydantic_form/field_renderers.py,sha256=
|
|
5
|
+
fh_pydantic_form/defaults.py,sha256=9vV0f4PapTOgqNsIxoW6rEbpYO66O4uiKvpd6hzR1-M,6189
|
|
6
|
+
fh_pydantic_form/field_renderers.py,sha256=twAqHvWkDL6M-HRcdi_JrR2BgzkPmMyF_vojId5ABa0,83574
|
|
7
7
|
fh_pydantic_form/form_parser.py,sha256=DsOMiCXRRHswL37Vqv7bvMv3Q7nQdXp0oP3_ZoIJfVc,26172
|
|
8
8
|
fh_pydantic_form/form_renderer.py,sha256=0OrOA0--KT1r-HX37AGeDkC2rmbUSbJ4fgL04wG7pI8,36224
|
|
9
9
|
fh_pydantic_form/list_path.py,sha256=AA8bmDmaYy4rlGIvQOOZ0fP2tgcimNUB2Re5aVGnYc8,5182
|
|
@@ -11,7 +11,7 @@ fh_pydantic_form/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
11
11
|
fh_pydantic_form/registry.py,sha256=b5zIjOpfmCUCs2njgp4PdDu70ioDIAfl49oU-Nf2pg4,4810
|
|
12
12
|
fh_pydantic_form/type_helpers.py,sha256=JUzHT8YrWj2_g7f_Wr2GL9i3BgP1zZftFrrO8xDPeis,7409
|
|
13
13
|
fh_pydantic_form/ui_style.py,sha256=UPK5OBwUVVTLnfvQ-yKukz2vbKZaT_GauaNB7OGc-Uw,3848
|
|
14
|
-
fh_pydantic_form-0.3.
|
|
15
|
-
fh_pydantic_form-0.3.
|
|
16
|
-
fh_pydantic_form-0.3.
|
|
17
|
-
fh_pydantic_form-0.3.
|
|
14
|
+
fh_pydantic_form-0.3.5.dist-info/METADATA,sha256=S3vgfnQpOhl4YAcDPje_4w9lNOtOnIRslrgnYiiYrT8,38420
|
|
15
|
+
fh_pydantic_form-0.3.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
16
|
+
fh_pydantic_form-0.3.5.dist-info/licenses/LICENSE,sha256=AOi2eNK3D2aDycRHfPRiuACZ7WPBsKHTV2tTYNl7cls,577
|
|
17
|
+
fh_pydantic_form-0.3.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|