flutter_scale_theme_kit 1.0.1 copy "flutter_scale_theme_kit: ^1.0.1" to clipboard
flutter_scale_theme_kit: ^1.0.1 copied to clipboard

Look companion for Flutter: semantic colors, light/dark tokens, and Material ThemeData. Pair with flutter_scale_kit for size. Independent — no scale_kit dependency.

Flutter Scale Theme Kit #

Pub Version

Look companion for Flutter: semantic colors, authored light/dark, and Material ThemeData. Stock widgets (and flutter_scale_kit SK* widgets) pick up fill, text, and borders.

Package Job Version
flutter_scale_kit Size.w, SKSize, SKCard, ScaleKitBuilder 2.0.0
flutter_scale_theme_kit LookSTTheme, context.st, ThemeData 1.0.1

The two repos sit at the same folder level (flutter_scale_kit next to flutter_scale_theme_kit). They do not depend on each other. An app may install one or both.

This package does not depend on flutter_scale_kit. Install one or both.

  • Dart ^3.7.2, Flutter >=3.29.0
  • Runtime dependency: Flutter SDK only
  • No STButton / STCard — use Flutter widgets (or SK widgets for size)
  • Dark colors are authored. Omit dark: and light is reused. Nothing invents a palette (ColorScheme.fromSeed is not the default)

Install #

dependencies:
  flutter_scale_theme_kit: ^1.0.1

With size (recommended for production apps):

dependencies:
  flutter_scale_kit: ^2.0.0
  flutter_scale_theme_kit: ^1.0.1
import 'package:flutter_scale_theme_kit/flutter_scale_theme_kit.dart';

1. Define tokens once #

final appST = STTheme(
  colors: STColors(
    primary: STColor(light: Color(0xFF6750A4), dark: Color(0xFFD0BCFF)),
    surface: STColor(light: Color(0xFFFFFFFF), dark: Color(0xFF1E1E1E)),
    background: STColor(light: Color(0xFFF7F7F7), dark: Color(0xFF121212)),
    text: STColor(light: Color(0xFF1C1B1F), dark: Color(0xFFE6E1E5)),
    extra: {'brand': STColor(light: Color(0xFFFFB800))},
  ),
  radius: const STRadius(sm: 8, md: 12, lg: 16),
);

Required colors: primary, surface, background, text. Optional: secondary, border, divider, textSecondary, error, success, warning, info.

2. Wire MaterialApp (and switch theme) #

STThemeModeScope(
  builder: (context, mode) {
    return MaterialApp(
      theme: appST.light,
      darkTheme: appST.dark,
      themeMode: mode.mode,
      home: const HomePage(),
    );
  },
);

Anywhere under that app:

context.stMode.setMode(ThemeMode.dark);
context.stMode.setDark(true);    // false → light
context.stMode.toggle();
context.stMode.cycle();          // system → light → dark → system
context.stMode.mode;
context.stMode.isDark(context);

const STThemeModeSwitch();       // stock Switch, forces light/dark

Without STThemeModeScope, pass themeMode yourself. Look still comes from theme / darkTheme.

Scaffold, Card, ElevatedButton, TextField, AppBar, NavigationBar, SearchBar, Slider, Chip, Dialog, and the other mapped Material widgets inherit look from ThemeData. No per-widget color: required.

3. Use tokens in widgets — context.st #

Text('Hello', style: TextStyle(color: context.st.text));
Container(
  decoration: BoxDecoration(
    color: context.st.surface,
    borderRadius: context.st.radius.md,
    border: Border.all(color: context.st.border),
  ),
);

Container / SKit.roundedContainerSize are not Material — pass color: context.st.surface.

Colors #

Call Meaning
context.st.primary Brand
context.st.secondary Secondary brand
context.st.surface Cards, sheets
context.st.background Scaffold
context.st.border Outlines
context.st.divider Dividers
context.st.text Primary copy
context.st.textSecondary Muted copy
context.st.error / .success / .warning / .info Status
context.st.color('brand') Extra or semantic name

Radius and shadow #

Call Type
context.st.radius.md BorderRadius
context.st.radius.mdValue double
context.st.radius.xs.xl same pattern
context.st.shadow.sm / .md / .lg List<BoxShadow>

Typography roles #

Text('Title', style: context.st.label);
Text('Muted', style: context.st.sublabel);
Text('Body', style: context.st.description);

Override on STTheme:

typography: STTypography(
  label: STTextToken(fontSize: 14, fontWeight: FontWeight.w600),
  sublabel: STTextToken(fontSize: 12, colorName: 'textSecondary'),
  description: STTextToken(fontSize: 14, height: 1.4, colorName: 'textSecondary'),
),

Named Material slots #

components: STComponents(
  card: STComponent(elevation: 0, radius: 16),
  button: STComponent(elevation: 0), // shared by button types
  fab: STComponent(fill: STColor(light: Color(0xFFFF5722))),
  chip: STComponent(radius: 20),
)
context.st.card.fill
context.st.fab.fill
context.st.chip
context.st.container('dialog')

4. Extra styles (second button, product card, price) #

No extra widgets. Add tokens, then apply Flutter constructors.

