SaaS-FrameWork 0.1.2__tar.gz → 0.1.4__tar.gz

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.
Files changed (103) hide show
  1. {saas_framework-0.1.2 → saas_framework-0.1.4}/MANIFEST.in +1 -1
  2. saas_framework-0.1.4/PKG-INFO +116 -0
  3. saas_framework-0.1.4/README.md +90 -0
  4. {saas_framework-0.1.2 → saas_framework-0.1.4}/SaaS_FrameWork.egg-info/SOURCES.txt +6 -1
  5. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/__init__.py +6 -0
  6. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_BtnFAB.py +5 -3
  7. saas_framework-0.1.4/components/buttons/DEx_BtnFilled.py +34 -0
  8. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_BtnGhost.py +13 -2
  9. saas_framework-0.1.4/components/buttons/DEx_BtnPrimary.py +41 -0
  10. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_BtnSegmented.py +4 -2
  11. saas_framework-0.1.4/components/buttons/DEx_BtnText.py +36 -0
  12. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_BtnTonal.py +6 -3
  13. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/cards/DEx_ContactCard.py +15 -5
  14. saas_framework-0.1.4/components/charts/DEx_BarChart.py +101 -0
  15. saas_framework-0.1.4/components/charts/DEx_LineChart.py +130 -0
  16. saas_framework-0.1.4/components/charts/DEx_PieChart.py +124 -0
  17. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_DataTable.py +20 -4
  18. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_ListTile.py +4 -2
  19. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_TreeView.py +7 -3
  20. saas_framework-0.1.4/components/feedback/DEx_AlertDialog.py +141 -0
  21. saas_framework-0.1.4/components/feedback/DEx_Notify.py +24 -0
  22. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_Checkbox.py +14 -2
  23. saas_framework-0.1.4/components/inputs/DEx_Dropdown.py +41 -0
  24. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_Slider.py +5 -2
  25. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_Switch.py +5 -2
  26. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_TagInput.py +5 -2
  27. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_TextField.py +22 -3
  28. saas_framework-0.1.4/components/layout/DEx_AppShell.py +137 -0
  29. saas_framework-0.1.4/components/layout/DEx_Header.py +80 -0
  30. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_NavItem.py +4 -3
  31. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_NavigationDrawer.py +9 -5
  32. saas_framework-0.1.4/components/layout/DEx_Sidebar.py +178 -0
  33. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_Stack.py +6 -3
  34. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_Tabs.py +4 -2
  35. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/metadata.py +35 -30
  36. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Avatar.py +5 -2
  37. saas_framework-0.1.4/components/primitives/__init__.py +0 -0
  38. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/project.py +23 -19
  39. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/theme/DEx_ColorThemes.py +112 -14
  40. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/theme/DEx_Theme.py +21 -7
  41. saas_framework-0.1.4/components/theme/platform_variant.py +72 -0
  42. {saas_framework-0.1.2 → saas_framework-0.1.4}/pyproject.toml +9 -2
  43. saas_framework-0.1.2/PKG-INFO +0 -450
  44. saas_framework-0.1.2/README.md +0 -427
  45. saas_framework-0.1.2/components/buttons/DEx_BtnFilled.py +0 -20
  46. saas_framework-0.1.2/components/buttons/DEx_BtnPrimary.py +0 -21
  47. saas_framework-0.1.2/components/buttons/DEx_BtnText.py +0 -22
  48. saas_framework-0.1.2/components/feedback/DEx_AlertDialog.py +0 -26
  49. saas_framework-0.1.2/components/feedback/DEx_Notify.py +0 -17
  50. saas_framework-0.1.2/components/inputs/DEx_Dropdown.py +0 -25
  51. saas_framework-0.1.2/components/layout/DEx_AppShell.py +0 -80
  52. saas_framework-0.1.2/components/layout/DEx_Header.py +0 -57
  53. saas_framework-0.1.2/components/layout/DEx_Sidebar.py +0 -131
  54. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_BtnIcon.py +0 -0
  55. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_MenuBar.py +0 -0
  56. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/DEx_PopupMenu.py +0 -0
  57. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/buttons/__init__.py +0 -0
  58. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/cards/DEx_Card.py +0 -0
  59. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/cards/DEx_MetricCard.py +0 -0
  60. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/cards/__init__.py +0 -0
  61. {saas_framework-0.1.2/components/data → saas_framework-0.1.4/components/charts}/__init__.py +0 -0
  62. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_ExpansionPanel.py +0 -0
  63. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_ExpansionTile.py +0 -0
  64. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_GridView.py +0 -0
  65. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_ListView.py +0 -0
  66. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/data/DEx_PipelineColumn.py +0 -0
  67. {saas_framework-0.1.2/components/feedback → saas_framework-0.1.4/components/data}/__init__.py +0 -0
  68. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_Banner.py +0 -0
  69. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_BottomSheet.py +0 -0
  70. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_ProgressBar.py +0 -0
  71. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_ProgressRing.py +0 -0
  72. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_Shimmer.py +0 -0
  73. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/feedback/DEx_Tooltip.py +0 -0
  74. {saas_framework-0.1.2/components/inputs → saas_framework-0.1.4/components/feedback}/__init__.py +0 -0
  75. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_AutoComplete.py +0 -0
  76. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_Chip.py +0 -0
  77. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_DatePicker.py +0 -0
  78. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_FilePicker.py +0 -0
  79. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_Radio.py +0 -0
  80. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_SearchBar.py +0 -0
  81. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_SearchField.py +0 -0
  82. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/inputs/DEx_TimePicker.py +0 -0
  83. {saas_framework-0.1.2/components/layout → saas_framework-0.1.4/components/inputs}/__init__.py +0 -0
  84. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_AnimatedSwitcher.py +0 -0
  85. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_AppBar.py +0 -0
  86. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_Draggable.py +0 -0
  87. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_GestureDetector.py +0 -0
  88. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_Marquee.py +0 -0
  89. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_NavigationBar.py +0 -0
  90. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_NavigationRail.py +0 -0
  91. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_ResponsiveRow.py +0 -0
  92. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/layout/DEx_Splitter.py +0 -0
  93. {saas_framework-0.1.2/components/primitives → saas_framework-0.1.4/components/layout}/__init__.py +0 -0
  94. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Badge.py +0 -0
  95. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Divider.py +0 -0
  96. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Icon.py +0 -0
  97. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Image.py +0 -0
  98. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_Markdown.py +0 -0
  99. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_SectionEyebrow.py +0 -0
  100. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/primitives/DEx_StatusDot.py +0 -0
  101. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/theme/__init__.py +0 -0
  102. {saas_framework-0.1.2 → saas_framework-0.1.4}/components/versioning.py +0 -0
  103. {saas_framework-0.1.2 → saas_framework-0.1.4}/setup.cfg +0 -0
