Как добавить шаблоны
- Откройте Settings → Editor → Live Templates → Dart.
- Скопируйте XML нужного шаблона ниже, выберите группу Dart в списке шаблонов и вставьте его через ⌘V на macOS или Ctrl+V на Windows/Linux. Нажмите Apply.
- В пустом
.dart-файле введите сокращение и нажмите Tab. УкажитеClassName;class_nameвычисляется черезsnakeCase(ClassName).

Примеры используют Dart 3.13+ и Freezed 4. В шаблонах BLoC и Freezed DTO используются primary constructors.
События и состояния используют сокращённую запись фабричных конструкторов.
В зависимости от выбранных шаблонов проекту нужны bloc, freezed_annotation и json_annotation, а в dev dependencies — build_runner, freezed и json_serializable.
Для BLoC создайте все три файла ниже в одной папке и укажите одинаковый ClassName в каждом шаблоне.
Freezed BLoC — frzbloc
<template name="frzbloc" value="import 'package:bloc/bloc.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part '$class_name$_bloc.freezed.dart'; part '$class_name$_event.dart'; part '$class_name$_state.dart'; final class $ClassName$Bloc() extends Bloc<$ClassName$Event, $ClassName$State> { this : super(const $ClassName$State.idle()) { on<_$ClassName$Started>(_start); } void _start(_$ClassName$Started event, Emitter<$ClassName$State> emitter) {} }" description="Freezed BLoC" toReformat="true" toShortenFQNames="true">
<variable name="ClassName" expression="" defaultValue="" alwaysStopAt="true" />
<variable name="class_name" expression="snakeCase(ClassName)" defaultValue="" alwaysStopAt="false" />
<context>
<option name="DART_TOPLEVEL" value="true" />
</context>
</template>
Результат: ClassName = Counter, counter_bloc.dart.
import 'package:bloc/bloc.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'counter_bloc.freezed.dart';
part 'counter_event.dart';
part 'counter_state.dart';
final class CounterBloc() extends Bloc<CounterEvent, CounterState> {
this : super(const CounterState.idle()) {
on<_CounterStarted>(_start);
}
void _start(_CounterStarted event, Emitter<CounterState> emitter) {}
}
Freezed BLoC event — frzevent
<template name="frzevent" value="part of '$class_name$_bloc.dart'; @Freezed(copyWith: false) sealed class $ClassName$Event with _$$$ClassName$Event { const factory start() = _$ClassName$Started; }" description="Freezed BLoC event" toReformat="true" toShortenFQNames="true">
<variable name="ClassName" expression="" defaultValue="" alwaysStopAt="true" />
<variable name="class_name" expression="snakeCase(ClassName)" defaultValue="" alwaysStopAt="false" />
<context>
<option name="DART_TOPLEVEL" value="true" />
</context>
</template>
Результат: ClassName = Counter, counter_event.dart.
part of 'counter_bloc.dart';
@Freezed(copyWith: false)
sealed class CounterEvent with _$CounterEvent {
const factory start() = _CounterStarted;
}
Freezed BLoC state — frzstate
<template name="frzstate" value="part of '$class_name$_bloc.dart'; @Freezed() sealed class $ClassName$State with _$$$ClassName$State { const factory idle() = $ClassName$Idle; const factory processing() = $ClassName$Processing; const factory success() = $ClassName$Success; const factory failure() = $ClassName$Failure; }" description="Freezed BLoC state" toReformat="true" toShortenFQNames="true">
<variable name="ClassName" expression="" defaultValue="" alwaysStopAt="true" />
<variable name="class_name" expression="snakeCase(ClassName)" defaultValue="" alwaysStopAt="false" />
<context>
<option name="DART_TOPLEVEL" value="true" />
</context>
</template>
Результат: ClassName = Counter, counter_state.dart.
part of 'counter_bloc.dart';
@Freezed()
sealed class CounterState with _$CounterState {
const factory idle() = CounterIdle;
const factory processing() = CounterProcessing;
const factory success() = CounterSuccess;
const factory failure() = CounterFailure;
}
Freezed DTO — frzdto
<template name="frzdto" value="import 'package:freezed_annotation/freezed_annotation.dart'; part '$class_name$.freezed.dart'; part '$class_name$.g.dart'; @Freezed(fromJson: false, toJson: false) @JsonSerializable(explicitToJson: true) class const $ClassName$({ required final String id, final String? name, }) with _$$$ClassName$ { factory $ClassName$.fromJson(Map<String, Object?> json) => _$$$ClassName$FromJson(json); Map<String, Object?> toJson() => _$$$ClassName$ToJson(this); }" description="Freezed DTO" toReformat="true" toShortenFQNames="true">
<variable name="ClassName" expression="" defaultValue="" alwaysStopAt="true" />
<variable name="class_name" expression="snakeCase(ClassName)" defaultValue="" alwaysStopAt="false" />
<context>
<option name="DART_TOPLEVEL" value="true" />
</context>
</template>
Результат: ClassName = UserDto, user_dto.dart.
import 'package:freezed_annotation/freezed_annotation.dart';
part 'user_dto.freezed.dart';
part 'user_dto.g.dart';
@Freezed(fromJson: false, toJson: false)
@JsonSerializable(explicitToJson: true)
class const UserDto({
required final String id,
final String? name,
}) with _$UserDto {
factory UserDto.fromJson(Map<String, Object?> json) =>
_$UserDtoFromJson(json);
Map<String, Object?> toJson() => _$UserDtoToJson(this);
}
json_serializable DTO — jsondto
<template name="jsondto" value="import 'package:json_annotation/json_annotation.dart'; part '$class_name$.g.dart'; @JsonSerializable(explicitToJson: true) class $ClassName$ { const $ClassName$({ required this.id, this.name, }); factory $ClassName$.fromJson(Map<String, Object?> json) => _$$$ClassName$FromJson(json); final String id; final String? name; Map<String, Object?> toJson() => _$$$ClassName$ToJson(this); }" description="json_serializable DTO" toReformat="true" toShortenFQNames="true">
<variable name="ClassName" expression="" defaultValue="" alwaysStopAt="true" />
<variable name="class_name" expression="snakeCase(ClassName)" defaultValue="" alwaysStopAt="false" />
<context>
<option name="DART_TOPLEVEL" value="true" />
</context>
</template>
Результат: ClassName = UserDto, user_dto.dart.
import 'package:json_annotation/json_annotation.dart';
part 'user_dto.g.dart';
@JsonSerializable(explicitToJson: true)
class UserDto {
const UserDto({
required this.id,
this.name,
});
factory UserDto.fromJson(Map<String, Object?> json) =>
_$UserDtoFromJson(json);
final String id;
final String? name;
Map<String, Object?> toJson() => _$UserDtoToJson(this);
}
После создания файлов сгенерируйте части .freezed.dart и .g.dart:
dart run build_runner build