Airsc miễn phí cho tất cả. Nếu nó giúp bạn, hãy ủng hộ $2–$20.

Ủng hộ
SkillAn toànGiao diện & thiết kếCần cài đặt chút

wind

fluttersdk · fluttersdk/wind

Một engine tạo kiểu giống Tailwind CSS cho Flutter cung cấp các lớp tiện ích, với 27 widget tiền tố W, một kỹ năng Claude Code và một máy chủ MCP tài liệu được lưu trữ cho các tác nhân AI.

Tailwind CSS cho Flutter. Các class tiện ích như flex, p-4 và dark:bg-gray-800 kết hợp thành các cây widget được tối ưu hóa. 27 widget tiền tố W, một skill Claude Code và một máy chủ MCP tài liệu được lưu trữ cho các AI agent.

41 sao2Giấy phép: MITCập nhật 19 ngày trước0 lượt mở

Xem trước

▍

Bạn có thể làm gì với nó

  • Tạo kiểu cho các ứng dụng Flutter bằng các lớp tiện ích Tailwind CSS với sự hỗ trợ của AI.
  • Sử dụng kỹ năng Claude Code để nhanh chóng tạo hoặc tinh chỉnh các thành phần UI của Flutter.
  • Truy cập tài liệu Wind thông qua máy chủ MCP để các tác nhân AI truy vấn trong quá trình phát triển UI.

Kiểm tra an toàn

An toàn

Không thấy dấu hiệu rủi ro trong các file đã quét.

Quét tự động các file trong repo. Luôn xem lại code trước khi chạy.

Trích từ README

Tailwind CSS for Flutter. Utility-first styling that turns className strings into optimized Flutter widget trees. If you know Tailwind, you already know Wind.

Documentation · Getting started · pub.dev · Issues


Flutter's structural styling costs you a six widget pyramid for a rounded card with a hover state, and the Flutter team has acknowledged the verbosity itself. Wind is the styling layer that closes the gap: one string, one widget, the same utility names you already write on the web.

WDiv(
  className: 'p-6 mx-4 bg-white dark:bg-gray-800 rounded-xl shadow-lg',
  child: WText('Hello', className: 'text-xl font-bold'),
)

The same thing in raw Flutter (click to show)

Container(
  padding: EdgeInsets.all(24),
  margin: EdgeInsets.symmetric(horizontal: 16),
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.circular(12),
    boxShadow: [
      BoxShadow(color: Colors.black.withOpacity(0.1), blurRadius: 10, offset: Offset(0, 4)),
    ],
  ),
  child: Text('Hello', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
)

Wind is a styling engine, not a widget catalogue. It composes with whatever component library you already use.

Install

flutter pub add fluttersdk_wind

Wrap the app once, then style everything with strings:

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

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

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

  @override
  Widget build(BuildContext context) {
    return WindTheme(
      data: WindThemeData(),
      builder: (context, controller) => MaterialApp(
        theme: controller.toThemeData(),
        home: const Home(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return WDiv(
      className: '''
        flex flex-col gap-4 p-6
        bg-white dark:bg-gray-800
        rounded-xl shadow-lg
        md:flex-row md:gap-6
        ios:rounded-2xl
        hover:shadow-xl
      ''',
      children: [
        WText('Wind', className: 'text-xl font-bold text-gray-900 dark:text-white'),
        WButton(
          className: 'px-4 py-2 rounded-lg bg-blue-500 dark:bg-blue-600 hover:bg-blue-600',
          onTap: () {},
          child: const WText('Get started', className: 'text-white font-medium'),
        ),
      ],
    );
  }
}

That runs as written. No MouseRegion, no setState, no _isHovered boolean, no MediaQuery branch for the tablet layout.

What you get

  • The Tailwind vocabulary you already know. flex, p-4, bg-blue-500, rounded-lg, shadow-md, parsed by 20 token parsers. Classes paste between a web project and a Flutter one unmodified.
  • 27 W-prefix widgets. WDiv, WText, WButton, WInput, WSelect, WPopover, WDatePicker, WCard, WTabs, WBadge, WSwitch, WRadio, WDynamic, and five FormField wrappers that drop straight into a Flutter Form.
  • Prefixes that stack. dark:, sm: to 2xl:, hover: / focus: / disabled: / loading: / selected:, and ios: / android: / web: / mobile: / macos: / windows: / linux: for the cases where one platform genuinely differs.
  • A theme you own. 24 WindThemeData fields covering every token scale: colors, spacing, typography, shadows, breakpoints, animations. Defaults track Tailwind's own. aliases let you name a bare token once and use it everywhere.
  • Variant composition. WindRecipe and WindSlotRecipe build a className (or a per-slot map) from a base, variant axes, compound variants and a caller override, in a strict emission order with no merge magic to reason about.
  • Forms that behave on a phone. A focused field lifts the whole input clear of the keyboard and of the keyboard toolbar above it, not just the line the caret sits on. A control with an onTap is one traversal stop and activates on Enter, Space, a gamepad A button and a TV remote.
  • Server-driven UI. WDynamic renders a widget tree from JSON against a whitelist of 13 Wind widgets and 16 Flutter core widgets, so a layout change can ship without a store release.
  • Written for agents as much as for people. A canonical skill, a hosted MCP server and an llms.txt inventory, all maintained in this repository.

className rules worth knowing before the first line

RuleWhat it means
Prefix order<state>::<dark>::<utility>, and prefixes stack freely.
ConflictsThe last class in a family wins. p-2 p-6 is padding 6.
Dark modeEvery color token carries its dark: pair in the SAME className. A missing pair is a bug, and the parser says so once in kDebugMode.
Unknown tokensDropped silently in release, named once in debug. A typo never throws and never renders a red screen.
Spacing scaleOne step is 4 logical pixels, so p-4 is 16. Font size and tracking are pixel based too.
CachingA parsed className is cached on className + breakpoint + brightness + platform + states, so rebuilds cost a map lookup.

Wind is not a literal Tailwind port. Transforms, filters, group-* / peer-*, container queries and @apply have no Flutter counterpart and are deliberately out of scope; the full list lives in the docs.

For coding agents

Wind ships its own agent surface rather than hoping a model guessed right:

npx skills add fluttersdk/ai --skill wind-ui

The skill at skills/wind-ui/SKILL.md is the source of truth for the className grammar, the widget surface, the dark-mode pairing rule and the anti-patterns. fluttersdk/ai distributes it to Claude Code, Cursor, OpenCode, Gemini CLI, VS Code Copilot, Codex CLI, Cline and Roo C

Xem mã nguồn trên GitHub