extras: [
  STExtra.button(
    'ghost',
    style: STComponent(
      elevation: 0,
      foreground: STColor(light: Color(0xFF6750A4), dark: Color(0xFFD0BCFF)),
      states: STComponentStates(
        disabled: STComponent(
          foreground: STColor(light: Color(0xFF9E9E9E), dark: Color(0xFF6D6D6D)),
        ),
        pressed: STComponent(
          fill: STColor(light: Color(0x1A6750A4), dark: Color(0x1AD0BCFF)),
        ),
      ),
    ),
  ),
  STExtra.button(
    'destructive',
    style: STComponent(
      fill: STColor(light: Color(0xFFB3261E), dark: Color(0xFFF2B8B5)),
      elevation: 0,
    ),
  ),
  STExtra.card('product', style: STComponent(radius: 20)),
  STExtra.container(
    'highlighted',
    style: STComponent(fill: STColor(light: Color(0xFFFFF8E1), dark: Color(0xFF3E2723))),
  ),
  STExtra.text(
    'price',
    token: STTextToken(fontSize: 18, fontWeight: FontWeight.w600, colorName: 'primary'),
  ),
],

Always available (no generate):

ElevatedButton(
  style: context.st.extraButton('ghost').toButtonStyle(),
  onPressed: save,
  child: const Text('Ghost'),
);
Text('\$48', style: context.st.extraText('price'));
DecoratedBox(
  decoration: context.st.extraCard('product').toBoxDecoration(),
  child: child,
);
color: context.st.color('brand')
color: context.st.extraContainer('highlighted').fill

STComponent.states: hovered, pressed, focused, disabled, selected. Mapped into ButtonStyle (WidgetStateProperty). If you omit disabled, rest fill/ink fades to 38% alpha (same hue). onPressed: null shows disabled.

5. Generate short getters #

From a Dart file that already has appST / STExtra.*:

part 'design.g.dart';
dart run flutter_scale_theme_kit:generate
dart run flutter_scale_theme_kit:generate lib/design.dart
dart run flutter_scale_theme_kit:generate watch

Writes design.g.dart (getters only — does not replace appST):

context.st.brand
context.st.ghostButtonStyle
context.st.destructiveButtonStyle
context.st.productCardDecoration
context.st.highlightedContainerColor
context.st.price

JSON is optional authoring input (not loaded at runtime):

dart run flutter_scale_theme_kit:generate st_theme.json
{
  "variable": "appST",
  "colors": {
    "primary": { "light": "#6750A4", "dark": "#D0BCFF" },
    "surface": { "light": "#FFFFFF" },
    "background": { "light": "#F7F7F7" },
    "text": { "light": "#1C1B1F" }
  },
  "extras": {
    "ghost": { "kind": "button", "elevation": 0 },
    "product": { "kind": "card", "radius": 20 },
    "highlighted": { "kind": "container", "fill": { "light": "#FFF8E1" } },
    "price": { "kind": "text", "fontSize": 18, "fontWeight": 600 }
  }
}

kind must be button | card | container | text. Omit file to pick lib/design.dart, design.dart, or st_theme.json. No build_runner.

With flutter_scale_kit #

Do not replace appST.light with ResponsiveThemeData.create alone (it drops card/button/input themes). Scale fonts in the app:

ScaleKitBuilder(
  designWidth: 375,
  designHeight: 812,
  child: Builder(
    builder: (context) {
      return STThemeModeScope(
        builder: (context, mode) {
          return MaterialApp(
            theme: appST.light.copyWith(
              textTheme: appST.light.createResponsiveTextTheme(
                appST.light.textTheme,
              ),
            ),
            darkTheme: appST.dark.copyWith(
              textTheme: appST.dark.createResponsiveTextTheme(
                appST.dark.textTheme,
              ),
            ),
            themeMode: mode.mode,
            home: const HomePage(),
          );
        },
      );
    },
  ),
);

Align radius numbers in the app: setRadiusSizes(md: 12) and STRadius(md: 12).

SKit.paddingSize(
  all: SKSize.md,
  child: SKCard(
    child: SKElevatedButton(
      onPressed: save,
      child: SKText('Save', fontSize: 16),
    ),
  ),
);

SKit.roundedContainerSize(
  all: SKSize.md,
  color: context.st.surface,
  borderColor: context.st.border,
);

Never SKContainer(width: 120.w) (double-scale).

AI agent skill #

If this package is in the app pubspec.yaml, coding agents must use it for look (STTheme, context.st). If Scale Kit is there too, they merge fonts with createResponsiveTextTheme (see above) — not ResponsiveThemeData.create.

npx skills add fodilfliti/flutter_scale_theme_kit
npx skills add fodilfliti/flutter_scale_kit

Then: Init Flutter Scale Theme Kit with defaults.

Skill source: skills/flutter-scale-theme-kit/

Example #

cd example
flutter run

Gallery: light/dark switch (STThemeModeScope), Material widgets, extras, disabled button states.

Not in this package #

Figma import, ColorScheme.fromSeed as the default API, STCard / STButton, Cupertino, spacing/.sp (that is flutter_scale_kit).

0
likes
70
points
143
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

Look companion for Flutter: semantic colors, light/dark tokens, and Material ThemeData. Pair with flutter_scale_kit for size. Independent — no scale_kit dependency.

Repository (GitHub)
View/report issues

Topics

#theme #design-system #material #tokens #colors

License

MIT (license)

Dependencies

flutter

More

Packages that depend on flutter_scale_theme_kit