Puls Design System

Дизайн-система «Puls Glass» для Flutter, создающая эффект матового стекла с динамическими анимациями, цветовой семантикой и тактильной обратной связью. Пакет включает готовые компоненты для быстрой сборки интерфейсов в стиле «неоморфизм» с акцентом на глубину, свет и движение.

Установка

Добавьте зависимость в pubspec.yaml вашего проекта:

dependencies:
  puls_design:
    path: ../path/to/puls_design  # локальный путь

Или используйте версию из pub.flutter-io.cn (если опубликовано):

dependencies:
  puls_design: ^0.0.1

Затем выполните:

flutter pub get

Импорт

import 'package:puls_design/puls_design.dart';

Компоненты

1. PulsTheme

Центральный узел конфигурации, содержащий цвета, типографику, тени и анимационные константы.

Основные цвета

PulsTheme.bgDeepBlack      // Глубокий OLED‑черный фон
PulsTheme.accentOrange     // Оранжевый акцент (по умолчанию)
PulsTheme.accentGreen      // Зелёный акцент (успех)
PulsTheme.accentRed        // Красный акцент (ошибка)
PulsTheme.glassWhite       // Полупрозрачный белый для стекла
PulsTheme.borderWhite      // Цвет границы

Типографика

PulsTheme.heading          // Заголовок (32pt, жирный)
PulsTheme.body             // Основной текст (16pt)
PulsTheme.bodyText         // Альтернативный основной текст
PulsTheme.labelText        // Метка (14pt, полужирный, широкий кернинг)

Тени и свечение

PulsTheme.glow(Color color, {bool active = false})
// Возвращает список BoxShadow с градиентным свечением.

Анимации

PulsTheme.animationFast    // Duration(milliseconds: 200)
PulsTheme.animationMedium  // Duration(milliseconds: 400)
PulsTheme.mainCurve        // Curves.easeOutCubic

2. PulsGlassCard

Карточка с эффектом матового стекла, поддерживающая hover‑анимацию (приподнимание, пульсацию) и настраиваемый акцентный цвет.

Параметры

Параметр Тип По умолчанию Описание
child Widget обязательно Содержимое карточки
accentColor Color Colors.white12 Цвет свечения и границы
pulseOnHover bool false Включить пульсацию границы при наведении

Пример

PulsGlassCard(
  accentColor: PulsTheme.accentOrange,
  pulseOnHover: true,
  child: Text(
    "Это матовое стекло карточки",
    style: PulsTheme.bodyText,
  ),
)

3. PulsSystemInput

Поле ввода с интеллектуальной цветовой индикацией состояния (нейтральное, фокус, успех, ошибка) и встроенной анимацией свечения.

Параметры

Параметр Тип По умолчанию Описание
hint String обязательно Текст‑подсказка
isValid bool? null null – нейтрально, true – успех, false – ошибка

Пример

const PulsSystemInput(
  hint: "Введите системный код",
  isValid: null, // Оранжевый цвет при фокусе
)

4. PulsGlassButton

Кнопка с тактильной обратной связью (вибрация), анимацией масштаба и многослойным свечением. Меняет интенсивность тени и цвета в зависимости от состояния нажатия.

Параметры

Параметр Тип По умолчанию Описание
label String обязательно Текст на кнопке
accentColor Color обязательно Акцентный цвет (свечение, граница)
onTap VoidCallback обязательно Обработчик нажатия

Пример

PulsGlassButton(
  label: "ПОДТВЕРДИТЬ",
  accentColor: PulsTheme.accentGreen,
  onTap: () => print("Action success"),
)

5. PulsStepper

Горизонтальный степпер с анимированным появлением шагов, настраиваемой длительностью, кривыми анимации и возможностью переключения состояния по тапу.

Класс PulsStep

PulsStep(
  title: "Ядро",
  description: "Загрузка модулей",
  isCompleted: true, // или false, или null (нейтрально)
)

Параметры PulsStepper

Параметр Тип По умолчанию Описание
steps List<PulsStep> обязательно Список шагов
duration Duration Duration(milliseconds: 1500) Длительность каскадной анимации
fadeCurve Curve Curves.easeIn Кривая затухания
slideCurve Curve Curves.easeOutCubic Кривая смещения
onStepTapped ValueChanged<int>? null Коллбэк при тапе на шаг (передаёт индекс)
indicatorHeight double 28 Высота индикатора
lineThickness double 2 Толщина соединительной линии

Пример

PulsStepper(
  steps: [
    PulsStep(title: "Ядро", description: "Загрузка модулей", isCompleted: true),
    PulsStep(title: "Интерфейс", description: "Рендеринг Puls Glass", isCompleted: null),
    PulsStep(title: "Безопасность", description: "Проверка протоколов", isCompleted: null),
  ],
  onStepTapped: (index) => print("Шаг $index tapped"),
)

Полный пример приложения

import 'package:flutter/material.dart';
import 'package:puls_design/puls_design.dart';

void main() => runApp(const PulsApp());

class PulsApp extends StatelessWidget {
  const PulsApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        scaffoldBackgroundColor: PulsTheme.bgDeepBlack,
        brightness: Brightness.dark,
      ),
      home: const TestDriveScreen(),
    );
  }
}

class TestDriveScreen extends StatefulWidget {
  const TestDriveScreen({super.key});

  @override
  State<TestDriveScreen> createState() => _TestDriveScreenState();
}

class _TestDriveScreenState extends State<TestDriveScreen> {
  List<PulsStep> steps = [
    PulsStep(title: "Ядро", description: "Загрузка модулей", isCompleted: true),
    PulsStep(title: "Интерфейс", description: "Рендеринг Puls Glass", isCompleted: null),
    PulsStep(title: "Безопасность", description: "Проверка протоколов", isCompleted: null),
  ];

  void _handleButtonTap() {
    setState(() {
      // Логика переключения состояния шагов
      for (int i = 0; i < steps.length; i++) {
        if (steps[i].isCompleted == null) {
          steps[i] = PulsStep(
            title: steps[i].title,
            description: steps[i].description,
            isCompleted: true,
          );
          break;
        }
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          padding: const EdgeInsets.all(30),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Text("Puls Design System", style: PulsTheme.heading),
              const SizedBox(height: 10),
              Text("Тест компонентов экосистемы", style: PulsTheme.bodyText),

              const SizedBox(height: 40),
              PulsGlassCard(
                accentColor: PulsTheme.accentOrange,
                child: Text("Это матовое стекло карточки", style: PulsTheme.bodyText),
              ),

              const SizedBox(height: 25),
              const PulsSystemInput(hint: "Введите системный код", isValid: null),

              const SizedBox(height: 25),
              PulsGlassButton(
                label: "ПОДТВЕРДИТЬ",
                accentColor: PulsTheme.accentGreen,
                onTap: _handleButtonTap,
              ),

              const SizedBox(height: 40),
              PulsStepper(steps: steps),
            ],
          ),
        ),
      ),
    );
  }
}

Поддержка

Пакет находится в активной разработке. Планируется добавление новых компонентов:

  • Навигация с эффектом стекла
  • Диалоговые окна
  • Индикаторы загрузки
  • Адаптивные сетки

Лицензия

MIT

Libraries

main
puls_design