257 lines
5.5 KiB
Dart
257 lines
5.5 KiB
Dart
// Flutter imports:
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
|
||
// Package imports:
|
||
import 'package:google_fonts/google_fonts.dart';
|
||
|
||
export '../../common/typography.dart';
|
||
|
||
abstract class TypographyType {
|
||
///
|
||
/// Размер шрифта
|
||
///
|
||
double get size;
|
||
|
||
///
|
||
/// Получение [TextStyle] для типа шрифта
|
||
///
|
||
TextStyle get style;
|
||
}
|
||
|
||
abstract class TypographyTypeRegular extends TypographyType {
|
||
///
|
||
/// Высота линии
|
||
///
|
||
double get height => 1.21;
|
||
|
||
@override
|
||
TextStyle get style {
|
||
return GoogleFonts.inter(
|
||
fontWeight: FontWeight.w400,
|
||
fontSize: size.sp,
|
||
height: height,
|
||
);
|
||
}
|
||
}
|
||
|
||
abstract class TypographyTypeMedium extends TypographyType {
|
||
///
|
||
/// Высота линии
|
||
///
|
||
double get height => 1.15;
|
||
|
||
@override
|
||
TextStyle get style {
|
||
return GoogleFonts.inter(
|
||
fontWeight: FontWeight.w500,
|
||
fontSize: size.sp,
|
||
height: height,
|
||
);
|
||
}
|
||
}
|
||
|
||
abstract class TypographyTypeSemiBold extends TypographyType {
|
||
///
|
||
/// Высота линии
|
||
///
|
||
double get height => 1.21;
|
||
|
||
@override
|
||
TextStyle get style {
|
||
return GoogleFonts.inter(
|
||
fontWeight: FontWeight.w600,
|
||
fontSize: size.sp,
|
||
height: height,
|
||
);
|
||
}
|
||
}
|
||
|
||
abstract class TypographyTypeBold extends TypographyType {
|
||
///
|
||
/// Высота линии
|
||
///
|
||
double get height => 1.21;
|
||
|
||
@override
|
||
TextStyle get style {
|
||
return GoogleFonts.inter(
|
||
fontWeight: FontWeight.w700,
|
||
fontSize: size.sp,
|
||
height: height,
|
||
);
|
||
}
|
||
}
|
||
|
||
abstract class TypographyTypeHeadBold extends TypographyType {
|
||
///
|
||
/// Высота линии
|
||
///
|
||
double get height => 1.36;
|
||
|
||
@override
|
||
TextStyle get style {
|
||
return GoogleFonts.inter(
|
||
fontWeight: FontWeight.w700,
|
||
fontSize: size.sp,
|
||
height: height,
|
||
);
|
||
}
|
||
}
|
||
|
||
///
|
||
/// Дополнительные возможности [AppTypography]
|
||
///
|
||
enum TypographyFeature {
|
||
///
|
||
/// Использование [Text]
|
||
///
|
||
DEFAULT,
|
||
|
||
///
|
||
/// Использование [RichText]
|
||
///
|
||
RICH,
|
||
|
||
///
|
||
/// Использование [SelectableText]
|
||
///
|
||
SELECTABLE,
|
||
}
|
||
|
||
///
|
||
/// Виджет для отображения текста в приложении
|
||
///
|
||
/// Тесно использует [TypographyType]
|
||
/// На его основе выбирается стиль текста
|
||
///
|
||
/// Важно: планшетная верстка не учитывается в стилях - меняется сам стиль,
|
||
/// поэтому контролировать нужно извне
|
||
///
|
||
class AppTypography extends StatelessWidget {
|
||
const AppTypography(
|
||
this.text, {
|
||
this.type,
|
||
this.color,
|
||
this.maxLines = 1,
|
||
this.textAlign = TextAlign.left,
|
||
this.fontWeight,
|
||
this.overflow = TextOverflow.ellipsis,
|
||
this.height,
|
||
this.softWrap,
|
||
this.textDecoration = TextDecoration.none,
|
||
super.key,
|
||
}) : typographyFeature = TypographyFeature.DEFAULT,
|
||
children = null;
|
||
|
||
const AppTypography.rich(
|
||
this.text, {
|
||
this.type,
|
||
this.color,
|
||
this.maxLines,
|
||
this.textAlign = TextAlign.left,
|
||
this.fontWeight,
|
||
this.overflow,
|
||
this.height,
|
||
this.softWrap,
|
||
this.textDecoration = TextDecoration.none,
|
||
this.children,
|
||
super.key,
|
||
}) : typographyFeature = TypographyFeature.RICH;
|
||
|
||
const AppTypography.selectable(
|
||
this.text, {
|
||
this.type,
|
||
this.color,
|
||
this.maxLines,
|
||
this.textAlign = TextAlign.left,
|
||
this.fontWeight,
|
||
this.overflow,
|
||
this.height,
|
||
this.softWrap,
|
||
this.textDecoration = TextDecoration.none,
|
||
super.key,
|
||
}) : typographyFeature = TypographyFeature.SELECTABLE,
|
||
children = null;
|
||
|
||
/// Текст
|
||
final String text;
|
||
|
||
/// Стиль текста
|
||
final TypographyType? type;
|
||
|
||
/// Цвет текста
|
||
final Color? color;
|
||
|
||
/// Кол-во линий
|
||
final int? maxLines;
|
||
|
||
/// Направление текста
|
||
final TextAlign textAlign;
|
||
|
||
/// Жирность шрифта
|
||
final FontWeight? fontWeight;
|
||
|
||
/// Overflow
|
||
final TextOverflow? overflow;
|
||
|
||
/// Межстрочный интервал
|
||
final double? height;
|
||
|
||
/// Мягкий перенос
|
||
final bool? softWrap;
|
||
|
||
/// Декорация текста
|
||
final TextDecoration textDecoration;
|
||
|
||
/// Использование фич типографии
|
||
final TypographyFeature typographyFeature;
|
||
|
||
/// Список [TextSpan]
|
||
final List<InlineSpan>? children;
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final DefaultTextStyle textStyle = DefaultTextStyle.of(context);
|
||
|
||
final TextStyle computeTextStyle =
|
||
type == null
|
||
? textStyle.style
|
||
: type!.style.copyWith(
|
||
color: color ?? textStyle.style.color,
|
||
fontWeight: fontWeight,
|
||
height: height,
|
||
decoration: textDecoration,
|
||
);
|
||
|
||
switch (typographyFeature) {
|
||
case TypographyFeature.DEFAULT:
|
||
return Text(
|
||
text,
|
||
maxLines: maxLines,
|
||
textAlign: textAlign,
|
||
overflow: overflow,
|
||
softWrap: softWrap,
|
||
style: computeTextStyle,
|
||
);
|
||
|
||
case TypographyFeature.RICH:
|
||
return RichText(
|
||
text: TextSpan(
|
||
text: text,
|
||
children: children,
|
||
style: computeTextStyle,
|
||
),
|
||
);
|
||
|
||
case TypographyFeature.SELECTABLE:
|
||
return SelectableText(
|
||
text,
|
||
maxLines: maxLines,
|
||
textAlign: textAlign,
|
||
style: computeTextStyle,
|
||
);
|
||
}
|
||
}
|
||
}
|