surface static method
Implementation
static String surface() => r'''
import 'dart:ui';
import 'package:flutter/material.dart';
import '../styles/design_style_config.dart';
import '../themes/app_theme_extensions.dart';
import '../tokens/app_blur.dart';
import '../tokens/app_colors.dart';
import '../tokens/app_motion.dart';
import '../tokens/app_radius.dart';
import '../tokens/app_shadows.dart';
import '../tokens/app_spacing.dart';
enum AppSurfaceDepth { flat, raised, floating, pressed, inset }
class AppSurface extends StatelessWidget {
const AppSurface({
super.key,
required this.child,
this.padding,
this.margin,
this.depth = AppSurfaceDepth.raised,
this.radius,
this.onTap,
this.semanticLabel,
this.width,
this.height,
});
final Widget child;
final EdgeInsetsGeometry? padding;
final EdgeInsetsGeometry? margin;
final AppSurfaceDepth depth;
final double? radius;
final VoidCallback? onTap;
final String? semanticLabel;
final double? width;
final double? height;
static bool allowExpensiveEffects(BuildContext context) {
final data = MediaQuery.maybeOf(context);
if (data == null) return true;
if (data.disableAnimations) return false;
return true;
}
@override
Widget build(BuildContext context) {
final surfaces = Theme.of(context).extension<AppSurfaceTheme>();
final radiusValue = radius ?? AppRadius.md;
final borderRadius = BorderRadius.circular(radiusValue);
final useBlur = AppStyleConfig.usesBlur &&
allowExpensiveEffects(context) &&
depth != AppSurfaceDepth.pressed &&
depth != AppSurfaceDepth.flat;
final sigma = depth == AppSurfaceDepth.floating
? AppBlur.large
: AppBlur.medium;
final decoration = _decoration(context, surfaces, borderRadius);
final content = Padding(
padding: padding ?? const EdgeInsets.all(AppSpacing.md),
child: child,
);
Widget painted = AnimatedContainer(
duration: AppMotion.fast,
curve: AppMotion.standardCurve,
width: width,
height: height,
decoration: useBlur ? decoration.copyWith(color: Colors.transparent) : decoration,
child: content,
);
if (useBlur) {
painted = ClipRRect(
borderRadius: borderRadius,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: sigma, sigmaY: sigma),
child: DecoratedBox(
decoration: decoration,
child: content,
),
),
);
}
if (AppStyleConfig.usesLiquidHighlight) {
painted = Stack(
children: <Widget>[
painted,
Positioned.fill(
child: IgnorePointer(
child: DecoratedBox(
decoration: BoxDecoration(
borderRadius: borderRadius,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: <Color>[
(surfaces?.highlight ?? AppColors.highlight)
.withAlpha(140),
Colors.transparent,
(surfaces?.highlight ?? AppColors.highlight)
.withAlpha(30),
],
),
),
),
),
),
],
);
}
if (AppStyleConfig.usesSpatialDepth &&
(depth == AppSurfaceDepth.floating ||
depth == AppSurfaceDepth.raised)) {
final scale = depth == AppSurfaceDepth.floating ? 1.02 : 1.0;
painted = AnimatedScale(
scale: scale,
duration: AppMotion.normal,
curve: AppMotion.entranceCurve,
child: painted,
);
}
if (onTap != null) {
painted = Material(
type: MaterialType.transparency,
child: InkWell(
onTap: onTap,
borderRadius: borderRadius,
child: painted,
),
);
}
if (semanticLabel != null) {
painted = Semantics(
label: semanticLabel,
button: onTap != null,
child: painted,
);
}
if (margin != null) {
painted = Padding(padding: margin!, child: painted);
}
return painted;
}
BoxDecoration _decoration(
BuildContext context,
AppSurfaceTheme? surfaces,
BorderRadius borderRadius,
) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final base = isDark ? AppColorsDark.surface : AppColors.surface;
final elevated =
isDark ? AppColorsDark.surfaceElevated : AppColors.surfaceElevated;
final translucent = surfaces?.surfaceTranslucent ??
(isDark
? AppColorsDark.surfaceTranslucent
: AppColors.surfaceTranslucent);
final outline = isDark ? AppColorsDark.outline : AppColors.outline;
Color color;
switch (depth) {
case AppSurfaceDepth.flat:
color = surfaces?.background ??
(isDark ? AppColorsDark.background : AppColors.background);
break;
case AppSurfaceDepth.floating:
color = elevated;
break;
case AppSurfaceDepth.pressed:
case AppSurfaceDepth.inset:
color = isDark
? AppColorsDark.surfaceVariant
: AppColors.surfaceVariant;
break;
case AppSurfaceDepth.raised:
color = base;
break;
}
if (AppStyleConfig.usesBlur &&
allowExpensiveEffects(context) &&
AppStyleConfig.reducedTransparencyFallback == false) {
color = translucent;
} else if (AppStyleConfig.usesBlur &&
!allowExpensiveEffects(context)) {
color = elevated;
}
Gradient? gradient;
if (AppStyleConfig.usesSkeuoGradient) {
gradient = LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: <Color>[
Color.lerp(color, Colors.white, 0.22)!,
color,
Color.lerp(color, Colors.black, 0.08)!,
],
);
}
return BoxDecoration(
color: gradient == null ? color : null,
gradient: gradient,
borderRadius: borderRadius,
border: _border(outline),
boxShadow: _shadows(),
);
}
Border? _border(Color outline) {
if (AppStyleConfig.usesHardOffsetShadow) {
return Border.all(color: outline, width: 3);
}
if (AppStyleConfig.usesBlur || AppStyleConfig.usesLiquidHighlight) {
return Border.all(
color: AppColors.highlight.withAlpha(140),
width: 1,
);
}
if (AppStyleConfig.usesNeoShadows) {
return null;
}
return Border.all(
color: AppColors.outlineVariant,
width: 1,
);
}
List<BoxShadow> _shadows() {
if (depth == AppSurfaceDepth.flat) return const <BoxShadow>[];
if (AppStyleConfig.usesNeoShadows) {
return depth == AppSurfaceDepth.pressed || depth == AppSurfaceDepth.inset
? AppShadows.neoInset
: AppShadows.neoRaised;
}
if (AppStyleConfig.usesHardOffsetShadow) {
return depth == AppSurfaceDepth.pressed
? const <BoxShadow>[]
: AppShadows.hardOffset;
}
if (AppStyleConfig.usesClayInflation) {
return AppShadows.clay;
}
switch (depth) {
case AppSurfaceDepth.floating:
return AppShadows.floating;
case AppSurfaceDepth.raised:
return AppShadows.medium;
case AppSurfaceDepth.pressed:
case AppSurfaceDepth.inset:
return AppShadows.low;
case AppSurfaceDepth.flat:
return const <BoxShadow>[];
}
}
}
''';