Compare commits
2 commits
b812ed21c5
...
373eeb7925
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
373eeb7925 | ||
|
|
53edb17712 |
10 changed files with 49 additions and 16 deletions
|
|
@ -4,12 +4,12 @@
|
||||||
Каждый пример — рабочий интерфейс и отдельная читаемая Python-функция; кнопка
|
Каждый пример — рабочий интерфейс и отдельная читаемая Python-функция; кнопка
|
||||||
`</>` рядом с примером открывает точную строку исходного кода в репозитории.
|
`</>` рядом с примером открывает точную строку исходного кода в репозитории.
|
||||||
|
|
||||||
В каталоге 27 интерактивных примеров: кнопки, поля ввода, controls выбора,
|
В каталоге 28 интерактивных примеров: кнопки, поля ввода, controls выбора,
|
||||||
типографика, карточки, списки, адаптивные layouts, навигация, таблицы, progress,
|
типографика, карточки, списки, адаптивные layouts, навигация, таблицы, progress,
|
||||||
dialogs, snackbar и bottom sheet. Постоянная кнопка настроек позволяет менять
|
dialogs, snackbar, banner и bottom sheet. Постоянная кнопка настроек позволяет менять
|
||||||
светлую/тёмную/системную тему, Material 3 accent color и видимость кнопок кода.
|
светлую/тёмную/системную тему, Material 3 accent color и видимость кнопок кода.
|
||||||
Разделы открываются через выдвижное меню в AppBar. Отдельный каталог всех иконок
|
Разделы открываются через выдвижное меню в AppBar. Отдельный каталог всех иконок
|
||||||
Flet поддерживает поиск по имени и копирует готовое выражение `ft.Icon(ft.Icons.HOME)`
|
Flet поддерживает поиск по имени и копирует имя иконки `ft.Icons.HOME`
|
||||||
при нажатии.
|
при нажатии.
|
||||||
|
|
||||||
## Запуск
|
## Запуск
|
||||||
|
|
@ -45,7 +45,7 @@ ARMv8 в Android соответствует ABI `arm64-v8a`:
|
||||||
uv run flet build apk src --arch arm64-v8a --yes \
|
uv run flet build apk src --arch arm64-v8a --yes \
|
||||||
--project flet_component_gallery \
|
--project flet_component_gallery \
|
||||||
--product "Flet Material Catalog" \
|
--product "Flet Material Catalog" \
|
||||||
--build-version 0.2.0 \
|
--build-version 0.3.0 \
|
||||||
--org su.snw
|
--org su.snw
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
[project]
|
[project]
|
||||||
name = "flet-component-gallery"
|
name = "flet-component-gallery"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
description = "Composer-inspired interactive gallery of Flet controls"
|
description = "Composer-inspired interactive gallery of Flet controls"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ class GalleryApp:
|
||||||
controls=[
|
controls=[
|
||||||
ft.Text(self.selected_category, theme_style=ft.TextThemeStyle.DISPLAY_SMALL),
|
ft.Text(self.selected_category, theme_style=ft.TextThemeStyle.DISPLAY_SMALL),
|
||||||
ft.Text(
|
ft.Text(
|
||||||
(f"{count} иконок · нажмите, чтобы скопировать код" if self.selected_category == "Иконки" else f"{count} интерактивных примеров · Flet 1.0.1 · каталог 0.2.0"),
|
(f"{count} иконок · нажмите, чтобы скопировать код" if self.selected_category == "Иконки" else f"{count} интерактивных примеров · Flet 1.0.1 · каталог 0.3.0"),
|
||||||
color=ft.Colors.ON_SURFACE_VARIANT,
|
color=ft.Colors.ON_SURFACE_VARIANT,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,28 @@ def bottom_sheet() -> ft.Control:
|
||||||
return ft.FilledButton("Открыть bottom sheet", icon=ft.Icons.VERTICAL_ALIGN_TOP, on_click=show)
|
return ft.FilledButton("Открыть bottom sheet", icon=ft.Icons.VERTICAL_ALIGN_TOP, on_click=show)
|
||||||
|
|
||||||
|
|
||||||
|
def banner() -> ft.Control:
|
||||||
|
def show(e: ft.Event[ft.FilledButton]) -> None:
|
||||||
|
page = e.control.page
|
||||||
|
page.show_dialog(
|
||||||
|
ft.Banner(
|
||||||
|
leading=ft.Icons.WIFI_OFF,
|
||||||
|
content="Нет подключения к сети. Проверьте соединение и повторите попытку.",
|
||||||
|
actions=[
|
||||||
|
ft.TextButton("Закрыть", on_click=lambda event: event.control.page.pop_dialog()),
|
||||||
|
ft.TextButton("Повторить", on_click=lambda event: event.control.page.pop_dialog()),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return ft.FilledButton("Показать banner", icon=ft.Icons.CAMPAIGN_OUTLINED, on_click=show)
|
||||||
|
|
||||||
|
|
||||||
EXAMPLES = [
|
EXAMPLES = [
|
||||||
Example("data-table", "DataTable", "Табличные структурированные данные.", "Данные и feedback", data_table),
|
Example("data-table", "DataTable", "Табличные структурированные данные.", "Данные и feedback", data_table),
|
||||||
Example("progress", "Progress indicators", "Определённая и бесконечная загрузка.", "Данные и feedback", progress_indicators),
|
Example("progress", "Progress indicators", "Определённая и бесконечная загрузка.", "Данные и feedback", progress_indicators),
|
||||||
Example("dialog", "AlertDialog", "Модальное подтверждение важного действия.", "Данные и feedback", alert_dialog),
|
Example("dialog", "AlertDialog", "Модальное подтверждение важного действия.", "Данные и feedback", alert_dialog),
|
||||||
Example("snackbar", "SnackBar", "Краткое неблокирующее сообщение.", "Данные и feedback", snackbar),
|
Example("snackbar", "SnackBar", "Краткое неблокирующее сообщение.", "Данные и feedback", snackbar),
|
||||||
Example("bottom-sheet", "BottomSheet", "Дополнительный мобильный слой.", "Данные и feedback", bottom_sheet),
|
Example("bottom-sheet", "BottomSheet", "Дополнительный мобильный слой.", "Данные и feedback", bottom_sheet),
|
||||||
|
Example("banner", "Banner", "Важное сообщение с действиями в верхней части экрана.", "Данные и feedback", banner),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,14 @@ def tabs() -> ft.Control:
|
||||||
content=ft.Column(
|
content=ft.Column(
|
||||||
controls=[
|
controls=[
|
||||||
ft.TabBar(tabs=[ft.Tab(label="Обзор", icon=ft.Icons.DASHBOARD), ft.Tab(label="Код", icon=ft.Icons.CODE), ft.Tab(label="API", icon=ft.Icons.DATA_OBJECT)]),
|
ft.TabBar(tabs=[ft.Tab(label="Обзор", icon=ft.Icons.DASHBOARD), ft.Tab(label="Код", icon=ft.Icons.CODE), ft.Tab(label="API", icon=ft.Icons.DATA_OBJECT)]),
|
||||||
ft.TabBarView(controls=[ft.Container(ft.Text("Обзор компонента"), padding=20), ft.Container(ft.Text("Пример кода"), padding=20), ft.Container(ft.Text("Справка API"), padding=20)]),
|
ft.TabBarView(
|
||||||
|
controls=[
|
||||||
|
ft.Container(ft.Text("Обзор компонента"), padding=20),
|
||||||
|
ft.Container(ft.Text("Пример кода"), padding=20),
|
||||||
|
ft.Container(ft.Text("Справка API"), padding=20),
|
||||||
|
],
|
||||||
|
height=96,
|
||||||
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
height=160,
|
height=160,
|
||||||
|
|
@ -45,4 +52,3 @@ EXAMPLES = [
|
||||||
Example("navigation-bar", "NavigationBar", "Основные разделы мобильного приложения.", "Навигация", navigation_bar),
|
Example("navigation-bar", "NavigationBar", "Основные разделы мобильного приложения.", "Навигация", navigation_bar),
|
||||||
Example("popup-menu", "PopupMenuButton", "Редкие действия в компактном меню.", "Навигация", popup_menu),
|
Example("popup-menu", "PopupMenuButton", "Редкие действия в компактном меню.", "Навигация", popup_menu),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,5 +14,4 @@ def matching_icons(query: str) -> tuple[str, ...]:
|
||||||
def icon_snippet(name: str) -> str:
|
def icon_snippet(name: str) -> str:
|
||||||
if name not in ICON_NAMES:
|
if name not in ICON_NAMES:
|
||||||
raise ValueError(f"Unknown Flet icon: {name}")
|
raise ValueError(f"Unknown Flet icon: {name}")
|
||||||
return f"ft.Icon(ft.Icons.{name})"
|
return f"ft.Icons.{name}"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import os
|
||||||
from importlib.resources import files
|
from importlib.resources import files
|
||||||
|
|
||||||
REPOSITORY = "https://git.snw.su/snw/FletAppDemo"
|
REPOSITORY = "https://git.snw.su/snw/FletAppDemo"
|
||||||
DEFAULT_REVISION = "e8830e846a40a6b4484b4c07d7ec752ca0faca87"
|
DEFAULT_REVISION = "53edb17712a6560cca0b10218896950431f7e8bf"
|
||||||
|
|
||||||
|
|
||||||
def _manifest() -> dict[str, dict[str, str | int]]:
|
def _manifest() -> dict[str, dict[str, str | int]]:
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
{
|
{
|
||||||
|
"banner": {
|
||||||
|
"function": "banner",
|
||||||
|
"line": 64,
|
||||||
|
"path": "src/gallery/examples/data_feedback.py"
|
||||||
|
},
|
||||||
"bottom-sheet": {
|
"bottom-sheet": {
|
||||||
"function": "bottom_sheet",
|
"function": "bottom_sheet",
|
||||||
"line": 49,
|
"line": 49,
|
||||||
|
|
@ -66,7 +71,7 @@
|
||||||
},
|
},
|
||||||
"navigation-bar": {
|
"navigation-bar": {
|
||||||
"function": "navigation_bar",
|
"function": "navigation_bar",
|
||||||
"line": 20,
|
"line": 27,
|
||||||
"path": "src/gallery/examples/navigation.py"
|
"path": "src/gallery/examples/navigation.py"
|
||||||
},
|
},
|
||||||
"outlined-buttons": {
|
"outlined-buttons": {
|
||||||
|
|
@ -76,7 +81,7 @@
|
||||||
},
|
},
|
||||||
"popup-menu": {
|
"popup-menu": {
|
||||||
"function": "popup_menu",
|
"function": "popup_menu",
|
||||||
"line": 31,
|
"line": 38,
|
||||||
"path": "src/gallery/examples/navigation.py"
|
"path": "src/gallery/examples/navigation.py"
|
||||||
},
|
},
|
||||||
"progress": {
|
"progress": {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import json
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from gallery.examples import ALL_EXAMPLES
|
from gallery.examples import ALL_EXAMPLES
|
||||||
|
from gallery.examples.navigation import tabs
|
||||||
from gallery.icon_catalog import ICON_NAMES, PAGE_SIZE, icon_snippet, matching_icons
|
from gallery.icon_catalog import ICON_NAMES, PAGE_SIZE, icon_snippet, matching_icons
|
||||||
|
|
||||||
ROOT = Path(__file__).resolve().parents[1]
|
ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
|
@ -31,4 +32,9 @@ def test_icon_catalog_searches_every_icon_and_copies_valid_flet_code() -> None:
|
||||||
assert len(ICON_NAMES) > PAGE_SIZE
|
assert len(ICON_NAMES) > PAGE_SIZE
|
||||||
assert "HOME" in matching_icons("home")
|
assert "HOME" in matching_icons("home")
|
||||||
assert "HOME_OUTLINED" in matching_icons("home outlined")
|
assert "HOME_OUTLINED" in matching_icons("home outlined")
|
||||||
assert icon_snippet("HOME") == "ft.Icon(ft.Icons.HOME)"
|
assert icon_snippet("HOME") == "ft.Icons.HOME"
|
||||||
|
|
||||||
|
|
||||||
|
def test_tabs_view_has_bounded_height() -> None:
|
||||||
|
tabs_control = tabs()
|
||||||
|
assert tabs_control.content.controls[1].height == 96
|
||||||
|
|
|
||||||
2
uv.lock
generated
2
uv.lock
generated
|
|
@ -50,7 +50,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flet-component-gallery"
|
name = "flet-component-gallery"
|
||||||
version = "0.2.0"
|
version = "0.3.0"
|
||||||
source = { virtual = "." }
|
source = { virtual = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "flet" },
|
{ name = "flet" },
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue