diff --git a/notes/flutter_web/lib/routes.g.dart b/notes/flutter_web/lib/routes.g.dart index 5f73b9b8..98a73055 100644 --- a/notes/flutter_web/lib/routes.g.dart +++ b/notes/flutter_web/lib/routes.g.dart @@ -25,7 +25,7 @@ import 'package:flutter_web/routes/notes/state/StatefulBuilder/page.dart' as _St import 'package:flutter_web/routes/notes/media&assets&file/file_desktop/page.dart' as _file_desktop_page; import 'package:flutter_web/routes/notes/media&assets&file/file_web/page.dart' as _file_web_page; import 'package:flutter_web/routes/notes/media&assets&file/assets/page.dart' as _assets_page; -import 'package:flutter_web/routes/notes/style&theming/material3/page.dart' as _material3_page; +import 'package:flutter_web/routes/notes/style&theming/colors/page.dart' as _colors_page; import 'package:flutter_web/routes/notes/pure_dart/dart3/page.dart' as _dart3_page; import 'package:flutter_web/routes/notes/pure_dart/async/page.dart' as _async_page; import 'package:flutter_web/routes/notes/pure_dart/safe_interface/page.dart' as _safe_interface_page; @@ -81,9 +81,7 @@ mixin RoutesMixin { ToNote('assets', page: _assets_page.build), ]), ToNote('style&theming', children: [ - ToNote('material3', page: _material3_page.build), - ToNote('colors'), - ToNote('Material'), + ToNote('colors', page: _colors_page.build, pageAnno: _Pages.notes_style_theming_colors), ]), ToNote('pure_dart', children: [ ToNote('dart3', page: _dart3_page.build), @@ -154,7 +152,7 @@ mixin RoutesMixin { late final ToNote routes_notes_media_assets_file_file_desktop = (root.find('/notes/media&assets&file/file_desktop')! as ToNote); late final ToNote routes_notes_media_assets_file_file_web = (root.find('/notes/media&assets&file/file_web')! as ToNote); late final ToNote routes_notes_media_assets_file_assets = (root.find('/notes/media&assets&file/assets')! as ToNote); - late final ToNote routes_notes_style_theming_material3 = (root.find('/notes/style&theming/material3')! as ToNote); + late final ToNote routes_notes_style_theming_colors = (root.find('/notes/style&theming/colors')! as ToNote); late final ToNote routes_notes_pure_dart_dart3 = (root.find('/notes/pure_dart/dart3')! as ToNote); late final ToNote routes_notes_pure_dart_async = (root.find('/notes/pure_dart/async')! as ToNote); late final ToNote routes_notes_pure_dart_safe_interface = (root.find('/notes/pure_dart/safe_interface')! as ToNote); @@ -188,5 +186,6 @@ class Routes with RoutesMixin {} class _Pages { static const notes = NoteAnnotation(label: "笔记"); + static const notes_style_theming_colors = NoteAnnotation(label: "Color roles", publish: true); static const notes_widgets_specific_widgets_button = NoteAnnotation(label: "按钮", publish: true); } diff --git a/notes/flutter_web/lib/routes/layout.dart b/notes/flutter_web/lib/routes/layout.dart index 986dc0e3..76d489f6 100644 --- a/notes/flutter_web/lib/routes/layout.dart +++ b/notes/flutter_web/lib/routes/layout.dart @@ -4,7 +4,7 @@ import 'package:you_flutter/better_ui.dart'; import 'package:you_flutter/note.dart'; import 'package:you_flutter/router.dart'; import 'package:you_flutter/state.dart'; -import 'package:url_launcher/url_launcher.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; /// [LayoutBuilder] Widget build(BuildContext context, Widget child) { @@ -184,7 +184,7 @@ extension _NoteTreeNode on To { } Future _launchUrl(Uri url) async { - if (!await launchUrl(url)) { + if (!await url_launcher.launchUrl(url)) { throw Exception('Could not launch $url'); } } @@ -274,6 +274,7 @@ class _ThemeViewState extends State<_ThemeView> { @override Widget build(BuildContext context) { + final route = YouRouter.of(context); final colors = Theme.of(context).colorScheme; List getChildrenColors(MaterialColor e) { @@ -300,8 +301,10 @@ class _ThemeViewState extends State<_ThemeView> { ]), ), const Divider(), - const SizedBox(height: 20,), + const SizedBox( + height: 20, + ), const Text("Theme mode"), Card( child: Watch((context) { @@ -319,7 +322,9 @@ class _ThemeViewState extends State<_ThemeView> { ); }), ), - const SizedBox(height: 20,), + const SizedBox( + height: 20, + ), const Text("Theme color seed"), Column( crossAxisAlignment: CrossAxisAlignment.center, @@ -332,6 +337,12 @@ class _ThemeViewState extends State<_ThemeView> { }), ], ).paddingAll$(10), + FilledButton( + onPressed: () { + route.to(routes.routes_notes_style_theming_colors.toUri()); + }, + child: const Text("open Material 3 color roles page")), + ], ).constrainedBox$( constraints: const BoxConstraints.tightFor(width: 280), diff --git a/notes/flutter_web/lib/routes/notes/style&theming/Material/sample1.dart b/notes/flutter_web/lib/routes/notes/style&theming/Material/sample1.dart deleted file mode 100644 index 3fceff34..00000000 --- a/notes/flutter_web/lib/routes/notes/style&theming/Material/sample1.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(const App()); - -// how to understand Material class? -class App extends StatelessWidget { - const App({super.key}); - - @override - Widget build(BuildContext context) { - var material = const Material( - color: Colors.blue, - child: Center( - child: Text( - 'xxxxx', - // style: Theme.of(context).textTheme.headline4, - textAlign: TextAlign.center, - ), - ), - ); - return MaterialApp( - theme: ThemeData.dark().copyWith(useMaterial3: true), - home: Scaffold( - body: material, - ), - ); - } -} diff --git a/notes/flutter_web/lib/routes/notes/style&theming/colors/page.dart b/notes/flutter_web/lib/routes/notes/style&theming/colors/page.dart new file mode 100644 index 00000000..0fc7674a --- /dev/null +++ b/notes/flutter_web/lib/routes/notes/style&theming/colors/page.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:you_flutter/better_ui.dart'; +import 'package:you_flutter/note.dart'; + +@NoteAnnotation(label: "Color roles",publish: true) +void build(BuildContext context, Cell print) { + final colors = Theme.of(context).colorScheme; + print(const MD(r''' +# Color roles + +ref + +- + + ''')); + + print( + Column( + children: [ + Wrap( + children: [ + ColorChip(label: "primary", color: colors.primary, onColors: [ColorItem(label: "onPrimary", color: colors.onPrimary)]), + ColorChip(label: "secondary", color: colors.secondary, onColors: [ColorItem(label: "onSecondary", color: colors.onSecondary)]), + ColorChip(label: "tertiary", color: colors.tertiary, onColors: [ColorItem(label: "onTertiary", color: colors.onTertiary)]), + ], + ), + Wrap( + children: [ + ColorChip(label: "primaryContainer", color: colors.primaryContainer, onColors: [ColorItem(label: "onPrimaryContainer", color: colors.onPrimaryContainer)]), + ColorChip(label: "secondaryContainer", color: colors.secondaryContainer, onColors: [ColorItem(label: "onSecondaryContainer", color: colors.onSecondaryContainer)]), + ColorChip(label: "tertiaryContainer", color: colors.tertiaryContainer, onColors: [ColorItem(label: "onTertiaryContainer", color: colors.onTertiaryContainer)]), + ], + ), + Wrap( + children: [ + ColorChip(label: "primaryFixed", color: colors.primaryFixed, onColors: [ColorItem(label: "onPrimaryFixed", color: colors.onPrimaryFixed)]), + ColorChip(label: "secondaryFixed", color: colors.secondaryFixed, onColors: [ColorItem(label: "onSecondaryFixed", color: colors.onSecondaryFixed)]), + ColorChip(label: "tertiaryFixed", color: colors.tertiaryFixed, onColors: [ColorItem(label: "onTertiaryFixed", color: colors.onTertiaryFixed)]), + ], + ), + Wrap( + children: [ + ColorChip(label: "primaryFixedDim", color: colors.primaryFixedDim, onColors: [ + ColorItem(label: "onPrimaryFixed", color: colors.onPrimaryFixed), + ColorItem(label: "onPrimaryFixedVariant", color: colors.onPrimaryFixedVariant), + ]), + ColorChip(label: "secondaryFixedDim", color: colors.secondaryFixedDim, onColors: [ + ColorItem(label: "onSecondaryFixed", color: colors.onSecondaryFixed), + ColorItem(label: "onSecondaryFixedVariant", color: colors.onSecondaryFixedVariant), + ]), + ColorChip(label: "tertiaryFixedDim", color: colors.tertiaryFixedDim, onColors: [ + ColorItem(label: "onTertiaryFixed", color: colors.onTertiaryFixed), + ColorItem(label: "onTertiaryFixedVariant", color: colors.onTertiaryFixedVariant), + ]), + ], + ), + Wrap( + children: [ + ColorChip(label: "error", color: colors.error, onColors: [ColorItem(label: "onError", color: colors.onError)]), + ColorChip(label: "errorContainer", color: colors.errorContainer, onColors: [ColorItem(label: "onError", color: colors.onErrorContainer)]), + ], + ), + Wrap( + children: [ + ColorChip(label: "surface", color: colors.surface, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceBright", color: colors.surfaceBright, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceDim", color: colors.surfaceDim, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ], + ), + Wrap( + children: [ + ColorChip(label: "surfaceContainerHighest", color: colors.surfaceContainerHighest, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceContainerHigh", color: colors.surfaceContainerHigh, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceContainer", color: colors.surfaceContainer, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceContainerLow", color: colors.surfaceContainerLow, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ColorChip(label: "surfaceContainerLowest", color: colors.surfaceContainerLowest, onColors: [ + ColorItem(label: "onSurface", color: colors.onSurface), + ColorItem(label: "onSurfaceVariant", color: colors.onSurfaceVariant), + ColorItem(label: "outline", color: colors.outline), + ColorItem(label: "outlineVariant", color: colors.outlineVariant), + ]), + ], + ), + ColorChip(label: "inverseSurface", color: colors.inverseSurface, onColors: [ + ColorItem(label: "onInverseSurface", color: colors.onInverseSurface), + ColorItem(label: "inversePrimary", color: colors.inversePrimary), + ]), + ], + ), + ); +} + +class ColorItem extends StatelessWidget { + const ColorItem({ + super.key, + required this.label, + required this.color, + }); + + final String label; + final Color color; + + @override + Widget build(BuildContext context) { + return Container( + alignment: Alignment.center, + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + // Container(color: color, width: 12, height: 12), + const SizedBox(width: 2), + Container(alignment: Alignment.center, child: Text(label, style: TextStyle(color: color))).borderAll$(), + ], + ).borderAll$(color: color), + ); + } +} + +class ColorChip extends StatelessWidget { + const ColorChip({ + super.key, + required this.label, + required this.color, + this.onColors = const [], + }); + + final Color color; + final List onColors; + final String label; + + static Color contrastColor(Color color) { + final Brightness brightness = ThemeData.estimateBrightnessForColor(color); + return brightness == Brightness.dark ? Colors.white : Colors.black; + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SizedBox(child: Text(label)), + Container( + // width: 200, + color: color, + child: Padding( + padding: const EdgeInsets.all(2), + child: Column( + children: [ + for (var onColor in onColors) onColor.marginAll$(4), + ], + ), + ), + ) + + ], + ).marginAll$(4).intrinsicWidth$(stepWidth: 200); + } +} diff --git a/notes/flutter_web/lib/routes/notes/style&theming/colors/index.md b/notes/flutter_web/lib/routes/notes/style&theming/index.md similarity index 92% rename from notes/flutter_web/lib/routes/notes/style&theming/colors/index.md rename to notes/flutter_web/lib/routes/notes/style&theming/index.md index ce5aa993..e1d32812 100644 --- a/notes/flutter_web/lib/routes/notes/style&theming/colors/index.md +++ b/notes/flutter_web/lib/routes/notes/style&theming/index.md @@ -12,4 +12,10 @@ Chroma(色度/ch彩度/纯度): 彩度或纯度指的是颜色的纯净程度或鲜艳程度,也就是颜色偏离灰色的程度。一个颜色的彩度越高,它就越接近该色相的最纯净形式,看起来越鲜艳、生动;反之,彩度越低,则颜色看起来越灰暗、浑浊。在不同的色彩模型中,彩度可能有不同的表达方式,例如在HSV色彩模型中,这个属性被称为饱和度(Saturation)。 Tone(色调): -不同于传统意义上的色调(即Hue色相),Tone更贴近于色彩的亮度或明暗程度,但它是在考虑了人对颜色感知的基础上,结合了色相和彩度调整的一个属性。在HCT色彩空间中,Tone可以帮助调整颜色使其适应不同的视觉环境,增强可读性和感知一致性,尤其适用于用户界面设计等领域。简而言之,Tone帮助调节颜色的整体明暗感受,使得颜色在不同背景下保持其特性的同时,更加和谐易读。 \ No newline at end of file +不同于传统意义上的色调(即Hue色相),Tone更贴近于色彩的亮度或明暗程度,但它是在考虑了人对颜色感知的基础上,结合了色相和彩度调整的一个属性。在HCT色彩空间中,Tone可以帮助调整颜色使其适应不同的视觉环境,增强可读性和感知一致性,尤其适用于用户界面设计等领域。简而言之,Tone帮助调节颜色的整体明暗感受,使得颜色在不同背景下保持其特性的同时,更加和谐易读。 + +## Material3 + +> Material3 组件索引参考: +> + diff --git a/notes/flutter_web/lib/routes/notes/style&theming/material3/page.dart b/notes/flutter_web/lib/routes/notes/style&theming/material3/page.dart deleted file mode 100644 index 01a20ba0..00000000 --- a/notes/flutter_web/lib/routes/notes/style&theming/material3/page.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:you_flutter/note.dart'; - -void build(BuildContext context, Cell print) { - print(const MD(r''' -# Material3 - -> Material3 组件索引参考: -> - - - - ''')); -} diff --git a/packages/you_flutter/lib/src/better_ui.dart b/packages/you_flutter/lib/src/better_ui.dart index 7aff9ec2..959573d4 100644 --- a/packages/you_flutter/lib/src/better_ui.dart +++ b/packages/you_flutter/lib/src/better_ui.dart @@ -92,6 +92,11 @@ final class BetterUI { } extension StyleExtension on Widget { + /// Warp a [Padding] + Widget marginAll$(double value) { + return Container(margin: EdgeInsets.all(value), child: this); + } + /// Warp a [Padding] Widget padding$(EdgeInsetsGeometry padding) => Padding(padding: padding, child: this); diff --git a/packages/you_flutter/lib/src/note/contents/contents.dart b/packages/you_flutter/lib/src/note/contents/contents.dart index 396824ab..88eb20c4 100644 --- a/packages/you_flutter/lib/src/note/contents/contents.dart +++ b/packages/you_flutter/lib/src/note/contents/contents.dart @@ -1,15 +1,24 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:you_flutter/src/note/contents/markdown_content.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; -final Contents contents=Contents._(); -class Contents{ +final Contents contents = Contents._(); + +class Contents { Contents._(); + Widget contentToWidget(content) { return switch (content) { - MD _ => MarkdownBody(data: content.text), + MD _ => MarkdownBody( + data: content.text, + onTapLink: (String text, String? href, String title) async { + if (href == null) return; + await url_launcher.launchUrl(Uri.parse(href)); + }, + ), Widget _ => content, _ => Text("$content"), }; } -} \ No newline at end of file +} diff --git a/packages/you_flutter/lib/src/note/contents/markdown_content.dart b/packages/you_flutter/lib/src/note/contents/markdown_content.dart index 2168a00e..e4ae4e53 100644 --- a/packages/you_flutter/lib/src/note/contents/markdown_content.dart +++ b/packages/you_flutter/lib/src/note/contents/markdown_content.dart @@ -3,8 +3,10 @@ import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:markdown/markdown.dart' as md; import 'package:meta/meta.dart'; import 'package:you_flutter/src/note/contents/outline.dart'; + // import 'package:you_flutter/src/note/flutter_highlight.dart'; // import 'package:flutter_highlight/themes/vs2015.dart'; +import 'package:url_launcher/url_launcher.dart' as url_launcher; class MD extends StatelessWidget { final String text; @@ -36,7 +38,10 @@ class MarkdownContent extends StatelessWidget { // 得研究下controller层层嵌套要怎么用 // controller: controller, shrinkWrap: true, - + onTapLink: (String text, String? href, String title)async { + if (href == null) return; + await url_launcher.launchUrl(Uri.parse(href)); + }, builders: { 'h1': headerBuilder, 'h2': headerBuilder, diff --git a/packages/you_flutter/pubspec.yaml b/packages/you_flutter/pubspec.yaml index d5f28274..b1dc2055 100644 --- a/packages/you_flutter/pubspec.yaml +++ b/packages/you_flutter/pubspec.yaml @@ -25,6 +25,7 @@ dependencies: source_map_stack_trace: ^2.1.1 source_maps: ^0.10.12 stack_trace: ^1.11.1 + url_launcher: ^6.2.6 you_dart: ^0.0.5