@@ -10,7 +10,7 @@ prune build
10
10
  prune catalog
11
11
  prune *.egg-info
12
12
  prune dist
13
- prune docs
13
+ prune Diretrizes
14
14
  prune tests
15
15
  prune use_cases
16
16
  exclude files.zip
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: SaaS-FrameWork
3
+ Version: 0.1.4
4
+ Summary: SaaS-FrameWork - sistema de componentes reutilizaveis para apps SaaS construido com Python e Flet
5
+ Author-email: Almir Duarte <almir.jg@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/DEx-SaaS/FrameWork
8
+ Keywords: flet,saas,framework,ui,components,design-system
9
+ Classifier: Development Status :: 1 - Planning
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Topic :: Software Development :: User Interfaces
13
+ Requires-Python: >=3.13
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: flet==0.84.0
16
+ Requires-Dist: flet-charts==0.84.0
17
+ Provides-Extra: web
18
+ Requires-Dist: flet-web==0.84.0; extra == "web"
19
+ Provides-Extra: dev
20
+ Requires-Dist: flet==0.84.0; extra == "dev"
21
+ Requires-Dist: pytest<10,>=9.1; extra == "dev"
22
+ Requires-Dist: build<2,>=1.3; extra == "dev"
23
+ Requires-Dist: twine<7,>=6.2; extra == "dev"
24
+ Provides-Extra: visual
25
+ Requires-Dist: playwright<2,>=1.40; extra == "visual"
26
+
27
+ # SaaS-FrameWork
28
+
29
+ Reusable SaaS UI components for [Flet](https://flet.dev): a versioned design system with
30
+ **70 catalogued components** — buttons, inputs, navigation, data tables and tree views,
31
+ overlays and dialogs, feedback, media and responsive layout — plus accessible color themes
32
+ and a navigable component catalog.
33
+
34
+ ## Install
35
+
36
+ ```bash
37
+ pip install SaaS-FrameWork
38
+ ```
39
+
40
+ For web deployments, install the web extra:
41
+
42
+ ```bash
43
+ pip install "SaaS-FrameWork[web]"
44
+ ```
45
+
46
+ ## Quickstart
47
+
48
+ ```python
49
+ import flet as ft
50
+ from components import DEx_BtnPrimary, DEx_MetricCard, DEx_Notify, DEx_TextField
51
+
52
+
53
+ def main(page: ft.Page) -> None:
54
+ page.title = "Hello SaaS-FrameWork"
55
+ name = DEx_TextField(label="Your name", hint="Type and press the button")
56
+ page.add(
57
+ DEx_MetricCard(label="Active users", value="1,024", delta="+12%"),
58
+ name,
59
+ DEx_BtnPrimary("Greet", on_click=lambda e: DEx_Notify(page, f"Hello, {name.value}!")),
60
+ )
61
+
62
+
63
+ ft.app(main)
64
+ ```
65
+
66
+ Save as `hello.py` and run:
67
+
68
+ ```bash
69
+ python hello.py
70
+ ```
71
+
72
+ Every public component is importable straight from `components`
73
+ (`from components import DEx_DataTable, DEx_AppShell, ...`).
74
+
75
+ ## Compatibility
76
+
77
+ | Requirement | Version |
78
+ |---|---|
79
+ | Python | `>= 3.13` |
80
+ | Flet | `== 0.84.0` (pinned) |
81
+
82
+ The Flet dependency is intentionally **pinned**: Flet's API still moves between releases, so
83
+ upgrades only land here after the project's upgrade policy revalidates all 70 use cases
84
+ against the candidate version. Installing this package therefore also pins your app's Flet
85
+ version.
86
+
87
+ ## Component catalog
88
+
89
+ Browse every component, its use case, parameters and source in the live catalog:
90
+
91
+ - **Online:** https://saas-framework-catalog.onrender.com
92
+ - **Local (from the repository):** `flet run catalog/catalog.py`
93
+
94
+ The catalog has global search, maturity filters and a responsive layout, and is audited for
95
+ accessibility (WCAG AA contrast, keyboard navigation).
96
+
97
+ ## Versioning and maturity
98
+
99
+ The project is **pre-1.0**: APIs may still change between minor releases. Each component
100
+ declares its own `COMPONENT_VERSION` and the catalog groups them into maturity bands —
101
+ Experimental (`0.0.x`), Evolving (`0.1.x+`) and Stable (`1.x+`). Every component change is
102
+ required (and CI-enforced) to bump the component version. Release history lives in
103
+ [CHANGELOG.md](CHANGELOG.md).
104
+
105
+ ## Feedback
106
+
107
+ Bug reports, questions and suggestions: https://github.com/DEx-SaaS/FrameWork/issues
108
+
109
+ ## Development
110
+
111
+ Contributor documentation — folder structure, naming conventions, versioning rules, test
112
+ suite and the component contract — lives in [CONTRIBUTING.md](CONTRIBUTING.md).
113
+
114
+ ## License
115
+
116
+ MIT.
@@ -0,0 +1,90 @@
1
+ # SaaS-FrameWork
2
+
3
+ Reusable SaaS UI components for [Flet](https://flet.dev): a versioned design system with
4
+ **70 catalogued components** — buttons, inputs, navigation, data tables and tree views,
5
+ overlays and dialogs, feedback, media and responsive layout — plus accessible color themes
6
+ and a navigable component catalog.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ pip install SaaS-FrameWork
12
+ ```
13
+
14
+ For web deployments, install the web extra:
15
+
16
+ ```bash
17
+ pip install "SaaS-FrameWork[web]"
18
+ ```
19
+
20
+ ## Quickstart
21
+
22
+ ```python
23
+ import flet as ft
24
+ from components import DEx_BtnPrimary, DEx_MetricCard, DEx_Notify, DEx_TextField
25
+
26
+
27
+ def main(page: ft.Page) -> None:
28
+ page.title = "Hello SaaS-FrameWork"
29
+ name = DEx_TextField(label="Your name", hint="Type and press the button")
30
+ page.add(
31
+ DEx_MetricCard(label="Active users", value="1,024", delta="+12%"),
32
+ name,
33
+ DEx_BtnPrimary("Greet", on_click=lambda e: DEx_Notify(page, f"Hello, {name.value}!")),
34
+ )
35
+
36
+
37
+ ft.app(main)
38
+ ```
39
+
40
+ Save as `hello.py` and run:
41
+
42
+ ```bash
43
+ python hello.py
44
+ ```
45
+
46
+ Every public component is importable straight from `components`
47
+ (`from components import DEx_DataTable, DEx_AppShell, ...`).
48
+
49
+ ## Compatibility
50
+
51
+ | Requirement | Version |
52
+ |---|---|
53
+ | Python | `>= 3.13` |
54
+ | Flet | `== 0.84.0` (pinned) |
55
+
56
+ The Flet dependency is intentionally **pinned**: Flet's API still moves between releases, so
57
+ upgrades only land here after the project's upgrade policy revalidates all 70 use cases
58
+ against the candidate version. Installing this package therefore also pins your app's Flet
59
+ version.
60
+
61
+ ## Component catalog
62
+
63
+ Browse every component, its use case, parameters and source in the live catalog:
64
+
65
+ - **Online:** https://saas-framework-catalog.onrender.com
66
+ - **Local (from the repository):** `flet run catalog/catalog.py`
67
+
68
+ The catalog has global search, maturity filters and a responsive layout, and is audited for
69
+ accessibility (WCAG AA contrast, keyboard navigation).
70
+
71
+ ## Versioning and maturity
72
+
73
+ The project is **pre-1.0**: APIs may still change between minor releases. Each component
74
+ declares its own `COMPONENT_VERSION` and the catalog groups them into maturity bands —
75
+ Experimental (`0.0.x`), Evolving (`0.1.x+`) and Stable (`1.x+`). Every component change is
76
+ required (and CI-enforced) to bump the component version. Release history lives in
77
+ [CHANGELOG.md](CHANGELOG.md).
78
+
79
+ ## Feedback
80
+
81
+ Bug reports, questions and suggestions: https://github.com/DEx-SaaS/FrameWork/issues
82
+
83
+ ## Development
84
+
85
+ Contributor documentation — folder structure, naming conventions, versioning rules, test
86
+ suite and the component contract — lives in [CONTRIBUTING.md](CONTRIBUTING.md).
87
+
88
+ ## License
89
+
90
+ MIT.
@@ -20,6 +20,10 @@ components/cards/DEx_Card.py
20
20
  components/cards/DEx_ContactCard.py
21
21
  components/cards/DEx_MetricCard.py
22
22
  components/cards/__init__.py
23
+ components/charts/DEx_BarChart.py
24
+ components/charts/DEx_LineChart.py
25
+ components/charts/DEx_PieChart.py
26
+ components/charts/__init__.py
23
27
  components/data/DEx_DataTable.py
24
28
  components/data/DEx_ExpansionPanel.py
25
29
  components/data/DEx_ExpansionTile.py
@@ -81,4 +85,5 @@ components/primitives/DEx_StatusDot.py
81
85
  components/primitives/__init__.py
82
86
  components/theme/DEx_ColorThemes.py
83
87
  components/theme/DEx_Theme.py
84
- components/theme/__init__.py
88
+ components/theme/__init__.py
89
+ components/theme/platform_variant.py
@@ -77,6 +77,10 @@ from components.feedback.DEx_ProgressBar import DEx_ProgressBar
77
77
  from components.feedback.DEx_ProgressRing import DEx_ProgressRing
78
78
  from components.feedback.DEx_Shimmer import DEx_ShimmerCard, DEx_ShimmerListItem, DEx_ShimmerList
79
79
 
80
+ from components.charts.DEx_LineChart import DEx_LineChart
81
+ from components.charts.DEx_BarChart import DEx_BarChart
82
+ from components.charts.DEx_PieChart import DEx_PieChart
83
+
80
84
  __version__ = "0.1.1"
81
85
 
82
86
  __all__ = [
@@ -120,6 +124,8 @@ __all__ = [
120
124
  "DEx_Notify", "DEx_AlertDialog", "DEx_BottomSheet", "DEx_Banner",
121
125
  "DEx_Tooltip", "DEx_ProgressBar", "DEx_ProgressRing",
122
126
  "DEx_ShimmerCard", "DEx_ShimmerListItem", "DEx_ShimmerList",
127
+ # charts
128
+ "DEx_LineChart", "DEx_BarChart", "DEx_PieChart",
123
129
  # meta
124
130
  "__version__",
125
131
  ]
@@ -1,7 +1,7 @@
1
1
  import flet as ft
2
2
  from components.theme.DEx_Theme import Colors, Spacing
3
3
 
4
- COMPONENT_VERSION = "0.0.1"
4
+ COMPONENT_VERSION = "0.0.2"
5
5
 
6
6
 
7
7
  def DEx_BtnFAB(
@@ -13,11 +13,13 @@ def DEx_BtnFAB(
13
13
  """Floating action button for the primary creation or positive action on a screen.
14
14
 
15
15
  Pass label for extended FAB; omit for compact circular form.
16
+ Rótulo e ícone em ``ACCENT_ON`` (token semântico "sobre ACCENT") —
17
+ débito técnico 12, S12/atv11.
16
18
  """
17
19
  if label:
18
20
  return ft.FloatingActionButton(
19
21
  content=ft.Row(
20
- [ft.Icon(icon, size=18, color=Colors.TEXT_PRIMARY), ft.Text(label, size=14, color=Colors.TEXT_PRIMARY)],
22
+ [ft.Icon(icon, size=18, color=Colors.ACCENT_ON), ft.Text(label, size=14, color=Colors.ACCENT_ON)],
21
23
  spacing=8,
22
24
  tight=True,
23
25
  ),
@@ -31,7 +33,7 @@ def DEx_BtnFAB(
31
33
  on_click=on_click,
32
34
  mini=mini,
33
35
  bgcolor=Colors.ACCENT,
34
- foreground_color=Colors.TEXT_PRIMARY,
36
+ foreground_color=Colors.ACCENT_ON,
35
37
  hover_color=Colors.ACCENT_DARK,
36
38
  shape=ft.RoundedRectangleBorder(radius=28),
37
39
  )
@@ -0,0 +1,34 @@
1
+ import flet as ft
2
+ from components.theme.platform_variant import adaptive_kwargs, is_cupertino
3
+ from components.theme.DEx_Theme import Colors, Spacing
4
+
5
+ COMPONENT_VERSION = "0.1.0"
6
+
7
+
8
+ def DEx_BtnFilled(label: str, on_click=None, icon=None, platform: str | None = None):
9
+ """Primary filled button — highest emphasis action in a view.
10
+
11
+ Rótulo em ``ACCENT_ON`` (token semântico "sobre ACCENT"), mesma higiene
12
+ do DEx_BtnPrimary — débito técnico 12, S12/atv11."""
13
+ if is_cupertino(platform):
14
+ return ft.CupertinoFilledButton(
15
+ content=label,
16
+ icon=icon,
17
+ on_click=on_click,
18
+ bgcolor=Colors.ACCENT,
19
+ color=Colors.ACCENT_ON,
20
+ border_radius=Spacing.BUTTON_BORDER_RADIUS,
21
+ )
22
+ return ft.FilledButton(
23
+ **adaptive_kwargs(platform),
24
+ content=label,
25
+ icon=icon,
26
+ on_click=on_click,
27
+ style=ft.ButtonStyle(
28
+ bgcolor=Colors.ACCENT,
29
+ color=Colors.ACCENT_ON,
30
+ overlay_color=Colors.ACCENT_DARK,
31
+ shape=ft.RoundedRectangleBorder(radius=Spacing.BUTTON_BORDER_RADIUS),
32
+ padding=ft.Padding.symmetric(horizontal=Spacing.MD, vertical=Spacing.SM + 2),
33
+ ),
34
+ )
@@ -1,12 +1,23 @@
1
1
  import flet as ft
2
+ from components.theme.platform_variant import adaptive_kwargs, is_cupertino
2
3
  from components.theme.DEx_Theme import Colors, Spacing
3
4
 
4
- COMPONENT_VERSION = "0.1.0"
5
+ COMPONENT_VERSION = "0.2.0"
5
6
 
6
7
 
7
- def DEx_BtnGhost(label: str, on_click=None, icon=None) -> ft.Button:
8
+ def DEx_BtnGhost(label: str, on_click=None, icon=None, platform: str | None = None):
8
9
  """Create the versioned secondary outlined button for lower-emphasis actions."""
10
+ if is_cupertino(platform):
11
+ return ft.CupertinoButton(
12
+ content=label,
13
+ icon=icon,
14
+ on_click=on_click,
15
+ bgcolor="transparent",
16
+ color=Colors.TEXT_PRIMARY,
17
+ border_radius=Spacing.BUTTON_BORDER_RADIUS,
18
+ )
9
19
  return ft.Button(
20
+ **adaptive_kwargs(platform),
10
21
  content=label,
11
22
  icon=icon,
12
23
  on_click=on_click,
@@ -0,0 +1,41 @@
1
+ import flet as ft
2
+ from components.theme.platform_variant import adaptive_kwargs, is_cupertino
3
+ from components.theme.DEx_Theme import Colors, Spacing
4
+
5
+ COMPONENT_VERSION = "0.2.0"
6
+
7
+
8
+ def DEx_BtnPrimary(label: str, on_click=None, icon=None, platform: str | None = None):
9
+ """Create the versioned primary action button for main user commands.
10
+
11
+ Rótulo em ``ACCENT_ON`` — o token semântico "sobre ACCENT" (5.17:1 no
12
+ tema default e AA por construção nos presets, que trocam o rótulo para
13
+ escuro quando o accent do preset é claro). ``TEXT_PRIMARY`` passava no
14
+ tema default mas não acompanha os presets (débito técnico 12, S12/atv11).
15
+
16
+ ``platform`` aceita ``"material"`` (padrão), ``"ios"`` (contraparte
17
+ Cupertino) e ``"auto"`` (o Flet escolhe em runtime) — ver
18
+ ``components/theme/platform_variant.py``."""
19
+ if is_cupertino(platform):
20
+ return ft.CupertinoFilledButton(
21
+ content=label,
22
+ icon=icon,
23
+ on_click=on_click,
24
+ bgcolor=Colors.ACCENT,
25
+ color=Colors.ACCENT_ON,
26
+ border_radius=Spacing.BUTTON_BORDER_RADIUS,
27
+ )
28
+ return ft.Button(
29
+ **adaptive_kwargs(platform),
30
+ content=label,
31
+ icon=icon,
32
+ on_click=on_click,
33
+ bgcolor=Colors.ACCENT,
34
+ color=Colors.ACCENT_ON,
35
+ elevation=1,
36
+ style=ft.ButtonStyle(
37
+ overlay_color=Colors.ACCENT_DARK,
38
+ shape=ft.RoundedRectangleBorder(radius=Spacing.BUTTON_BORDER_RADIUS),
39
+ padding=ft.Padding.symmetric(horizontal=Spacing.MD, vertical=Spacing.SM + 2),
40
+ ),
41
+ )
@@ -1,7 +1,7 @@
1
1
  import flet as ft
2
2
  from components.theme.DEx_Theme import Colors, Spacing
3
3
 
4
- COMPONENT_VERSION = "0.0.1"
4
+ COMPONENT_VERSION = "0.0.2"
5
5
 
6
6
 
7
7
  def DEx_BtnSegmented(
@@ -14,6 +14,8 @@ def DEx_BtnSegmented(
14
14
  """Multi-option toggle control for mutually exclusive or multi-select choices.
15
15
 
16
16
  Each entry in segments: {"value": str, "label": str, "icon": str | None}
17
+ Rótulo do segmento selecionado em ``ACCENT_ON`` (token semântico
18
+ "sobre ACCENT") — débito técnico 12, S12/atv11.
17
19
  """
18
20
  _selected = list(selected) if selected else [segments[0]["value"]]
19
21
  return ft.SegmentedButton(
@@ -35,7 +37,7 @@ def DEx_BtnSegmented(
35
37
  ft.ControlState.DEFAULT: Colors.BG_ELEVATED,
36
38
  },
37
39
  color={
38
- ft.ControlState.SELECTED: Colors.TEXT_PRIMARY,
40
+ ft.ControlState.SELECTED: Colors.ACCENT_ON,
39
41
  ft.ControlState.DEFAULT: Colors.TEXT_SECONDARY,
40
42
  },
41
43
  side=ft.BorderSide(1, Colors.BORDER),
@@ -0,0 +1,36 @@
1
+ import flet as ft
2
+ from components.theme.platform_variant import adaptive_kwargs, is_cupertino
3
+ from components.theme.DEx_Theme import Colors, Spacing
4
+
5
+ COMPONENT_VERSION = "0.2.0"
6
+
7
+
8
+ def DEx_BtnText(label: str, on_click=None, icon=None, platform: str | None = None):
9
+ """Lowest-emphasis action button: no border and no background fill.
10
+
11
+ Rótulo em ``ACCENT_TEXT`` (violeta AA para texto pequeno, >= 4.5:1 nos
12
+ três fundos) — ``ACCENT`` é token de UI e media 3.44:1 como texto
13
+ (débito técnico 12, S12/atv11)."""
14
+ if is_cupertino(platform):
15
+ return ft.CupertinoButton(
16
+ content=label,
17
+ icon=icon,
18
+ on_click=on_click,
19
+ bgcolor="transparent",
20
+ color=Colors.ACCENT_TEXT,
21
+ )
22
+ return ft.Button(
23
+ **adaptive_kwargs(platform),
24
+ content=label,
25
+ icon=icon,
26
+ on_click=on_click,
27
+ bgcolor="transparent",
28
+ color=Colors.ACCENT_TEXT,
29
+ elevation=0,
30
+ style=ft.ButtonStyle(
31
+ color=Colors.ACCENT_TEXT,
32
+ overlay_color=Colors.BG_ELEVATED,
33
+ shape=ft.RoundedRectangleBorder(radius=Spacing.BUTTON_BORDER_RADIUS),
34
+ padding=ft.Padding.symmetric(horizontal=Spacing.SM, vertical=Spacing.SM + 2),
35
+ ),
36
+ )
@@ -1,18 +1,21 @@
1
1
  import flet as ft
2
2
  from components.theme.DEx_Theme import Colors, Spacing
3
3
 
4
- COMPONENT_VERSION = "0.0.1"
4
+ COMPONENT_VERSION = "0.0.2"
5
5
 
6
6
 
7
7
  def DEx_BtnTonal(label: str, on_click=None, icon=None) -> ft.FilledTonalButton:
8
- """Secondary filled button with muted emphasis — between outlined and filled."""
8
+ """Secondary filled button with muted emphasis — between outlined and filled.
9
+
10
+ Rótulo em ``ACCENT_TEXT`` (>= 4.76:1 sobre BG_ELEVATED) — ``ACCENT``
11
+ media 3.13:1 sobre o fundo elevado (débito técnico 12, S12/atv11)."""
9
12
  return ft.FilledTonalButton(
10
13
  content=label,
11
14
  icon=icon,
12
15
  on_click=on_click,
13
16
  style=ft.ButtonStyle(
14
17
  bgcolor=Colors.BG_ELEVATED,
15
- color=Colors.ACCENT,
18
+ color=Colors.ACCENT_TEXT,
16
19
  overlay_color=Colors.ACCENT_DARK,
17
20
  shape=ft.RoundedRectangleBorder(radius=Spacing.BUTTON_BORDER_RADIUS),
18
21
  padding=ft.Padding.symmetric(horizontal=Spacing.MD, vertical=Spacing.SM + 2),
@@ -4,7 +4,7 @@ from components.cards.DEx_Card import DEx_Card
4
4
  from components.primitives.DEx_Badge import DEx_Badge
5
5
  from components.primitives.DEx_Divider import DEx_Divider
6
6
 
7
- COMPONENT_VERSION = "0.0.1"
7
+ COMPONENT_VERSION = "0.0.2"
8
8
 
9
9
 
10
10
  def DEx_ContactCard(
@@ -15,13 +15,19 @@ def DEx_ContactCard(
15
15
  tag: str = None,
16
16
  value: str = None,
17
17
  ) -> ft.Container:
18
- """Create the versioned contact/entity card with avatar and optional footer."""
18
+ """Create the versioned contact/entity card with avatar and optional footer.
19
+
20
+ S12/atv11: iniciais e tag em ``ACCENT_TEXT`` (>= 4.69:1 sobre o fill
21
+ translúcido composto com o fundo do card, débito técnico 12); os fills
22
+ com sufixo hex ``22``/``33`` viravam AARRGGBB no Flutter e pintavam
23
+ esverdeados (BUG5) — agora usam ``ft.Colors.with_opacity``.
24
+ """
19
25
  initials = "".join(p[0].upper() for p in name.split()[:2])
20
26
 
21
27
  avatar = ft.Container(
22
- content=ft.Text(initials, size=14, weight=ft.FontWeight.W_700, color=Colors.ACCENT),
28
+ content=ft.Text(initials, size=14, weight=ft.FontWeight.W_700, color=Colors.ACCENT_TEXT),
23
29
  width=42, height=42,
24
- bgcolor=f"{Colors.ACCENT}22",
30
+ bgcolor=ft.Colors.with_opacity(0.13, Colors.ACCENT),
25
31
  border_radius=21,
26
32
  alignment=ft.Alignment(0, 0),
27
33
  )
@@ -35,7 +41,11 @@ def DEx_ContactCard(
35
41
  footer_controls = []
36
42
  if tag:
37
43
  footer_controls.append(
38
- DEx_Badge(tag, color=f"{Colors.ACCENT}33", text_color=Colors.ACCENT)
44
+ DEx_Badge(
45
+ tag,
46
+ color=ft.Colors.with_opacity(0.13, Colors.ACCENT),
47
+ text_color=Colors.ACCENT_TEXT,
48
+ )
39
49
  )
40
50
  if value:
41
51
  footer_controls.append(
@@ -0,0 +1,101 @@
1
+ """DEx_BarChart — comparação por categoria, com os tokens do tema.
2
+
3
+ Construído sobre ``flet_charts`` (decisão D5). Aceita uma série (barras
4
+ simples) ou várias (barras agrupadas por categoria), com legenda opcional.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import flet as ft
9
+ import flet_charts as fc
10
+
11
+ from components.charts.DEx_LineChart import series_color
12
+ from components.theme.DEx_Theme import Colors, Spacing
13
+
14
+ COMPONENT_VERSION = "0.0.1"
15
+
16
+
17
+ def _legenda(nomes: list[str]) -> ft.Row:
18
+ itens: list[ft.Control] = []
19
+ for i, nome in enumerate(nomes):
20
+ itens.append(
21
+ ft.Row(
22
+ [
23
+ ft.Container(width=10, height=10, bgcolor=series_color(i), border_radius=2),
24
+ ft.Text(nome, size=11, color=Colors.TEXT_SECONDARY),
25
+ ],
26
+ spacing=6,
27
+ tight=True,
28
+ )
29
+ )
30
+ return ft.Row(itens, spacing=Spacing.MD, wrap=True)
31
+
32
+
33
+ def DEx_BarChart(
34
+ categories: list[str],
35
+ series: list[dict],
36
+ height: int = 260,
37
+ show_legend: bool = True,
38
+ show_grid: bool = True,
39
+ bar_width: int = 16,
40
+ horizontal: bool = False,
41
+ ) -> ft.Column:
42
+ """Gráfico de barras agrupadas por categoria.
43
+
44
+ Args:
45
+ categories: rótulos do eixo de categorias (uma entrada por grupo).
46
+ series: lista de séries. Cada série é um dicionário com ``name`` (str)
47
+ e ``values`` (lista de números, alinhada a ``categories``). Aceita
48
+ ``color`` para fixar a cor.
49
+ height: altura do gráfico em pixels.
50
+ show_legend: exibe a legenda de séries abaixo do gráfico.
51
+ show_grid: exibe a grade horizontal.
52
+ bar_width: largura de cada barra em pixels.
53
+ horizontal: ainda não suportado pelo backend; mantido para
54
+ compatibilidade futura de assinatura e ignorado hoje.
55
+ """
56
+ nomes = [s.get("name", f"Série {i + 1}") for i, s in enumerate(series)]
57
+
58
+ grupos: list[fc.BarChartGroup] = []
59
+ for indice_categoria in range(len(categories)):
60
+ barras: list[fc.BarChartRod] = []
61
+ for i, serie in enumerate(series):
62
+ valores = serie.get("values", [])
63
+ if indice_categoria >= len(valores):
64
+ continue
65
+ barras.append(
66
+ fc.BarChartRod(
67
+ to_y=valores[indice_categoria],
68
+ width=bar_width,
69
+ color=serie.get("color") or series_color(i),
70
+ border_radius=4,
71
+ )
72
+ )
73
+ grupos.append(fc.BarChartGroup(x=indice_categoria, rods=barras))
74
+
75
+ eixo_x = fc.ChartAxis(
76
+ labels=[
77
+ fc.ChartAxisLabel(
78
+ value=i,
79
+ label=ft.Text(rotulo, size=10, color=Colors.TEXT_SECONDARY),
80
+ )
81
+ for i, rotulo in enumerate(categories)
82
+ ],
83
+ label_size=28,
84
+ )
85
+
86
+ grafico = fc.BarChart(
87
+ groups=grupos,
88
+ bottom_axis=eixo_x,
89
+ left_axis=fc.ChartAxis(label_size=40),
90
+ border=ft.Border.all(1, Colors.BORDER),
91
+ horizontal_grid_lines=(
92
+ fc.ChartGridLines(color=Colors.BORDER, width=1) if show_grid else None
93
+ ),
94
+ tooltip=fc.BarChartTooltip(bgcolor=Colors.BG_ELEVATED),
95
+ expand=True,
96
+ )
97
+
98
+ conteudo: list[ft.Control] = [ft.Container(content=grafico, height=height)]
99
+ if show_legend and nomes:
100
+ conteudo.append(_legenda(nomes))
101
+ return ft.Column(conteudo, spacing=Spacing.SM, tight=True)