Files
eatvio_app/lib/features/diets/presentation/widgets/expandable_text.dart

134 lines
4.2 KiB
Dart

import 'dart:math' as math;
import 'package:eatvio_app/generated/l10n.dart';
import 'package:eatvio_app/core/theme/custom_text_style.dart';
import 'package:eatvio_app/core/theme/theme_helper.dart';
import 'package:eatvio_app/core/widgets/markdown_html_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class ExpandableText extends StatefulWidget {
final String text;
final int maxLines;
const ExpandableText({
super.key,
required this.text,
this.maxLines = 5, // по умолчанию 5 строк
});
@override
State<ExpandableText> createState() => _ExpandableTextState();
}
class _ExpandableTextState extends State<ExpandableText> {
bool isExpanded = false;
bool showExpandButton = false;
final GlobalKey _textKey = GlobalKey();
@override
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance.addPostFrameCallback((_) => _checkTextOverflow());
}
void _checkTextOverflow() {
final textRenderObject = _textKey.currentContext?.findRenderObject();
if (textRenderObject is RenderBox) {
final fontSize = TextStyles.textMMediumAuto.fontSize ?? 16;
final lineHeight = fontSize * 1.5;
final maxLinesHeight = widget.maxLines * lineHeight;
final actualHeight = textRenderObject.size.height;
if (actualHeight > maxLinesHeight && !showExpandButton) {
setState(() {
showExpandButton = true;
});
}
}
}
void toggleExpansion() {
setState(() {
isExpanded = !isExpanded;
});
}
@override
Widget build(BuildContext context) {
final s = S.of(context);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: AnimatedSize(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
child: Stack(
children: [
ClipRect(
child: ConstrainedBox(
constraints: BoxConstraints(
maxHeight: isExpanded ? double.infinity : (widget.maxLines * (TextStyles.textMMediumAuto.fontSize ?? 16) * 1.5),
),
child: MarkdownHtmlWidget(
key: _textKey,
markdownText: widget.text,
fontSize: TextStyles.textMMediumAuto.fontSize ?? 16,
textColor: appTheme.black,
),
),
),
if (!isExpanded && showExpandButton)
Positioned.fill(
child: Align(
alignment: Alignment.bottomCenter,
child: Container(
height: 35,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.white.withAlpha(0),
Colors.white.withAlpha((255 * 0.6).toInt()),
Colors.white,
],
),
),
),
),
),
],
),
),
),
if (showExpandButton)
Align(
alignment: Alignment.bottomCenter,
child: GestureDetector(
onTap: toggleExpansion,
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
isExpanded ? s.hide : s.expand,
style: TextStyles.textMMedium.copyWith(color: appTheme.blueA400),
),
const SizedBox(width: 4),
Transform.rotate(
angle: isExpanded ? math.pi : 0,
child: SvgPicture.asset('assets/icons/arrow_down.svg', width: 12, height: 12),
),
],
),
),
),
],
);
}
}